1 /***************************************************************************************[Options.h]
2 Copyright (c) 2008-2010, Niklas Sorensson
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:
10 The above copyright notice and this permission notice shall be included in all copies or
11 substantial portions of the Software.
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 **************************************************************************************************/
20 #ifndef Minisat_Options_h
21 #define Minisat_Options_h
30 #include "ParseUtils.h"
34 //==================================================================================================
35 // Top-level option parse/help functions:
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
);
44 //==================================================================================================
45 // Options is an abstract class that gives the interface for all types options:
52 const char* description
;
54 const char* type_name
;
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
; }
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);
67 Option(const char* name_
,
76 getOptionList().push(this);
82 virtual bool parse (const char* str
) = 0;
83 virtual void help (bool verbose
= false) = 0;
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
);
92 //==================================================================================================
93 // Range classes with specialization for floating types:
99 IntRange(int b
, int e
) : begin(b
), end(e
) {}
105 Int64Range(int64_t b
, int64_t e
) : begin(b
), end(e
) {}
111 bool begin_inclusive
;
113 DoubleRange(double b
, bool binc
, double e
, bool einc
) : begin(b
), end(e
), begin_inclusive(binc
), end_inclusive(einc
) {}
117 //==================================================================================================
121 class DoubleOption
: public Option
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.
133 operator double (void) const { return value
; }
134 operator double& (void) { return value
; }
135 DoubleOption
& operator=(double x
) { value
= x
; return *this; }
137 virtual bool parse(const char* str
){
138 const char* span
= str
;
140 if (!match(span
, "-") || !match(span
, name
) || !match(span
, "="))
144 double tmp
= strtod(span
, &end
);
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
);
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
);
156 // fprintf(stderr, "READ VALUE: %g\n", value);
161 virtual void help (bool verbose
= false){
162 fprintf(stderr
, " -%-12s = %-8s %c%4.2g .. %4.2g%c (default: %g)\n",
164 range
.begin_inclusive
? '[' : '(',
167 range
.end_inclusive
? ']' : ')',
170 fprintf(stderr
, "\n %s\n", description
);
171 fprintf(stderr
, "\n");
177 //==================================================================================================
181 class IntOption
: public Option
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
) {}
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; }
195 virtual bool parse(const char* str
){
196 const char* span
= str
;
198 if (!match(span
, "-") || !match(span
, name
) || !match(span
, "="))
202 int32_t tmp
= strtol(span
, &end
, 10);
206 else if (tmp
> range
.end
){
207 fprintf(stderr
, "ERROR! value <%s> is too large for option \"%s\".\n", span
, name
);
209 }else if (tmp
< range
.begin
){
210 fprintf(stderr
, "ERROR! value <%s> is too small for option \"%s\".\n", span
, name
);
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");
223 fprintf(stderr
, "%4d", range
.begin
);
225 fprintf(stderr
, " .. ");
226 if (range
.end
== INT32_MAX
)
227 fprintf(stderr
, "imax");
229 fprintf(stderr
, "%4d", range
.end
);
231 fprintf(stderr
, "] (default: %d)\n", value
);
233 fprintf(stderr
, "\n %s\n", description
);
234 fprintf(stderr
, "\n");
240 // Leave this out for visual C++ until Microsoft implements C99 and gets support for strtoll.
243 class Int64Option
: public Option
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
) {}
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; }
257 virtual bool parse(const char* str
){
258 const char* span
= str
;
260 if (!match(span
, "-") || !match(span
, name
) || !match(span
, "="))
264 int64_t tmp
= strtoll(span
, &end
, 10);
268 else if (tmp
> range
.end
){
269 fprintf(stderr
, "ERROR! value <%s> is too large for option \"%s\".\n", span
, name
);
271 }else if (tmp
< range
.begin
){
272 fprintf(stderr
, "ERROR! value <%s> is too small for option \"%s\".\n", span
, name
);
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");
285 fprintf(stderr
, "%4" PRIi64
, range
.begin
);
287 fprintf(stderr
, " .. ");
288 if (range
.end
== INT64_MAX
)
289 fprintf(stderr
, "imax");
291 fprintf(stderr
, "%4" PRIi64
, range
.end
);
293 fprintf(stderr
, "] (default: %" PRIi64
")\n", value
);
295 fprintf(stderr
, "\n %s\n", description
);
296 fprintf(stderr
, "\n");
302 //==================================================================================================
306 class StringOption
: public Option
310 StringOption(const char* c
, const char* n
, const char* d
, const char* def
= NULL
)
311 : Option(n
, d
, c
, "<string>"), value(def
) {}
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; }
317 virtual bool parse(const char* str
){
318 const char* span
= str
;
320 if (!match(span
, "-") || !match(span
, name
) || !match(span
, "="))
327 virtual void help (bool verbose
= false){
328 fprintf(stderr
, " -%-10s = %8s\n", name
, type_name
);
330 fprintf(stderr
, "\n %s\n", description
);
331 fprintf(stderr
, "\n");
337 //==================================================================================================
341 class BoolOption
: public Option
346 BoolOption(const char* c
, const char* n
, const char* d
, bool v
)
347 : Option(n
, d
, c
, "<bool>"), value(v
) {}
349 operator bool (void) const { return value
; }
350 operator bool& (void) { return value
; }
351 BoolOption
& operator=(bool b
) { value
= b
; return *this; }
353 virtual bool parse(const char* str
){
354 const char* span
= str
;
356 if (match(span
, "-")){
357 bool b
= !match(span
, "no-");
359 if (strcmp(span
, name
) == 0){
367 virtual void help (bool verbose
= false){
369 fprintf(stderr
, " -%s, -no-%s", name
, name
);
371 for (uint32_t i
= 0; i
< 32 - strlen(name
)*2; i
++)
372 fprintf(stderr
, " ");
374 fprintf(stderr
, " ");
375 fprintf(stderr
, "(default: %s)\n", value
? "on" : "off");
377 fprintf(stderr
, "\n %s\n", description
);
378 fprintf(stderr
, "\n");
383 //=================================================================================================