ruby-minisat 1.14.2 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -21
  3. data/Gemfile +4 -0
  4. data/LICENSE +3 -2
  5. data/README.md +42 -0
  6. data/Rakefile +1 -48
  7. data/examples/shikaku.rb +2 -2
  8. data/ext/minisat/extconf.rb +19 -4
  9. data/ext/minisat/minisat-wrap.cpp +11 -5
  10. data/ext/minisat/minisat.c +17 -3
  11. data/ext/minisat/minisat.h +1 -1
  12. data/minisat/minisat-2.2.0.tar.gz +0 -0
  13. data/minisat/{MiniSat_v1.14 → minisat}/LICENSE +2 -1
  14. data/minisat/minisat/README +24 -0
  15. data/minisat/minisat/core/Dimacs.h +89 -0
  16. data/minisat/minisat/core/Main.cc +192 -0
  17. data/minisat/minisat/core/Solver.cc +923 -0
  18. data/minisat/minisat/core/Solver.h +373 -0
  19. data/minisat/minisat/core/SolverTypes.h +407 -0
  20. data/minisat/minisat/mtl/Alg.h +84 -0
  21. data/minisat/minisat/mtl/Alloc.h +131 -0
  22. data/minisat/minisat/mtl/Heap.h +148 -0
  23. data/minisat/minisat/mtl/IntTypes.h +42 -0
  24. data/minisat/minisat/mtl/Map.h +193 -0
  25. data/minisat/minisat/mtl/Queue.h +69 -0
  26. data/minisat/{MiniSat_v1.14 → minisat/mtl}/Sort.h +14 -47
  27. data/minisat/minisat/mtl/Vec.h +130 -0
  28. data/minisat/minisat/mtl/XAlloc.h +45 -0
  29. data/minisat/minisat/mtl/config.mk +6 -0
  30. data/minisat/minisat/mtl/template.mk +107 -0
  31. data/minisat/minisat/simp/Main.cc +211 -0
  32. data/minisat/minisat/simp/SimpSolver.cc +717 -0
  33. data/minisat/minisat/simp/SimpSolver.h +197 -0
  34. data/minisat/minisat/utils/Options.cc +91 -0
  35. data/minisat/minisat/utils/Options.h +386 -0
  36. data/minisat/minisat/utils/ParseUtils.h +122 -0
  37. data/minisat/minisat/utils/System.cc +95 -0
  38. data/minisat/minisat/utils/System.h +60 -0
  39. data/ruby-minisat.gemspec +21 -0
  40. metadata +94 -75
  41. data/README.rdoc +0 -56
  42. data/minisat/MiniSat_v1.14.2006-Aug-29.src.zip +0 -0
  43. data/minisat/MiniSat_v1.14/Global.h +0 -274
  44. data/minisat/MiniSat_v1.14/Heap.h +0 -100
  45. data/minisat/MiniSat_v1.14/Main.C +0 -244
  46. data/minisat/MiniSat_v1.14/Makefile +0 -88
  47. data/minisat/MiniSat_v1.14/README +0 -30
  48. data/minisat/MiniSat_v1.14/Solver.C +0 -781
  49. data/minisat/MiniSat_v1.14/Solver.h +0 -206
  50. data/minisat/MiniSat_v1.14/Solver.o +0 -0
  51. data/minisat/MiniSat_v1.14/SolverTypes.h +0 -130
  52. data/minisat/MiniSat_v1.14/TODO +0 -73
  53. data/minisat/MiniSat_v1.14/VarOrder.h +0 -96
@@ -0,0 +1,197 @@
1
+ /************************************************************************************[SimpSolver.h]
2
+ Copyright (c) 2006, Niklas Een, Niklas Sorensson
3
+ Copyright (c) 2007-2010, Niklas Sorensson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction,
7
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
8
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or
12
+ substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18
+ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+ **************************************************************************************************/
20
+
21
+ #ifndef Minisat_SimpSolver_h
22
+ #define Minisat_SimpSolver_h
23
+
24
+ #include "mtl/Queue.h"
25
+ #include "core/Solver.h"
26
+
27
+
28
+ namespace Minisat {
29
+
30
+ //=================================================================================================
31
+
32
+
33
+ class SimpSolver : public Solver {
34
+ public:
35
+ // Constructor/Destructor:
36
+ //
37
+ SimpSolver();
38
+ ~SimpSolver();
39
+
40
+ // Problem specification:
41
+ //
42
+ Var newVar (bool polarity = true, bool dvar = true);
43
+ bool addClause (const vec<Lit>& ps);
44
+ bool addEmptyClause(); // Add the empty clause to the solver.
45
+ bool addClause (Lit p); // Add a unit clause to the solver.
46
+ bool addClause (Lit p, Lit q); // Add a binary clause to the solver.
47
+ bool addClause (Lit p, Lit q, Lit r); // Add a ternary clause to the solver.
48
+ bool addClause_( vec<Lit>& ps);
49
+ bool substitute(Var v, Lit x); // Replace all occurences of v with x (may cause a contradiction).
50
+
51
+ // Variable mode:
52
+ //
53
+ void setFrozen (Var v, bool b); // If a variable is frozen it will not be eliminated.
54
+ bool isEliminated(Var v) const;
55
+
56
+ // Solving:
57
+ //
58
+ bool solve (const vec<Lit>& assumps, bool do_simp = true, bool turn_off_simp = false);
59
+ lbool solveLimited(const vec<Lit>& assumps, bool do_simp = true, bool turn_off_simp = false);
60
+ bool solve ( bool do_simp = true, bool turn_off_simp = false);
61
+ bool solve (Lit p , bool do_simp = true, bool turn_off_simp = false);
62
+ bool solve (Lit p, Lit q, bool do_simp = true, bool turn_off_simp = false);
63
+ bool solve (Lit p, Lit q, Lit r, bool do_simp = true, bool turn_off_simp = false);
64
+ bool eliminate (bool turn_off_elim = false); // Perform variable elimination based simplification.
65
+
66
+ // Memory managment:
67
+ //
68
+ virtual void garbageCollect();
69
+
70
+
71
+ // Generate a (possibly simplified) DIMACS file:
72
+ //
73
+ #if 0
74
+ void toDimacs (const char* file, const vec<Lit>& assumps);
75
+ void toDimacs (const char* file);
76
+ void toDimacs (const char* file, Lit p);
77
+ void toDimacs (const char* file, Lit p, Lit q);
78
+ void toDimacs (const char* file, Lit p, Lit q, Lit r);
79
+ #endif
80
+
81
+ // Mode of operation:
82
+ //
83
+ int grow; // Allow a variable elimination step to grow by a number of clauses (default to zero).
84
+ int clause_lim; // Variables are not eliminated if it produces a resolvent with a length above this limit.
85
+ // -1 means no limit.
86
+ int subsumption_lim; // Do not check if subsumption against a clause larger than this. -1 means no limit.
87
+ double simp_garbage_frac; // A different limit for when to issue a GC during simplification (Also see 'garbage_frac').
88
+
89
+ bool use_asymm; // Shrink clauses by asymmetric branching.
90
+ bool use_rcheck; // Check if a clause is already implied. Prett costly, and subsumes subsumptions :)
91
+ bool use_elim; // Perform variable elimination.
92
+
93
+ // Statistics:
94
+ //
95
+ int merges;
96
+ int asymm_lits;
97
+ int eliminated_vars;
98
+
99
+ protected:
100
+
101
+ // Helper structures:
102
+ //
103
+ struct ElimLt {
104
+ const vec<int>& n_occ;
105
+ explicit ElimLt(const vec<int>& no) : n_occ(no) {}
106
+
107
+ // TODO: are 64-bit operations here noticably bad on 32-bit platforms? Could use a saturating
108
+ // 32-bit implementation instead then, but this will have to do for now.
109
+ uint64_t cost (Var x) const { return (uint64_t)n_occ[toInt(mkLit(x))] * (uint64_t)n_occ[toInt(~mkLit(x))]; }
110
+ bool operator()(Var x, Var y) const { return cost(x) < cost(y); }
111
+
112
+ // TODO: investigate this order alternative more.
113
+ // bool operator()(Var x, Var y) const {
114
+ // int c_x = cost(x);
115
+ // int c_y = cost(y);
116
+ // return c_x < c_y || c_x == c_y && x < y; }
117
+ };
118
+
119
+ struct ClauseDeleted {
120
+ const ClauseAllocator& ca;
121
+ explicit ClauseDeleted(const ClauseAllocator& _ca) : ca(_ca) {}
122
+ bool operator()(const CRef& cr) const { return ca[cr].mark() == 1; } };
123
+
124
+ // Solver state:
125
+ //
126
+ int elimorder;
127
+ bool use_simplification;
128
+ vec<uint32_t> elimclauses;
129
+ vec<char> touched;
130
+ OccLists<Var, vec<CRef>, ClauseDeleted>
131
+ occurs;
132
+ vec<int> n_occ;
133
+ Heap<ElimLt> elim_heap;
134
+ Queue<CRef> subsumption_queue;
135
+ vec<char> frozen;
136
+ vec<char> eliminated;
137
+ int bwdsub_assigns;
138
+ int n_touched;
139
+
140
+ // Temporaries:
141
+ //
142
+ CRef bwdsub_tmpunit;
143
+
144
+ // Main internal methods:
145
+ //
146
+ lbool solve_ (bool do_simp = true, bool turn_off_simp = false);
147
+ bool asymm (Var v, CRef cr);
148
+ bool asymmVar (Var v);
149
+ void updateElimHeap (Var v);
150
+ void gatherTouchedClauses ();
151
+ bool merge (const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause);
152
+ bool merge (const Clause& _ps, const Clause& _qs, Var v, int& size);
153
+ bool backwardSubsumptionCheck (bool verbose = false);
154
+ bool eliminateVar (Var v);
155
+ void extendModel ();
156
+
157
+ void removeClause (CRef cr);
158
+ bool strengthenClause (CRef cr, Lit l);
159
+ void cleanUpClauses ();
160
+ bool implied (const vec<Lit>& c);
161
+ void relocAll (ClauseAllocator& to);
162
+ };
163
+
164
+
165
+ //=================================================================================================
166
+ // Implementation of inline methods:
167
+
168
+
169
+ inline bool SimpSolver::isEliminated (Var v) const { return eliminated[v]; }
170
+ inline void SimpSolver::updateElimHeap(Var v) {
171
+ assert(use_simplification);
172
+ // if (!frozen[v] && !isEliminated(v) && value(v) == l_Undef)
173
+ if (elim_heap.inHeap(v) || (!frozen[v] && !isEliminated(v) && value(v) == l_Undef))
174
+ elim_heap.update(v); }
175
+
176
+
177
+ inline bool SimpSolver::addClause (const vec<Lit>& ps) { ps.copyTo(add_tmp); return addClause_(add_tmp); }
178
+ inline bool SimpSolver::addEmptyClause() { add_tmp.clear(); return addClause_(add_tmp); }
179
+ inline bool SimpSolver::addClause (Lit p) { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); }
180
+ inline bool SimpSolver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); }
181
+ inline bool SimpSolver::addClause (Lit p, Lit q, Lit r) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); }
182
+ inline void SimpSolver::setFrozen (Var v, bool b) { frozen[v] = (char)b; if (use_simplification && !b) { updateElimHeap(v); } }
183
+
184
+ inline bool SimpSolver::solve ( bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); return solve_(do_simp, turn_off_simp) == l_True; }
185
+ inline bool SimpSolver::solve (Lit p , bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_(do_simp, turn_off_simp) == l_True; }
186
+ inline bool SimpSolver::solve (Lit p, Lit q, bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_(do_simp, turn_off_simp) == l_True; }
187
+ inline bool SimpSolver::solve (Lit p, Lit q, Lit r, bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); assumptions.push(r); return solve_(do_simp, turn_off_simp) == l_True; }
188
+ inline bool SimpSolver::solve (const vec<Lit>& assumps, bool do_simp, bool turn_off_simp){
189
+ budgetOff(); assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp) == l_True; }
190
+
191
+ inline lbool SimpSolver::solveLimited (const vec<Lit>& assumps, bool do_simp, bool turn_off_simp){
192
+ assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp); }
193
+
194
+ //=================================================================================================
195
+ }
196
+
197
+ #endif
@@ -0,0 +1,91 @@
1
+ /**************************************************************************************[Options.cc]
2
+ Copyright (c) 2008-2010, Niklas Sorensson
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5
+ associated documentation files (the "Software"), to deal in the Software without restriction,
6
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
7
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all copies or
11
+ substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
17
+ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18
+ **************************************************************************************************/
19
+
20
+ #include "mtl/Sort.h"
21
+ #include "utils/Options.h"
22
+ #include "utils/ParseUtils.h"
23
+
24
+ using namespace Minisat;
25
+
26
+ void Minisat::parseOptions(int& argc, char** argv, bool strict)
27
+ {
28
+ int i, j;
29
+ for (i = j = 1; i < argc; i++){
30
+ const char* str = argv[i];
31
+ if (match(str, "--") && match(str, Option::getHelpPrefixString()) && match(str, "help")){
32
+ if (*str == '\0')
33
+ printUsageAndExit(argc, argv);
34
+ else if (match(str, "-verb"))
35
+ printUsageAndExit(argc, argv, true);
36
+ } else {
37
+ bool parsed_ok = false;
38
+
39
+ for (int k = 0; !parsed_ok && k < Option::getOptionList().size(); k++){
40
+ parsed_ok = Option::getOptionList()[k]->parse(argv[i]);
41
+
42
+ // fprintf(stderr, "checking %d: %s against flag <%s> (%s)\n", i, argv[i], Option::getOptionList()[k]->name, parsed_ok ? "ok" : "skip");
43
+ }
44
+
45
+ if (!parsed_ok)
46
+ if (strict && match(argv[i], "-"))
47
+ fprintf(stderr, "ERROR! Unknown flag \"%s\". Use '--%shelp' for help.\n", argv[i], Option::getHelpPrefixString()), exit(1);
48
+ else
49
+ argv[j++] = argv[i];
50
+ }
51
+ }
52
+
53
+ argc -= (i - j);
54
+ }
55
+
56
+
57
+ void Minisat::setUsageHelp (const char* str){ Option::getUsageString() = str; }
58
+ void Minisat::setHelpPrefixStr (const char* str){ Option::getHelpPrefixString() = str; }
59
+ void Minisat::printUsageAndExit (int argc, char** argv, bool verbose)
60
+ {
61
+ const char* usage = Option::getUsageString();
62
+ if (usage != NULL)
63
+ fprintf(stderr, usage, argv[0]);
64
+
65
+ sort(Option::getOptionList(), Option::OptionLt());
66
+
67
+ const char* prev_cat = NULL;
68
+ const char* prev_type = NULL;
69
+
70
+ for (int i = 0; i < Option::getOptionList().size(); i++){
71
+ const char* cat = Option::getOptionList()[i]->category;
72
+ const char* type = Option::getOptionList()[i]->type_name;
73
+
74
+ if (cat != prev_cat)
75
+ fprintf(stderr, "\n%s OPTIONS:\n\n", cat);
76
+ else if (type != prev_type)
77
+ fprintf(stderr, "\n");
78
+
79
+ Option::getOptionList()[i]->help(verbose);
80
+
81
+ prev_cat = Option::getOptionList()[i]->category;
82
+ prev_type = Option::getOptionList()[i]->type_name;
83
+ }
84
+
85
+ fprintf(stderr, "\nHELP OPTIONS:\n\n");
86
+ fprintf(stderr, " --%shelp Print help message.\n", Option::getHelpPrefixString());
87
+ fprintf(stderr, " --%shelp-verb Print verbose help message.\n", Option::getHelpPrefixString());
88
+ fprintf(stderr, "\n");
89
+ exit(0);
90
+ }
91
+
@@ -0,0 +1,386 @@
1
+ /***************************************************************************************[Options.h]
2
+ Copyright (c) 2008-2010, Niklas Sorensson
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5
+ associated documentation files (the "Software"), to deal in the Software without restriction,
6
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
7
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all copies or
11
+ substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
17
+ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18
+ **************************************************************************************************/
19
+
20
+ #ifndef Minisat_Options_h
21
+ #define Minisat_Options_h
22
+
23
+ #include <stdlib.h>
24
+ #include <stdio.h>
25
+ #include <math.h>
26
+ #include <string.h>
27
+
28
+ #include "mtl/IntTypes.h"
29
+ #include "mtl/Vec.h"
30
+ #include "utils/ParseUtils.h"
31
+
32
+ namespace Minisat {
33
+
34
+ //==================================================================================================
35
+ // Top-level option parse/help functions:
36
+
37
+
38
+ extern void parseOptions (int& argc, char** argv, bool strict = false);
39
+ extern void printUsageAndExit(int argc, char** argv, bool verbose = false);
40
+ extern void setUsageHelp (const char* str);
41
+ extern void setHelpPrefixStr (const char* str);
42
+
43
+
44
+ //==================================================================================================
45
+ // Options is an abstract class that gives the interface for all types options:
46
+
47
+
48
+ class Option
49
+ {
50
+ protected:
51
+ const char* name;
52
+ const char* description;
53
+ const char* category;
54
+ const char* type_name;
55
+
56
+ static vec<Option*>& getOptionList () { static vec<Option*> options; return options; }
57
+ static const char*& getUsageString() { static const char* usage_str; return usage_str; }
58
+ static const char*& getHelpPrefixString() { static const char* help_prefix_str = ""; return help_prefix_str; }
59
+
60
+ struct OptionLt {
61
+ bool operator()(const Option* x, const Option* y) {
62
+ int test1 = strcmp(x->category, y->category);
63
+ return test1 < 0 || test1 == 0 && strcmp(x->type_name, y->type_name) < 0;
64
+ }
65
+ };
66
+
67
+ Option(const char* name_,
68
+ const char* desc_,
69
+ const char* cate_,
70
+ const char* type_) :
71
+ name (name_)
72
+ , description(desc_)
73
+ , category (cate_)
74
+ , type_name (type_)
75
+ {
76
+ getOptionList().push(this);
77
+ }
78
+
79
+ public:
80
+ virtual ~Option() {}
81
+
82
+ virtual bool parse (const char* str) = 0;
83
+ virtual void help (bool verbose = false) = 0;
84
+
85
+ friend void parseOptions (int& argc, char** argv, bool strict);
86
+ friend void printUsageAndExit (int argc, char** argv, bool verbose);
87
+ friend void setUsageHelp (const char* str);
88
+ friend void setHelpPrefixStr (const char* str);
89
+ };
90
+
91
+
92
+ //==================================================================================================
93
+ // Range classes with specialization for floating types:
94
+
95
+
96
+ struct IntRange {
97
+ int begin;
98
+ int end;
99
+ IntRange(int b, int e) : begin(b), end(e) {}
100
+ };
101
+
102
+ struct Int64Range {
103
+ int64_t begin;
104
+ int64_t end;
105
+ Int64Range(int64_t b, int64_t e) : begin(b), end(e) {}
106
+ };
107
+
108
+ struct DoubleRange {
109
+ double begin;
110
+ double end;
111
+ bool begin_inclusive;
112
+ bool end_inclusive;
113
+ DoubleRange(double b, bool binc, double e, bool einc) : begin(b), end(e), begin_inclusive(binc), end_inclusive(einc) {}
114
+ };
115
+
116
+
117
+ //==================================================================================================
118
+ // Double options:
119
+
120
+
121
+ class DoubleOption : public Option
122
+ {
123
+ protected:
124
+ DoubleRange range;
125
+ double value;
126
+
127
+ public:
128
+ DoubleOption(const char* c, const char* n, const char* d, double def = double(), DoubleRange r = DoubleRange(-HUGE_VAL, false, HUGE_VAL, false))
129
+ : Option(n, d, c, "<double>"), range(r), value(def) {
130
+ // FIXME: set LC_NUMERIC to "C" to make sure that strtof/strtod parses decimal point correctly.
131
+ }
132
+
133
+ operator double (void) const { return value; }
134
+ operator double& (void) { return value; }
135
+ DoubleOption& operator=(double x) { value = x; return *this; }
136
+
137
+ virtual bool parse(const char* str){
138
+ const char* span = str;
139
+
140
+ if (!match(span, "-") || !match(span, name) || !match(span, "="))
141
+ return false;
142
+
143
+ char* end;
144
+ double tmp = strtod(span, &end);
145
+
146
+ if (end == NULL)
147
+ return false;
148
+ else if (tmp >= range.end && (!range.end_inclusive || tmp != range.end)){
149
+ fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
150
+ exit(1);
151
+ }else if (tmp <= range.begin && (!range.begin_inclusive || tmp != range.begin)){
152
+ fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
153
+ exit(1); }
154
+
155
+ value = tmp;
156
+ // fprintf(stderr, "READ VALUE: %g\n", value);
157
+
158
+ return true;
159
+ }
160
+
161
+ virtual void help (bool verbose = false){
162
+ fprintf(stderr, " -%-12s = %-8s %c%4.2g .. %4.2g%c (default: %g)\n",
163
+ name, type_name,
164
+ range.begin_inclusive ? '[' : '(',
165
+ range.begin,
166
+ range.end,
167
+ range.end_inclusive ? ']' : ')',
168
+ value);
169
+ if (verbose){
170
+ fprintf(stderr, "\n %s\n", description);
171
+ fprintf(stderr, "\n");
172
+ }
173
+ }
174
+ };
175
+
176
+
177
+ //==================================================================================================
178
+ // Int options:
179
+
180
+
181
+ class IntOption : public Option
182
+ {
183
+ protected:
184
+ IntRange range;
185
+ int32_t value;
186
+
187
+ public:
188
+ IntOption(const char* c, const char* n, const char* d, int32_t def = int32_t(), IntRange r = IntRange(INT32_MIN, INT32_MAX))
189
+ : Option(n, d, c, "<int32>"), range(r), value(def) {}
190
+
191
+ operator int32_t (void) const { return value; }
192
+ operator int32_t& (void) { return value; }
193
+ IntOption& operator= (int32_t x) { value = x; return *this; }
194
+
195
+ virtual bool parse(const char* str){
196
+ const char* span = str;
197
+
198
+ if (!match(span, "-") || !match(span, name) || !match(span, "="))
199
+ return false;
200
+
201
+ char* end;
202
+ int32_t tmp = strtol(span, &end, 10);
203
+
204
+ if (end == NULL)
205
+ return false;
206
+ else if (tmp > range.end){
207
+ fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
208
+ exit(1);
209
+ }else if (tmp < range.begin){
210
+ fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
211
+ exit(1); }
212
+
213
+ value = tmp;
214
+
215
+ return true;
216
+ }
217
+
218
+ virtual void help (bool verbose = false){
219
+ fprintf(stderr, " -%-12s = %-8s [", name, type_name);
220
+ if (range.begin == INT32_MIN)
221
+ fprintf(stderr, "imin");
222
+ else
223
+ fprintf(stderr, "%4d", range.begin);
224
+
225
+ fprintf(stderr, " .. ");
226
+ if (range.end == INT32_MAX)
227
+ fprintf(stderr, "imax");
228
+ else
229
+ fprintf(stderr, "%4d", range.end);
230
+
231
+ fprintf(stderr, "] (default: %d)\n", value);
232
+ if (verbose){
233
+ fprintf(stderr, "\n %s\n", description);
234
+ fprintf(stderr, "\n");
235
+ }
236
+ }
237
+ };
238
+
239
+
240
+ // Leave this out for visual C++ until Microsoft implements C99 and gets support for strtoll.
241
+ #ifndef _MSC_VER
242
+
243
+ class Int64Option : public Option
244
+ {
245
+ protected:
246
+ Int64Range range;
247
+ int64_t value;
248
+
249
+ public:
250
+ Int64Option(const char* c, const char* n, const char* d, int64_t def = int64_t(), Int64Range r = Int64Range(INT64_MIN, INT64_MAX))
251
+ : Option(n, d, c, "<int64>"), range(r), value(def) {}
252
+
253
+ operator int64_t (void) const { return value; }
254
+ operator int64_t& (void) { return value; }
255
+ Int64Option& operator= (int64_t x) { value = x; return *this; }
256
+
257
+ virtual bool parse(const char* str){
258
+ const char* span = str;
259
+
260
+ if (!match(span, "-") || !match(span, name) || !match(span, "="))
261
+ return false;
262
+
263
+ char* end;
264
+ int64_t tmp = strtoll(span, &end, 10);
265
+
266
+ if (end == NULL)
267
+ return false;
268
+ else if (tmp > range.end){
269
+ fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
270
+ exit(1);
271
+ }else if (tmp < range.begin){
272
+ fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
273
+ exit(1); }
274
+
275
+ value = tmp;
276
+
277
+ return true;
278
+ }
279
+
280
+ virtual void help (bool verbose = false){
281
+ fprintf(stderr, " -%-12s = %-8s [", name, type_name);
282
+ if (range.begin == INT64_MIN)
283
+ fprintf(stderr, "imin");
284
+ else
285
+ fprintf(stderr, "%4"PRIi64, range.begin);
286
+
287
+ fprintf(stderr, " .. ");
288
+ if (range.end == INT64_MAX)
289
+ fprintf(stderr, "imax");
290
+ else
291
+ fprintf(stderr, "%4"PRIi64, range.end);
292
+
293
+ fprintf(stderr, "] (default: %"PRIi64")\n", value);
294
+ if (verbose){
295
+ fprintf(stderr, "\n %s\n", description);
296
+ fprintf(stderr, "\n");
297
+ }
298
+ }
299
+ };
300
+ #endif
301
+
302
+ //==================================================================================================
303
+ // String option:
304
+
305
+
306
+ class StringOption : public Option
307
+ {
308
+ const char* value;
309
+ public:
310
+ StringOption(const char* c, const char* n, const char* d, const char* def = NULL)
311
+ : Option(n, d, c, "<string>"), value(def) {}
312
+
313
+ operator const char* (void) const { return value; }
314
+ operator const char*& (void) { return value; }
315
+ StringOption& operator= (const char* x) { value = x; return *this; }
316
+
317
+ virtual bool parse(const char* str){
318
+ const char* span = str;
319
+
320
+ if (!match(span, "-") || !match(span, name) || !match(span, "="))
321
+ return false;
322
+
323
+ value = span;
324
+ return true;
325
+ }
326
+
327
+ virtual void help (bool verbose = false){
328
+ fprintf(stderr, " -%-10s = %8s\n", name, type_name);
329
+ if (verbose){
330
+ fprintf(stderr, "\n %s\n", description);
331
+ fprintf(stderr, "\n");
332
+ }
333
+ }
334
+ };
335
+
336
+
337
+ //==================================================================================================
338
+ // Bool option:
339
+
340
+
341
+ class BoolOption : public Option
342
+ {
343
+ bool value;
344
+
345
+ public:
346
+ BoolOption(const char* c, const char* n, const char* d, bool v)
347
+ : Option(n, d, c, "<bool>"), value(v) {}
348
+
349
+ operator bool (void) const { return value; }
350
+ operator bool& (void) { return value; }
351
+ BoolOption& operator=(bool b) { value = b; return *this; }
352
+
353
+ virtual bool parse(const char* str){
354
+ const char* span = str;
355
+
356
+ if (match(span, "-")){
357
+ bool b = !match(span, "no-");
358
+
359
+ if (strcmp(span, name) == 0){
360
+ value = b;
361
+ return true; }
362
+ }
363
+
364
+ return false;
365
+ }
366
+
367
+ virtual void help (bool verbose = false){
368
+
369
+ fprintf(stderr, " -%s, -no-%s", name, name);
370
+
371
+ for (uint32_t i = 0; i < 32 - strlen(name)*2; i++)
372
+ fprintf(stderr, " ");
373
+
374
+ fprintf(stderr, " ");
375
+ fprintf(stderr, "(default: %s)\n", value ? "on" : "off");
376
+ if (verbose){
377
+ fprintf(stderr, "\n %s\n", description);
378
+ fprintf(stderr, "\n");
379
+ }
380
+ }
381
+ };
382
+
383
+ //=================================================================================================
384
+ }
385
+
386
+ #endif