configure.cc

来自「用于计算矩阵的特征值,及矩阵的其他运算.可以用与稀疏矩阵」· CC 代码 · 共 1,016 行 · 第 1/2 页

CC
1,016
字号
// Copyright (C) 2002 David R. Martin <dmartin@eecs.berkeley.edu>// Copyright (C) 2002 Charless C. Fowlkes <fowlkes@eecs.berkeley.edu>//// This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License as// published by the Free Software Foundation; either version 2 of the// License, or (at your option) any later version.//// This program is distributed in the hope that it will be useful, but// WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU// General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA// 02111-1307, USA, or see http://www.gnu.org/copyleft/gpl.html.#include <stdlib.h>#include <string.h>#include <stdio.h>#include <assert.h>#include "configure.hh"#include "message.hh"#include "string.hh"#include "exception.hh"#include "util.hh"#include "types.hh"using Util::int64;using Util::String;using Util::Exception;using Util::Message;  // So we can convert Type to strings.  enum Type { BOOL, INT, FLOAT, STRING, ENUM };  static const char *typeNames[] = { "bool", "int", "float", "string", "enum" };  static const char *configKey = "config";  union Value  {    bool _bool;    int64 _int;    double _float;    const char *_string;    uint _enum;  };  static void checkKey (const char *key);  class Option  {  public:    Option (Type type, const char *key,            const char *description, const char *const *enumValues,            Value value, bool printHex)    {      checkKey (key);      _type = type;      _key = strdup (key);      _description = strdup (description);      _enumValues = enumValues;      _defaultValue = value;      _value = value;      _printHex = printHex;    }    bool equals (const char *key)    {      return (strcmp (key, _key) == 0);    }    Type _type;    const char *_key;    const char *_description;    const char *const *_enumValues;    Value _defaultValue;    Value _value;    bool _printHex;  };  class Map  {  public:    Map ()    {      _count = 0;      for (uint i = 0; i < _numBuckets; i++)      {        _buckets[i] = NULL;      }    }    void put (Option * option)    {      if (get (option->_key) != NULL)      {        throw          Exception (String                     ("Configure: Option %s is already registered.",                      option->_key));      }      uint index = _hash (option->_key);      _buckets[index] = new Node (option, _buckets[index]);      _count++;    }    Option *get (const char *key)    {      uint index = _hash (key);      for (Node * node = _buckets[index]; node != NULL; node = node->_next)      {        if (node->_option->equals (key))        {          return node->_option;        }      }      return NULL;    }    Option *getAlways (const char *key, Type type)    {      Option *option = get (key);      if (option == NULL)      {        throw          Exception (String ("Configure: Option %s is not registered.", key));      }      if (option->_type != type)      {        throw Exception (String ("Configure:: Option %s "                                 "is not type %s, it is type %s.",                                 key,                                 typeNames[type], typeNames[option->_type]));      }      return option;    }    Option **getAll ()    {      Option **options = new Option *[_count];      uint c = 0;      for (uint i = 0; i < _numBuckets; i++)      {        for (Node * node = _buckets[i]; node != NULL; node = node->_next)        {          options[c++] = node->_option;        }      }      assert (c == _count);      return options;    }    uint count ()    {      return _count;    }  private:    static const uint _numBuckets = 1024;    class Node    {    public:      Node (Option * option, Node * next)      {        _option = option;        _next = next;      }      Option *_option;      Node *_next;    };    uint _hash (const char *key)    {      uint v = 0;      for (const char *p = key; *p != '\0'; p++)      {        v = ((v << 1) + v) ^ (*p);      }      return v % _numBuckets;    }    Node *_buckets[_numBuckets];    uint _count;  };  // Where the option->value map lives.  static Map map;  // Register options...  void  Configure::registerBool (const char *key, bool defaultValue,                           const char *description)  {    Value value;    value._bool = defaultValue;    Option *option = new Option (BOOL, key, description, NULL, value, false);    map.put (option);  }  void  Configure::registerInt (const char *key, int64 defaultValue,                          const char *description, bool printHex)  {    Value value;    value._int = defaultValue;    Option *option = new Option (INT, key, description, NULL, value, printHex);    map.put (option);  }  void  Configure::registerFloat (const char *key, double defaultValue,                            const char *description)  {    Value value;    value._float = defaultValue;    Option *option = new Option (FLOAT, key, description, NULL, value, false);    map.put (option);  }  void  Configure::registerString (const char *key, const char *defaultValue,                             const char *description)  {    Value value;    value._string = (defaultValue == NULL) ? NULL : strdup (defaultValue);    Option *option = new Option (STRING, key, description, NULL, value, false);    map.put (option);  }  void  Configure::registerEnum (const char *key,                           const char *const *values, uint defaultValue,                           const char *description)  {    Value value;    value._enum = defaultValue;    Option *option = new Option (ENUM, key, description, values, value, false);    map.put (option);  }  // Retrieve options...  bool  Configure::getBool (const char *key)  {    Option *option = map.getAlways (key, BOOL);    return option->_value._bool;  }  int64  Configure::getInt (const char *key)  {    Option *option = map.getAlways (key, INT);    return option->_value._int;  }  double  Configure::getFloat (const char *key)  {    Option *option = map.getAlways (key, FLOAT);    return option->_value._float;  }  char *  Configure::getString (const char *key)  {    Option *option = map.getAlways (key, STRING);    if (option->_value._string == NULL)    {      return NULL;    }    else    {      return strdup (option->_value._string);    }  }  uint  Configure::getEnum (const char *key)  {    Option *option = map.getAlways (key, ENUM);    return option->_value._enum;  }  // Check if the given string is valid as a key.  static bool  validKey (const char *key)  {    uint len = strlen (key);    for (uint i = 0; i < len; i++)    {      int c = key[i];      if (c == '_')      {        continue;      }      if (c == ':')      {        continue;      }      if (i == 0 && isalpha (c))      {        continue;      }      if (i > 0 && isalnum (c))      {        continue;      }      return false;    }    return true;  }  // Make sure the given string is valid as a key.  static void  checkKey (const char *key)  {    if (key == NULL)    {      throw Exception ("Configure: NULL key.");    }    if (strcmp (key, configKey) == 0)    {      throw        Exception (String ("Configure: Option conflicts with builtin"                           "config option '%s'.", configKey));    }    if (!validKey (key))    {      throw Exception (String ("Configure: Illegal key \"%s\".", key));    }  }  // Return true on success, false on failure.  // <arg> := <key>=<value>  static bool  parseArg (const String & arg, String & key, String & value)  {    // Make sure there is an '=' character in the middle of arg.    const char *p = arg.text ();    const char *eq = strchr (p, '=');    if (eq == NULL)    {      return false;    }    uint offset = eq - p;    if (offset == 0)    {      return false;    }    key.clear ();    value.clear ();    uint i;    for (i = 0; i < offset; i++)    {      key.append (p[i]);    }    assert (p[i] == '=');    for (i++; i < arg.length (); i++)    {      value.append (p[i]);    }    return true;  }  // Throw exception on failure.  static void  parseBool (const char *s, bool & val)  {    String str ("%s", s);    if (str == "no")    {      val = false;      return;    }    if (str == "off")    {      val = false;      return;    }    if (str == "0")    {      val = false;      return;    }    if (str == "false")    {      val = false;      return;    }    if (str == "yes")    {      val = true;      return;    }    if (str == "on")    {      val = true;      return;    }    if (str == "1")    {      val = true;      return;    }    if (str == "true")    {      val = true;      return;    }    throw Exception (String ("Error parsing boolean value \"%s\"", s));  }  // Throw exception on failure.  static void  parseInt (const char *s, int64 & val)  {    int c, n;    c = sscanf (s, "%lld%n", &val, &n);    if (c == 1 && s[n] == '\0')    {      return;    }    c = sscanf (s, "%llx%n", &val, &n);    if (c == 1 && s[n] == '\0')    {      return;    }    throw Exception (String ("Error parsing integer value \"%s\"", s));  }  // Throw exception on failure.  static void  parseFloat (const char *s, double &val)  {    int n;    int c = sscanf (s, "%lf%n", &val, &n);    if (c == 1 && s[n] == '\0')    {      return;    }    throw Exception (String ("Error parsing floating-point value \"%s\"", s));  }  // Throw exception on failure.  static void  parseEnum (const char *s, const char *const *values, uint & val)  {    String str ("%s", s);    for (uint index = 0; values[index] != NULL; index++)    {      if (str == values[index])      {        val = index;        return;      }    }    throw Exception (String ("Error parsing enumeration value \"%s\"", s));  }  // Throw exception on failure.  // Trailing whitespace is allowed.  static Value  parseValue (Type type, const char *const *enumValues, const char *s)  {    // Remove any whitespace from the end of s.    uint len = strlen (s);    while (len > 0 && isspace (s[len - 1]))    {      len--;    }    String val;    val.append (len, s);    Value value;    switch (type)    {    case BOOL:      parseBool (val, value._bool);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?