// 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); }
// 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"; } }