// Returns the parsed command line. If ErrorDescription is non-null, then the parse failed.
    internal static CommandLineOptions ParseCommandLine(string[] args)
    {
        var result = new CommandLineOptions();

        result.ParseCommandLineStrings(args);

        // Convert the language strings to language values.
        var languageTokenizer = new CommandlineTokenizer <Lang>(Lang.Ambiguous)
                                .AddKeyword(Lang.CSharp)
                                .AddKeyword(Lang.Cx, "cppcx")
                                .AddKeyword(Lang.Cx)
                                .AddKeyword(Lang.Cppwinrt)
                                .AddKeyword(Lang.Cppwinrt, "winrtcpp")
                                .AddKeyword(Lang.LottieYaml)
                                .AddKeyword(Lang.WinCompDgml, "dgml")
                                .AddKeyword(Lang.Stats);

        var languages = new List <Lang>();

        // Parse the language string.
        foreach (var languageString in result._languageStrings)
        {
            languageTokenizer.TryMatchKeyword(languageString, out var language);
            languages.Add(language);
            switch (language)
            {
            case Lang.Unknown:
                result.ErrorDescription = $"Unrecognized language: {languageString}";
                break;

            case Lang.Ambiguous:
                result.ErrorDescription = $"Ambiguous language: {languageString}";
                break;
            }
        }

        result.Languages = languages.Distinct().ToArray();

        // Sort any additional interfaces and remove duplicates.
        var additionalInterfaces = result._additionalInterfaces.OrderBy(name => name).Distinct().ToArray();

        result._additionalInterfaces.Clear();
        result._additionalInterfaces.AddRange(additionalInterfaces);

        return(result);
    }
Beispiel #2
0
    // Returns the parsed command line. If ErrorDescription is non-null, then the parse failed.
    internal static CommandLineOptions ParseCommandLine(string[] args)
    {
        var result = new CommandLineOptions();

        result.ParseCommandLineStrings(args);

        // Convert the language strings to language values.
        var languageTokenizer = new CommandlineTokenizer <Lang>(Lang.Ambiguous)
                                .AddKeyword("csharp", Lang.CSharp)
                                .AddKeyword("cppcx", Lang.Cx)
                                .AddKeyword("cx", Lang.Cx)
                                .AddKeyword("cppwinrt", Lang.Cppwinrt)
                                .AddKeyword("winrtcpp", Lang.Cppwinrt)
                                .AddKeyword("lottiexml", Lang.LottieXml)
                                .AddKeyword("lottieyaml", Lang.LottieYaml)
                                .AddKeyword("wincompxml", Lang.WinCompXml)
                                .AddKeyword("dgml", Lang.WinCompDgml)
                                .AddKeyword("stats", Lang.Stats);

        var languages = new List <Lang>();

        // Parse the language string.
        foreach (var languageString in result._languageStrings)
        {
            languageTokenizer.TryMatchKeyword(languageString, out var language);
            languages.Add(language);
            switch (language)
            {
            case Lang.Unknown:
                result.ErrorDescription = $"Unrecognized language: {languageString}";
                break;

            case Lang.Ambiguous:
                result.ErrorDescription = $"Ambiguous language: {languageString}";
                break;
            }
        }

        result.Languages = languages.Distinct();

        return(result);
    }
    void ParseCommandLineStrings(string[] args)
    {
        // Define the keywords accepted on the command line.
        var tokenizer = new CommandlineTokenizer <Keyword>(Keyword.Ambiguous)
                        .AddPrefixedKeyword(Keyword.DisableCodeGenOptimizer)
                        .AddPrefixedKeyword(Keyword.DisableTranslationOptimizer)
                        .AddPrefixedKeyword(Keyword.GenerateColorBindings)
                        .AddPrefixedKeyword(Keyword.GenerateDependencyObject)
                        .AddPrefixedKeyword(Keyword.Help, "?")
                        .AddPrefixedKeyword(Keyword.Help)
                        .AddPrefixedKeyword(Keyword.InputFile)
                        .AddPrefixedKeyword(Keyword.Interface)
                        .AddPrefixedKeyword(Keyword.Language)
                        .AddPrefixedKeyword(Keyword.MinimumUapVersion)
                        .AddPrefixedKeyword(Keyword.Namespace)
                        .AddPrefixedKeyword(Keyword.OutputFolder)
                        .AddPrefixedKeyword(Keyword.Public)
                        .AddPrefixedKeyword(Keyword.Strict)
                        .AddPrefixedKeyword(Keyword.TargetUapVersion)
                        .AddPrefixedKeyword(Keyword.TestMode)
                        .AddPrefixedKeyword(Keyword.WinUI3Mode);

        // The last keyword recognized. This defines what the following parameter value is for,
        // or None if not expecting a parameter value.
        var previousKeyword = Keyword.None;

        foreach (var(keyword, arg) in tokenizer.Tokenize(args))
        {
            var prev = previousKeyword;
            previousKeyword = Keyword.None;
            switch (prev)
            {
            case Keyword.None:
                // Expecting a keyword.
                switch (keyword)
                {
                case Keyword.Ambiguous:
                    ErrorDescription = $"Ambiguous: \"{arg}\".";
                    return;

                case Keyword.None:
                    ErrorDescription = $"Unexpected: \"{arg}\".";
                    return;

                case Keyword.GenerateColorBindings:
                    GenerateColorBindings = true;
                    break;

                case Keyword.GenerateDependencyObject:
                    GenerateDependencyObject = true;
                    break;

                case Keyword.Help:
                    HelpRequested = true;
                    return;

                case Keyword.Strict:
                    StrictMode = true;
                    break;

                case Keyword.TestMode:
                    TestMode = true;
                    break;

                case Keyword.WinUI3Mode:
                    WinUI3Mode = true;
                    break;

                case Keyword.DisableCodeGenOptimizer:
                    DisableCodeGenOptimizer = true;
                    break;

                case Keyword.DisableTranslationOptimizer:
                    DisableTranslationOptimizer = true;
                    break;

                case Keyword.Public:
                    Public = true;
                    break;

                // The following keywords require a parameter as the next token.
                case Keyword.InputFile:
                case Keyword.Interface:
                case Keyword.Language:
                case Keyword.Namespace:
                case Keyword.OutputFolder:
                case Keyword.MinimumUapVersion:
                case Keyword.TargetUapVersion:
                    previousKeyword = keyword;
                    break;

                default:
                    // Should never get here.
                    throw new InvalidOperationException();
                }

                break;

            case Keyword.InputFile:
                if (InputFile != null)
                {
                    ErrorDescription = ArgumentSpecifiedMoreThanOnce("Input");
                    return;
                }

                InputFile       = arg;
                previousKeyword = Keyword.None;
                break;

            case Keyword.Interface:
                if (Interface != null)
                {
                    ErrorDescription = ArgumentSpecifiedMoreThanOnce("Interface");
                    return;
                }

                Interface       = arg;
                previousKeyword = Keyword.None;
                break;

            case Keyword.Language:
                _languageStrings.Add(arg);
                break;

            case Keyword.Namespace:
                if (Namespace != null)
                {
                    ErrorDescription = ArgumentSpecifiedMoreThanOnce("Namespace");
                    return;
                }

                Namespace = arg;
                break;

            case Keyword.OutputFolder:
                if (OutputFolder != null)
                {
                    ErrorDescription = ArgumentSpecifiedMoreThanOnce("Output folder");
                    return;
                }

                OutputFolder = arg;
                break;

            case Keyword.MinimumUapVersion:
                if (MinimumUapVersion != null)
                {
                    ErrorDescription = ArgumentSpecifiedMoreThanOnce("Minimum UAP version");
                    return;
                }

                {
                    if (!uint.TryParse(arg, out var version))
                    {
                        ErrorDescription = ArgumentMustBeAPositiveInteger("Minimum UAP version");
                        return;
                    }

                    MinimumUapVersion = version;
                }

                break;

            case Keyword.TargetUapVersion:
                if (TargetUapVersion != null)
                {
                    ErrorDescription = ArgumentSpecifiedMoreThanOnce("Target UAP version");
                    return;
                }

                {
                    if (!uint.TryParse(arg, out var version))
                    {
                        ErrorDescription = ArgumentMustBeAPositiveInteger("Target UAP version");
                        return;
                    }

                    TargetUapVersion = version;
                }

                break;

            default:
                // Should never get here.
                throw new InvalidOperationException();
            }
        }

        // All tokens consumed. Ensure we are not waiting for the final parameter value.
        if (previousKeyword != Keyword.None)
        {
            ErrorDescription = "Missing value.";
        }
    }
    void ParseCommandLineStrings(string[] args)
    {
        // Define the keywords accepted on the command line.
        var tokenizer = new CommandlineTokenizer <Keyword>(Keyword.Ambiguous)
                        .AddPrefixedKeyword("?", Keyword.Help)
                        .AddPrefixedKeyword("help", Keyword.Help)
                        .AddPrefixedKeyword("inputfile", Keyword.InputFile)
                        .AddPrefixedKeyword("language", Keyword.Language)
                        .AddPrefixedKeyword("classname", Keyword.ClassName)
                        .AddPrefixedKeyword("outputfolder", Keyword.OutputFolder)
                        .AddPrefixedKeyword("strict", Keyword.Strict)
                        .AddPrefixedKeyword("disablecodegenoptimizer", Keyword.DisableCodeGenOptimizer)
                        .AddPrefixedKeyword("disabletranslationoptimizer", Keyword.DisableTranslationOptimizer)
                        .AddPrefixedKeyword("verbose", Keyword.Verbose);

        // The last keyword recognized. This defines what the following parameter value is for,
        // or None if not expecting a parameter value.
        var previousKeyword = Keyword.None;

        foreach (var(keyword, arg) in tokenizer.Tokenize(args))
        {
            var prev = previousKeyword;
            previousKeyword = Keyword.None;
            switch (prev)
            {
            case Keyword.None:
                // Expecting a keyword.
                switch (keyword)
                {
                case Keyword.Ambiguous:
                    ErrorDescription = $"Ambiguous: {arg}";
                    return;

                case Keyword.None:
                    ErrorDescription = $"Unexpected: {arg}";
                    return;

                case Keyword.Help:
                    HelpRequested = true;
                    return;

                case Keyword.Strict:
                    StrictMode = true;
                    break;

                case Keyword.DisableCodeGenOptimizer:
                    DisableCodeGenOptimizer = true;
                    break;

                case Keyword.DisableTranslationOptimizer:
                    DisableTranslationOptimizer = true;
                    break;

                case Keyword.Verbose:
                    Verbose = true;
                    break;

                // The following keywords require a parameter as the next token.
                case Keyword.InputFile:
                case Keyword.Language:
                case Keyword.ClassName:
                case Keyword.OutputFolder:
                    previousKeyword = keyword;
                    break;

                default:
                    // Should never get here.
                    throw new InvalidOperationException();
                }

                break;

            case Keyword.InputFile:
                if (InputFile != null)
                {
                    ErrorDescription = "input specified more than once";
                    return;
                }

                InputFile       = arg;
                previousKeyword = Keyword.None;
                break;

            case Keyword.Language:
                _languageStrings.Add(arg);
                break;

            case Keyword.ClassName:
                if (ClassName != null)
                {
                    ErrorDescription = "class name specified more than once";
                    return;
                }

                ClassName = arg;
                break;

            case Keyword.OutputFolder:
                if (OutputFolder != null)
                {
                    ErrorDescription = "output folder specified more than once";
                    return;
                }

                OutputFolder = arg;
                break;

            default:
                // Should never get here.
                throw new InvalidOperationException();
            }
        }

        // All tokens consumed. Ensure we are not waiting for the final parameter value.
        if (previousKeyword != Keyword.None)
        {
            ErrorDescription = "Missing value";
        }
    }