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-07-14 20:32:01 +0200 (Wed, 14 Jul 2010) $ by $Author: schulte $ 00011 * $Revision: 11195 $ 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 // STATISTICS: driver-any