Beispiel #1
0
 public void ResolveEnumReference(HmdEnum hmdEnum)
 {
     if (hmdEnum == null)
     {
         throw new ArgumentNullException("hmdEnum");
     }
     this.enumReference = hmdEnum;
 }
Beispiel #2
0
 public void AddEnum(HmdEnum newEnum)
 {
     if (enumList == null)
     {
         enumList = new List <HmdEnum>();
     }
     enumList.Add(newEnum);
 }
Beispiel #3
0
        public void ValidateHmdEnum(HmdEnum hmdEnum, String name, params String[] values)
        {
            Assert.IsTrue(hmdEnum.name.Equals(name, StringComparison.CurrentCultureIgnoreCase));

            Assert.AreEqual(values.Length, hmdEnum.ValueCount);
            for (int i = 0; i < values.Length; i++)
            {
                Assert.IsTrue(hmdEnum.IsValidEnumValue(values[i]));
            }
        }
        public String GetTypeName(HmdEnum hmdEnum)
        {
            String typeName;

            if (!enumDictionary.TryGetValue(hmdEnum, out typeName))
            {
                typeName = GenerateEnumIDTypeName(hmdEnum);
                enumDictionary.Add(hmdEnum, typeName);
            }
            return(typeName);
        }
Beispiel #5
0
        public void HmdEnumReferenceInlineTest()
        {
            HmdEnum hmdEnum;

            hmdEnum = new HmdEnum(null, "  \n\n full\t\t  high");
            Assert.IsTrue(hmdEnum.IsValidEnumValue("high"));
            Assert.IsTrue(hmdEnum.IsValidEnumValue("HIGH"));
            Assert.IsTrue(hmdEnum.IsValidEnumValue("full"));
            Assert.IsTrue(hmdEnum.IsValidEnumValue("FuLl"));

            hmdEnum = new HmdEnum(null, "  a1234");
            Assert.IsTrue(hmdEnum.IsValidEnumValue("a1234"));
            Assert.IsTrue(hmdEnum.IsValidEnumValue("A1234"));
        }
Beispiel #6
0
        public static void TestPropertyParserInlineEnum(String propertyString, params String[] values)
        {
            HmdValueIDProperties valueIDProperties = CallParserWithDefaults(propertyString, TestPropertyDictionary);

            VerifyValueProperties(String.Empty, valueIDProperties, UnrestrictedCount.Instance, HmdType.Enumeration, "");

            //
            // Verify enum values
            //
            HmdEnumReference hmdEnumReference = valueIDProperties.EnumReference;
            HmdEnum          hmdEnum          = hmdEnumReference.TryGetReference;

            Assert.IsNotNull(hmdEnum);
            for (int i = 0; i < values.Length; i++)
            {
                Assert.IsTrue(hmdEnum.IsValidEnumValue(values[i]));
            }
        }
Beispiel #7
0
 public void PrintEnums(TextWriter output)
 {
     if (enumList == null || enumList.Count <= 0)
     {
         output.WriteLine("Enums Defined: NONE");
     }
     else
     {
         output.WriteLine("Enums Defined:");
         for (int i = 0; i < enumList.Count; i++)
         {
             HmdEnum hmdEnum = enumList[i];
             output.Write("   {0}:", hmdEnum.name);
             for (int j = 0; j < hmdEnum.ValueCount; j++)
             {
                 output.Write(" {0}", hmdEnum.GetValue(j));
             }
             output.WriteLine();
         }
     }
 }
Beispiel #8
0
        public Boolean IsValidValue(String value, HmdProperties hmdProperties)
        {
            switch (hmdType)
            {
            case HmdType.String:
                return(true);

            case HmdType.Boolean:
                return(value.Equals("true", StringComparison.CurrentCultureIgnoreCase) ||
                       value.Equals("false", StringComparison.CurrentCultureIgnoreCase));

            case HmdType.Int:
                return(value.IsValidInteger(false, 4));

            case HmdType.Int1:
                return(value.IsValidInteger(false, 1));

            case HmdType.Int2:
                return(value.IsValidInteger(false, 2));

            case HmdType.Int3:
                return(value.IsValidInteger(false, 3));

            case HmdType.Int4:
                return(value.IsValidInteger(false, 4));

            case HmdType.Int5:
                return(value.IsValidInteger(false, 5));

            case HmdType.Int6:
                return(value.IsValidInteger(false, 6));

            case HmdType.Int7:
                return(value.IsValidInteger(false, 7));

            case HmdType.Int8:
                return(value.IsValidInteger(false, 8));

            case HmdType.Int9:
                return(value.IsValidInteger(false, 9));

            case HmdType.Int10:
                return(value.IsValidInteger(false, 10));

            case HmdType.Int11:
                return(value.IsValidInteger(false, 11));

            case HmdType.Int12:
                return(value.IsValidInteger(false, 12));

            case HmdType.Int13:
                return(value.IsValidInteger(false, 13));

            case HmdType.Int14:
                return(value.IsValidInteger(false, 14));

            case HmdType.Int15:
                return(value.IsValidInteger(false, 15));

            case HmdType.Int16:
                return(value.IsValidInteger(false, 16));

            case HmdType.UInt:
                return(value.IsValidInteger(true, 4));

            case HmdType.UInt1:
                return(value.IsValidInteger(true, 1));

            case HmdType.UInt2:
                return(value.IsValidInteger(true, 2));

            case HmdType.UInt3:
                return(value.IsValidInteger(true, 3));

            case HmdType.UInt4:
                return(value.IsValidInteger(true, 4));

            case HmdType.UInt5:
                return(value.IsValidInteger(true, 5));

            case HmdType.UInt6:
                return(value.IsValidInteger(true, 6));

            case HmdType.UInt7:
                return(value.IsValidInteger(true, 7));

            case HmdType.UInt8:
                return(value.IsValidInteger(true, 8));

            case HmdType.UInt9:
                return(value.IsValidInteger(true, 9));

            case HmdType.UInt10:
                return(value.IsValidInteger(true, 10));

            case HmdType.UInt11:
                return(value.IsValidInteger(true, 11));

            case HmdType.UInt12:
                return(value.IsValidInteger(true, 12));

            case HmdType.UInt13:
                return(value.IsValidInteger(true, 13));

            case HmdType.UInt14:
                return(value.IsValidInteger(true, 14));

            case HmdType.UInt15:
                return(value.IsValidInteger(true, 15));

            case HmdType.UInt16:
                return(value.IsValidInteger(true, 16));

            case HmdType.Decimal:
                throw new NotImplementedException();

            case HmdType.Enumeration:
                HmdEnum hmdEnum = enumReference.TryGetReference;
                if (hmdEnum == null)
                {
                    hmdEnum = hmdProperties.TryGetEnum(enumReference.Name);
                    if (hmdEnum == null)
                    {
                        throw new InvalidOperationException(String.Format("Can't resolve enum reference '{0}'", enumReference.Name));
                    }
                    this.enumReference = hmdEnum;
                }
                return(hmdEnum.IsValidEnumValue(value.Trim()));

            case HmdType.Empty:
                throw new InvalidOperationException("Cannot validate the type of a null type");

            default:
                throw new InvalidOperationException(String.Format("HmdType {0} ({1}) is unrecognized", hmdType, (Int32)hmdType));
            }
        }
        private String GenerateEnumIDTypeName(HmdEnum hmdEnum)
        {
            String nameWithoutRoot = (hmdEnum.name[0] == '%') ? hmdEnum.name.Substring(6) : hmdEnum.name;

            return(nameWithoutRoot.Replace(".", String.Empty));
        }
        public void GenerateParserClasses(TextWriter output, HmdBlockIDProperties block,
                                          HmdProperties hmdProperties, String hmdTypePrefix, Boolean isRoot)
        {
            String className = isRoot ? rootClassName : (hmdTypePrefix + typeNameTable.GetTypeName(block));

            //
            // Generate the class for the current block
            //
            int tabs = 1;

            output.WriteLine(tabs, "public class {0}", className);
            output.WriteLine(tabs++, "{");

            //
            // Print Fields
            //
            foreach (HmdIDProperties childIDProperties in block)
            {
                if (childIDProperties.isBlock)
                {
                    HmdBlockIDProperties childBlockProperties = childIDProperties.CastAsBlockIDProperties;

                    String type = hmdTypePrefix + typeNameTable.GetTypeName(childBlockProperties);

                    if (childBlockProperties.CountProperty.Multiple)
                    {
                        type = languageGenerator.ListType(type);
                    }

                    output.WriteLine(tabs, "public {0} {1};", type, childBlockProperties.idOriginalCase);
                }
                else
                {
                    HmdValueIDProperties childValueProperties = childIDProperties.CastAsValueIDProperties;
                    if (childValueProperties.hmdType != HmdType.Empty)
                    {
                        String type;
                        if (childValueProperties.hmdType == HmdType.Enumeration)
                        {
                            HmdEnum hmdEnum = childValueProperties.EnumReference.TryGetReference;
                            if (hmdEnum == null)
                            {
                                hmdEnum = hmdProperties.TryGetEnum(childValueProperties.EnumReference.Name);
                                if (hmdEnum == null)
                                {
                                    throw new FormatException(String.Format("Can't resolve enum reference '{0}'", childValueProperties.EnumReference.Name));
                                }
                                childValueProperties.ResolveEnumReference(hmdEnum);
                            }
                            type = typeNameTable.GetTypeName(hmdEnum);
                        }
                        else
                        {
                            type = languageGenerator.HmdTypeToLanguageType(childValueProperties.hmdType);
                        }

                        if (childValueProperties.CountProperty.Multiple)
                        {
                            type = languageGenerator.ListType(type);
                        }
                        output.WriteLine(tabs, "public {0} {1};", type, childValueProperties.idOriginalCase);
                    }
                }
            }

            //
            // Print Constructor
            //
            output.WriteLine(tabs, "public {0}(HmdBlockID blockID, HmdProperties hmdProperties)", className);
            output.WriteLine(tabs++, "{");
            output.WriteLine(tabs, "for(int i = 0; i < blockID.ChildCount; i++)");
            output.WriteLine(tabs++, "{");
            output.WriteLine(tabs, "HmdID childID = blockID.GetChild(i);");
            output.WriteLine(tabs, "if(childID.isBlock)");
            output.WriteLine(tabs++, "{");
            output.WriteLine(tabs, "HmdBlockID childBlockID = (HmdBlockID)childID;");
            Int32 blockChildCount = 0;

            foreach (HmdIDProperties childIDProperties in block)
            {
                if (childIDProperties.isBlock)
                {
                    HmdBlockIDProperties childBlockProperties = childIDProperties.CastAsBlockIDProperties;
                    blockChildCount++;

                    output.WriteLine(tabs, "// parse field {0}", childIDProperties.idOriginalCase);
                    output.WriteLine(tabs, "{0}if(childBlockID.idLowerCase.Equals(\"{1}\",StringComparison.CurrentCultureIgnoreCase))", blockChildCount > 1 ? "else " : String.Empty, childIDProperties.idLowerCase);
                    output.WriteLine(tabs++, "{");
                    if (childIDProperties.CountProperty.Multiple)
                    {
                        output.WriteLine(tabs, "// set List to not null");
                        output.WriteLine(tabs, "this.{0}.Add(new {1}{2}(childBlockID, hmdProperties));",
                                         childIDProperties.idOriginalCase, hmdTypePrefix, typeNameTable.GetTypeName(childBlockProperties));
                    }
                    else
                    {
                        output.WriteLine(tabs, "// check that field is not set already");
                        output.WriteLine(tabs, "if(this.{0} != null)", childIDProperties.idOriginalCase);
                        output.WriteLine(tabs++, "{");
                        output.WriteLine(tabs, "throw new FormatException(\"Found multiple block id's \\\"{0}\\\"\");", childIDProperties.idOriginalCase);
                        output.WriteLine(--tabs, "}");
                        output.WriteLine(tabs, "this.{0} = new {1}{2}(childBlockID, hmdProperties);",
                                         childIDProperties.idOriginalCase, hmdTypePrefix, typeNameTable.GetTypeName(childBlockProperties));
                    }
                    output.WriteLine(--tabs, "}");
                }
            }
            if (blockChildCount > 0)
            {
                output.WriteLine(tabs, "else");
                output.WriteLine(tabs++, "{");
            }
            output.WriteLine(tabs, "throw new FormatException(String.Format(\"Unrecognized child block id \\\"{0}\\\"\",childID.idOriginalCase));");
            if (blockChildCount > 0)
            {
                output.WriteLine(--tabs, "}");
            }
            output.WriteLine(--tabs, "}");
            output.WriteLine(tabs, "else");
            output.WriteLine(tabs++, "{");
            output.WriteLine(tabs, "HmdValueID childValueID = (HmdValueID)childID;");
            Int32 valueChildCount = 0;

            foreach (HmdIDProperties childIDProperties in block)
            {
                if (!childIDProperties.isBlock)
                {
                    HmdValueIDProperties childValueIDProperties = childIDProperties.CastAsValueIDProperties;
                    valueChildCount++;
                    output.WriteLine(tabs, "// parse field {0}", childIDProperties.idOriginalCase);
                    output.WriteLine(tabs, "{0}if(childValueID.idLowerCase.Equals(\"{1}\",StringComparison.CurrentCultureIgnoreCase))", valueChildCount > 1 ? "else " : String.Empty, childIDProperties.idLowerCase);
                    output.WriteLine(tabs++, "{");

                    String variableName = "childValueID.value";
                    String parseCode    = null;
                    if (childValueIDProperties.hmdType == HmdType.Enumeration)
                    {
                        parseCode = languageGenerator.GenerateStringToEnumParseCode(
                            typeNameTable.GetTypeName(childValueIDProperties.EnumReference.TryGetReference),
                            variableName);
                    }
                    else
                    {
                        parseCode = languageGenerator.GenerateStringToTypeParseCode(
                            childValueIDProperties.hmdType,
                            variableName);
                    }

                    if (childIDProperties.CountProperty.Multiple)
                    {
                        output.WriteLine(tabs, "this.{0}.Add({1});", childIDProperties.idOriginalCase, parseCode);
                    }
                    else
                    {
                        output.WriteLine(tabs, "// check that field is not set already");
                        output.WriteLine(tabs, "if(this.{0} != null)", childIDProperties.idOriginalCase);
                        output.WriteLine(tabs++, "{");
                        output.WriteLine(tabs, "throw new FormatException(\"Found multiple value id's \\\"{0}\\\"\");", childIDProperties.idOriginalCase);
                        output.WriteLine(--tabs, "}");
                        output.WriteLine(tabs, "this.{0} = {1};", childIDProperties.idOriginalCase, parseCode);
                    }
                    output.WriteLine(--tabs, "}");
                }
            }
            if (valueChildCount > 0)
            {
                output.WriteLine(tabs, "else");
                output.WriteLine(tabs++, "{");
            }
            output.WriteLine(tabs, "throw new FormatException(String.Format(\"Unrecognized child value id \\\"{0}\\\"\",childID.idOriginalCase));");
            if (valueChildCount > 0)
            {
                output.WriteLine(--tabs, "}");
            }
            output.WriteLine(--tabs, "}");

            output.WriteLine(--tabs, "}");
            output.WriteLine(--tabs, "}");
            output.WriteLine(--tabs, "}");
        }
Beispiel #11
0
        //
        // Maybe change to pass in the string offset and length?
        //
        public static HmdValueIDProperties ParseValueProperties(String idString, String props, HmdBlockIDProperties definitionParent, HmdProperties hmdProperties)
        {
            if (idString == null)
            {
                throw new ArgumentNullException("idString");
            }

            Boolean defaultCountPropertyOverriden = false;
            Boolean defaultHmdTypeOverriden       = false;

            ICountProperty countProperty = hmdProperties.defaultCountProperty;
            HmdType        hmdType       = hmdProperties.defaultHmdType;

            HmdEnumReference enumReference = null;

            HmdParentReference[] parentOverrideList = null;

            Int32 offset = 0, saveOffset;

            //
            // TODO: To save on memory, maybe I'll add some type of hash lookup so I don't have to instantiate multiple HmdType classes?
            //
            while (true)
            {
                while (true)
                {
                    if (offset >= props.Length)
                    {
                        return(new HmdValueIDProperties(idString, countProperty, hmdType, enumReference,
                                                        definitionParent, parentOverrideList));
                    }
                    if (!Char.IsWhiteSpace(props[offset]))
                    {
                        break;
                    }
                    offset++;
                }

                if (props[offset] >= '0' && props[offset] <= '9')
                {
                    saveOffset = offset;

                    // keep going while you see 0-9, '-' or '*'
                    do
                    {
                        offset++;
                        if (offset >= props.Length)
                        {
                            break;
                        }
                    } while ((props[offset] >= '0' && props[offset] <= '9') || props[offset] == '-' || props[offset] == '*');

                    //
                    // Check that the 'count' property has not been specified Twice
                    //
                    if (defaultCountPropertyOverriden)
                    {
                        throw new FormatException("You've specified the 'count' property twice!");
                    }
                    defaultCountPropertyOverriden = true;

                    countProperty = CountProperty.Parse(props.Substring(saveOffset, offset - saveOffset));
                }
                else if (props[offset] == 's')
                {
                    if (offset + 6 > props.Length) // 6 = "string".Length
                    {
                        throw new FormatException(String.Format("Found character '{0}', expected to become \"{1}\", but there are some characters missing",
                                                                HmdTypeClass.String[0], HmdTypeClass.String));
                    }

                    if (props[offset + 1] != 't' ||
                        props[offset + 2] != 'r' ||
                        props[offset + 3] != 'i' ||
                        props[offset + 4] != 'n' ||
                        props[offset + 5] != 'g')
                    {
                        throw new FormatException(String.Format("Expected 'string', but got '{0}'", props.Substring(offset, 6)));
                    }

                    offset += 6;

                    //
                    // Check that the 'type' property has not been specified Twice
                    //
                    if (defaultHmdTypeOverriden)
                    {
                        throw new FormatException("You've specified the 'type' property twice!");
                    }
                    defaultHmdTypeOverriden = true;

                    hmdType = HmdType.String;
                }
                else if (props[offset] == HmdTypeClass.Boolean[0])
                {
                    if (offset + HmdTypeClass.Boolean.Length > props.Length)
                    {
                        throw new FormatException(
                                  String.Format("Found character '{0}', expected to become \"{1}\", but there are some characters missing",
                                                HmdTypeClass.Boolean[0], HmdTypeClass.Boolean));
                    }
                    offset++;
                    for (int i = 1; i < HmdTypeClass.Boolean.Length; i++)
                    {
                        if (props[offset] != HmdTypeClass.Boolean[i])
                        {
                            throw new FormatException(String.Format("Expected \"{0}\", but got \"{1}\"", HmdTypeClass.Boolean, props.Substring(offset - i, HmdTypeClass.Boolean.Length)));
                        }
                        offset++;
                    }

                    //
                    // Check that the 'type' property has not been specified Twice
                    //
                    if (defaultHmdTypeOverriden)
                    {
                        throw new FormatException("You've specified the 'type' property twice!");
                    }
                    defaultHmdTypeOverriden = true;

                    hmdType = HmdType.Boolean;
                }
                else if (props[offset] == 'i' || props[offset] == 'u')
                {
                    Byte    byteSize;
                    Boolean isUnsigned = false;
                    if (props[offset] == 'u')
                    {
                        isUnsigned = true;
                        offset++;
                        if (props[offset] != 'i')
                        {
                            throw new FormatException(
                                      String.Format("Found character 'u', expected to become \"uint\", but the next character was '{0}'", props[offset]));
                        }
                    }

                    if (offset + 3 > props.Length)
                    {
                        throw new FormatException(
                                  String.Format("Found character '{0}', expected to become \"{1}\", but there are some characters missing",
                                                isUnsigned ? 'u' : 'i', isUnsigned ? "uint" : "int"));
                    }

                    if (props[offset + 1] != 'n' || props[offset + 2] != 't')
                    {
                        throw new FormatException(String.Format("Expected \"{0}\", but got \"{1}\"",
                                                                isUnsigned ? "uint" : "int", isUnsigned ? props.Substring(offset - 1, 4) : props.Substring(offset, 3)));
                    }

                    offset += 3;

                    if (offset < props.Length && props[offset] >= '0' && props[offset] <= '9')
                    {
                        saveOffset = offset;
                        do
                        {
                            offset++;
                        } while (offset < props.Length && props[offset] >= '0' && props[offset] <= '9');
                        byteSize = Byte.Parse(props.Substring(saveOffset, offset - saveOffset));
                    }
                    else
                    {
                        byteSize = 0;
                    }

                    //
                    // Check that the 'type' property has not been specified Twice
                    //
                    if (defaultHmdTypeOverriden)
                    {
                        throw new FormatException("You've specified the 'type' property twice!");
                    }
                    defaultHmdTypeOverriden = true;

                    hmdType = HmdTypeClass.GetIntegerType(isUnsigned, byteSize);
                }
                else if (props[offset] == 'e')
                {
                    offset++;
                    if (offset >= props.Length)
                    {
                        throw new FormatException("Found character 'e', expected to become \"enum\" or \"empty\" but the string abrubtly ended");
                    }

                    if (props[offset] == HmdTypeClass.Empty[1])
                    {
                        if (offset + HmdTypeClass.Empty.Length - 1 > props.Length)
                        {
                            throw new FormatException("Found \"em\", expected to become \"empty\", but there are some characters missing");
                        }
                        offset++;
                        for (int i = 2; i < HmdTypeClass.Empty.Length; i++)
                        {
                            if (props[offset] != HmdTypeClass.Empty[i])
                            {
                                throw new FormatException(String.Format("Expected \"{0}\", but got \"{1}\"", HmdTypeClass.Empty, props.Substring(offset - i, HmdTypeClass.Empty.Length)));
                            }
                            offset++;
                        }

                        //
                        // Check that the 'type' property has not been specified Twice
                        //
                        if (defaultHmdTypeOverriden)
                        {
                            throw new FormatException("You've specified the 'type' property twice!");
                        }
                        defaultHmdTypeOverriden = true;

                        hmdType = HmdType.Empty;
                    }
                    else if (props[offset] == HmdTypeClass.Enumeration[1])
                    {
                        if (offset + HmdTypeClass.Enumeration.Length + 1 > props.Length)
                        {
                            throw new FormatException(
                                      String.Format("Found \"en\", expected to become \"{0}\", but there are some characters missing",
                                                    HmdTypeClass.Enumeration));
                        }
                        offset++;
                        for (int i = 2; i < HmdTypeClass.Enumeration.Length; i++)
                        {
                            if (props[offset] != HmdTypeClass.Enumeration[i])
                            {
                                throw new FormatException(String.Format("Expected \"{0}\", but got \"{1}\"", HmdTypeClass.Enumeration, props.Substring(offset - i, HmdTypeClass.Enumeration.Length)));
                            }
                            offset++;
                        }

                        // skip whitespace
                        while (true)
                        {
                            if (offset >= props.Length)
                            {
                                throw new FormatException("Expected '(' or 'a-zA-Z', but got EOF");
                            }
                            if (!Char.IsWhiteSpace(props[offset]))
                            {
                                break;
                            }
                            offset++;
                        }

                        if (props[offset] == '(')
                        {
                            saveOffset = offset + 1;
                            // skip to the next whitespace or ';'
                            while (true)
                            {
                                offset++;
                                if (offset >= props.Length)
                                {
                                    throw new FormatException("Expected ')' but reached end of string");
                                }
                                if (props[offset] == ')')
                                {
                                    break;
                                }
                            }

                            String enumReferenceName = (definitionParent == null || definitionParent.definitionContext == null) ?
                                                       idString.ToLower() : HmdIDProperties.CombineIDContext(definitionParent.idWithContext, idString.ToLower());
                            HmdEnum newInlineEnum = new HmdEnum(enumReferenceName, props.Substring(saveOffset, offset - saveOffset));

                            enumReference = newInlineEnum;
                            if (hmdProperties != null)
                            {
                                hmdProperties.AddEnum(newInlineEnum);
                            }

                            offset++;

                            if (defaultHmdTypeOverriden)
                            {
                                throw new FormatException("You've specified the 'type' property twice!");
                            }
                            defaultHmdTypeOverriden = true;
                            hmdType = HmdType.Enumeration;
                        }
                        else if ((props[offset] >= 'a' && props[offset] <= 'z') || (props[offset] >= 'A' && props[offset] <= 'Z'))
                        {
                            saveOffset = offset;
                            // skip to the next whitespace or ';'
                            while (true)
                            {
                                offset++;
                                if (offset >= props.Length)
                                {
                                    break;
                                }
                                if (Char.IsWhiteSpace(props[offset]))
                                {
                                    break;
                                }
                            }
                            if (offset - saveOffset <= 0)
                            {
                                throw new FormatException("Unable to parse enum type, the \"enum\" keyword must be either \"enum <type>\" (with only one space before <type>) or \"enum(<value> <value> ...)\"");
                            }

                            enumReference = new HmdEnumReferenceByString(props.Substring(saveOffset, offset - saveOffset));

                            if (defaultHmdTypeOverriden)
                            {
                                throw new FormatException("You've specified the 'type' property twice!");
                            }
                            defaultHmdTypeOverriden = true;
                            hmdType = HmdType.Enumeration;
                        }
                        else
                        {
                            throw new FormatException(String.Format("Expected '(' or 'a-zA-Z' after \"enum\", but got '{0}'", props[offset]));
                        }
                    }
                    else
                    {
                        throw new FormatException(String.Format(
                                                      "Found character 'e', expected to become \"enum\" or \"empty\" but the second character is '{0}'", props[offset]));
                    }
                }
                else if (props[offset] == '(')
                {
                    if (parentOverrideList != null)
                    {
                        throw new FormatException("You've specified the 'parents' property twice!");
                    }

                    parentOverrideList = ParseParentList(props, ref offset);
                }
                else
                {
                    throw new FormatException(
                              String.Format("Could not recognize first character of property '{0}', of the props string \"{1}\"", props[offset], props));
                }
            }
        }