Wednesday, March 3, 2010

Comandline argument parser

Class that parses the commandline arguments.

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace TestArgumentParser
{
    public class ArgumentParser
    {
        public string QuoteChars { get; set; }
        public string ValueSeparatorChars { get; set; }
        public string PrefixChars { get; set; }
        public Dictionary Params = new Dictionary();

        public string this[string key] { get{ return Params[key]; } }

        public ArgumentParser()
        {
            SetDefaultValues();
            string argString = GetComandLineArguments();
            Parse(argString);
        }

        public ArgumentParser(string args)
        {
            SetDefaultValues();
            Parse(args);
        }

        private static string GetComandLineArguments()
        {
            string argString = Environment.CommandLine;
            argString = argString.Replace("\"" + Process.GetCurrentProcess().MainModule.FileName + "\"", "");
            return argString;
        }

        public void Parse(string arguments)
        {
            string currentParam = string.Empty;
            string currentValue = string.Empty;
            bool readingParam = false;
            bool readingValue = false;
            bool startQuotes = false;
            foreach (char c in arguments)
            {
                if (IsPrefix(c))
                {
                    HandlePrefix(Params, ref currentParam, ref currentValue, ref readingParam);
                    continue;
                }
                if (readingParam)
                {
                    HandleParam(ref currentParam, ref readingParam, ref readingValue, c);
                    continue;
                }
                if (readingValue)
                {
                    HandleValue(ref currentValue, ref startQuotes, c);
                    continue;
                }

            }
            if (!string.IsNullOrEmpty(currentParam))
            {
                Params.Add(currentParam, currentValue);
            }
        }

        private void SetDefaultValues()
        {
            QuoteChars = "\"\'";
            ValueSeparatorChars = ":= ";
            PrefixChars = "-/";
        }

        private void HandlePrefix(Dictionary list, ref string currentParam, ref string currentValue, ref bool readingParam)
        {
            if (!string.IsNullOrEmpty(currentParam))
            {
                list.Add(currentParam, currentValue);
            }
            currentParam = string.Empty;
            currentValue = string.Empty;
            readingParam = true;
        }

        private void HandleValue(ref string currentValue, ref bool startQuotes, char c)
        {
            if (IsQuote(c))
            {
                startQuotes = !startQuotes;
                return;
            }
            if (!startQuotes && char.IsWhiteSpace(c))
            {
                return;
            }
            currentValue += c;
        }

        private void HandleParam(ref string currentParam, ref bool readingParam, ref bool readingValue, char c)
        {
            bool isValueSeparator = IsValueSeparator(c);
            if (!isValueSeparator)
            {
                currentParam += c;
            }
            else
            {
                readingValue = true;
                readingParam = false;
            }
        }

        private bool IsQuote(char c)
        {
            return QuoteChars.IndexOf(c) > -1;
        }

        private bool IsValueSeparator(char c)
        {
            return ValueSeparatorChars.IndexOf(c) > -1;
        }

        private bool IsPrefix(char c)
        {
            return PrefixChars.IndexOf(c) > -1;
        }
    }
}

Share: