Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Ticket #688: ArgParser.diff

File ArgParser.diff, 5.1 kB (added by Jim Panic, 10 months ago)
  • tango/util/ArgParser.d

    old new  
    3838*/ 
    3939alias void delegate () ArgParserSimpleCallback; 
    4040 
     41 
    4142/** 
     43    A struct that represents a "{Prefix}{Identifier}" string. 
     44*/ 
     45struct Argument { 
     46    char[] prefix; 
     47    char[] identifier; 
     48 
     49    /** 
     50        Creates a new Argument instance with given prefix and identifier. 
     51    */ 
     52    static Argument opCall ( char[] prefix, char[] identifier ) { 
     53        Argument result; 
     54 
     55        result.prefix = prefix; 
     56        result.identifier = identifier; 
     57 
     58        return result; 
     59    } 
     60} 
     61 
     62/** 
     63    Alias for for the lazy people. 
     64*/ 
     65alias Argument Arg; 
     66 
     67 
     68/** 
    4269    A utility class to parse and handle your command line arguments. 
    4370*/ 
    4471class ArgParser{ 
     
    153180    } 
    154181 
    155182    /** 
     183        Binds a delegate callback to an argument. 
     184 
     185        Params: 
     186            argument = argument to respond to 
     187            callback = the delegate that should be called when the argument is found 
     188    */ 
     189    public void bind (Argument argument, ArgParserCallback callback) { 
     190        bind(argument.prefix, argument.identifier, callback); 
     191    } 
     192 
     193    /** 
     194        Binds a delegate callback to a couple of arguments. 
     195 
     196        Params: 
     197            arguments = an array of Argument struct instances 
     198            callback = the delegate that should be called when one of the arguments is found 
     199    */ 
     200    public void bind ( Argument[] arguments, void delegate(char[]) callback ) { 
     201        foreach (argument; arguments) { bind(argument, callback); } 
     202    } 
     203 
     204    /** 
     205        Binds a delegate callback to an identifier, the sloppy way. This means, 
     206        it binds for both prefixes "-" and "--", as well as identifier with, and 
     207        without a delimiting "=" between identifier and value. 
     208 
     209        Params: 
     210            identifier = argument identifier 
     211            callback = the delegate that should be called when one of the arguments is found 
     212    */ 
     213    public void bindSimilar ( char[] identifier, ArgParserCallback callback ) { 
     214        bind([ Argument("-", identifier ~ "="), Argument("-", identifier), 
     215               Argument("--", identifier ~ "="), Argument("--", identifier) ], callback); 
     216    } 
     217 
     218    /** 
     219        Binds a delegate callback to a bunch of identifiers, the sloppy way.  
     220        See bindSimilar(identifier, callback). 
     221 
     222        Params: 
     223            arguments = an array of argument identifiers 
     224            callback = the delegate that should be called when one of the arguments is found 
     225    */ 
     226    public void bindSimilar ( char[][] identifiers, ArgParserCallback callback ) { 
     227        foreach (identifier; identifiers) { bindSimilar(identifier, callback); } 
     228    } 
     229 
     230    /** 
    156231        Parses the arguments provided by the parameter. The bound 
    157232        callbacks are called as arguments are recognized. 
    158233 
     
    162237    */ 
    163238    public void parse(char[][] arguments, bool resetOrdinals = false){ 
    164239        if (bindings.length == 0) return; 
     240 
    165241        if (resetOrdinals) { 
    166242            defaultOrdinal = 0; 
    167243            foreach (key; prefixOrdinals.keys) { 
     
    171247 
    172248        foreach (char[] arg; arguments) { 
    173249            char[] argData = arg; 
     250            char[] argOrig = argData; 
    174251            bool found = false; 
    175             char[] argOrig = argData; 
     252 
    176253            foreach (char[] prefix; prefixSearchOrder) { 
    177254                if(argData.length < prefix.length) continue;  
    178                 if(argData[0..prefix.length] != prefix) { 
    179                     continue; 
    180                 } 
    181                 else { 
    182                     argData = argData[prefix.length..$]; 
    183                 }  
     255 
     256                if(argData[0..prefix.length] != prefix) continue; 
     257                else argData = argData[prefix.length..$]; 
     258 
    184259                if (prefix in bindings) { 
     260                    PrefixCallback[] candidates; 
     261 
    185262                    foreach (PrefixCallback cb; bindings[prefix]) { 
    186263                        if (argData.length < cb.id.length) continue; 
     264                         
    187265                        uint cbil = cb.id.length; 
     266 
    188267                        if (cb.id == argData[0..cbil]) { 
    189268                            found = true; 
    190                             argData = argData[cbil..$]; 
    191                             cb.cb(argData); 
    192                             break; 
     269                            candidates ~= cb; 
    193270                        } 
    194271                    } 
     272 
     273                    if (found) { 
     274                        // Find the longest matching callback identifier from the candidates. 
     275                        uint indexLongestMatch = 0; 
     276 
     277                        if (candidates.length > 1) { 
     278                            foreach (i, candidate; candidates) { 
     279                                if (candidate.id.length > candidates[indexLongestMatch].id.length) { 
     280                                    indexLongestMatch = i; 
     281                                } 
     282                            } 
     283                        } 
     284 
     285                        // Call the best matching callback. 
     286                        with(candidates[indexLongestMatch]) { cb(argData[id.length..$]); } 
     287                    } 
    195288                } 
    196289                if (found) { 
    197290                    break;