Exemple #1
0
        static void VerifyFieldCount(LfdLine line, Int32 fieldCount)
        {
            int lineFieldCount = (line.fields == null) ? 0 : line.fields.Length;

            if (lineFieldCount != fieldCount)
            {
                throw new ParseException(line, "Expected line to have {0} fields but had {1}", fieldCount, lineFieldCount);
            }
        }
Exemple #2
0
    // Assumption: filename already exists and is already verified to be a file
    public static void LoadFile(MetabuildProject metabuild, String filename)
    {
        Console.WriteLine("[DEBUG] Metabuild.LoadFile \"{0}\"", filename);
        String relativeDir = null;

        using (LfdTextReader reader = new LfdTextReader(new StreamReader(new FileStream(
                                                                             filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))))
        {
            LfdParser parser = new LfdParser(reader, filename);
            LfdLine   line   = parser.reader.ReadLineIgnoreComments();
            for (; ;)
            {
                if (line == null)
                {
                    return;
                }

                if (line.id == "Import")
                {
                    parser.errors.EnforceFieldCount(line, 1);
                    MetabuildUnit.LoadDirOrFile(metabuild, line.fields[0]);
                    line = parser.reader.ReadLineIgnoreComments();
                }
                else if (line.id == "CSharpProject")
                {
                    if (relativeDir == null)
                    {
                        relativeDir = Path.GetDirectoryName(filename);
                    }
                    line = CSharpProject.Parse(metabuild, parser, line, false, relativeDir);
                }
                else if (line.id == "CSharpTestProject")
                {
                    if (relativeDir == null)
                    {
                        relativeDir = Path.GetDirectoryName(filename);
                    }
                    line = CSharpProject.Parse(metabuild, parser, line, true, relativeDir);
                }
                else if (line.id == "GeneratePathPrefix")
                {
                    parser.errors.EnforceFieldCount(line, 1);
                    if (metabuild.generatePathPrefix != null)
                    {
                        throw parser.errors.Error(line, "GeneratePathPrefix was set more than once");
                    }
                    metabuild.generatePathPrefix = line.fields[0];
                    line = parser.reader.ReadLineIgnoreComments();
                }
                else
                {
                    throw parser.errors.Error(line, "unknown directive '{0}'", line.id);
                }
            }
        }
    }
Exemple #3
0
    public void EnforceFieldCount(LfdLine line, UInt32 expected)
    {
        UInt32 fieldsLength = (line.fields == null) ? 0 : (UInt32)line.fields.Length;

        if (fieldsLength != expected)
        {
            throw Error(line, "property '{0}' requires {1} field(s) but got {2}",
                        line.id, expected, fieldsLength);
        }
    }
Exemple #4
0
        public static PdlArrayType Parse(LfdLine line, String sizeTypeString)
        {
            if (String.IsNullOrEmpty(sizeTypeString))
            {
                return(BasedOnCommandLength);
            }

            Char firstChar = sizeTypeString[0];

            if (firstChar >= '0' && firstChar <= '9')
            {
                UInt32 fixedLength;
                if (!UInt32.TryParse(sizeTypeString, out fixedLength))
                {
                    throw new ParseException(line, "First character of array size type '{0}' was a number but coult not parse it as a number", sizeTypeString);
                }

                return(new PdlFixedLengthArrayType(fixedLength));
            }

            PdlArraySizeTypeEnum typeEnum;

            try
            {
                typeEnum = (PdlArraySizeTypeEnum)Enum.Parse(typeof(PdlArraySizeTypeEnum), sizeTypeString);
            }
            catch (ArgumentException)
            {
                throw new ParseException(line,
                                         "The array size type inside the brackets '{0}' is invalid, expected 'Byte','UInt16','UInt24' or 'UInt32'", sizeTypeString);
            }

            if (typeEnum == PdlArraySizeTypeEnum.Fixed)
            {
                throw new InvalidOperationException("Fixed is an invalid array size type, use an unsigned integer to specify a fixed length array");
            }

            switch (typeEnum)
            {
            case PdlArraySizeTypeEnum.BasedOnCommand: return(BasedOnCommandLength);

            case PdlArraySizeTypeEnum.Byte: return(ByteLength);

            case PdlArraySizeTypeEnum.UInt16: return(UInt16Length);

            case PdlArraySizeTypeEnum.UInt24: return(UInt24Length);

            case PdlArraySizeTypeEnum.UInt32: return(UInt32Length);

            case PdlArraySizeTypeEnum.UInt64: return(UInt64Length);
            }

            throw new InvalidOperationException(String.Format("CodeBug: Unhandled PdlArraySizeTypeEnum {0}", typeEnum));
        }
Exemple #5
0
        static void ParseEnumOrFlagsDefinition(BinaryFormatFile file, LfdLineReader reader, NamedObjectDefinition currentObjectDefinition, LfdLine enumDefinitionLine, out LfdLine nextLine, Boolean isFlagsDefinition)
        {
            String enumOrFlagsString = isFlagsDefinition ? "Flags" : "Enum";

            VerifyFieldCount(enumDefinitionLine, 2);

            String           underlyingIntegerTypeString = enumDefinitionLine.fields[0];
            BinaryFormatType underlyingIntegerType       = BinaryFormatTypeExtensions.ParseIntegerType(underlyingIntegerTypeString);

            EnumOrFlagsDefinition definition;

            try
            {
                definition = new EnumOrFlagsDefinition(file, isFlagsDefinition, currentObjectDefinition,
                                                       underlyingIntegerType, enumDefinitionLine.fields[1]);
            }
            catch (FormatException e) { throw new ParseException(enumDefinitionLine, e.Message); }

            Debug("  Entering {0} '{1}' (IntegerType={2})", enumOrFlagsString, enumDefinitionLine.id, definition.underlyingIntegerType);

            //
            // Read enum values
            //
            nextLine = reader.ReadLineIgnoreComments();
            while (nextLine != null && nextLine.parent == enumDefinitionLine)
            {
                LfdLine enumValueLine = nextLine;
                VerifyFieldCount(enumValueLine, 1);
                Debug("    {0} {1} {2}", enumOrFlagsString, enumValueLine.id, enumValueLine.fields[0]);

                if (isFlagsDefinition)
                {
                    definition.Add(new FlagsValueDefinition(enumValueLine.fields[0], Byte.Parse(enumValueLine.id)));
                }
                else
                {
                    definition.Add(new EnumValueDefinition(enumValueLine.id, enumValueLine.fields[0]));
                }

                nextLine = reader.ReadLineIgnoreComments();
            }
            Debug("  Exiting {0} '{1}'", enumOrFlagsString, definition.typeName);
        }
Exemple #6
0
        public static void ParsePdlFile(PdlFile pdlFile, LfdReader reader)
        {
            LfdLine nextLine = reader.ReadLineIgnoreComments();

            while (nextLine != null)
            {
                if (nextLine.id.Equals("enum", StringComparison.OrdinalIgnoreCase))
                {
                    ParseEnumOrFlagsDefinition(pdlFile, reader, null, nextLine, out nextLine, false);
                }
                else if (nextLine.id.Equals("flags", StringComparison.OrdinalIgnoreCase))
                {
                    ParseEnumOrFlagsDefinition(pdlFile, reader, null, nextLine, out nextLine, true);
                }
                else
                {
                    LfdLine currentCommandLine = nextLine;

                    VerifyFieldCount(currentCommandLine, 0);
                    NamedObjectDefinition objectDefinition = ParseObjectDefinition(pdlFile, reader, currentCommandLine, null, currentCommandLine.id, out nextLine);
                }
            }
        }
Exemple #7
0
 public ParseException(LfdLine line, String reason)
     : base(String.Format("Parse Error (line {0}): {1}\n at line: \"{2}\"",
                          line.actualLineNumber, reason, line.ToString()))
 {
 }
Exemple #8
0
        public static void ParseObjectFieldLine(PdlFile pdlFile, LfdReader reader, NamedObjectDefinition containingNamedObject,
                                                IFieldContainer containingObject, LfdLine fieldLine, out LfdLine nextLine)
        {
            //
            // Check if it is only a definition (enum or flag)
            //
            if (fieldLine.id.Equals("enum", StringComparison.OrdinalIgnoreCase))
            {
                ParseEnumOrFlagsDefinition(pdlFile, reader, containingNamedObject, fieldLine, out nextLine, false);
                return;
            }
            if (fieldLine.id.Equals("flags", StringComparison.OrdinalIgnoreCase))
            {
                ParseEnumOrFlagsDefinition(pdlFile, reader, containingNamedObject, fieldLine, out nextLine, true);
                return;
            }

            String typeString = fieldLine.id;

            //
            // The rest of the fields can have arrayParse the Array Size Type
            //
            PdlArrayType arrayType;

            int indexOfOpenBracket = typeString.IndexOf('[');

            if (indexOfOpenBracket < 0)
            {
                arrayType = null;
            }
            else
            {
                String arraySizeTypeString = typeString.Substring(indexOfOpenBracket + 1);

                typeString = typeString.Remove(indexOfOpenBracket);

                int indexOfCloseBracket = arraySizeTypeString.IndexOf(']');
                if (indexOfCloseBracket < 0)
                {
                    throw new ParseException(fieldLine, "Found an opening bracket '[' without a closing bracket");
                }
                if (indexOfCloseBracket != arraySizeTypeString.Length - 1)
                {
                    throw new ParseException(fieldLine, "The array size type '{0}' had a closing bracket, but the closing bracket was not the last character", arraySizeTypeString);
                }

                arraySizeTypeString = arraySizeTypeString.Remove(indexOfCloseBracket);
                arrayType           = PdlArrayType.Parse(fieldLine, arraySizeTypeString);
            }

            //
            // Parse object inline definition
            //
            if (typeString.Equals("object", StringComparison.OrdinalIgnoreCase))
            {
                VerifyFieldCount(fieldLine, 1);

                String objectDefinitionAndFieldName = fieldLine.fields[0];

                NamedObjectDefinition fieldObjectDefinition = ParseObjectDefinition(pdlFile, reader, fieldLine,
                                                                                    containingNamedObject, objectDefinitionAndFieldName, out nextLine);

                containingObject.AddField(new ObjectDefinitionField(
                                              new ObjectTypeReference(objectDefinitionAndFieldName, fieldObjectDefinition, arrayType),
                                              objectDefinitionAndFieldName));
                return;
            }

            //
            // Check if it is a serializer
            //
            if (fieldLine.id.Equals("serializer", StringComparison.OrdinalIgnoreCase))
            {
                VerifyFieldCount(fieldLine, 2);
                String       serializerLengthTypeString = fieldLine.fields[0];
                String       serializerFieldName        = fieldLine.fields[1];
                PdlArrayType serializerLengthType       = PdlArrayType.Parse(fieldLine, serializerLengthTypeString);

                containingObject.AddField(new ObjectDefinitionField(new SerializerTypeReference(serializerLengthType, arrayType), serializerFieldName));

                nextLine = reader.ReadLineIgnoreComments();
                return;
            }

            //
            // Check if it is an 'if' type
            //
            if (typeString.Equals("if", StringComparison.OrdinalIgnoreCase))
            {
                VerifyFieldCount(fieldLine, 1);

                IfTypeReference ifType = ParseIf(pdlFile, reader, fieldLine,
                                                 containingNamedObject, out nextLine);

                containingObject.AddField(new ObjectDefinitionField(ifType, null));
                return;
            }

            //
            // Check if it is a switch type
            //
            if (typeString.Equals("switch", StringComparison.OrdinalIgnoreCase))
            {
                VerifyFieldCount(fieldLine, 1);

                SwitchTypeReference switchType = ParseSwitch(pdlFile, reader, fieldLine,
                                                             containingNamedObject, out nextLine);

                containingObject.AddField(new ObjectDefinitionField(switchType, null));
                return;
            }

            //
            // The field is only one line, so read the next line now for the caller
            //
            nextLine = reader.ReadLineIgnoreComments();



            EnumOrFlagsDefinition enumDefinition = pdlFile.TryGetEnumOrFlagsDefinition(containingNamedObject, typeString);

            if (enumDefinition != null)
            {
                VerifyFieldCount(fieldLine, 1);
                containingObject.AddField(new ObjectDefinitionField(new EnumOrFlagsTypeReference(typeString, enumDefinition, arrayType),
                                                                    fieldLine.fields[0]));
                return;
            }

            // Check if it is an object type
            NamedObjectDefinition objectDefinition = pdlFile.TryGetObjectDefinition(containingNamedObject, typeString);

            if (objectDefinition != null)
            {
                if (fieldLine.fields == null || fieldLine.fields.Length <= 0)
                {
                    //
                    // Add each field from the object definition to the current object definition
                    //
                    List <ObjectDefinitionField> objectDefinitionFields = objectDefinition.Fields;
                    for (int i = 0; i < objectDefinitionFields.Count; i++)
                    {
                        ObjectDefinitionField fieldDefinition = objectDefinitionFields[i];
                        containingObject.AddField(fieldDefinition);
                    }
                }
                else if (fieldLine.fields.Length == 1)
                {
                    containingObject.AddField(new ObjectDefinitionField(
                                                  new ObjectTypeReference(typeString, objectDefinition, arrayType), fieldLine.fields[0]));
                }
                else
                {
                    throw new ParseException(fieldLine, "Expected line to have 0 or 1 fields but had {0}", fieldLine.fields.Length);
                }
                return;
            }

            //
            // Check if it a string type
            //
            if (typeString.Equals("ascii", StringComparison.OrdinalIgnoreCase))
            {
                VerifyFieldCount(fieldLine, 1);
                containingObject.AddField(new ObjectDefinitionField(
                                              new AsciiTypeReference(typeString, arrayType), fieldLine.fields[0]));
                return;
            }


            //
            // It must be an integer type
            //
            VerifyFieldCount(fieldLine, 1);

            PdlType type;

            try { type = (PdlType)Enum.Parse(typeof(PdlType), typeString, true); }
            catch (ArgumentException) { throw new FormatException(String.Format("Unknown Pdl Type '{0}'", typeString)); }
            if (!type.IsIntegerType())
            {
                throw new InvalidOperationException(String.Format("Unhandled PDL type '{0}'", type));
            }

            containingObject.AddField(new ObjectDefinitionField(new IntegerTypeReference(type, arrayType), fieldLine.fields[0]));
        }
Exemple #9
0
        static NamedObjectDefinition ParseObjectDefinition(PdlFile pdlFile, LfdReader reader, LfdLine objectDefinitionLine,
                                                           NamedObjectDefinition currentObjectDefinition, String objectDefinitionName, out LfdLine nextLine)
        {
            NamedObjectDefinition objectDefinition = new NamedObjectDefinition(pdlFile, objectDefinitionName,
                                                                               objectDefinitionName.ToLowerInvariant(), currentObjectDefinition);

            Debug("Entering Object Definition '{0}'", objectDefinition.name);

            nextLine = reader.ReadLineIgnoreComments();
            while (nextLine != null && nextLine.parent == objectDefinitionLine)
            {
                ParseObjectFieldLine(pdlFile, reader, objectDefinition, objectDefinition, nextLine, out nextLine);
            }

            objectDefinition.CalculateFixedSerializationLength();

            return(objectDefinition);
        }
Exemple #10
0
        static SwitchTypeReference ParseSwitch(PdlFile pdlFile, LfdReader reader, LfdLine switchLine, NamedObjectDefinition containingNamedObject, out LfdLine nextLine)
        {
            List <Case> cases = new List <Case>();

            String switchFieldString = switchLine.fields[0];

            Debug("Entering Switch Definition '{0}'", switchFieldString);

            nextLine = reader.ReadLineIgnoreComments();
            while (nextLine != null && nextLine.parent == switchLine)
            {
                Boolean isCase = nextLine.id.Equals("case", StringComparison.OrdinalIgnoreCase);
                if (!isCase && !nextLine.id.Equals("default", StringComparison.OrdinalIgnoreCase))
                {
                    throw new FormatException(String.Format("Expected 'Case' or 'Default' but got '{0}'", nextLine));
                }

                VerifyFieldCount(nextLine, isCase ? 1 : 0);

                LfdLine          currentCaseLine             = nextLine;
                String           currentCaseValueString      = isCase ? nextLine.fields[0] : null;
                ObjectDefinition currentCaseObjectDefinition = new ObjectDefinition(pdlFile);

                nextLine = reader.ReadLineIgnoreComments();
                while (nextLine != null && nextLine.parent == currentCaseLine)
                {
                    ParseObjectFieldLine(pdlFile, reader, containingNamedObject, currentCaseObjectDefinition, nextLine, out nextLine);
                }

                currentCaseObjectDefinition.CalculateFixedSerializationLength();
                cases.Add(new Case(currentCaseValueString, currentCaseObjectDefinition));
            }

            return(new SwitchTypeReference(switchFieldString, cases));
        }
Exemple #11
0
        static IfTypeReference ParseIf(PdlFile pdlFile, LfdReader reader, LfdLine ifLine, NamedObjectDefinition containingNamedObject, out LfdLine nextLine)
        {
            Case trueCase, falseCase = null;

            String conditionString = ifLine.fields[0];

            Debug("Entering If Definition '{0}'", conditionString);

            ObjectDefinition trueCaseObjectDefinition = new ObjectDefinition(pdlFile);

            nextLine = reader.ReadLineIgnoreComments();
            while (nextLine != null && nextLine.parent == ifLine)
            {
                ParseObjectFieldLine(pdlFile, reader, containingNamedObject, trueCaseObjectDefinition, nextLine, out nextLine);
            }
            trueCaseObjectDefinition.CalculateFixedSerializationLength();
            trueCase = new Case(conditionString, trueCaseObjectDefinition);

            if (nextLine != null && nextLine.id.Equals("else", StringComparison.OrdinalIgnoreCase))
            {
                LfdLine          falseCaseLine             = nextLine;
                ObjectDefinition falseCaseObjectDefinition = new ObjectDefinition(pdlFile);

                nextLine = reader.ReadLineIgnoreComments();
                while (nextLine != null && nextLine.parent == falseCaseLine)
                {
                    ParseObjectFieldLine(pdlFile, reader, containingNamedObject, falseCaseObjectDefinition, nextLine, out nextLine);
                }
                falseCaseObjectDefinition.CalculateFixedSerializationLength();
                falseCase = new Case(conditionString, falseCaseObjectDefinition);
            }

            return(new IfTypeReference(conditionString, trueCase, falseCase));
        }
Exemple #12
0
 public ParseException(LfdLine line, String reasonFmt, params Object[] reasonObj)
     : this(line, String.Format(reasonFmt, reasonObj))
 {
 }
Exemple #13
0
 public UnresolvedCSharpProjectReference(CSharpProject project, LfdErrorReporter errors, LfdLine line)
 {
     this.project = project;
     this.errors  = errors;
     this.line    = line;
     errors.EnforceFieldCount(line, 1);
     this.referenceName = line.fields[0];
 }
Exemple #14
0
    public static LfdLine Parse(MetabuildProject metabuild, LfdParser parser, LfdLine projectLine, Boolean isTestProject, String relativePath)
    {
        parser.errors.EnforceFieldCount(projectLine, 1);
        CSharpProject project       = new CSharpProject(relativePath, projectLine.fields[0], isTestProject);
        bool          setOutputType = false;

        LfdLine line;

        for (; ;)
        {
            line = parser.reader.ReadLineIgnoreComments();
            if (line == null)
            {
                break;
            }
            if (line.id == "ProjectGuid")
            {
                parser.errors.EnforceFieldCount(line, 1);
                if (project.projectGuid != default(Guid))
                {
                    throw parser.errors.Error(line, "ProjectGuid was set more than once");
                }
                project.projectGuid = new Guid(line.fields[0]);
            }
            else if (line.id == "OutputType")
            {
                parser.errors.EnforceFieldCount(line, 1);
                if (setOutputType)
                {
                    throw parser.errors.Error(line, "OutputType was set more than once");
                }
                setOutputType      = true;
                project.outputType = (OutputType)Enum.Parse(typeof(OutputType), line.fields[0], false);
            }
            else if (line.id == "AssemblyName")
            {
                parser.errors.EnforceFieldCount(line, 1);
                if (project.assemblyName != null)
                {
                    throw parser.errors.Error(line, "AssemblyName was set more than once");
                }
                project.assemblyName = line.fields[0];
            }
            else if (line.id == "AllowUnsafeBlocks")
            {
                parser.errors.EnforceFieldCount(line, 0);
                if (project.allowUnsafeBlocks)
                {
                    throw parser.errors.Error(line, "AllowUnsafeBlocks was set more than once");
                }
                project.allowUnsafeBlocks = true;
            }
            else if (line.id == "Reference")
            {
                parser.errors.EnforceFieldCount(line, 1);
                project.referenceList.Add(line.fields[0]);
            }
            else if (line.id == "ProjectReference")
            {
                metabuild.AddUnresolvedReference(new UnresolvedCSharpProjectReference(project, parser.errors, line));
            }
            else if (line.id == "Source")
            {
                parser.errors.EnforceFieldCount(line, 1);
                project.sourceList.Add(line.fields[0]);
            }
            else
            {
                break;
            }
        }

        //
        // Verify the project is valid
        //
        if (!setOutputType)
        {
            throw parser.errors.ErrorNoLine("Missing the 'OutputType' property");
        }
        if (project.assemblyName == null)
        {
            project.assemblyName = project.name;
        }
        if (project.projectGuid == default(Guid))
        {
            project.projectGuid = Guid.NewGuid();
        }
        metabuild.units.Add(project);
        return(line);
    }
Exemple #15
0
 public void PrintError(LfdLine line, String fmt, params Object[] obj)
 {
     Console.WriteLine("{0}({1}) Error: {2}",
                       filenameForErrors, line.actualLineNumber, String.Format(fmt, obj));
 }
Exemple #16
0
 public ProjectLoadException Error(LfdLine line, String fmt, params Object[] obj)
 {
     return(new ProjectLoadException(String.Format("{0}({1}) {2}",
                                                   filenameForErrors, line.actualLineNumber, String.Format(fmt, obj))));
 }