From 0062b2c5ba3c946de045cd8c39d9fa9a24840a70 Mon Sep 17 00:00:00 2001 From: Stefan O'Rear Date: Sun, 3 Jun 2012 22:12:04 -0700 Subject: [PATCH] Port GetOptLong --- lib/Utils.cs | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/lib/Utils.cs b/lib/Utils.cs index 64ebd4df..5f52ef1e 100644 --- a/lib/Utils.cs +++ b/lib/Utils.cs @@ -1033,4 +1033,105 @@ public sealed class RatApproxer { deno = sden; } } + + public sealed class GetoptLong { + public bool Permute { get; set; } + public Action OnArg { get; set; } + public Action OnError { get; set; } + + List opkeys; + List nonopt; + bool breakout; + Dictionary needarg = new Dictionary(); + Dictionary> handlers = + new Dictionary>(); + + public GetoptLong() { + Permute = true; + OnArg = delegate (string s) { + nonopt.Add(s); + if (!Permute) breakout = true; + }; + OnError = delegate (string s) { + Console.Error.WriteLine(s); + Environment.Exit(1); + }; + opkeys = new List(); + nonopt = new List(); + } + + string pick_long(string arg) { + var cand = new List(); + foreach (string s in opkeys) + if (s.Length > 1 && s.Length >= arg.Length && + s.Substring(0, arg.Length) == arg) cand.Add(s); + if (cand.Count > 1) + OnError("Ambiguous long option --"+arg+"; could be any of "+Kernel.JoinS(" ",cand)); + if (cand.Count == 0) + OnError("No match for long option --"+arg); + return cand[0]; + } + + // 0=no 1=yes 2=opt + public void Opt(string ops, int reqd, Action handler) { + foreach (var s in ops.Split('|')) { + opkeys.Add(s); + needarg[s] = reqd; + handlers[s] = handler; + } + } + + public void Parse(ref string[] argv) { + breakout = false; + nonopt.Clear(); + for (int i = 0; i < argv.Length; ) { + string opt = argv[i++]; + if (opt == "--" || breakout) { + if (breakout) i--; + while (i < argv.Length) OnArg(argv[i++]); + break; + } + if (opt.Length >= 2 && opt.Substring(0,2) == "--") { + int eq = opt.IndexOf('='); + if (eq >= 0) { + var obl = pick_long(opt.Substring(2,eq-2)); + if (needarg[obl] == 0) + OnError("Long option --"+obl+" does not accept an argument"); + handlers[obl](opt.Substring(eq+1)); + } + else { + var obl = pick_long(opt.Substring(2)); + if (needarg[obl] == 1) { + if (i == argv.Length - 1) + OnError("Argument required for long option --"+obl); + handlers[obl](argv[i++]); + } else { + handlers[obl](null); + } + } + } + else if (opt.Length > 1 && opt[0] == '-') { + int chi = 1; + while (chi != opt.Length) { + string ch = opt.Substring(chi++, 1); + if (!handlers.ContainsKey(ch)) + OnError("No match for short option -"+ch); + var req = needarg[ch]; + if (req == 0 || req == 2 && chi == opt.Length) + handlers[ch](null); + else if (chi != opt.Length) { + handlers[ch](opt.Substring(chi)); + chi = opt.Length; + } else if (i != argv.Length) + handlers[ch](argv[i++]); + else + OnError("Argument required for short option -"+ch); + } + } + else + OnArg(opt); + } + argv = nonopt.ToArray(); + } + } }