00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
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
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
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
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 = atoi(argv[2]);
00213
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
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
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 std::cerr << "enabled (" << Support::Thread::npu() << " processing units)";
00298 #else
00299 std::cerr << "disabled";
00300 #endif
00301 std::cerr << std::endl
00302 << " - Gist support: ";
00303 #ifdef GECODE_HAS_GIST
00304 std::cerr << "enabled";
00305 #else
00306 std::cerr << "disabled";
00307 #endif
00308 std::cerr << std::endl << std::endl
00309 << "Options for " << name() << ":" << std::endl
00310 << "\t-help, --help, -?" << std::endl
00311 << "\t\tprint this help message" << std::endl;
00312 for (Driver::BaseOption* o = fst; o != NULL; o = o->next)
00313 o->help();
00314 }
00315
00316 void
00317 BaseOptions::parse(int& argc, char* argv[]) {
00318 next:
00319 for (Driver::BaseOption* o = fst; o != NULL; o = o->next)
00320 if (o->parse(argc,argv))
00321 goto next;
00322 if (argc < 2)
00323 return;
00324 if (!strcmp(argv[1],"-help") || !strcmp(argv[1],"--help") ||
00325 !strcmp(argv[1],"-?")) {
00326 help();
00327 exit(EXIT_SUCCESS);
00328 }
00329 return;
00330 }
00331
00332 BaseOptions::~BaseOptions(void) {
00333 Driver::BaseOption::strdel(_name);
00334 }
00335
00336
00337 Options::Options(const char* n)
00338 : BaseOptions(n),
00339
00340 _model("-model","model variants"),
00341 _symmetry("-symmetry","symmetry variants"),
00342 _propagation("-propagation","propagation variants"),
00343 _icl("-icl","integer consistency level",ICL_DEF),
00344 _branching("-branching","branching variants"),
00345
00346 _search("-search","search engine variants"),
00347 _solutions("-solutions","number of solutions (0 = all)",1),
00348 _threads("-threads","number of threads (0 = #processing units)",
00349 Search::Config::threads),
00350 _c_d("-c-d","recomputation commit distance",Search::Config::c_d),
00351 _a_d("-a-d","recomputation adaptation distance",Search::Config::a_d),
00352 _node("-node","node cutoff (0 = none, solution mode)"),
00353 _fail("-fail","failure cutoff (0 = none, solution mode)"),
00354 _time("-time","time (in ms) cutoff (0 = none, solution mode)"),
00355
00356 _mode("-mode","how to execute script",SM_SOLUTION),
00357 _samples("-samples","how many samples (time mode)",1),
00358 _iterations("-iterations","iterations per sample (time mode)",1)
00359 {
00360
00361 _icl.add(ICL_DEF, "def"); _icl.add(ICL_VAL, "val");
00362 _icl.add(ICL_BND, "bnd"); _icl.add(ICL_DOM, "dom");
00363
00364 _mode.add(SM_SOLUTION, "solution");
00365 _mode.add(SM_TIME, "time");
00366 _mode.add(SM_STAT, "stat");
00367 _mode.add(SM_GIST, "gist");
00368
00369 add(_model); add(_symmetry); add(_propagation); add(_icl);
00370 add(_branching);
00371 add(_search); add(_solutions); add(_threads); add(_c_d); add(_a_d);
00372 add(_node); add(_fail); add(_time);
00373 add(_mode); add(_iterations); add(_samples);
00374 }
00375
00376
00377 SizeOptions::SizeOptions(const char* e)
00378 : Options(e), _size(0) {}
00379
00380 void
00381 SizeOptions::help(void) {
00382 Options::help();
00383 std::cerr << "\t(unsigned int) default: " << size() << std::endl
00384 << "\t\twhich version/size for script" << std::endl;
00385 }
00386
00387 void
00388 SizeOptions::parse(int& argc, char* argv[]) {
00389 Options::parse(argc,argv);
00390 if (argc < 2)
00391 return;
00392 size(atoi(argv[1]));
00393 }
00394
00395 }
00396
00397