pike.git / lib / modules / Arg.pmod

version» Context lines:

pike.git/lib/modules/Arg.pmod:1:   //   // Argument parser   // By Martin Nilsson - // $Id: Arg.pmod,v 1.2 2008/05/01 21:07:35 nilsson Exp $ + // $Id: Arg.pmod,v 1.3 2008/05/02 00:45:24 nilsson Exp $   //      #pike __REAL_VERSION__    -  + class ArgLibrary + { +     //! Base class for parsing an argument. Inherit this class to create    //! custom made argument types.    class Arg    {    constant is_arg = 1;    static Arg next;    -  //! Should return 1 for set options or a string containing the value -  //! of the option. Returning 0 means the option was not set (or -  //! matched). To properly chain arguments parsers, return -  //! @expr{::get_value(argv, env)@} instead of @expr{0@}, unless you -  //! want to explicitly stop the chain and not set this option. +  //! Should return 1 for set options or a string containing the +  //! value of the option. Returning 0 means the option was not set +  //! (or matched). To properly chain arguments parsers, return +  //! @expr{::get_value(argv, env)@} instead of @expr{0@}, unless +  //! you want to explicitly stop the chain and not set this option.    int(0..1)|string get_value(array(string) argv, mapping(string:string) env)    {    if(next) return next->get_value(argv, env);    return 0;    }       //! Should return a list of arguments that is parsed. To properly -  //! chain argument parsers, return @expr{your_args + ::get_args()@}. +  //! chain argument parsers, return @expr{your_args + +  //! ::get_args()@}.    array(string) get_args()    {    return next->get_args();    }       static this_program `|(mixed thing)    {    if( !objectp(thing) || !thing->is_arg )    error("Can only or %O with another %O.\n",    this, this_program);
pike.git/lib/modules/Arg.pmod:40:    if( next )    {    next = next | thing;    return this;    }       next = thing;    return this;    }    -  //! This function will be called by @expr{_sprintf@}, which handles -  //! formatting of chaining between objects. +  //! This function will be called by @expr{_sprintf@}, which +  //! handles formatting of chaining between objects.    static string __sprintf()    {    return sprintf("%O()", this_program);    }       static string _sprintf(int t)    {    if( t!='O' ) return UNDEFINED;    if( !next )    return __sprintf();
pike.git/lib/modules/Arg.pmod:79:    {    if( sizeof(_arg)>2 && has_prefix(_arg, "--") )    double = 1;    else if( sizeof(_arg)!=2 || _arg[0]!='-' || _arg=="--" )    error("%O not a valid argument.\n", _arg);    arg = _arg;    }       int(0..1)|string get_value(array(string) argv, mapping(string:string) env)    { +  if( !sizeof(argv) ) return ::get_value(argv, env); +     if( double )    {    if( argv[0]==arg )    {    argv[0] = 0;    return 1;    }    return ::get_value(argv, env);    }   
pike.git/lib/modules/Arg.pmod:168:    return value;    }       static string __sprintf()    {    return sprintf("%O(%O)", this_program, value);    }   }      //! Parses an argument that may have a parameter. @tt{--foo@}, - //! @tt{-x@} and x in a sequence like @tt{-axb@} will set the variable - //! to @expr{1@}. @tt{--foo=bar@}, @tt{-x bar@} and @tt{-x=bar@} will - //! set the variable to @expr{bar@}. +  //! @tt{-x@} and x in a sequence like @tt{-axb@} will set the +  //! variable to @expr{1@}. @tt{--foo=bar@}, @tt{-x bar@} and +  //! @tt{-x=bar@} will set the variable to @expr{bar@}.    //!    //! @example - //! Arg debug = MaybyArg("--debug"); - class MaybyArg +  //! Arg debug = MaybeArg("--debug"); +  class MaybeArg    {    inherit NoArg;       int(0..1)|string get_value(array(string) argv, mapping(string:string) env)    { -  +  if( !sizeof(argv) ) return ::get_value(argv, env); +     if( double )    {    // --foo    if( argv[0]==arg )    {    argv[0] = 0;    return 1;    }       // --foo=bar
pike.git/lib/modules/Arg.pmod:243:   //! bar@} and @tt{-x=bar@} will set the variable to @expr{bar@}.   //!   //! @example   //! Arg user = HasArg("--user")|HasArg("-u");   class HasArg   {    inherit NoArg;       int(0..1)|string get_value(array(string) argv, mapping(string:string) env)    { +  if( !sizeof(argv) ) return ::get_value(argv, env); +     if( double )    {    // --foo bar    if( argv[0]==arg )    {    if( sizeof(argv)>1 )    {    argv[0] = 0;    string ret = argv[1];    argv[1] = 0;
pike.git/lib/modules/Arg.pmod:270:    {    argv[0] = 0;    return ret;    }    return ::get_value(argv, env);    }       if( sizeof(argv[0])>1 && argv[0][0]=='-' && argv[0][1]!='-' )    {    array parts = argv[0]/"="; -  if( sizeof(parts[0]) && parts[0][-1]==arg[1..1] ) +  if( sizeof(parts[0]) && parts[0][-1]==arg[1] )    {    if( sizeof(parts)==1 )    {    // "-xxxy z"    if(sizeof(argv)>1)    {    parts[0] -= arg[1..1];    if( parts[0]=="-" )    argv[0] = 0;    else
pike.git/lib/modules/Arg.pmod:307:    argv[0] = parts[0];    return parts[1..]*"=";    }    }    }       return ::get_value(argv, env);    }   }    + } // -- ArgLibrary +    object REST = class {    static string _sprintf(int t)    {    return "Arg.REST";    }    }();      // FIXME: Support for rc files? ( Arg x = Arg("--x")|INIFile(path, name); )   // FIXME: Support for type casts? ( Arg level = Integer(Arg("--level"));      class LowOptions   { -  +  static inherit ArgLibrary; +     static mapping(string:Arg) args = ([]);    static mapping(string:int(1..1)|string) values = ([]);    static array(string) argv;       static void create(array(string) _argv, void|mapping(string:string) env)    {    if(!env)    env = getenv();       // Make a list of all the arguments we can parse.    foreach(::_indices(2), string index)    {    mixed val = ::`[](index, 2);    if(objectp(val) && val->is_arg) args[index]=val;    }       argv = _argv[1..];    mapping(string:Arg) unset = args+([]); -  +     while(1)    { -  if(!sizeof(argv)) break; -  +     int(0..1)|string value;    foreach(unset; string index; Arg arg)    {    value = arg->get_value(argv, env);    if(value)    {    m_delete(unset, index);    values[index] = value;    break;    }    }       if(!value)    value = unhandled_argument(argv, env);       if(!value)    break;    else    while( sizeof(argv) && argv[0] == 0 )    argv = argv[1..]; -  +  +  if(!sizeof(argv)) break;    }    if( sizeof(unset) )    {    // FIXME: Make sure all fallbacks are properly fetched. Call    // with (0, env)?    }       }       static int(0..1) unhandled_argument(array(string) argv,
pike.git/lib/modules/Arg.pmod:404:    return values[id];    }    static string|int `->(string id)    {    return values[id];    }       static int(0..1)|string unhandled_argument(array(string) argv,    mapping(string:string) env)    { -  if( argv[0]!="--help" ) return 0; +  if( !sizeof(argv) || argv[0]!="--help" ) return 0;       string s = index("help_pre");    if( s )    write( s+"\n" );       foreach(args; string i; Arg arg)    {    // FIXME: Make a list of the attibutes parsed by arg.       s = index(i+"_help");
pike.git/lib/modules/Arg.pmod:502:    return (mapping)SimpleOptions(argv);   }         // --- test stuff      class Getopt   {    inherit Options;    Arg verbose = NoArg("-v")|NoArg("--verbose")|Env("VERBOSE"); +  Arg name = HasArg("-n")|HasArg("--name")|Default("Donald"); +  Arg debug = MaybeArg("-d")|MaybeArg("--debug");   }         void main(int num, array args)   { -  // werror("%O\n", Getopt( args )->verbose ); -  werror("%O\n", parse(args)); +  Options o = Getopt(args); +  werror("%O\n", (mapping)o );   }