Generated on Mon Nov 30 23:53:18 2009 for Gecode by doxygen 1.6.1

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: 2009-10-13 15:19:20 +0200 (Tue, 13 Oct 2009) $ by $Author: schulte $
00011  *     $Revision: 9887 $
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     void
00080     StringOption::add(int v, const char* o, const char* h) {
00081       Value* n = new Value;
00082       n->val  = v;
00083       n->opt  = strdup(o);
00084       n->help = strdup(h);
00085       n->next = NULL;
00086       if (fst == NULL) {
00087         fst = n;
00088       } else {
00089         lst->next = n;
00090       }
00091       lst = n;
00092     }
00093     
00094     bool
00095     StringOption::parse(int& argc, char* argv[]) {
00096       if ((argc < 2) || strcmp(argv[1],opt))
00097         return false;
00098       if (argc == 2) {
00099         std::cerr << "Missing argument for option \"" << opt << "\"" << std::endl;
00100         exit(EXIT_FAILURE);
00101       }
00102       for (Value* v = fst; v != NULL; v = v->next)
00103         if (!strcmp(argv[2],v->opt)) {
00104           cur = v->val;
00105           // Remove options
00106           argc -= 2;
00107           for (int i=1; i<argc; i++)
00108             argv[i] = argv[i+2];
00109           return true;
00110         }
00111       std::cerr << "Wrong argument \"" << argv[2]
00112                 << "\" for option \"" << opt << "\""
00113                 << std::endl;
00114       exit(EXIT_FAILURE);
00115     }
00116     
00117     void
00118     StringOption::help(void) {
00119       if (fst == NULL)
00120         return;
00121       std::cerr << '\t' << opt << " (";
00122       const char* d = NULL;
00123       for (Value* v = fst; v != NULL; v = v->next) {
00124         std::cerr << v->opt << ((v->next != NULL) ? ", " : "");
00125         if (v->val == cur)
00126           d = v->opt;
00127       }
00128       std::cerr << ")";
00129       if (d != NULL)
00130         std::cerr << " default: " << d;
00131       std::cerr << std::endl << "\t\t" << exp << std::endl;
00132       for (Value* v = fst; v != NULL; v = v->next)
00133         if (v->help != NULL)
00134           std::cerr << "\t\t  " << v->opt << ": " << v->help << std::endl;
00135     }
00136     
00137     StringOption::~StringOption(void) {
00138       Value* v = fst;
00139       while (v != NULL) {
00140         strdel(v->opt);
00141         strdel(v->help);
00142         Value* n = v->next;
00143         delete v;
00144         v = n;
00145       }
00146     }
00147     
00148     
00149     bool
00150     IntOption::parse(int& argc, char* argv[]) {
00151       if ((argc < 2) || strcmp(argv[1],opt))
00152         return false;
00153       if (argc == 2) {
00154         std::cerr << "Missing argument for option \"" << opt << "\"" << std::endl;
00155         exit(EXIT_FAILURE);
00156       }
00157       cur = atoi(argv[2]);
00158       // Remove options
00159       argc -= 2;
00160       for (int i=1; i<argc; i++)
00161         argv[i] = argv[i+2];
00162       return true;
00163     }
00164     
00165     void
00166     IntOption::help(void) {
00167       using namespace std;
00168       cerr << '\t' << opt << " (int) default: " << cur << endl
00169            << "\t\t" << exp << endl;
00170     }
00171   
00172 
00173     bool
00174     UnsignedIntOption::parse(int& argc, char* argv[]) {
00175       if ((argc < 2) || strcmp(argv[1],opt))
00176         return false;
00177       if (argc == 2) {
00178         std::cerr << "Missing argument for option \"" << opt << "\"" << std::endl;
00179         exit(EXIT_FAILURE);
00180       }
00181       cur = atoi(argv[2]);
00182       // Remove options
00183       argc -= 2;
00184       for (int i=1; i<argc; i++)
00185         argv[i] = argv[i+2];
00186       return true;
00187     }
00188     
00189     void
00190     UnsignedIntOption::help(void) {
00191       using namespace std;
00192       cerr << '\t' << opt << " (unsigned int) default: " << cur << endl
00193            << "\t\t" << exp << endl;
00194     }
00195   
00196 
00197     bool
00198     DoubleOption::parse(int& argc, char* argv[]) {
00199       if ((argc < 2) || strcmp(argv[1],opt))
00200         return false;
00201       if (argc == 2) {
00202         std::cerr << "Missing argument for option \"" << opt << "\"" << std::endl;
00203         exit(EXIT_FAILURE);
00204       }
00205       cur = atof(argv[2]);
00206       // Remove options
00207       argc -= 2;
00208       for (int i=1; i<argc; i++)
00209         argv[i] = argv[i+2];
00210       return true;
00211     }
00212     
00213     void
00214     DoubleOption::help(void) {
00215       using namespace std;
00216       cerr << '\t' << opt << " (double) default: " << cur << endl
00217            << "\t\t" << exp << endl;
00218     }
00219 
00220     bool
00221     BoolOption::parse(int& argc, char* argv[]) {
00222       if ((argc < 2) || strcmp(argv[1],opt)) {
00223         return false;
00224       }
00225       // Remove options
00226       argc--;
00227       for (int i=1; i<argc; i++)
00228         argv[i] = argv[i+1];
00229       cur = true;
00230       return true;
00231     }
00232 
00233     void 
00234     BoolOption::help(void) {
00235       using namespace std;
00236       cerr << '\t' << opt << endl << "\t\t" << exp << endl;
00237     }
00238 
00239   
00240   }
00241 
00242   BaseOptions::BaseOptions(const char* n)
00243     : fst(NULL), lst(NULL), 
00244       _name(Driver::BaseOption::strdup(n)) {}
00245 
00246   void
00247   BaseOptions::name(const char* n) {
00248     Driver::BaseOption::strdel(_name);
00249     _name = Driver::BaseOption::strdup(n);
00250   }
00251 
00252   void
00253   BaseOptions::help(void) {
00254     std::cerr << "Gecode configuration information:" << std::endl
00255               << " - Version: " << GECODE_VERSION << std::endl
00256               << " - Variable types: ";
00257 #ifdef GECODE_HAS_INT_VARS
00258     std::cerr << "BoolVar IntVar ";
00259 #endif
00260 #ifdef GECODE_HAS_SET_VARS
00261     std::cerr << "SetVar";
00262 #endif
00263     std::cerr << std::endl
00264               << " - Thread support: ";
00265 #ifdef GECODE_HAS_THREADS
00266     std::cerr << "enabled (" << Support::Thread::npu() << " processing units)";
00267 #else
00268     std::cerr << "disabled";
00269 #endif
00270     std::cerr << std::endl
00271               << " - Gist support: ";
00272 #ifdef GECODE_HAS_GIST
00273     std::cerr << "enabled";
00274 #else
00275     std::cerr << "disabled";
00276 #endif
00277     std::cerr << std::endl << std::endl
00278               << "Options for " << name() << ":" << std::endl
00279               << "\t-help, --help, -?" << std::endl
00280               << "\t\tprint this help message" << std::endl;
00281     for (Driver::BaseOption* o = fst; o != NULL; o = o->next)
00282       o->help();
00283   }
00284 
00285   void
00286   BaseOptions::parse(int& argc, char* argv[]) {
00287   next:
00288     for (Driver::BaseOption* o = fst; o != NULL; o = o->next)
00289       if (o->parse(argc,argv))
00290         goto next;
00291     if (argc < 2)
00292       return;
00293     if (!strcmp(argv[1],"-help") || !strcmp(argv[1],"--help") ||
00294         !strcmp(argv[1],"-?")) {
00295       help();
00296       exit(EXIT_SUCCESS);
00297     }
00298     return;
00299   }
00300   
00301   BaseOptions::~BaseOptions(void) {
00302     Driver::BaseOption::strdel(_name);
00303   }
00304 
00305 
00306   Options::Options(const char* n)
00307     : BaseOptions(n),
00308       
00309       _model("-model","model variants"),
00310       _symmetry("-symmetry","symmetry variants"),
00311       _propagation("-propagation","propagation variants"),
00312       _icl("-icl","integer consistency level",ICL_DEF),
00313       _branching("-branching","branching variants"),
00314       
00315       _search("-search","search engine variants"),
00316       _solutions("-solutions","number of solutions (0 = all)",1),
00317       _threads("-threads","number of threads (0 = #processing units)",
00318                Search::Config::threads),
00319       _c_d("-c-d","recomputation commit distance",Search::Config::c_d),
00320       _a_d("-a-d","recomputation adaptation distance",Search::Config::a_d),
00321       _node("-node","node cutoff (0 = none, solution mode)"),
00322       _fail("-fail","failure cutoff (0 = none, solution mode)"),
00323       _time("-time","time (in ms) cutoff (0 = none, solution mode)"),
00324       
00325       _mode("-mode","how to execute script",SM_SOLUTION),
00326       _samples("-samples","how many samples (time mode)",1),
00327       _iterations("-iterations","iterations per sample (time mode)",1)
00328   {
00329     
00330     _icl.add(ICL_DEF, "def"); _icl.add(ICL_VAL, "val");
00331     _icl.add(ICL_BND, "bnd"); _icl.add(ICL_DOM, "dom");
00332     
00333     _mode.add(SM_SOLUTION, "solution");
00334     _mode.add(SM_TIME, "time");
00335     _mode.add(SM_STAT, "stat");
00336     _mode.add(SM_GIST, "gist");
00337     
00338     add(_model); add(_symmetry); add(_propagation); add(_icl); 
00339     add(_branching);
00340     add(_search); add(_solutions); add(_threads); add(_c_d); add(_a_d);
00341     add(_node); add(_fail); add(_time);
00342     add(_mode); add(_iterations); add(_samples);
00343   }
00344 
00345   
00346   SizeOptions::SizeOptions(const char* e)
00347     : Options(e), _size(0) {}
00348   
00349   void
00350   SizeOptions::help(void) {
00351     Options::help();
00352     std::cerr << "\t(unsigned int) default: " << size() << std::endl
00353               << "\t\twhich version/size for script" << std::endl;
00354   }
00355 
00356   void
00357   SizeOptions::parse(int& argc, char* argv[]) {
00358     Options::parse(argc,argv);
00359     if (argc < 2)
00360       return;
00361     size(atoi(argv[1]));
00362   }
00363 
00364 }
00365 
00366 // STATISTICS: driver-any