1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
Jip J. Dekker 6719176975 Squashed 'software/gecode/' changes from 313e87646d..70a1cfa856
70a1cfa856 Add reasoning about why a restart happens
5db96c6afc Add initial version of the 'complete' propagator
3410436fc5 Fix include problems on Linux and Windows
0218f3e7be Remove deprecated restart_count from the variables set on restart
7f4a528ced Fix makefile mistake for LastVal constraint
8a39aee00d Initialise LastVal stored as the minimal in the domain
86707c674e Update STATUS to match the new enum
44d672100f Add support for LastVal from FlatZinc
bd8af2e8f6 Subsume after propagation
2f07e027ab Add LastVal propagator
f05cf9daba Output number of copies
707e30c0f0 Update generated parser files
179ee693cc Add restart_number() builtin (to work around the problem that otherwise we can't implement round robin style search)
04a492da17 Fix restart numbers (didn't count incomplete neighbourhoods)
fbaa3529ec Initial implementation of on_restart
6dd39a73dd Update LICENSE
8f5ea30eba Update LICENSE
4236a2e5ec Use std::vector instead of std::array
c53655d685 Dynamically adjust test batch sizes
37248557b6 Require C++11
cc60ea7cde Minor, remove exraneous newline in changelog
74c5f54b9f Make Region pool thread local
6f04ac3514 Use atomic for propagator identifier
2e0c275b07 Add support for parallel testing
3ada422b76 Refactor, extracted run_test function
787c41b8c4 Refactor, move data and logic into Options
120fc512a7 Refactor, extract run_tests function
85dd87a4af Refactoring: Thread rand through calls in test
cece9da4ef Refactor Assignments operator() to has_more
564410e4ee Refactor Assignment operator++ to next()
e1c84af894 Separate test filtering from running
8558856298 Remove empty statement warnings
a9d8cb64fa Fix compilation errors for CPProfiler support
9ec81a69b2 Add RestartStop
REVERT: 313e87646d Fix include problems on Linux and Windows
REVERT: 358b8ca63b Remove deprecated restart_count from the variables set on restart
REVERT: 83508d5de2 Fix makefile mistake for LastVal constraint
REVERT: 530bbaf107 Initialise LastVal stored as the minimal in the domain
REVERT: 96ba0d3d7e Update STATUS to match the new enum
REVERT: 7d772297f9 Add support for LastVal from FlatZinc
REVERT: 98b0162d75 Subsume after propagation
REVERT: 5cd4552144 Add LastVal propagator
REVERT: 9b80e644b7 Output number of copies
REVERT: aaa5301366 Update generated parser files
REVERT: 6ff4efe6a4 Add restart_number() builtin (to work around the problem that otherwise we can't implement round robin style search)
REVERT: 8bcbec5d6e Fix restart numbers (didn't count incomplete neighbourhoods)
REVERT: 3f63e743b2 Initial implementation of on_restart
REVERT: b6ffa462d1 Update LICENSE
REVERT: ad0621c26c Update LICENSE
REVERT: 93caa97684 Use std::vector instead of std::array
REVERT: 32d6399b35 Dynamically adjust test batch sizes
REVERT: e7f00e9977 Require C++11
REVERT: a5ba8e4282 Minor, remove exraneous newline in changelog
REVERT: b24831354d Make Region pool thread local
REVERT: b1a109ac2e Use atomic for propagator identifier
REVERT: 3d77aaad71 Add support for parallel testing
REVERT: b1b9526049 Refactor, extracted run_test function
REVERT: 85b8a57f65 Refactor, move data and logic into Options
REVERT: d2c1961437 Refactor, extract run_tests function
REVERT: 0236327c75 Refactoring: Thread rand through calls in test
REVERT: ba81289b02 Refactor Assignments operator() to has_more
REVERT: 038a554bd8 Refactor Assignment operator++ to next()
REVERT: f34f125131 Separate test filtering from running
REVERT: cec6336ede Remove empty statement warnings
REVERT: d63e1fc042 Fix compilation errors for CPProfiler support

git-subtree-dir: software/gecode
git-subtree-split: 70a1cfa856d138b0845d2681c46ca16f8507aebf
2021-07-11 16:26:15 +10:00

745 lines
21 KiB
C++
Executable File

/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Christian Schulte <schulte@gecode.org>
*
* Copyright:
* Christian Schulte, 2004
*
* This file is part of Gecode, the generic constraint
* development environment:
* http://www.gecode.org
*
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <gecode/driver.hh>
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cstring>
namespace Gecode {
namespace Driver {
/*
* Option baseclass
*
*/
char*
BaseOption::strdup(const char* s) {
if (s == nullptr)
return nullptr;
size_t l = strlen(s) + 1;
char* d = static_cast<char*>(heap.ralloc(l));
(void) memcpy(d,s,l);
return d;
}
char*
BaseOption::stredup(const char* s) {
if (s == nullptr)
return nullptr;
size_t l = strlen(s) + 1;
char* d = static_cast<char*>(heap.ralloc(l+1));
d[0] = '-';
(void) memcpy(d+1,s,l);
return d;
}
void
BaseOption::strdel(const char* s) {
if (s == nullptr)
return;
heap.rfree(const_cast<char*>(s));
}
char*
BaseOption::argument(int argc, char* argv[]) const {
if (argc < 2)
return nullptr;
const char* s = argv[1];
if (s[0] == '-') {
s++;
if (s[0] == '-')
s++;
} else {
return nullptr;
}
if (strcmp(s,eopt))
return nullptr;
if (argc == 2) {
std::cerr << "Missing argument for option \"" << iopt << "\""
<< std::endl;
exit(EXIT_FAILURE);
}
return argv[2];
}
BaseOption::BaseOption(const char* o, const char* e)
: eopt(strdup(o)), iopt(stredup(o)), exp(strdup(e)) {}
BaseOption::~BaseOption(void) {
strdel(eopt);
strdel(iopt);
strdel(exp);
}
StringValueOption::StringValueOption(const char* o, const char* e,
const char* v)
: BaseOption(o,e), cur(strdup(v)) {}
void
StringValueOption::value(const char* v) {
strdel(cur);
cur = strdup(v);
}
int
StringValueOption::parse(int argc, char* argv[]) {
if (char* a = argument(argc,argv)) {
cur = strdup(a);
return 2;
}
return 0;
}
void
StringValueOption::help(void) {
std::cerr << '\t' << iopt << " (string) default: "
<< ((cur == nullptr) ? "NONE" : cur) << std::endl
<< "\t\t" << exp << std::endl;
}
StringValueOption::~StringValueOption(void) {
strdel(cur);
}
void
StringOption::add(int v, const char* o, const char* h) {
Value* n = new Value;
n->val = v;
n->opt = strdup(o);
n->help = strdup(h);
n->next = nullptr;
if (fst == nullptr) {
fst = n;
} else {
lst->next = n;
}
lst = n;
}
int
StringOption::parse(int argc, char* argv[]) {
if (char* a = argument(argc,argv)) {
for (Value* v = fst; v != nullptr; v = v->next)
if (!strcmp(a,v->opt)) {
cur = v->val;
return 2;
}
std::cerr << "Wrong argument \"" << a
<< "\" for option \"" << iopt << "\""
<< std::endl;
exit(EXIT_FAILURE);
}
return 0;
}
void
StringOption::help(void) {
if (fst == nullptr)
return;
std::cerr << '\t' << iopt << " (";
const char* d = nullptr;
for (Value* v = fst; v != nullptr; v = v->next) {
std::cerr << v->opt << ((v->next != nullptr) ? ", " : "");
if (v->val == cur)
d = v->opt;
}
std::cerr << ")";
if (d != nullptr)
std::cerr << " default: " << d;
std::cerr << std::endl << "\t\t" << exp << std::endl;
for (Value* v = fst; v != nullptr; v = v->next)
if (v->help != nullptr)
std::cerr << "\t\t " << v->opt << ": " << v->help << std::endl;
}
StringOption::~StringOption(void) {
Value* v = fst;
while (v != nullptr) {
strdel(v->opt);
strdel(v->help);
Value* n = v->next;
delete v;
v = n;
}
}
int
IntOption::parse(int argc, char* argv[]) {
if (char* a = argument(argc,argv)) {
cur = atoi(a);
return 2;
}
return 0;
}
void
IntOption::help(void) {
std::cerr << '\t' << iopt << " (int) default: " << cur << std::endl
<< "\t\t" << exp << std::endl;
}
int
UnsignedIntOption::parse(int argc, char* argv[]) {
if (char* a = argument(argc,argv)) {
cur = static_cast<unsigned int>(atoi(a));
return 2;
}
return 0;
}
void
UnsignedIntOption::help(void) {
std::cerr << '\t' << iopt << " (unsigned int) default: "
<< cur << std::endl
<< "\t\t" << exp << std::endl;
}
int
UnsignedLongLongIntOption::parse(int argc, char* argv[]) {
if (char* a = argument(argc,argv)) {
cur = static_cast<unsigned int>(atoll(a));
return 2;
}
return 0;
}
void
UnsignedLongLongIntOption::help(void) {
std::cerr << '\t' << iopt << " (unsigned long long int) default: "
<< cur << std::endl
<< "\t\t" << exp << std::endl;
}
int
DoubleOption::parse(int argc, char* argv[]) {
if (char* a = argument(argc,argv)) {
cur = atof(a);
return 2;
}
return 0;
}
void
DoubleOption::help(void) {
using namespace std;
cerr << '\t' << iopt << " (double) default: " << cur << endl
<< "\t\t" << exp << endl;
}
int
BoolOption::parse(int argc, char* argv[]) {
if (argc < 2)
return 0;
const char* s = argv[1];
if (s[0] == '-') {
s++;
if (s[0] == '-')
s++;
} else {
return 0;
}
if (strcmp(s,eopt))
return 0;
if (argc == 2) {
// Option without argument
cur = true;
return 1;
} else if (!strcmp(argv[2],"true") || !strcmp(argv[2],"1")) {
cur = true;
return 2;
} else if (!strcmp(argv[2],"false") || !strcmp(argv[2],"0")) {
cur = false;
return 2;
} else {
// Option without argument
cur = true;
return 1;
}
return 0;
}
void
BoolOption::help(void) {
using namespace std;
cerr << '\t' << iopt << " (optional: false, 0, true, 1) default: "
<< (cur ? "true" : "false") << endl
<< "\t\t" << exp << endl;
}
/*
* Integer propagation level option
*
*/
IplOption::IplOption(IntPropLevel ipl)
: BaseOption("ipl","integer propagation level (comma-separated list)"),
cur(ipl) {}
int
IplOption::parse(int argc, char* argv[]) {
if (char* a = argument(argc,argv)) {
int b = IPL_DEF;
int m = IPL_DEF;
do {
// Search for a comma
char* c = a;
while ((*c != ',') && (*c != 0))
c++;
unsigned int e = static_cast<unsigned int>(c-a);
if (!strncmp("def",a,e)) { b = IPL_DEF; }
else if (!strncmp("val",a,e)) { b = IPL_VAL; }
else if (!strncmp("bnd",a,e)) { b = IPL_BND; }
else if (!strncmp("dom",a,e)) { b = IPL_DOM; }
else if (!strncmp("basic",a,e)) { m |= IPL_BASIC; }
else if (!strncmp("advanced",a,e)) { m |= IPL_ADVANCED; }
else {
std::cerr << "Wrong argument \"" << a
<< "\" for option \"" << iopt << "\""
<< std::endl;
exit(EXIT_FAILURE);
}
if (*c == ',') a = c+1; else a = c;
} while (*a != 0);
cur = static_cast<IntPropLevel>(b | m);
return 2;
}
return 0;
}
void
IplOption::help(void) {
using namespace std;
cerr << '\t' << iopt
<< " (def,val,bnd,dom,basic,advanced)" << endl
<< "\t\tdefault: ";
switch (vbd(cur)) {
case IPL_DEF: cerr << "def"; break;
case IPL_VAL: cerr << "val"; break;
case IPL_BND: cerr << "bnd"; break;
case IPL_DOM: cerr << "dom"; break;
default: GECODE_NEVER;
}
if (cur & IPL_BASIC) cerr << ",basic";
if (cur & IPL_ADVANCED) cerr << ",advanced";
cerr << endl << "\t\t" << exp << endl;
}
/*
* Trace flag option
*
*/
TraceOption::TraceOption(int f)
: BaseOption("trace","trace flags (comma-separated list)"),
cur(f) {}
int
TraceOption::parse(int argc, char* argv[]) {
if (char* a = argument(argc,argv)) {
cur = 0;
do {
// Search for a comma
char* c = a;
while ((*c != ',') && (*c != 0))
c++;
unsigned int e = static_cast<unsigned int>(c-a);
if (!strncmp("init",a,e)) { cur |= TE_INIT; }
else if (!strncmp("prune",a,e)) { cur |= TE_PRUNE; }
else if (!strncmp("fix",a,e)) { cur |= TE_FIX; }
else if (!strncmp("fail",a,e)) { cur |= TE_FAIL; }
else if (!strncmp("done",a,e)) { cur |= TE_DONE ; }
else if (!strncmp("propagate",a,e)) { cur |= TE_PROPAGATE; }
else if (!strncmp("commit",a,e)) { cur |= TE_COMMIT; }
else if (!strncmp("post",a,e)) { cur |= TE_POST; }
else if (!strncmp("none",a,e) ||
!strncmp("false",a,e) ||
!strncmp("0",a,e)) { cur = 0; }
else if (!strncmp("all",a,e) ||
!strncmp("1",a,e)) { cur = (TE_INIT |
TE_PRUNE |
TE_FIX |
TE_FAIL |
TE_DONE |
TE_PROPAGATE |
TE_COMMIT |
TE_POST); }
else if (!strncmp("variable",a,e)) { cur = (TE_INIT |
TE_PRUNE |
TE_FIX |
TE_FAIL |
TE_DONE); }
else if (!strncmp("general",a,e)) { cur = (TE_PROPAGATE |
TE_COMMIT |
TE_POST); }
else {
std::cerr << "Wrong argument \"" << a
<< "\" for option \"" << iopt << "\""
<< std::endl;
exit(EXIT_FAILURE);
}
if (*c == ',') a = c+1; else a = c;
} while (*a != 0);
return 2;
}
return 0;
}
void
TraceOption::help(void) {
using namespace std;
cerr << '\t' << iopt
<< " (init,prune,fix,fail,done,propagate,commit,post,none,all,variable,general)"
<< " default: ";
if (cur == 0) {
cerr << "none";
} else if (cur == (TE_INIT | TE_PRUNE | TE_FIX | TE_FAIL | TE_DONE |
TE_PROPAGATE | TE_COMMIT | TE_POST)) {
cerr << "all";
} else if (cur == (TE_INIT | TE_PRUNE | TE_FIX | TE_FAIL | TE_DONE)) {
cerr << "variable";
} else if (cur == (TE_PROPAGATE | TE_COMMIT | TE_POST)) {
cerr << "general";
} else {
int f = cur;
if ((f & TE_INIT) != 0) {
cerr << "init";
f -= TE_INIT;
if (f != 0) cerr << ',';
}
if ((f & TE_PRUNE) != 0) {
cerr << "prune";
f -= TE_PRUNE;
if (f != 0) cerr << ',';
}
if ((f & TE_FIX) != 0) {
cerr << "fix";
f -= TE_FIX;
if (f != 0) cerr << ',';
}
if ((f & TE_FAIL) != 0) {
cerr << "fail";
f -= TE_FAIL;
if (f != 0) cerr << ',';
}
if ((f & TE_DONE) != 0) {
cerr << "done";
f -= TE_DONE;
if (f != 0) cerr << ',';
}
if ((f & TE_PROPAGATE) != 0) {
cerr << "propagate";
f -= TE_PROPAGATE;
if (f != 0) cerr << ',';
}
if ((f & TE_COMMIT) != 0) {
cerr << "commit";
f -= TE_COMMIT;
if (f != 0) cerr << ',';
}
if ((f & TE_POST) != 0) {
cerr << "post";
}
}
cerr << endl << "\t\t" << exp << endl;
}
int ProfilerOption::parse(int argc, char* argv[]) {
if (char* a = argument(argc, argv)) {
char* sep = strchr(a, ',');
if (!sep) {
std::cerr << "Wrong argument \"" << a << "\" for option \"" << iopt << "\"" << std::endl;
exit(EXIT_FAILURE);
}
cur_execution_id = static_cast<unsigned int>(atoi(a));
cur_port = atoi(sep + 1);
return 2;
}
return 0;
}
void ProfilerOption::help(void) { std::cerr << '\t' << iopt << " (unsigned int,int) default: " << cur_port << "," << cur_execution_id << std::endl << "\t\t" << exp << std::endl; }
}
void
BaseOptions::add(Driver::BaseOption& o) {
o.next = nullptr;
if (fst == nullptr) {
fst=&o;
} else {
lst->next=&o;
}
lst=&o;
}
BaseOptions::BaseOptions(const char* n)
: fst(nullptr), lst(nullptr),
_name(Driver::BaseOption::strdup(n)) {}
void
BaseOptions::name(const char* n) {
Driver::BaseOption::strdel(_name);
_name = Driver::BaseOption::strdup(n);
}
void
BaseOptions::help(void) {
std::cerr << "Gecode configuration information:" << std::endl
<< " - Version: " << GECODE_VERSION << std::endl
<< " - Variable types: ";
#ifdef GECODE_HAS_INT_VARS
std::cerr << "BoolVar IntVar ";
#endif
#ifdef GECODE_HAS_SET_VARS
std::cerr << "SetVar ";
#endif
#ifdef GECODE_HAS_FLOAT_VARS
std::cerr << "FloatVar "
<< std::endl
<< " - Trigonometric and transcendental float constraints: ";
#ifdef GECODE_HAS_MPFR
std::cerr << "enabled";
#else
std::cerr << "disabled";
#endif
#endif
std::cerr << std::endl;
std::cerr << " - Thread support: ";
#ifdef GECODE_HAS_THREADS
if (Support::Thread::npu() == 1)
std::cerr << "enabled (1 processing unit)";
else
std::cerr << "enabled (" << Support::Thread::npu()
<< " processing units)";
#else
std::cerr << "disabled";
#endif
std::cerr << std::endl
<< " - Gist support: ";
#ifdef GECODE_HAS_GIST
std::cerr << "enabled";
#else
std::cerr << "disabled";
#endif
std::cerr << std::endl
<< " - CPProfiler support: ";
#ifdef GECODE_HAS_CPPROFILER
std::cerr << "enabled";
#else
std::cerr << "disabled";
#endif
std::cerr << std::endl << std::endl
<< "Options for " << name() << ":" << std::endl
<< "\t-help, --help, -?" << std::endl
<< "\t\tprint this help message" << std::endl;
for (Driver::BaseOption* o = fst; o != nullptr; o = o->next)
o->help();
}
void
BaseOptions::parse(int& argc, char* argv[]) {
int c = argc;
char** v = argv;
next:
for (Driver::BaseOption* o = fst; o != nullptr; o = o->next)
if (int a = o->parse(c,v)) {
c -= a; v += a;
goto next;
}
if (c >= 2) {
if (!strcmp(v[1],"-help") || !strcmp(v[1],"--help") ||
!strcmp(v[1],"-?")) {
help();
exit(EXIT_SUCCESS);
}
}
// Copy remaining arguments
argc = c;
for (int i=1; i<argc; i++)
argv[i] = v[i];
return;
}
BaseOptions::~BaseOptions(void) {
Driver::BaseOption::strdel(_name);
}
Options::Options(const char* n)
: BaseOptions(n),
_model("model","model variants"),
_symmetry("symmetry","symmetry variants"),
_propagation("propagation","propagation variants"),
_branching("branching","branching variants"),
_decay("decay","decay factor",1.0),
_seed("seed","random number generator seed",1U),
_step("step","step distance for float optimization",0.0),
_search("search","search engine variants"),
_solutions("solutions","number of solutions (0 = all)",1),
_threads("threads","number of threads (0 = #processing units)",
Search::Config::threads),
_c_d("c-d","recomputation commit distance",Search::Config::c_d),
_a_d("a-d","recomputation adaptation distance",Search::Config::a_d),
_d_l("d-l","discrepancy limit for LDS",Search::Config::d_l),
_node("node","node cutoff (0 = none, solution mode)"),
_fail("fail","failure cutoff (0 = none, solution mode)"),
_time("time","time (in ms) cutoff (0 = none, solution mode)"),
_assets("assets","#portfolio assets (#engines)",0),
_slice("slice","portfolio slice (in #failures)",Search::Config::slice),
_restart("restart","restart sequence type",RM_NONE),
_r_base("restart-base","base for geometric restart sequence",
Search::Config::base),
_r_scale("restart-scale","scale factor for restart sequence",
Search::Config::slice),
_r_limit("restart-limit","restart cutoff (0 = none, solution mode)"),
_nogoods("nogoods","whether to use no-goods from restarts",false),
_nogoods_limit("nogoods-limit","depth limit for no-good extraction",
Search::Config::nogoods_limit),
_relax("relax","probability for relaxing variable", 0.0),
_interrupt("interrupt","whether to catch Ctrl-C (true) or not (false)",
true),
_mode("mode","how to execute script",SM_SOLUTION),
_samples("samples","how many samples (time mode)",1),
_iterations("iterations","iterations per sample (time mode)",1),
_print_last("print-last",
"whether to only print the last solution (solution mode)",
false),
_out_file("file-sol", "where to print solutions "
"(supports stdout, stdlog, stderr)","stdout"),
_log_file("file-stat", "where to print statistics "
"(supports stdout, stdlog, stderr)","stdout"),
_trace(0)
#ifdef GECODE_HAS_CPPROFILER
,
_profiler("cp-profiler", "use this execution id and port (comma separated) with CP-profiler")
#endif
{
_mode.add(SM_SOLUTION, "solution");
_mode.add(SM_TIME, "time");
_mode.add(SM_STAT, "stat");
_mode.add(SM_GIST, "gist");
_restart.add(RM_NONE,"none");
_restart.add(RM_CONSTANT,"constant");
_restart.add(RM_LINEAR,"linear");
_restart.add(RM_LUBY,"luby");
_restart.add(RM_GEOMETRIC,"geometric");
add(_model); add(_symmetry); add(_propagation); add(_ipl);
add(_branching); add(_decay); add(_seed); add(_step);
add(_search); add(_solutions); add(_threads); add(_c_d); add(_a_d);
add(_d_l);
add(_node); add(_fail); add(_time); add(_interrupt);
add(_assets); add(_slice);
add(_restart); add(_r_base); add(_r_scale); add(_r_limit);
add(_nogoods); add(_nogoods_limit);
add(_relax);
add(_mode); add(_iterations); add(_samples); add(_print_last);
add(_out_file); add(_log_file); add(_trace);
#ifdef GECODE_HAS_CPPROFILER
add(_profiler);
#endif
}
SizeOptions::SizeOptions(const char* e)
: Options(e), _size(0) {}
void
SizeOptions::help(void) {
Options::help();
std::cerr << "\t(unsigned int) default: " << size() << std::endl
<< "\t\twhich version/size for script" << std::endl;
}
void
SizeOptions::parse(int& argc, char* argv[]) {
Options::parse(argc,argv);
if (argc < 2)
return;
size(static_cast<unsigned int>(atoi(argv[1])));
}
InstanceOptions::InstanceOptions(const char* e)
: Options(e), _inst(nullptr) {}
void
InstanceOptions::instance(const char* s) {
Driver::BaseOption::strdel(_inst);
_inst = Driver::BaseOption::strdup(s);
}
void
InstanceOptions::help(void) {
Options::help();
std::cerr << "\t(string) default: " << instance() << std::endl
<< "\t\twhich instance for script" << std::endl;
}
void
InstanceOptions::parse(int& argc, char* argv[]) {
Options::parse(argc,argv);
if (argc < 2)
return;
instance(argv[1]);
}
InstanceOptions::~InstanceOptions(void) {
Driver::BaseOption::strdel(_inst);
}
}
// STATISTICS: driver-any