|
|
- /***************************************************************************************[Options.h]
- Copyright (c) 2008-2010, Niklas Sorensson
-
- 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.
- **************************************************************************************************/
-
- #ifndef Minisat_Options_h
- #define Minisat_Options_h
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <string.h>
-
- #include "mtl/IntTypes.h"
- #include "mtl/Vec.h"
- #include "utils/ParseUtils.h"
-
- namespace Minisat {
-
- //==================================================================================================
- // Top-level option parse/help functions:
-
-
- extern void parseOptions (int& argc, char** argv, bool strict = false);
- extern void printUsageAndExit(int argc, char** argv, bool verbose = false);
- extern void setUsageHelp (const char* str);
- extern void setHelpPrefixStr (const char* str);
-
-
- //==================================================================================================
- // Options is an abstract class that gives the interface for all types options:
-
-
- class Option
- {
- protected:
- const char* name;
- const char* description;
- const char* category;
- const char* type_name;
-
- static vec<Option*>& getOptionList () { static vec<Option*> options; return options; }
- static const char*& getUsageString() { static const char* usage_str; return usage_str; }
- static const char*& getHelpPrefixString() { static const char* help_prefix_str = ""; return help_prefix_str; }
-
- struct OptionLt {
- bool operator()(const Option* x, const Option* y) {
- int test1 = strcmp(x->category, y->category);
- return test1 < 0 || test1 == 0 && strcmp(x->type_name, y->type_name) < 0;
- }
- };
-
- Option(const char* name_,
- const char* desc_,
- const char* cate_,
- const char* type_) :
- name (name_)
- , description(desc_)
- , category (cate_)
- , type_name (type_)
- {
- getOptionList().push(this);
- }
-
- public:
- virtual ~Option() {}
-
- virtual bool parse (const char* str) = 0;
- virtual void help (bool verbose = false) = 0;
-
- friend void parseOptions (int& argc, char** argv, bool strict);
- friend void printUsageAndExit (int argc, char** argv, bool verbose);
- friend void setUsageHelp (const char* str);
- friend void setHelpPrefixStr (const char* str);
- };
-
-
- //==================================================================================================
- // Range classes with specialization for floating types:
-
-
- struct IntRange {
- int begin;
- int end;
- IntRange(int b, int e) : begin(b), end(e) {}
- };
-
- struct Int64Range {
- int64_t begin;
- int64_t end;
- Int64Range(int64_t b, int64_t e) : begin(b), end(e) {}
- };
-
- struct DoubleRange {
- double begin;
- double end;
- bool begin_inclusive;
- bool end_inclusive;
- DoubleRange(double b, bool binc, double e, bool einc) : begin(b), end(e), begin_inclusive(binc), end_inclusive(einc) {}
- };
-
-
- //==================================================================================================
- // Double options:
-
-
- class DoubleOption : public Option
- {
- protected:
- DoubleRange range;
- double value;
-
- public:
- DoubleOption(const char* c, const char* n, const char* d, double def = double(), DoubleRange r = DoubleRange(-HUGE_VAL, false, HUGE_VAL, false))
- : Option(n, d, c, "<double>"), range(r), value(def) {
- // FIXME: set LC_NUMERIC to "C" to make sure that strtof/strtod parses decimal point correctly.
- }
-
- operator double (void) const { return value; }
- operator double& (void) { return value; }
- DoubleOption& operator=(double x) { value = x; return *this; }
-
- virtual bool parse(const char* str){
- const char* span = str;
-
- if (!match(span, "-") || !match(span, name) || !match(span, "="))
- return false;
-
- char* end;
- double tmp = strtod(span, &end);
-
- if (end == NULL)
- return false;
- else if (tmp >= range.end && (!range.end_inclusive || tmp != range.end)){
- fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
- exit(1);
- }else if (tmp <= range.begin && (!range.begin_inclusive || tmp != range.begin)){
- fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
- exit(1); }
-
- value = tmp;
- // fprintf(stderr, "READ VALUE: %g\n", value);
-
- return true;
- }
-
- virtual void help (bool verbose = false){
- fprintf(stderr, " -%-12s = %-8s %c%4.2g .. %4.2g%c (default: %g)\n",
- name, type_name,
- range.begin_inclusive ? '[' : '(',
- range.begin,
- range.end,
- range.end_inclusive ? ']' : ')',
- value);
- if (verbose){
- fprintf(stderr, "\n %s\n", description);
- fprintf(stderr, "\n");
- }
- }
- };
-
-
- //==================================================================================================
- // Int options:
-
-
- class IntOption : public Option
- {
- protected:
- IntRange range;
- int32_t value;
-
- public:
- IntOption(const char* c, const char* n, const char* d, int32_t def = int32_t(), IntRange r = IntRange(INT32_MIN, INT32_MAX))
- : Option(n, d, c, "<int32>"), range(r), value(def) {}
-
- operator int32_t (void) const { return value; }
- operator int32_t& (void) { return value; }
- IntOption& operator= (int32_t x) { value = x; return *this; }
-
- virtual bool parse(const char* str){
- const char* span = str;
-
- if (!match(span, "-") || !match(span, name) || !match(span, "="))
- return false;
-
- char* end;
- int32_t tmp = strtol(span, &end, 10);
-
- if (end == NULL)
- return false;
- else if (tmp > range.end){
- fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
- exit(1);
- }else if (tmp < range.begin){
- fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
- exit(1); }
-
- value = tmp;
-
- return true;
- }
-
- virtual void help (bool verbose = false){
- fprintf(stderr, " -%-12s = %-8s [", name, type_name);
- if (range.begin == INT32_MIN)
- fprintf(stderr, "imin");
- else
- fprintf(stderr, "%4d", range.begin);
-
- fprintf(stderr, " .. ");
- if (range.end == INT32_MAX)
- fprintf(stderr, "imax");
- else
- fprintf(stderr, "%4d", range.end);
-
- fprintf(stderr, "] (default: %d)\n", value);
- if (verbose){
- fprintf(stderr, "\n %s\n", description);
- fprintf(stderr, "\n");
- }
- }
- };
-
-
- // Leave this out for visual C++ until Microsoft implements C99 and gets support for strtoll.
- #ifndef _MSC_VER
-
- class Int64Option : public Option
- {
- protected:
- Int64Range range;
- int64_t value;
-
- public:
- Int64Option(const char* c, const char* n, const char* d, int64_t def = int64_t(), Int64Range r = Int64Range(INT64_MIN, INT64_MAX))
- : Option(n, d, c, "<int64>"), range(r), value(def) {}
-
- operator int64_t (void) const { return value; }
- operator int64_t& (void) { return value; }
- Int64Option& operator= (int64_t x) { value = x; return *this; }
-
- virtual bool parse(const char* str){
- const char* span = str;
-
- if (!match(span, "-") || !match(span, name) || !match(span, "="))
- return false;
-
- char* end;
- int64_t tmp = strtoll(span, &end, 10);
-
- if (end == NULL)
- return false;
- else if (tmp > range.end){
- fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
- exit(1);
- }else if (tmp < range.begin){
- fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
- exit(1); }
-
- value = tmp;
-
- return true;
- }
-
- virtual void help (bool verbose = false){
- fprintf(stderr, " -%-12s = %-8s [", name, type_name);
- if (range.begin == INT64_MIN)
- fprintf(stderr, "imin");
- else
- fprintf(stderr, "%4"PRIi64, range.begin);
-
- fprintf(stderr, " .. ");
- if (range.end == INT64_MAX)
- fprintf(stderr, "imax");
- else
- fprintf(stderr, "%4"PRIi64, range.end);
-
- fprintf(stderr, "] (default: %"PRIi64")\n", value);
- if (verbose){
- fprintf(stderr, "\n %s\n", description);
- fprintf(stderr, "\n");
- }
- }
- };
- #endif
-
- //==================================================================================================
- // String option:
-
-
- class StringOption : public Option
- {
- const char* value;
- public:
- StringOption(const char* c, const char* n, const char* d, const char* def = NULL)
- : Option(n, d, c, "<string>"), value(def) {}
-
- operator const char* (void) const { return value; }
- operator const char*& (void) { return value; }
- StringOption& operator= (const char* x) { value = x; return *this; }
-
- virtual bool parse(const char* str){
- const char* span = str;
-
- if (!match(span, "-") || !match(span, name) || !match(span, "="))
- return false;
-
- value = span;
- return true;
- }
-
- virtual void help (bool verbose = false){
- fprintf(stderr, " -%-10s = %8s\n", name, type_name);
- if (verbose){
- fprintf(stderr, "\n %s\n", description);
- fprintf(stderr, "\n");
- }
- }
- };
-
-
- //==================================================================================================
- // Bool option:
-
-
- class BoolOption : public Option
- {
- bool value;
-
- public:
- BoolOption(const char* c, const char* n, const char* d, bool v)
- : Option(n, d, c, "<bool>"), value(v) {}
-
- operator bool (void) const { return value; }
- operator bool& (void) { return value; }
- BoolOption& operator=(bool b) { value = b; return *this; }
-
- virtual bool parse(const char* str){
- const char* span = str;
-
- if (match(span, "-")){
- bool b = !match(span, "no-");
-
- if (strcmp(span, name) == 0){
- value = b;
- return true; }
- }
-
- return false;
- }
-
- virtual void help (bool verbose = false){
-
- fprintf(stderr, " -%s, -no-%s", name, name);
-
- for (uint32_t i = 0; i < 32 - strlen(name)*2; i++)
- fprintf(stderr, " ");
-
- fprintf(stderr, " ");
- fprintf(stderr, "(default: %s)\n", value ? "on" : "off");
- if (verbose){
- fprintf(stderr, "\n %s\n", description);
- fprintf(stderr, "\n");
- }
- }
- };
-
- //=================================================================================================
- }
-
- #endif
|