From 823169ca91cd70aeba043fc16582e229a960bb0d Mon Sep 17 00:00:00 2001 From: Timerix Date: Sat, 26 Apr 2025 04:19:14 +0500 Subject: [PATCH] LaunchArgumentParser.HelpMessageHeader --- DTLib/Console/LaunchArgumentParser.cs | 185 ++++++++++++++------------ 1 file changed, 102 insertions(+), 83 deletions(-) diff --git a/DTLib/Console/LaunchArgumentParser.cs b/DTLib/Console/LaunchArgumentParser.cs index 2333b4a..092dc86 100644 --- a/DTLib/Console/LaunchArgumentParser.cs +++ b/DTLib/Console/LaunchArgumentParser.cs @@ -2,32 +2,123 @@ namespace DTLib.Console; public class LaunchArgumentParser { + public string HelpMessageHeader = "USAGE:"; public bool IsAllowedNoArguments; private readonly Dictionary argDict = new(); private readonly List argList = new(); - public class ExitAfterHelpException : Exception + public LaunchArgumentParser() { - internal ExitAfterHelpException() : base("your program can use this exception to exit after displaying help message") - { } + var help = new LaunchArgument(new[] { "h", "help" }, + "shows help message", HelpHandler); + Add(help); + var helpArg = new LaunchArgument(new[] { "ha", "helparg" }, + "shows help message for specific argument", + HelpArgHandler, "argument"); + Add(helpArg); } + public LaunchArgumentParser(ICollection arguments) : this() => WithArgs(arguments); + public LaunchArgumentParser(params LaunchArgument[] arguments) : this() => WithArgs(arguments); + + public LaunchArgumentParser WithArgs(IEnumerable args) + { + foreach (var arg in args) + Add(arg); + return this; + } + + public LaunchArgumentParser WithArgs(params LaunchArgument[] args) + { + foreach (var arg in args) + Add(arg); + return this; + } + + public LaunchArgumentParser WithHelpMessageHeader(string header) + { + HelpMessageHeader = header; + return this; + } + + public LaunchArgumentParser AllowNoArguments() + { + IsAllowedNoArguments = true; + return this; + } + public string CreateHelpMessage() { - StringBuilder b = new(); - foreach (var arg in argList) - arg.AppendHelpInfo(b).Append('\n'); - b.Remove(b.Length-1, 1); + StringBuilder b = new(HelpMessageHeader); + foreach (var arg in argList) + { + b.Append('\n'); + arg.AppendHelpInfo(b); + } return b.ToString(); } + public string CreateHelpArgMessage(string argAlias) { StringBuilder b = new(); - var arg = Parse(argAlias); + var arg = ParseArg(argAlias); arg.AppendHelpInfo(b); return b.ToString(); } + + public void Add(LaunchArgument arg) + { + argList.Add(arg); + foreach (string alias in arg.Aliases) + argDict.Add(alias, arg); + } + + public LaunchArgument ParseArg(string argAlias) + { + // different argument providing patterns + if (!argDict.TryGetValue(argAlias, out var arg) && // arg + !(argAlias.StartsWith("--") && argDict.TryGetValue(argAlias.Substring(2), out arg)) && // --arg + !(argAlias.StartsWith('-') && argDict.TryGetValue(argAlias.Substring(1), out arg)) && // -arg + !(argAlias.StartsWith('/') && argDict.TryGetValue(argAlias.Substring(1), out arg))) // /arg + throw new Exception($"invalid argument: {argAlias}\n{CreateHelpMessage()}"); + + return arg; + } + + /// program launch args + /// argument {args[i]} should have a parameter after it + /// argument hasn't got any handlers + /// happens after help message is displayed + public void ParseAndHandle(string[] args) + { + // show help message and throw ExitAfterHelpException + if (args.Length == 0 && !IsAllowedNoArguments) + HelpHandler(); + + List execQueue = new(); + + for (int i = 0; i < args.Length; i++) + { + var arg = ParseArg(args[i]); + for (int j = 0; j < arg.Params.Length; j++) + { + if (++i >= args.Length) + throw new Exception( + $"argument '{arg.Aliases[0]}' should have parameter '{arg.Params[j]}' after it"); + arg.Params[j].Value = args[i]; + } + + execQueue.Add(arg); + } + + // ascending sort by priority + execQueue.Sort((a0, a1) => a0.Priority - a1.Priority); + // finally executing handlers + foreach (var a in execQueue) + a.Handle(); + } + private void HelpHandler() { System.Console.WriteLine(CreateHelpMessage()); @@ -40,83 +131,11 @@ public class LaunchArgumentParser throw new ExitAfterHelpException(); } - - public LaunchArgumentParser() + public class ExitAfterHelpException : Exception { - var help = new LaunchArgument(new[] { "h", "help" }, - "shows help message", HelpHandler); - Add(help); - var helpArg = new LaunchArgument( new[]{ "ha", "helparg" }, - "shows help message for particular argument", - HelpArgHandler, "argAlias"); - Add(helpArg); - } - - public LaunchArgumentParser AllowNoArguments() - { - IsAllowedNoArguments = true; - return this; - } - - public LaunchArgumentParser(ICollection arguments) : this() - { - foreach (var arg in arguments) - Add(arg); - } - public LaunchArgumentParser(params LaunchArgument[] arguments) : this() - { - foreach (var arg in arguments) - Add(arg); - } - - public void Add(LaunchArgument arg) - { - argList.Add(arg); - foreach (string alias in arg.Aliases) - argDict.Add(alias, arg); - } - - public LaunchArgument Parse(string argAlias) - { - // different argument providing patterns - if (!argDict.TryGetValue(argAlias, out var arg) && // arg - !(argAlias.StartsWith("--") && argDict.TryGetValue(argAlias.Substring(2), out arg)) && // --arg - !(argAlias.StartsWith('-') && argDict.TryGetValue(argAlias.Substring(1), out arg)) && // -arg - !(argAlias.StartsWith('/') && argDict.TryGetValue(argAlias.Substring(1), out arg))) // /arg - throw new Exception($"invalid argument: {argAlias}\n{CreateHelpMessage()}"); - - return arg; - } - - /// program launch args - /// argument {args[i]} should have a parameter after it - /// argument hasn't got any handlers - /// happens after help message is displayed - public void ParseAndHandle(string[] args) - { - // show help message and throw ExitAfterHelpException - if (args.Length == 0 && !IsAllowedNoArguments) - HelpHandler(); - - List execQueue = new(); - - for (int i = 0; i < args.Length; i++) + public ExitAfterHelpException() + : base("your program can use this exception to exit after displaying help message") { - LaunchArgument arg = Parse(args[i]); - for (int j = 0; j < arg.Params.Length; j++) - { - if (++i >= args.Length) - throw new Exception($"argument '{arg.Aliases[0]}' should have parameter '{arg.Params[j]}' after it"); - arg.Params[j].Value = args[i]; - } - - execQueue.Add(arg); } - - // ascending sort by priority - execQueue.Sort((a0, a1) => a0.Priority-a1.Priority); - // finally executing handlers - foreach (var a in execQueue) - a.Handle(); } } \ No newline at end of file