configure.cc

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

CC
1,016
字号
      break;    case INT:      parseInt (val, value._int);      break;    case FLOAT:      parseFloat (val, value._float);      break;    case STRING:      value._string = strdup (val.text ());      break;    case ENUM:      parseEnum (val, enumValues, value._enum);      break;    default:      assert (0);    }    return value;  }  // LEX-defined externals.  extern int __cfl_lex ();  extern int __cfl_lineNo;  extern int __cfl_columnNo;  extern FILE *__cfl_in;  // Shared state for LEX callbaks.  static const char *yyConfigFileName = NULL;  static String yyKey;  static Option *yyOption;  enum LexStateType  {    lstKey,                       // Looking for a key.    lstValue                      // Looking for a value.  };  static LexStateType lexState;  // LEX callbacks.  void  __cfl_SyntaxError (const char *msg)  {    throw      Exception (String                 ("Syntax error while parsing configuration file:\n"                  "%s:%d: %s", yyConfigFileName, __cfl_lineNo, msg));  }  void  __cfl_FoundToken (const char *s)  {    switch (lexState)    {    case lstKey:      {        // Make sure the key is valid.        if (!validKey (s))        {          throw            Exception (String ("%s:%d: Invalid key \"%s\".",                               yyConfigFileName, __cfl_lineNo, s));        }        // Look up the option to make sure its there.        yyOption = map.get (s);        if (yyOption == NULL)        {          Message::error(String("%s:%d: Skipping unknown option \"%s\".\n",                                 yyConfigFileName, __cfl_lineNo, s));  //              throw Exception (String (  //                  "%s:%d: Unknown option \"%s\".",  //                  yyConfigFileName, __cfl_lineNo, s));        }        yyKey.clear ();        yyKey.append ("%s", s);        lexState = lstValue;        break;      }    case lstValue:      {        // Parse the value and add it to the map.        if (yyOption != NULL)        {          try          {            yyOption->_value =              parseValue (yyOption->_type, yyOption->_enumValues, s);          }          catch (Exception & e)          {            throw              Exception (String ("%s:%d: %s for \"%s\".",                                 yyConfigFileName, __cfl_lineNo,                                 e.msg (), yyKey.text ()));          }        }        lexState = lstKey;        break;      }    default:      assert (0);    }  }  void  __cfl_FoundString (const char *s)  {    __cfl_FoundToken (s);  }  void  __cfl_AllDone ()  {    switch (lexState)    {    case lstKey:      {        // Ok.        break;      }    case lstValue:      {        throw          Exception (String ("%s:%d: Missing value for \"%s\".",                             yyConfigFileName, __cfl_lineNo, yyKey.text ()));        break;      }    default:      assert (0);    }  }  // Parse the configuration file using a LEX-generated lexer.  static void  processConfigFile (const char *fileName)  {    FILE *strm = NULL;    try    {      strm = Util::openInputStrm (fileName);      yyConfigFileName = fileName;      lexState = lstKey;      __cfl_in = strm;      int rval = __cfl_lex ();      if (rval != 0)      {        throw Exception (String ("Lex error (%d) on file %s.", rval, fileName));      }    }    catch (Exception & e)    {      if (strm != NULL)      {        fclose (strm);      }      throw;    }  }  void  Configure::init (const char *key, const char *value)  {    assert (key != NULL);    // Look for special config key.    if (strcmp (key, configKey) == 0)    {      processConfigFile (value);      return;    }    // Look up the key.    Option *option = map.get (key);    if (option == NULL)    {      throw Exception (String ("Option %s not found.", key));    }    // Parse the value and store the result.    try    {      option->_value = parseValue (option->_type, option->_enumValues, value);    }    catch (Exception & e)    {      throw Exception (String ("%s for option \"%s\".", e.msg (), key));    }  }  // Apply all the options on the command-line to the map.  // Read any config files specified on the command-line as well.  uint  Configure::init (int argc, const char **argv)  {    // First scan command-line for the 'Config' flags.    for (int index = 1; index < argc; index++)    {      String arg ("%s", argv[index]);      String key, value;      if (arg == "--")      {        index++;        break;      }      if (parseArg (arg, key, value))      {        if (!validKey (key))        {          break;        }      }      else if (argv[index][0] == '-')      {        key.append ("%s", argv[index] + 1);        if (!validKey (key))        {          break;        }        if (index == argc - 1)        {          break;        }        index++;        value.append ("%s", argv[index]);      }      else      {        break;      }      if (key == configKey)      {        processConfigFile (value);      }    }    // Process options on the command-line.    int index;    for (index = 1; index < argc; index++)    {      String arg ("%s", argv[index]);      String key, value;      Option *option;      if (arg == "--")      {        index++;        break;      }      if (parseArg (arg, key, value))      {        assert (validKey (key));        if (key == configKey)        {          continue;        }        option = map.get (key);        if (option == NULL)        {          break;        }      }      else if (argv[index][0] == '-')      {        key.append ("%s", argv[index] + 1);        if (!validKey (key))        {          break;        }        assert (validKey (key));        if (index == argc - 1)        {          break;        }        if (key == configKey)        {          index++;          continue;        }        option = map.get (key);        if (option == NULL)        {          break;        }        index++;        value.append ("%s", argv[index]);      }      else      {        break;      }      try      {        option->_value = parseValue (option->_type, option->_enumValues,                                     value.text ());      }      catch (Exception & e)      {        throw          Exception (String ("%s for option \"%s\".", e.msg (), key.text ()));      }    }    // Return the index at which command-line processing failed.    // Return argc on no error.    return index;  }  // For qsort().  static int  cmpOption (const void *x, const void *y)  {    Option *a = *(Option **) x;    Option *b = *(Option **) y;    bool aRoot = (strstr (a->_key, "::") == NULL);    bool bRoot = (strstr (a->_key, "::") == NULL);    if (aRoot && !bRoot)    {      return 1;    }    if (!aRoot && bRoot)    {      return -1;    }    return strcmp (a->_key, b->_key);  }  // Append the given value to the string.  static void  valueString (String & val, Option * option, Value value)  {    switch (option->_type)    {    case BOOL:      val.append ("%s", value._bool ? "true" : "false");      break;    case INT:      if (option->_printHex)      {        val.append ("0x%llx", value._int);      }      else      {        val.append ("%lld", value._int);      }      break;    case FLOAT:      val.append ("%g", value._float);      break;    case STRING:      val.append ("%s", (value._string == NULL) ? "<null>" : value._string);      break;    case ENUM:      val.append ("%s", option->_enumValues[value._enum]);      break;    default:      assert (0);    }  }  // A little state machine to do word wrapping.#define CHAROUT(c) { \      assert ((c) != '\n'); \      fputc ((c), strm); \      col++; \  }#define NEWLINE { \      fputc ('\n', strm); \      col = 1; \      for (uint i = 0; i < indent - 1; i++) { \          CHAROUT(' '); \      } \  }  static void  wrapText (FILE * strm, uint col, uint indent, uint width, const char *text)  {    const char *start = text;    while (*start != '\0')    {      // Start a new line if we hit a newline character.      if (*start == '\n')      {        NEWLINE;        start++;        continue;      }      // For whitespace, echo spaces as long as they fit on the current line.      if (isspace (*start))      {        if (col < width)        {          CHAROUT (' ');        }        start++;        continue;      }      // Find the end of the next word.      const char *end = start;      while (*end != '\0' && !isspace (*end))      {        end++;      }      uint len = end - start;      // Output the word if it fits on this line.      if (col + len < width)      {        while (start != end)        {          CHAROUT (*start);          start++;        }        continue;      }      // The word goes off the end of the line.      // If we're in the middle of the line, then put this word on the next line.      if (col > indent)      {        NEWLINE;        continue;      }      // The word is wider than the output column.  We need to break the word      // in half.      while (col < width)      {        CHAROUT (*start);        start++;        assert (start <= end);      }    }    fputc ('\n', strm);  }  // Print a usage message to strm.  void  Configure::usage()  {    FILE* strm = stderr;    uint argWidth = 25;    String fmt ("  %%-%ds ", argWidth);    uint indent = 4 + argWidth;    uint width = 79;    fprintf (strm, "\n");    String key ("%s[=<null>]", configKey);    fprintf (strm, fmt.text (), key.text ());    wrapText (strm, indent, indent, width, "Configuration file.");    Option **options = map.getAll ();    qsort ((void *) options, map.count (), sizeof (*options), cmpOption);    for (uint i = 0; i < map.count (); i++)    {      assert (options[i] != NULL);      String val;      valueString (val, options[i], options[i]->_defaultValue);      String key ("%s[=%s]", options[i]->_key, val.text ());      String desc ("%s", options[i]->_description);      if (options[i]->_type == ENUM)      {        String values ("%s", "Possible values are {");        for (uint index = 0; options[i]->_enumValues[index] != NULL; index++)        {          if (index > 0)          {            values.append (',');          }          values.append ("%s", options[i]->_enumValues[index]);        }        values.append ("}.");        desc.append ("  %s", values.text ());      }      uint col = (key.length () > argWidth) ? width : indent;      fprintf (strm, fmt.text (), key.text ());      wrapText (strm, col, indent, width, desc.text ());    }    delete[]options;  }  // Print the map to strm.  void  Configure::show()  {    Message::debug("\n\nCONFIGURATION BEGIN",1);    Option **options = map.getAll ();    qsort ((void *) options, map.count (), sizeof (*options), cmpOption);    for (uint i = 0; i < map.count (); i++)    {      assert (options[i] != NULL);      String val;      valueString (val, options[i], options[i]->_value);      String key ("%s", options[i]->_key);      Message::debug(String("%s %s", options[i]->_key, val.text ()),1);    }    Message::debug("CONFIGURATION END\n\n",1);    delete[]options;  }

⌨️ 快捷键说明

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