diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/configfile.cc | 137 | ||||
| -rw-r--r-- | src/configfile.h | 2 | 
2 files changed, 127 insertions, 12 deletions
| diff --git a/src/configfile.cc b/src/configfile.cc index bb7155f..e659a51 100644 --- a/src/configfile.cc +++ b/src/configfile.cc @@ -46,12 +46,12 @@  #ifdef WIN32    #define SEP "\\" -  #define CONFIGDIRNAME ".drumgizmo"  #else    #define SEP "/" -  #define CONFIGDIRNAME ".drumgizmo"  #endif +#define CONFIGDIRNAME ".drumgizmo" +  /**   * Return the path containing the config files.   */ @@ -89,7 +89,7 @@ static bool createConfigPath()  #else      if(mkdir(configpath.c_str(), 0755) < 0) {   #endif -      DEBUG(pluginconfig, "Could not create config directory\n"); +      DEBUG(configfile, "Could not create config directory\n");      }      return false; @@ -110,7 +110,7 @@ ConfigFile::~ConfigFile()  void ConfigFile::load()  { -  DEBUG(pluginconfig, "Loading config file...\n"); +  DEBUG(configfile, "Loading config file...\n");    if(!open("r")) return;    values.clear(); @@ -125,14 +125,129 @@ void ConfigFile::load()        line = line.substr(0, line.size() - 1); // strip ending newline.      } -    std::size_t colon = line.find(':'); +    std::string key; +    std::string value; +    enum { +      before_key, +      in_key, +      after_key, +      before_value, +      in_value, +      in_value_single_quoted, +      in_value_double_quoted, +      after_value, +    } state = before_key; + +    for(std::size_t p = 0; p < line.size(); ++p) { +      switch(state) { +      case before_key: +        if(line[p] == '#') { +          // Comment: Ignore line. +          p = line.size(); +          continue; +        } +        if(std::isspace(line[p])) { +          continue; +        } +        key += line[p]; +        state = in_key; +        break; + +      case in_key: +        if(std::isspace(line[p])) { +          state = after_key; +          continue; +        } +        if(line[p] == ':' || line[p] == '=') { +          state = before_value; +          continue; +        } +        key += line[p]; +        break; + +      case after_key: +        if(std::isspace(line[p])) { +          continue; +        } +        if(line[p] == ':' || line[p] == '=') { +          state = before_value; +          continue; +        } +        // ERROR: Bad symbol, expecting only whitespace or key/value seperator +        break; + +      case before_value: +        if(std::isspace(line[p])) { +          continue; +        } +        if(line[p] == '\'') { +          state = in_value_single_quoted; +          continue; +        } +        if(line[p] == '"') { +          state = in_value_double_quoted; +          continue; +        } +        value += line[p]; +        state = in_value; +        break; + +      case in_value: +        if(std::isspace(line[p])) { +          state = after_value; +          continue; +        } +        if(line[p] == '#') { +          // Comment: Ignore the rest of the line. +          p = line.size(); +          state = after_value; +          continue; +        } +        value += line[p]; +        break; + +      case in_value_single_quoted: +        if(line[p] == '\'') { +          state = after_value; +          continue; +        } +        value += line[p]; +        break; + +      case in_value_double_quoted: +        if(line[p] == '"') { +          state = after_value; +          continue; +        } +        value += line[p]; +        break; + +      case after_value: +        if(std::isspace(line[p])) { +          continue; +        } +        if(line[p] == '#') { +          // Comment: Ignore the rest of the line. +          p = line.size(); +          continue; +        } +        // ERROR: Bad symbol, expecting only whitespace or key/value seperator +        break; +      } +    } -    if(colon == std::string::npos) break; // malformed line +    if(state == before_key) { +      // Line did not contain any data (empty or comment) +      continue; +    } -    std::string key = line.substr(0, colon); -    std::string value = line.substr(colon + 1); +    // If state == in_value_XXX_quoted here, the string was not terminated. +    if(state != after_value && state != in_value) { +      // ERROR: Malformed line. +      break; +    } -    printf("key['%s'] value['%s']\n", key.c_str(), value.c_str()); +    DEBUG(configfile, "key['%s'] value['%s']\n", key.c_str(), value.c_str());      if(key != "") {        values[key] = value; @@ -144,7 +259,7 @@ void ConfigFile::load()  void ConfigFile::save()  { -  DEBUG(pluginconfig, "Saving configuration...\n"); +  DEBUG(configfile, "Saving configuration...\n");    createConfigPath(); @@ -182,7 +297,7 @@ bool ConfigFile::open(std::string mode)    configfile += SEP;    configfile += filename; -  DEBUG(pluginconfig, "Opening config file '%s'\n", configfile.c_str()); +  DEBUG(configfile, "Opening config file '%s'\n", configfile.c_str());    fp = fopen(configfile.c_str(), mode.c_str());    if(!fp) return false; diff --git a/src/configfile.h b/src/configfile.h index 21a6b88..a3fd588 100644 --- a/src/configfile.h +++ b/src/configfile.h @@ -46,7 +46,7 @@ protected:    std::map<std::string, std::string> values;    std::string filename; -  bool open(std::string mode); +  virtual bool open(std::string mode);    void close();    std::string readLine(); | 
