Generated on Thu Mar 22 10:39:31 2012 for Gecode by doxygen 1.6.3

options.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2004
00008  *
00009  *  Last modified:
00010  *     $Date: 2010-10-06 22:44:30 +0200 (Wed, 06 Oct 2010) $ by $Author: schulte $
00011  *     $Revision: 11465 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *
00018  *  Permission is hereby granted, free of charge, to any person obtaining
00019  *  a copy of this software and associated documentation files (the
00020  *  "Software"), to deal in the Software without restriction, including
00021  *  without limitation the rights to use, copy, modify, merge, publish,
00022  *  distribute, sublicense, and/or sell copies of the Software, and to
00023  *  permit persons to whom the Software is furnished to do so, subject to
00024  *  the following conditions:
00025  *
00026  *  The above copyright notice and this permission notice shall be
00027  *  included in all copies or substantial portions of the Software.
00028  *
00029  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00030  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00031  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00032  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00033  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00034  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00035  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00036  *
00037  */
00038 
00039 #include <gecode/driver.hh>
00040 
00041 #include <iostream>
00042 #include <iomanip>
00043 
00044 #include <cstdlib>
00045 #include <cstring>
00046 
00047 namespace Gecode {
00048 
00049   namespace Driver {
00050 
00051     /*
00052      * Option baseclass
00053      *
00054      */
00055     char*
00056     BaseOption::strdup(const char* s) {
00057       if (s == NULL)
00058         return NULL;
00059       char* d = heap.alloc<char>(static_cast<unsigned long int>(strlen(s)+1));
00060       (void) strcpy(d,s);
00061       return d;
00062     }
00063 
00064     void
00065     BaseOption::strdel(const char* s) {
00066       if (s == NULL)
00067         return;
00068       heap.rfree(const_cast<char*>(s));
00069     }
00070 
00071     BaseOption::BaseOption(const char* o, const char* e)
00072       : opt(strdup(o)), exp(strdup(e)) {}
00073 
00074     BaseOption::~BaseOption(void) {
00075       strdel(opt);
00076       strdel(exp);
00077     }
00078 
00079 
00080     bool
00081     StringValueOption::parse(int& argc, char* argv[]) {
00082       if ((argc < 2) || strcmp(argv[1],opt))
00083         return false;
00084       if (argc == 2) {
00085         std::cerr << "Missing argument for option \"" << opt << "\"" << std::endl;
00086         exit(EXIT_FAILURE);
00087       }
00088       cur = strdup(argv[2]);
00089       // Remove options
00090       argc -= 2;
00091       for (int i=1; i<argc; i++)
00092         argv[i] = argv[i+2];
00093       return true;
00094     }
00095     
00096     void
00097     StringValueOption::help(void) {
00098       using namespace std;
00099       cerr << '\t' << opt << " (string) default: " 
00100            << ((cur == NULL) ? "NONE" : cur) << endl
00101            << "\t\t" << exp << endl;
00102     }
00103   
00104     StringValueOption::~StringValueOption(void) {
00105       strdel(cur);
00106     }
00107   
00108 
00109 
00110     void
00111     StringOption::add(int v, const char* o, const char* h) {
00112       Value* n = new Value;
00113       n->val  = v;
00114       n->opt  = strdup(o);
00115       n->help = strdup(h);
00116       n->next = NULL;
00117       if (fst == NULL) {
00118         fst = n;
00119       } else {
00120         lst->next = n;
00121       }
00122       lst = n;
00123     }
00124     
00125     bool
00126     StringOption::parse(int& argc, char* argv[]) {
00127       if ((argc < 2) || strcmp(argv[1],opt))
00128         return false;
00129       if (argc == 2) {
00130         std::cerr << "Missing argument for option \"" << opt << "\"" << std::endl;
00131         exit(EXIT_FAILURE);
00132       }
00133       for (Value* v = fst; v != NULL; v = v->next)
00134         if (!strcmp(argv[2],v->opt)) {
00135           cur = v->val;
00136           // Remove options
00137           argc -= 2;
00138           for (int i=1; i<argc; i++)
00139             argv[i] = argv[i+2];
00140           return true;
00141         }
00142       std::cerr << "Wrong argument \"" << argv[2]
00143                 << "\" for option \"" << opt << "\""
00144                 << std::endl;
00145       exit(EXIT_FAILURE);
00146     }
00147     
00148     void
00149     StringOption::help(void) {
00150       if (fst == NULL)
00151         return;
00152       std::cerr << '\t' << opt << " (";
00153       const char* d = NULL;
00154       for (Value* v = fst; v != NULL; v = v->next) {
00155         std::cerr << v->opt << ((v->next != NULL) ? ", " : "");
00156         if (v->val == cur)
00157           d = v->opt;
00158       }
00159       std::cerr << ")";
00160       if (d != NULL)
00161         std::cerr << " default: " << d;
00162       std::cerr << std::endl << "\t\t" << exp << std::endl;
00163       for (Value* v = fst; v != NULL; v = v->next)
00164         if (v->help != NULL)
00165           std::cerr << "\t\t  " << v->opt << ": " << v->help << std::endl;
00166     }
00167     
00168     StringOption::~StringOption(void) {
00169       Value* v = fst;
00170       while (v != NULL) {
00171         strdel(v->opt);
00172         strdel(v->help);
00173         Value* n = v->next;
00174         delete v;
00175         v = n;
00176       }
00177     }
00178     
00179     
00180     bool
00181     IntOption::parse(int& argc, char* argv[]) {
00182       if ((argc < 2) || strcmp(argv[1],opt))
00183         return false;
00184       if (argc == 2) {
00185         std::cerr << "Missing argument for option \"" << opt << "\"" << std::endl;
00186         exit(EXIT_FAILURE);
00187       }
00188       cur = atoi(argv[2]);
00189       // Remove options
00190       argc -= 2;
00191       for (int i=1; i<argc; i++)
00192         argv[i] = argv[i+2];
00193       return true;
00194     }
00195     
00196     void
00197     IntOption::help(void) {
00198       using namespace std;
00199       cerr << '\t' << opt << " (int) default: " << cur << endl
00200            << "\t\t" << exp << endl;
00201     }
00202   
00203 
00204     bool
00205     UnsignedIntOption::parse(int& argc, char* argv[]) {
00206       if ((argc < 2) || strcmp(argv[1],opt))
00207         return false;
00208       if (argc == 2) {
00209         std::cerr << "Missing argument for option \"" << opt << "\"" << std::endl;
00210         exit(EXIT_FAILURE);
00211       }
00212       cur = static_cast<unsigned int>(atoi(argv[2]));
00213       // Remove options
00214       argc -= 2;
00215       for (int i=1; i<argc; i++)
00216         argv[i] = argv[i+2];
00217       return true;
00218     }
00219     
00220     void
00221     UnsignedIntOption::help(void) {
00222       using namespace std;
00223       cerr << '\t' << opt << " (unsigned int) default: " << cur << endl
00224            << "\t\t" << exp << endl;
00225     }
00226   
00227 
00228     bool
00229     DoubleOption::parse(int& argc, char* argv[]) {
00230       if ((argc < 2) || strcmp(argv[1],opt))
00231         return false;
00232       if (argc == 2) {
00233         std::cerr << "Missing argument for option \"" << opt << "\"" << std::endl;
00234         exit(EXIT_FAILURE);
00235       }
00236       cur = atof(argv[2]);
00237       // Remove options
00238       argc -= 2;
00239       for (int i=1; i<argc; i++)
00240         argv[i] = argv[i+2];
00241       return true;
00242     }
00243     
00244     void
00245     DoubleOption::help(void) {
00246       using namespace std;
00247       cerr << '\t' << opt << " (double) default: " << cur << endl
00248            << "\t\t" << exp << endl;
00249     }
00250 
00251     bool
00252     BoolOption::parse(int& argc, char* argv[]) {
00253       if ((argc < 2) || strcmp(argv[1],opt)) {
00254         return false;
00255       }
00256       // Remove options
00257       argc--;
00258       for (int i=1; i<argc; i++)
00259         argv[i] = argv[i+1];
00260       cur = true;
00261       return true;
00262     }
00263 
00264     void 
00265     BoolOption::help(void) {
00266       using namespace std;
00267       cerr << '\t' << opt << endl << "\t\t" << exp << endl;
00268     }
00269 
00270   
00271   }
00272 
00273   BaseOptions::BaseOptions(const char* n)
00274     : fst(NULL), lst(NULL), 
00275       _name(Driver::BaseOption::strdup(n)) {}
00276 
00277   void
00278   BaseOptions::name(const char* n) {
00279     Driver::BaseOption::strdel(_name);
00280     _name = Driver::BaseOption::strdup(n);
00281   }
00282 
00283   void
00284   BaseOptions::help(void) {
00285     std::cerr << "Gecode configuration information:" << std::endl
00286               << " - Version: " << GECODE_VERSION << std::endl
00287               << " - Variable types: ";
00288 #ifdef GECODE_HAS_INT_VARS
00289     std::cerr << "BoolVar IntVar ";
00290 #endif
00291 #ifdef GECODE_HAS_SET_VARS
00292     std::cerr << "SetVar";
00293 #endif
00294     std::cerr << std::endl
00295               << " - Thread support: ";
00296 #ifdef GECODE_HAS_THREADS
00297     if (Support::Thread::npu() == 1)
00298       std::cerr << "enabled (1 processing unit)";
00299     else
00300       std::cerr << "enabled (" << Support::Thread::npu() 
00301                 << " processing units)";
00302 #else
00303     std::cerr << "disabled";
00304 #endif
00305     std::cerr << std::endl
00306               << " - Gist support: ";
00307 #ifdef GECODE_HAS_GIST
00308     std::cerr << "enabled";
00309 #else
00310     std::cerr << "disabled";
00311 #endif
00312     std::cerr << std::endl << std::endl
00313               << "Options for " << name() << ":" << std::endl
00314               << "\t-help, --help, -?" << std::endl
00315               << "\t\tprint this help message" << std::endl;
00316     for (Driver::BaseOption* o = fst; o != NULL; o = o->next)
00317       o->help();
00318   }
00319 
00320   void
00321   BaseOptions::parse(int& argc, char* argv[]) {
00322   next:
00323     for (Driver::BaseOption* o = fst; o != NULL; o = o->next)
00324       if (o->parse(argc,argv))
00325         goto next;
00326     if (argc < 2)
00327       return;
00328     if (!strcmp(argv[1],"-help") || !strcmp(argv[1],"--help") ||
00329         !strcmp(argv[1],"-?")) {
00330       help();
00331       exit(EXIT_SUCCESS);
00332     }
00333     return;
00334   }
00335   
00336   BaseOptions::~BaseOptions(void) {
00337     Driver::BaseOption::strdel(_name);
00338   }
00339 
00340 
00341   Options::Options(const char* n)
00342     : BaseOptions(n),
00343       
00344       _model("-model","model variants"),
00345       _symmetry("-symmetry","symmetry variants"),
00346       _propagation("-propagation","propagation variants"),
00347       _icl("-icl","integer consistency level",ICL_DEF),
00348       _branching("-branching","branching variants"),
00349       
00350       _search("-search","search engine variants"),
00351       _solutions("-solutions","number of solutions (0 = all)",1),
00352       _threads("-threads","number of threads (0 = #processing units)",
00353                Search::Config::threads),
00354       _c_d("-c-d","recomputation commit distance",Search::Config::c_d),
00355       _a_d("-a-d","recomputation adaptation distance",Search::Config::a_d),
00356       _node("-node","node cutoff (0 = none, solution mode)"),
00357       _fail("-fail","failure cutoff (0 = none, solution mode)"),
00358       _time("-time","time (in ms) cutoff (0 = none, solution mode)"),
00359       _interrupt("-interrupt","whether to catch Ctrl-C (true) or not (false)", true),
00360       
00361       _mode("-mode","how to execute script",SM_SOLUTION),
00362       _samples("-samples","how many samples (time mode)",1),
00363       _iterations("-iterations","iterations per sample (time mode)",1)
00364   {
00365     
00366     _icl.add(ICL_DEF, "def"); _icl.add(ICL_VAL, "val");
00367     _icl.add(ICL_BND, "bnd"); _icl.add(ICL_DOM, "dom");
00368     
00369     _mode.add(SM_SOLUTION, "solution");
00370     _mode.add(SM_TIME, "time");
00371     _mode.add(SM_STAT, "stat");
00372     _mode.add(SM_GIST, "gist");
00373     
00374     _interrupt.add(false, "false");
00375     _interrupt.add(true, "true");
00376     
00377     add(_model); add(_symmetry); add(_propagation); add(_icl); 
00378     add(_branching);
00379     add(_search); add(_solutions); add(_threads); add(_c_d); add(_a_d);
00380     add(_node); add(_fail); add(_time); add(_interrupt);
00381     add(_mode); add(_iterations); add(_samples);
00382   }
00383 
00384   
00385   SizeOptions::SizeOptions(const char* e)
00386     : Options(e), _size(0) {}
00387   
00388   void
00389   SizeOptions::help(void) {
00390     Options::help();
00391     std::cerr << "\t(unsigned int) default: " << size() << std::endl
00392               << "\t\twhich version/size for script" << std::endl;
00393   }
00394 
00395   void
00396   SizeOptions::parse(int& argc, char* argv[]) {
00397     Options::parse(argc,argv);
00398     if (argc < 2)
00399       return;
00400     size(static_cast<unsigned int>(atoi(argv[1])));
00401   }
00402 
00403 
00404 
00405   InstanceOptions::InstanceOptions(const char* e)
00406     : Options(e), _inst(NULL) {}
00407   
00408   void
00409   InstanceOptions::instance(const char* s) {
00410     Driver::BaseOption::strdel(_inst);
00411     _inst = strdup(s);
00412   }
00413 
00414   void
00415   InstanceOptions::help(void) {
00416     Options::help();
00417     std::cerr << "\t(string) default: " << instance() << std::endl
00418               << "\t\twhich instance for script" << std::endl;
00419   }
00420 
00421   void
00422   InstanceOptions::parse(int& argc, char* argv[]) {
00423     Options::parse(argc,argv);
00424     if (argc < 2)
00425       return;
00426     instance(argv[1]);
00427   }
00428 
00429   InstanceOptions::~InstanceOptions(void) {
00430     Driver::BaseOption::strdel(_inst);
00431   }
00432 
00433 }
00434 
00435 // STATISTICS: driver-any