I wanted to write some apps that'd take arguments in the POSIXy way,
and so I decided to implement a Getopt class which provides all the
common things, and aside from the fact that I use an exception to
show the end of args (other than using an output parameter boolean
and checking that, I couldn't think of a saneish way), I'm fairly
happy with it.  I have no idea if anyone but me would even begin to
find this useful, but it follows in this message, and the usage is
such (it will even do a lazy usage() style message for you, if you
don't want to construct a prettier one yourself):

% public static void Main(string[] args)
% {
%       Getopt getopt = new Getopt(args, "a:b");
%       char ch;
%       for (;;) {
%               try {
%                       ch = getopt.Next();
%               } catch (IndexOutOfRangeException) {
%                       goto EndOfArgs;
%               } catch (Exception e) {
%                       Console.WriteLine("Getopt got {0}", e);
%                       System.Environment.Exit(1);
%                       //Notreached.
%                       return;
%               }
%               switch (ch) {
%               case 'a':
%                       Console.WriteLine("Got -a with arg {0}", 
getopt.OptionArgument);
%                       break;
%               case 'b':
%                       Console.WriteLine("Got -b");
%                       break;
%               case '?':
%               default:
%                       getopt.Usage();
%                       System.Environment.Exit(1);
%                       //Notreached.
%                       return;
%               }
%       }
% EndOfArgs:
%       // Finished argument parsing.

And here's getopt.cs:

%%%
using System;
using System.Reflection;

class Getopt
{
        public static char BadCharacter = '?';
        public static char BadArgument = ':';

        public bool Error = true;
        public int Index = 0;
        public char Option;
        public bool Reset;
        public string OptionArgument;

        public string ProgramName;

        private Assembly CallingAssembly;

        private int Length;
        private string[] Array;
        private string Options;

        private string Place;

        public Getopt(string progname, int argc, string[] argv, string ostr)
        {
                CallingAssembly = System.Reflection.Assembly.GetEntryAssembly();
                Length = argc;
                Array = argv;
                Options = ostr;
                if (progname == null)
                        progname = CallingAssembly.ToString();
                ProgramName = progname;
        }

        public Getopt(string progname, string[] argv, string ostr)
        : this(progname, argv.Length, argv, ostr)
        {
        }

        public Getopt(int argc, string[] argv, string ostr)
        : this(null, argc, argv, ostr)
        {
        }

        public Getopt(string[] argv, string ostr)
        : this(argv.Length, argv, ostr)
        {
        }

        public void Usage()
        {
                string iterator;
                string usageString;

                usageString = String.Format("usage: {0}", ProgramName);

                iterator = Options;
                if (iterator == null) {
                        Console.WriteLine(usageString);
                        return;
                }
                if (iterator[0] == ':') {
                        iterator = GetStringNext(iterator);
                }
                if (iterator == null) {
                        Console.WriteLine(usageString);
                        return;
                }
                do {
                        if (iterator.Length == 0)
                                break;
                        char optionFlag = iterator[0];
                        usageString += String.Format(" -{0}", optionFlag);
                        if (iterator.Length > 1) {
                                if (iterator[1] == ':') {
                                        usageString += " <argument>";
                                        iterator = GetStringNext(iterator);
                                }
                        }
                        iterator = GetStringNext(iterator);
                } while (iterator != null);
                Console.WriteLine(usageString);
        }

        public char Next()
        {
                if (Place == null)
                        Place = "";
                if (Reset || Place.Length == 0) {
                        Reset = false;
                        if (Index >= Length || (Place = Array[Index])[0] != '-') {
                                Place = null;
                                throw new IndexOutOfRangeException();
                        }
                        if (Place[0] == '-' && Place[1] == '-') {
                                Index++;
                                Place = null;
                                throw new IndexOutOfRangeException();
                        }
                        Place = GetStringNext(Place);
                }

                Option = Place[0];
                Place = GetStringNext(Place);
                if (Place == null)
                        throw new IndexOutOfRangeException();
                int optionLetterIndex = Options.IndexOf(Option);
                if (Option == ':' || optionLetterIndex == -1) {
                        if (Option == '-')
                                throw new IndexOutOfRangeException();
                        if (Place.Length == 0)
                                Index++;
                        if (Error && Options[0] != ':' && Option != BadCharacter)
                                Console.WriteLine("{0}: illegal option -- {1}", 
ProgramName, Option);
                        return BadCharacter;
                }
                if (Options[optionLetterIndex + 1] != ':') {
                        OptionArgument = null;
                        if (Place.Length == 0)
                                Index++;
                } else {
                        if (Place.Length != 0)
                                OptionArgument = Place;
                        else if (Length <= ++Index) {
                                Place = null;
                                if (Options[0] != ':')
                                        return BadArgument;
                                if (Error)
                                        Console.WriteLine("{0}: option requires an 
argument -- {1}", ProgramName, Option);
                                return BadCharacter;
                        } else
                                OptionArgument = Array[Index];
                        Place = null;
                        Index++;
                }
                return Option;
        }

        private string GetStringNext(string ThisString)
        {
                try {
                        ThisString = ThisString.Substring(1);
                } catch {
                        ThisString = null;
                }
                return ThisString;

        }
}
%%%

Thanx & let me know if you find it useful,
juli.
-- 
Juli Mallett <[EMAIL PROTECTED]>
OpenDarwin, Mono, FreeBSD Developer.
ircd-hybrid Developer, EFnet addict.
FreeBSD on MIPS-Anything on FreeBSD.

_______________________________________________
Mono-list maillist  -  [EMAIL PROTECTED]
http://lists.ximian.com/mailman/listinfo/mono-list

Reply via email to