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.3 2008/05/02 00:45:24 nilsson Exp $ + // $Id: Arg.pmod,v 1.4 2008/05/03 14:18:53 nilsson Exp $   //      #pike __REAL_VERSION__    - class ArgLibrary + class OptLibrary   {       //! Base class for parsing an argument. Inherit this class to create -  //! custom made argument types. -  class Arg +  //! custom made option types. +  class Opt    { -  constant is_arg = 1; -  static Arg next; +  constant is_opt = 1; +  static Opt 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.    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()@}. -  array(string) get_args() +  //! Should return a list of options that are parsed. To properly +  //! chain argument parsers, return @expr{your_opts + +  //! ::get_opts()@}. +  array(string) get_opts()    { -  return next->get_args(); +  return next->get_opts();    }       static this_program `|(mixed thing)    { -  if( !objectp(thing) || !thing->is_arg ) +  if( !objectp(thing) || !thing->is_opt )    error("Can only or %O with another %O.\n",    this, this_program);       if( next )    {    next = next | thing;    return this;    }       next = thing;
pike.git/lib/modules/Arg.pmod:61:    static string _sprintf(int t)    {    if( t!='O' ) return UNDEFINED;    if( !next )    return __sprintf();    else    return sprintf("%s|%O", __sprintf(), next);    }    }    -  //! Parses an argument without parameter, such as --help, -x or "x" +  //! Parses an option without parameter, such as --help, -x or "x"    //! from -axb.    //!    //! @example -  //! Arg verbose = NoArg("-v")|NoArg("--verbose"); -  class NoArg +  //! Opt verbose = NoOpt("-v")|NoOpt("--verbose"); +  class NoOpt    { -  inherit Arg; -  static string arg; +  inherit Opt; +  static string opt;    static int double;    -  static void create(string _arg) +  static void create(string _opt)    { -  if( sizeof(_arg)>2 && has_prefix(_arg, "--") ) +  if( sizeof(_opt)>2 && has_prefix(_opt, "--") )    double = 1; -  else if( sizeof(_arg)!=2 || _arg[0]!='-' || _arg=="--" ) -  error("%O not a valid argument.\n", _arg); -  arg = _arg; +  else if( sizeof(_opt)!=2 || _opt[0]!='-' || _opt=="--" ) +  error("%O not a valid option.\n", _opt); +  opt = _opt;    }       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 ) +  if( argv[0]==opt )    {    argv[0] = 0;    return 1;    }    return ::get_value(argv, env);    }       if( sizeof(argv[0])>1 && argv[0][0]=='-' && argv[0][1]!='-' )    {    array parts = argv[0]/"="; -  if( has_value(parts[0], arg[1..1]) ) +  if( has_value(parts[0], opt[1..1]) )    { -  parts[0] -= arg[1..1]; +  parts[0] -= opt[1..1];    argv[0] = parts*"=";    if(argv[0]=="-") argv[0] = 0;    return 1;    }    }       return ::get_value(argv, env);    }    -  array(string) get_args() +  array(string) get_opts()    { -  return ({ arg }) + ::get_args(); +  return ({ opt }) + ::get_opts();    }       static string __sprintf()    { -  return sprintf("%O(%O)", this_program, arg); +  return sprintf("Arg.NoOpt(%O)", opt);    }    }    -  //! Environment fallback for an argument. Can of course be used as -  //! only Arg source. +  //! Environment fallback for an option. Can of course be used as +  //! only Opt source.    //!    //! @example -  //! Arg debug = NoArg("--debug")|Env("MY_DEBUG"); +  //! Opt debug = NoOpt("--debug")|Env("MY_DEBUG");    class Env    { -  inherit Arg; +  inherit Opt;    static string name;       static void create(string _name)    {    name = _name;    }       int(0..1)|string get_value(array(string) argv, mapping(string:string) env)    {    if( env[name] ) return env[name];    return ::get_value(argv, env);    }       static string __sprintf()    { -  return sprintf("%O(%O)", this_program, name); +  return sprintf("Arg.Env(%O)", name);    }    }       //! Default value for a setting.    //!    //! @example -  //! Arg output = HasArg("-o")|Default("a.out"); +  //! Opt output = HasOpt("-o")|Default("a.out");    class Default    { -  inherit Arg; +  inherit Opt;    static string value;       static void create(string _value)    {    value = _value;    }       string get_value(array(string) argv, mapping(string:string) env)    {    return value;    }       static string __sprintf()    { -  return sprintf("%O(%O)", this_program, value); +  return sprintf("Arg.Default(%O)", value);    }    }    -  //! Parses an argument that may have a parameter. @tt{--foo@}, +  //! Parses an option 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@}.    //!    //! @example -  //! Arg debug = MaybeArg("--debug"); -  class MaybeArg +  //! Opt debug = MaybeOpt("--debug"); +  class MaybeOpt    { -  inherit NoArg; +  inherit NoOpt;       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 ) +  if( argv[0]==opt )    {    argv[0] = 0;    return 1;    }       // --foo=bar -  if( sscanf(argv[0], arg+"=%s", string ret)==1 ) +  if( sscanf(argv[0], opt+"=%s", string ret)==1 )    {    argv[0] = 0;    return ret;    }       return ::get_value(argv, env);    }       // -x    if( sizeof(argv[0])>1 && argv[0][0]=='-' && argv[0][1]!='-' )    {    array parts = argv[0]/"=";    -  if( has_value(parts[0], arg[1..1]) && +  if( has_value(parts[0], opt[1..1]) &&    ( sizeof(parts)==1 || -  parts[0][-1]!=arg[1] ) ) +  parts[0][-1]!=opt[1] ) )    {    // -xy, -xy=z -  parts[0] -= arg[1..1]; +  parts[0] -= opt[1..1];    argv[0] = parts*"=";    if(argv[0]=="-") argv[0] = 0;    return 1;    } -  else if( sizeof(parts)>1 && parts[0][-1]==arg[1] ) +  else if( sizeof(parts)>1 && parts[0][-1]==opt[1] )    {    // -yx=z -  parts[0] -= arg[1..1]; +  parts[0] -= opt[1..1];    if( parts[0]=="-" )    argv[0] = 0;    else    argv[0] = parts[0];    return parts[1..]*"=";    }       return ::get_value(argv, env);    }       return ::get_value(argv, env);    } -  +  +  static string __sprintf() +  { +  return sprintf("Arg.MaybeOpt(%O)", opt);    } -  +  }    -  //! Parses an argument that has a parameter. @tt{--foo=bar@}, @tt{-x +  //! Parses an option that has a parameter. @tt{--foo=bar@}, @tt{-x    //! bar@} and @tt{-x=bar@} will set the variable to @expr{bar@}.    //!    //! @example -  //! Arg user = HasArg("--user")|HasArg("-u"); -  class HasArg +  //! Opt user = HasOpt("--user")|HasOpt("-u"); +  class HasOpt    { -  inherit NoArg; +  inherit NoOpt;       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( argv[0]==opt )    {    if( sizeof(argv)>1 )    {    argv[0] = 0;    string ret = argv[1];    argv[1] = 0;    return ret;    }    return 0; // FIXME: Signal failure    }       // --foo=bar -  if( sscanf(argv[0], arg+"=%s", string ret)==1 ) +  if( sscanf(argv[0], opt+"=%s", string ret)==1 )    {    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] ) +  if( sizeof(parts[0]) && parts[0][-1]==opt[1] )    {    if( sizeof(parts)==1 )    {    // "-xxxy z"    if(sizeof(argv)>1)    { -  parts[0] -= arg[1..1]; +  parts[0] -= opt[1..1];    if( parts[0]=="-" )    argv[0] = 0;    else    argv[0] = parts[0];    string ret = argv[1];    argv[1] = 0;    return ret;    }       // Fail. "-y" without any more elements in argv.    return ::get_value(argv, env);    }    else    {    // "-xxxy=z" -  parts[0] -= arg[1..1]; +  parts[0] -= opt[1..1];    if( parts[0]=="-" )    argv[0] = 0;    else    argv[0] = parts[0];    return parts[1..]*"=";    }    }    }       return ::get_value(argv, env);    } -  +  +  static string __sprintf() +  { +  return sprintf("Arg.HasOpt(%O)", opt);    } -  +  }    - } // -- ArgLibrary + } // -- OptLibrary      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")); + // FIXME: Support for rc files? ( Opt x = Opt("--x")|INIFile(path, name); ) + // FIXME: Support for type casts? ( Opt level = Integer(Opt("--level"));      class LowOptions   { -  static inherit ArgLibrary; +  static inherit OptLibrary;    -  static mapping(string:Arg) args = ([]); +  static mapping(string:Opt) opts = ([]);    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; +  if(objectp(val) && val->is_opt) opts[index]=val;    }       argv = _argv[1..]; -  mapping(string:Arg) unset = args+([]); +  mapping(string:Opt) unset = opts+([]);       while(1)    { -  +  if(!sizeof(argv)) break; +     int(0..1)|string value; -  foreach(unset; string index; Arg arg) +  foreach(unset; string index; Opt 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)? +  int(0..1)|string value; +  foreach(unset; string index; Opt arg) +  { +  value = arg->get_value(({}), env); +  if(value) +  { +  m_delete(unset, index); +  values[index] = value;    } -  +  } +  }       }       static int(0..1) unhandled_argument(array(string) argv,    mapping(string:string) env)    {    return 0;    }       static mixed cast(string to)
pike.git/lib/modules/Arg.pmod:425:       static int(0..1)|string unhandled_argument(array(string) argv,    mapping(string:string) env)    {    if( !sizeof(argv) || argv[0]!="--help" ) return 0;       string s = index("help_pre");    if( s )    write( s+"\n" );    -  foreach(args; string i; Arg arg) +  foreach(opts; string i; Opt opt)    {    // FIXME: Make a list of the attibutes parsed by arg.       s = index(i+"_help");    if( s )    write( s ); // FIXME: Format    }       s = index("help_post");    if( s )
pike.git/lib/modules/Arg.pmod:500:   // --foo -> "foo":1   // --foo=bar -> "foo":"bar"   // -bar -> "b":1,"a":1,"r":1   // -bar=foo -> "b":1,"a":1,"r":"foo" (?)   // --foo --bar -> "foo":1,"bar":1   // --foo - --bar -> "foo":1   // --foo x --bar -> "foo":1 (?)   //   // void main(int n, array argv)   // { - // mapping args = Arg.parse(argv); - // argv = args[Arg.REST]; + // mapping opts = Arg.parse(argv); + // argv = opts[Arg.REST];   // }         mapping(string:string|int(1..1)) parse(array(string) argv)   {    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) - { -  Options o = Getopt(args); -  werror("%O\n", (mapping)o ); - } +