Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

vul_arg.cxx

Go to the documentation of this file.
00001 // This is core/vul/vul_arg.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // Note that even though this file defines instances of a templated
00008 // class, it is a .cxx file and not a .txx file because it does not
00009 // supply a class definition for use by clients.
00010 //
00011 // If you need to define your own vul_arg<T>, you should #include vul_arg.h
00012 // ONLY, in your source file (myarg.cxx, say), define these three global
00013 // functions (which can by static if you like) in myarg.cxx
00014 // \code
00015 //   void settype(vul_arg<T> &);
00016 //   void print_value(vul_arg<T> const &, vcl_ostream &);
00017 //   int  parse(vul_arg<T>*, char**);
00018 // \endcode
00019 // and then instantiate the class vul_arg<T> as usual (in myarg.cxx).
00020 
00021 #include "vul_arg.h"
00022 
00023 #include <vcl_cassert.h>
00024 #include <vcl_algorithm.h>
00025 #include <vcl_iostream.h>
00026 #include <vcl_cstring.h>
00027 #include <vcl_cstdlib.h> // exit()
00028 #include <vcl_cmath.h>   // floor()
00029 #include <vcl_vector.h>
00030 #include <vcl_list.h>
00031 
00032 #include <vul/vul_sprintf.h>
00033 #include <vul/vul_string.h>
00034 #include <vul/vul_reg_exp.h>
00035 #include <vul/vul_printf.h>
00036 
00037 //------------------------------------------------------------------------------
00038 
00039 char const* vul_arg_base::option()
00040 { return option_.c_str(); }
00041 
00042 char const* vul_arg_base::help()
00043 { return help_.c_str(); }
00044 
00045 //: Parse the list of arguments....
00046 void vul_arg_parse(int& argc, char **& argv,
00047                    bool warn_about_unrecognized_arguments)
00048 {
00049   vul_arg_base::parse_deprecated(argc, argv,
00050                                  warn_about_unrecognized_arguments);
00051 }
00052 
00053 //: Add an externally supplied list of args to the global list.
00054 void vul_arg_include(vul_arg_info_list& l)
00055 {
00056   vul_arg_base::include_deprecated(l);
00057 }
00058 
00059 //: Print all args, and usage messages.
00060 void vul_arg_display_usage_and_exit(char const* msg)
00061 {
00062   vul_arg_base::display_usage_and_exit(msg);
00063 }
00064 
00065 
00066 //: Returns true if arg was set on the command line.
00067 bool vul_arg_base::set() const
00068 { return set_; }
00069 
00070 static vul_arg_info_list& current_list() // instance "method"
00071 {
00072   static vul_arg_info_list list;
00073   return list;
00074 }
00075 
00076 //: Add another vul_arg_info_list to the current one.
00077 // This allows for the inclusion of different sets of arguments into the
00078 // main program, from different libraries.
00079 void vul_arg_base::include_deprecated(vul_arg_info_list& l)
00080 {
00081   current_list().include(l);
00082 }
00083 
00084 //
00085 void vul_arg_base::add_to_current(vul_arg_base* a)
00086 {
00087   current_list().add(a);
00088 }
00089 
00090 //: The main static method.
00091 void vul_arg_base::parse_deprecated(int& argc, char **& argv, bool warn_about_unrecognized_arguments)
00092 {
00093   current_list().parse(argc, argv, warn_about_unrecognized_arguments);
00094 }
00095 
00096 void vul_arg_base::set_help_option(char const* str)
00097 {
00098   current_list().set_help_option( str);
00099 }
00100 
00101 void vul_arg_base::set_help_precis(char const* str)
00102 {
00103   current_list().set_help_precis( str);
00104 }
00105 
00106 void vul_arg_base::set_help_description(char const* str)
00107 {
00108   current_list().set_help_description( str);
00109 }
00110 
00111 void vul_arg_base::display_usage(char const* msg)
00112 {
00113   if (msg) vcl_cerr << "** WARNING ** " << msg << vcl_endl;
00114   current_list().display_help("");
00115 }
00116 
00117 void vul_arg_base::display_usage_and_exit(char const* msg)
00118 {
00119   if (msg) vcl_cerr << "** ERROR ** " << msg << vcl_endl;
00120   current_list().display_help("");
00121   vcl_exit(-1);
00122 }
00123 
00124 // vul_arg_base constructors
00125 
00126 vul_arg_base::vul_arg_base(vul_arg_info_list& l, char const* option_string, char const* helpstring)
00127 : option_(option_string?option_string:"\0"),
00128   help_(helpstring?helpstring:"\0")
00129 {
00130   l.add(this);
00131 }
00132 
00133 vul_arg_base::vul_arg_base(char const* option_string, char const* helpstring)
00134 : option_(option_string?option_string:"\0"),
00135   help_(helpstring?helpstring:"\0")
00136 {
00137   current_list().add(this);
00138 }
00139 
00140 //------------------------------------------------------------------------------
00141 
00142 //: Change the help operator (defaults to -?)
00143 void vul_arg_info_list::set_help_option(char const* str)
00144 {
00145   // check that the operator isn't already being used
00146   for (unsigned int i=0; i<args_.size(); i++) {
00147     if (vcl_strcmp(args_[i]->option(),str) == 0) {
00148       vcl_cerr << "vul_arg_info_list: WARNING: requested help operator already assigned\n";
00149       return;
00150     }
00151   }
00152 
00153   help_ = str;
00154 }
00155 
00156 
00157 //: Add an argument to the list.
00158 void vul_arg_info_list::add(vul_arg_base* argmt)
00159 {
00160   if ( argmt->option() && help_ == argmt->option() )
00161     vcl_cerr << "vul_arg_info_list: WARNING: '-" << help_
00162              << "' option reserved and will be ignored\n";
00163   else
00164     args_.push_back(argmt);
00165 }
00166 
00167 //: Append another list.  The other list is not copied, just pointed to.
00168 void vul_arg_info_list::include(vul_arg_info_list& l)
00169 {
00170   assert(&l != this);
00171 
00172   for (unsigned int i = 0; i < l.args_.size(); ++i)
00173     add(l.args_[i]);
00174 }
00175 
00176 //: Display help about each option in the arg list.
00177 // Note that this function does not exit at the end.
00178 void vul_arg_info_list::display_help( char const*progname)
00179 {
00180   if (progname)
00181     vcl_cerr << "Usage: " << progname << ' ';
00182   else
00183     vcl_cerr << "Usage: aprog ";
00184 
00185   // Print "prog [-a int] string string"
00186   for (unsigned int i=0; i< args_.size(); i++) {
00187     if (args_[i]->option()) {
00188       vcl_cerr << '[' << args_[i]->option();
00189       if (vcl_strlen(args_[i]->type_)> 0)
00190         vcl_cerr << ' ' << args_[i]->type_;
00191       vcl_cerr << "] ";
00192     } else {
00193       // options without switches are required.
00194       vcl_cerr << args_[i]->type_ << ' ';
00195     }
00196   }
00197 
00198   vcl_cerr << vcl_endl << command_precis_ << vcl_endl;
00199 
00200   // Find longest option, type name, or default
00201   int maxl_option  = vcl_max(vcl_size_t(8), help_.size()); // Length of "REQUIRED" or help option
00202   int maxl_type    = 4; // Length of "Type", minimum "bool"
00203   //  int maxl_default = 0;
00204   for (unsigned int i=0; i< args_.size(); i++)
00205     if (!args_[i]->help_.empty()) {
00206       if (!args_[i]->option_.empty()) {
00207         int l = vcl_strlen(args_[i]->option());
00208         if (l > maxl_option) maxl_option = l;
00209       }
00210       int l = vcl_strlen(args_[i]->type_);
00211       if (l > maxl_type) maxl_type = l;
00212     }
00213 
00214   // Print long form of args
00215   vcl_string fmtbuf = vul_sprintf("%%%ds %%-%ds %%s ", maxl_option, maxl_type);
00216 
00217   // Do required args first
00218   vul_printf(vcl_cerr, "REQUIRED:\n");
00219   for (unsigned int i=0; i< args_.size(); i++)
00220     if (!args_[i]->help_.empty())
00221       if (args_[i]->option_.empty()) {
00222         vul_printf(vcl_cerr, fmtbuf.c_str(), "", args_[i]->type_, args_[i]->help_.c_str());
00223         vcl_cerr << " ["; args_[i]->print_value(vcl_cerr); vcl_cerr << "]\n"; // default
00224       }
00225   vcl_cerr << vcl_endl;
00226 
00227   // Then others
00228   vul_printf(vcl_cerr, "Optional:\n");
00229   vul_printf(vcl_cerr, fmtbuf.c_str(), "Switch", "Type", "Help [default value]") << vcl_endl << vcl_endl;
00230   for (unsigned int i=0; i< args_.size(); i++)
00231     if (!args_[i]->help_.empty())
00232       if (!args_[i]->option_.empty()) {
00233         vul_printf(vcl_cerr, fmtbuf.c_str(), args_[i]->option(), args_[i]->type_, args_[i]->help_.c_str());
00234         vcl_cerr << " ["; args_[i]->print_value(vcl_cerr); vcl_cerr << "]\n"; // default
00235       }
00236   vul_printf(vcl_cerr, fmtbuf.c_str(), help_.c_str(), "bool", "Print this message\n");
00237 
00238   if (!description_.empty()) vcl_cerr << '\n' << description_;
00239 }
00240 
00241 //: Parse the command line, using the current list of args.
00242 //  Remove all recognised arguments from the command line by modifying argc and argv.
00243 void vul_arg_info_list::parse(int& argc, char **& argv, bool warn_about_unrecognized_arguments)
00244 {
00245   vcl_vector<bool> done_once(args_.size(), false);
00246 
00247   // 0. Check that there are no duplicate switches, O(n^2) as n is tiny.
00248   for (unsigned int i = 0; i < args_.size(); ++i)
00249     if (!args_[i]->option_.empty())
00250       for (unsigned int j = i+1; j < args_.size(); ++j)
00251         if (args_[i]->option_ == args_[j]->option_)
00252           vcl_cerr << "vul_arg_info_list: WARNING: repeated switch ["
00253                    << args_[j]->option_ << "]\n";
00254 
00255   // 0a. Clear "set" flags on args
00256   for (unsigned int i = 0; i < args_.size(); ++i)
00257     args_[i]->set_ = false;
00258 
00259   // Generate shorter command name
00260   char * cmdname = argv[0]+vcl_strlen(argv[0]);
00261   while (cmdname > argv[0] && *cmdname != '/' && *cmdname != '\\') --cmdname ;
00262   if (*cmdname == '\\' || *cmdname == '/') cmdname++;
00263 
00264 
00265   // 1. Collect option arguments (i.e. ones with "-"),
00266   // and squeeze them out of argv.
00267   // Make sure to do things sequentially
00268 
00269   char ** my_argv = argv + 1; // Skip program name
00270   while (*my_argv) {
00271     char* argmt = *my_argv;
00272     bool eaten = false;
00273     for (unsigned int i = 0; i < args_.size(); ++i) {
00274       if (!args_[i]->option_.empty()) {
00275         if ( help_ == argmt ) { // look for the '-?' operator (i.e. HELP)
00276           display_help(cmdname);
00277           vcl_exit(1);
00278         }
00279 
00280         if (args_[i]->option_==argmt) {
00281           done_once[i] = true;
00282           int advance = args_[i]->parse(my_argv + 1);
00283           args_[i]->set_ = true;
00284           if (advance >= 0) {
00285             // Pull down remaining args
00286             for (char ** av = my_argv; *(av + advance); ++av)
00287               *av = *(av + advance + 1);
00288 
00289             eaten = true;
00290             break;
00291           }
00292         }
00293       }
00294     }
00295     if (!eaten)
00296       ++my_argv;
00297   }
00298 
00299   if (verbose_) {
00300     vcl_cerr << "args remaining:";
00301     for (char ** av = argv; *av; ++av)
00302       vcl_cerr << " [" << *av << ']';
00303     vcl_cerr << vcl_endl;
00304   }
00305 
00306 
00307   // 2. Just take from the list to fill the non-option arguments
00308   my_argv = argv + 1;
00309   int num_satisfied = 0;
00310   for (unsigned int i = 0; i < args_.size(); ++i)
00311     if (args_[i]->option_.empty())
00312       if (*my_argv) {
00313         done_once[i] = true;
00314         int advance = args_[i]->parse(my_argv);
00315         args_[i]->set_ = true;
00316         my_argv += advance;
00317         ++num_satisfied;
00318       } else {
00319         display_help(cmdname);
00320 
00321         vcl_cerr << "\nargParse::ERROR: Required arg " << (num_satisfied+1)
00322                  << " not supplied\n\n";
00323         vcl_exit(1);
00324       }
00325 
00326 
00327   // 3. Move my_argv down to first unused arg, and reset argc
00328   argc = 1;
00329   for (char ** av = my_argv; *av; ++av)
00330     ++argc;
00331   for (int i = 1; i < argc; ++i)
00332     argv[i] = my_argv[i-1];
00333   argv[argc] = 0;
00334 
00335   // 4. Error checking.
00336   //
00337   // 4.2 Sometimes it's bad if all args weren't used (i.e. trailing args)
00338   if (autonomy_ == all) {
00339     vcl_cerr << "vul_arg_info_list: Some arguments were unused: ";
00340     for (char ** av = argv; *av; ++av)
00341       vcl_cerr << ' ' << *av;
00342     vcl_cerr << vcl_endl;
00343     display_help(cmdname);
00344   }
00345 
00346   // 4.3 It's often bad if a switch was not recognized.
00347   if (warn_about_unrecognized_arguments)
00348     for (char ** av = argv; *av; ++av)
00349       if (**av == '-') {
00350         display_help(cmdname);
00351         vcl_cerr << "vul_arg_info_list: WARNING: Unparsed switch [" << *av << "]\n";
00352       }
00353 
00354   // 5. Some people like a chatty program.
00355 #ifdef DEBUG //fsm: do not print outcome - it looks like an error message.
00356   if (verbose_) {
00357     // Print outcome
00358     for (unsigned int i = 0; i < args_.size(); ++i)
00359       if (args[i]->option_) {
00360         vcl_cerr << "Switch " << args_[i]->option_ << ": "
00361                  << (!done_once[i] ? "not " : "") << "done, value [";
00362         args[i]->print_value(vcl_cerr);
00363         vcl_cerr << "]\n";
00364       }
00365 
00366     for (unsigned int i = 0; i < args.size(); ++i)
00367       if (!args[i]->option_) {
00368         vcl_cerr << "Trailer: ";
00369         args_[i]->print_value(vcl_cerr);
00370         vcl_cerr << vcl_endl;
00371       }
00372 
00373     vcl_cerr << "args remaining [argc = " << argc << "]:";
00374     for (char ** av = argv; *av; ++av)
00375       vcl_cerr << ' ' << *av;
00376     vcl_cerr << "\n--------------\n";
00377   }
00378 #endif
00379 }
00380 
00381 
00382 //------------------------------------------------------------------------------
00383 
00384 //: function to parse matlab or UNIX style integer ranges.
00385 // eg. 1:3 is matlab for 1,2,3 and 1-3 is UNIX for 1,2,3
00386 //
00387 // parsed as follows:
00388 //   any character other than '-' and ':' is considered a list separator
00389 //   simple ranges can be written as 1:3 or 1-3 (=1,2,3) or 3:1 (=3,2,1)
00390 //   complete ranges can be written as 1:2:5 or 1-2-5 (=1,3,5)
00391 //   negative numbers are handled 'transparently'
00392 //   (e.g. -1:-3 or -1--3 or even -1--1--3 ...:).
00393 //
00394 // Returns 1 on success and 0 on failure.
00395 //
00396 static int list_parse(vcl_list<int> &out, char ** argv)
00397 {
00398   out.clear();
00399 
00400   // Empty list specified as the last argument.
00401   if ( !argv[0] ) return 0; // failure
00402 
00403   vcl_string str(argv[0]);
00404 
00405 #define REGEXP_INTEGER "\\-?[0123456789]+"
00406 
00407   vul_reg_exp range_regexp("(" REGEXP_INTEGER ")"      // int
00408                            "([:-]" REGEXP_INTEGER ")?" // :int [optional]
00409                            "([:-]" REGEXP_INTEGER ")?" // :int [optional]
00410                           );
00411 
00412   while (str.length() > 0 && range_regexp.find(str)) {
00413     // the start/end positions (ref from 0) of the
00414     //    current ',' separated token.
00415     vcl_ptrdiff_t start= range_regexp.start(0);
00416     vcl_ptrdiff_t endp = range_regexp.end(0);
00417     if (start != 0) {
00418       vcl_cerr << "vul_arg<vcl_list<int> >: Bad argument [" << argv[0] << "]\n";
00419       return 0; // failure
00420     }
00421 
00422 #ifdef DEBUG
00423     // this is the current token.
00424     vcl_string token = str.substr(start, endp);
00425     vcl_cerr << "token = " << token << '\n';
00426 #endif
00427     vcl_string match1 = range_regexp.match(1);
00428 #ifdef DEBUG
00429     vcl_cerr << "match1 = " << match1 << '\n';
00430 #endif
00431     vcl_string match2 = range_regexp.match(2);
00432 #ifdef DEBUG
00433     vcl_cerr << "match2 = " << match2 << '\n';
00434 #endif
00435     vcl_string match3 = range_regexp.match(3);
00436 #ifdef DEBUG
00437     vcl_cerr << "match3 = " << match3 << '\n';
00438 #endif
00439 
00440     // Remove this match from the front of string.
00441     str.erase(0, endp + 1);
00442 
00443 #if 0
00444     vcl_cerr << "Range regexp matched [" << token <<  "]: parts ["
00445              << match1<<"] ["<<match2<<"] ["<<match3<<"]\n"
00446              << "  str->[" << str << "]\n";
00447 #endif
00448 
00449     bool matched2 = range_regexp.match(2).size() > 0;
00450     bool matched3 = range_regexp.match(3).size() > 0;
00451 
00452     int s = vul_string_atoi(match1);
00453     int d = 1;
00454     int e = s;
00455     if (matched3) {
00456       // "1:2:10"
00457       d = vul_string_atoi(match2.substr(1));
00458       e = vul_string_atoi(match3.substr(1));
00459     }
00460     else if (matched2)
00461       e = vul_string_atoi(match2.substr(1));
00462 
00463 #ifdef DEBUG
00464     vcl_cerr << "  " << s << ':' << d << ':' << e << '\n';
00465 #endif
00466     if (e >= s) {
00467       if (d < 0) {
00468         vcl_cerr << "WARNING: d < 0\n";
00469         d = -d;
00470       }
00471       for (int i = s; i <= e; i += d)
00472         out.push_back(i);
00473     } else {
00474       if (d > 0) {
00475         vcl_cerr << "WARNING: d > 0\n";
00476         d = -d;
00477       }
00478       for (int i = s; i >= e; i += d)
00479         out.push_back(i);
00480     }
00481   }
00482 
00483   return 1; // success
00484 }
00485 
00486 //------------------------------------------------------------------------------
00487 
00488 // specializations for specific types.
00489 // In emacs, C-s for "//: unsigned" to find the implementation for vul_arg<unsigned>
00490 // In vi: "/^\/\/: unsigned"
00491 
00492 #if 1
00493 # define VDS VCL_DEFINE_SPECIALIZATION
00494 #else
00495 # define VDS /* template <> */
00496 #endif
00497 
00498 //: bool
00499 VDS void settype(vul_arg<bool> &argmt) { argmt.type_ = "bool"; }
00500 
00501 VDS void print_value(vcl_ostream &s, vul_arg<bool> const &argmt)
00502 { s << (argmt() ? "set" : "not set"); }
00503 
00504 VDS int parse(vul_arg<bool>* argmt, char ** /*argv*/)
00505 {
00506   argmt->value_ = true;
00507   return 0; // bool sucks zero args, most others take one.
00508 }
00509 
00510 template class vul_arg<bool>;
00511 
00512 //: int
00513 VDS void settype(vul_arg<int> &argmt) { argmt.type_ = "integer"; }
00514 
00515 VDS void print_value(vcl_ostream  &s, vul_arg<int> const &argmt)
00516 { s << argmt(); }
00517 
00518 VDS int parse(vul_arg<int>* argmt, char ** argv)
00519 {
00520   if ( !argv ||  !argv[0] ) {
00521     // no input
00522     vcl_cerr << "vul_arg_parse: Expected integer, none is provided.\n";
00523     return -1;
00524   }
00525 
00526   char* endptr = 0;
00527   double v = vcl_strtod(argv[0], &endptr);
00528   if (*endptr != '\0') {
00529     // There is junk after the number, or no number was found
00530     vcl_cerr << "vul_arg_parse: WARNING: Attempt to parse \"" << *argv << "\" as int\n";
00531     return -1;
00532   }
00533   if (v != vcl_floor(v)) {
00534     vcl_cerr << "vul_arg_parse: Expected integer: saw " << argv[0] << vcl_endl;
00535     return -1;
00536   }
00537   argmt->value_ = int(v);
00538   return 1;
00539 }
00540 
00541 template class vul_arg<int>;
00542 
00543 //: unsigned
00544 VDS void settype(vul_arg<unsigned> &argmt) { argmt.type_ = "integer"; }
00545 
00546 VDS void print_value(vcl_ostream &s, vul_arg<unsigned> const &argmt)
00547 { s << argmt(); }
00548 
00549 VDS int parse(vul_arg<unsigned>* argmt, char ** argv)
00550 {
00551   if ( !argv ||  !argv[0] ) {
00552     // no input
00553     vcl_cerr << "vul_arg_parse: Expected integer, none is provided.\n";
00554     return -1;
00555   }
00556 
00557   char* endptr = 0;
00558   double v = vcl_strtod(argv[0], &endptr);
00559   if (*endptr != '\0') {
00560     // There is junk after the number, or no number was found
00561     vcl_cerr << "vul_arg_parse: WARNING: Attempt to parse " << *argv << " as int\n";
00562     return -1;
00563   }
00564   if (v != vcl_floor(v)) {
00565     vcl_cerr << "vul_arg_parse: Expected integer: saw " << argv[0] << vcl_endl;
00566     return -1;
00567   }
00568   argmt->value_ = unsigned(v);
00569   return 1;
00570 }
00571 
00572 template class vul_arg<unsigned>;
00573 
00574 //: float
00575 VDS void settype(vul_arg<float> &argmt) { argmt.type_ = "float"; }
00576 
00577 VDS void print_value(vcl_ostream &s, vul_arg<float> const &argmt)
00578 { s << argmt(); }
00579 
00580 VDS int parse(vul_arg<float>* argmt, char ** argv)
00581 {
00582   if ( !argv ||  !argv[0] ) {
00583     // no input
00584     vcl_cerr << "vul_arg_parse: Expected floating number, none is provided.\n";
00585     return -1;
00586   }
00587 
00588   char* endptr = 0;
00589   argmt->value_ = (float)vcl_strtod(argv[0], &endptr);
00590   if (*endptr == '\0')
00591     return 1;
00592   // There is junk after the number, or no number was found
00593   vcl_cerr << "vul_arg_parse: WARNING: Attempt to parse " << *argv << " as float\n";
00594   return -1;
00595 }
00596 
00597 template class vul_arg<float>;
00598 
00599 //: double
00600 VDS void settype(vul_arg<double> &argmt) { argmt.type_ = "float"; }
00601 
00602 VDS void print_value(vcl_ostream &s, vul_arg<double> const &argmt)
00603 { s << argmt(); }
00604 
00605 VDS int parse(vul_arg<double>* argmt, char ** argv)
00606 {
00607   if ( !argv ||  !argv[0] ) {
00608     // no input
00609     vcl_cerr << "vul_arg_parse: Expected floating number, none is provided.\n";
00610     return -1;
00611   }
00612 
00613   char* endptr = 0;
00614   argmt->value_ = vcl_strtod(argv[0], &endptr);
00615   if (*endptr == '\0')
00616     return 1;
00617   // There is junk after the number, or no number was found
00618   vcl_cerr << "vul_arg_parse: WARNING: Attempt to parse " << *argv << " as double\n";
00619   return -1;
00620 }
00621 
00622 template class vul_arg<double>;
00623 
00624 //: char *
00625 VDS void settype(vul_arg<char *> &argmt) { argmt.type_ = "string"; }
00626 
00627 VDS void print_value(vcl_ostream &s, vul_arg<char *> const &argmt)
00628 { s << '\'' << (argmt()?argmt():"(null)") << '\''; }
00629 
00630 VDS int parse(vul_arg<char*>* argmt, char ** argv)
00631 {
00632   argmt->value_ = argv[0]; // argv is valid till the end of the program so
00633   return 1;                // it's ok to just grab the pointer.
00634 }
00635 
00636 template class vul_arg<char*>;
00637 
00638 //: char const *
00639 VDS void settype(vul_arg<char const *> &argmt) { argmt.type_ = "string"; }
00640 
00641 VDS void print_value(vcl_ostream &s, vul_arg<char const *> const &argmt)
00642 { s << '\'' << (argmt()?argmt():"(null)") << '\''; }
00643 
00644 VDS int parse(vul_arg<char const *>* argmt, char ** argv)
00645 {
00646   if ( !argv ||  !argv[0] ) {
00647     // no input
00648     vcl_cerr << "vul_arg_parse: Expected string, none is provided.\n";
00649     return -1;
00650   }
00651 
00652   argmt->value_ = argv[0]; // argv is valid till the end of the program so
00653   return 1;                // it's ok to just grab the pointer.
00654 }
00655 
00656 template class vul_arg<char const*>;
00657 
00658 //: vcl_string
00659 VDS void settype(vul_arg<vcl_string> &argmt) { argmt.type_ = "string"; }
00660 
00661 VDS void print_value(vcl_ostream &s, vul_arg<vcl_string> const &argmt)
00662 { s << '\'' << argmt() << '\''; }
00663 
00664 VDS int parse(vul_arg<vcl_string>* argmt, char ** argv)
00665 {
00666   if ( !argv ||  !argv[0] ) {
00667     // no input
00668     vcl_cerr << "vul_arg_parse: Expected string, none is provided.\n";
00669     return -1;
00670   }
00671 
00672   if (argv[0]) {
00673     argmt->value_ = argv[0];
00674     return 1;
00675   }
00676   else {
00677     vcl_cerr << __FILE__ ": no argument to string option\n";
00678     return 0;
00679   }
00680 }
00681 
00682 template class vul_arg<vcl_string>;
00683 
00684 //: vcl_list<int>
00685 VDS void settype(vul_arg<vcl_list<int> > &argmt) { argmt.type_ = "integer list"; }
00686 
00687 VDS void print_value(vcl_ostream &s, vul_arg<vcl_list<int> > const &argmt)
00688 {
00689   for (vcl_list<int>::const_iterator i=argmt().begin(); i!=argmt().end(); ++i)
00690     s << ' ' << *i;
00691 }
00692 
00693 VDS int parse(vul_arg<vcl_list<int> >* argmt, char ** argv)
00694 {
00695   return list_parse(argmt->value_,argv);
00696 }
00697 
00698 template class vul_arg<vcl_list<int> >;
00699 
00700 //: vcl_vector<int>
00701 VDS void settype(vul_arg<vcl_vector<int> > &argmt) { argmt.type_ = "integer list"; }
00702 
00703 VDS void print_value(vcl_ostream &s, vul_arg<vcl_vector<int> > const &argmt)
00704 {
00705   for (unsigned int i=0; i<argmt().size(); ++i)
00706     s << ' ' << argmt()[i];
00707 }
00708 
00709 VDS int parse(vul_arg<vcl_vector<int> >* argmt, char ** argv)
00710 {
00711   vcl_list<int> tmp;
00712   int retval = list_parse(tmp,argv);
00713   // Defaults should be cleared when the user supplies a value
00714   argmt->value_.clear();
00715   for (vcl_list<int>::iterator i=tmp.begin(); i!=tmp.end(); ++i)
00716     argmt->value_.push_back( *i );
00717   return retval;
00718 }
00719 
00720 template class vul_arg<vcl_vector<int> >;
00721 
00722 //: vcl_vector<unsigned>
00723 VDS void settype(vul_arg<vcl_vector<unsigned> > &argmt){argmt.type_="integer list";}
00724 
00725 VDS void print_value(vcl_ostream &s, vul_arg<vcl_vector<unsigned> > const &argmt)
00726 {
00727   for (unsigned int i=0; i<argmt().size(); ++i)
00728     s << ' ' << argmt()[i];
00729 }
00730 
00731 VDS int parse(vul_arg<vcl_vector<unsigned> >* argmt, char ** argv)
00732 {
00733   vcl_list<int> tmp;
00734   int retval = list_parse(tmp,argv);
00735   // Defaults should be cleared when the user supplies a value
00736   argmt->value_.clear();
00737   for (vcl_list<int>::iterator i=tmp.begin(); i!=tmp.end(); ++i)
00738     argmt->value_.push_back( unsigned(*i) );
00739   return retval;
00740 }
00741 
00742 template class vul_arg<vcl_vector<unsigned> >;
00743 
00744 //: vcl_vector<double>
00745 VDS void settype(vul_arg<vcl_vector<double> > &argmt) {argmt.type_ = "double list";}
00746 
00747 VDS void print_value(vcl_ostream &s, vul_arg<vcl_vector<double> > const &argmt)
00748 {
00749   for (unsigned int i=0; i<argmt().size(); ++i)
00750     s << ' ' << argmt()[i];
00751 }
00752 
00753 VDS int parse(vul_arg<vcl_vector<double> >* argmt, char ** argv)
00754 {
00755   if ( !argv ||  !argv[0] ) {
00756     // no input
00757     vcl_cerr << "vul_arg_parse: Expected a vector of floating number, none is provided.\n";
00758     return -1;
00759   }
00760 
00761   int sucked = 0;
00762   // Defaults should be cleared when the user supplies a value
00763   argmt->value_.clear();
00764   char *current = argv[0];
00765   while (current) {
00766     char* endptr = 0;
00767     double tmp = vcl_strtod(current, &endptr);
00768     //argmt->value_
00769     if (*endptr == '\0') {
00770       argmt->value_.push_back(tmp);
00771       ++ sucked;
00772       ++ argv;
00773       current = argv[0];
00774     }
00775     else if (*endptr == ',')
00776     {
00777       argmt->value_.push_back(tmp);
00778       current = endptr+1;
00779     }
00780     else if (endptr == current)
00781       break; // OK. end of list of doubles.
00782     else {
00783       // There is junk after the number, or no number was found
00784       vcl_cerr << "vul_arg_parse: WARNING: Attempt to parse " << current << " as double\n";
00785       return -1;
00786     }
00787   }
00788   return sucked;
00789 }
00790 
00791 template class vul_arg<vcl_vector<double> >;

Generated on Thu Jan 10 14:41:00 2008 for core/vul by  doxygen 1.4.4