commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 01/03: Rewrote the prefs parser to be based


From: git
Subject: [Commit-gnuradio] [gnuradio] 01/03: Rewrote the prefs parser to be based on boost::program_options
Date: Mon, 16 May 2016 15:13:07 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

jcorgan pushed a commit to branch master
in repository gnuradio.

commit b37d9fd7dba8ba2dacb8f72f092832041d2428ec
Author: Marcus Müller <address@hidden>
Date:   Thu May 12 17:32:28 2016 +0200

    Rewrote the prefs parser to be based on boost::program_options
---
 gnuradio-runtime/include/gnuradio/prefs.h |   3 +-
 gnuradio-runtime/lib/prefs.cc             | 137 ++++++++----------------------
 2 files changed, 37 insertions(+), 103 deletions(-)

diff --git a/gnuradio-runtime/include/gnuradio/prefs.h 
b/gnuradio-runtime/include/gnuradio/prefs.h
index 4dc92b3..287f86c 100644
--- a/gnuradio-runtime/include/gnuradio/prefs.h
+++ b/gnuradio-runtime/include/gnuradio/prefs.h
@@ -165,8 +165,7 @@ namespace gr {
 
   protected:
     virtual std::vector<std::string> _sys_prefs_filenames();
-    virtual std::string _read_files(const std::vector<std::string> &filenames);
-    virtual void _convert_to_map(const std::string &conf);
+    virtual void _read_files(const std::vector<std::string> &filenames);
     virtual char * option_to_env(std::string section, std::string option);
 
   private:
diff --git a/gnuradio-runtime/lib/prefs.cc b/gnuradio-runtime/lib/prefs.cc
index 7fd38ef..341028e 100644
--- a/gnuradio-runtime/lib/prefs.cc
+++ b/gnuradio-runtime/lib/prefs.cc
@@ -27,12 +27,18 @@
 #include <gnuradio/prefs.h>
 #include <gnuradio/sys_paths.h>
 #include <gnuradio/constants.h>
+
 #include <algorithm>
+#include <fstream>
 
 #include <boost/filesystem/operations.hpp>
 #include <boost/filesystem/path.hpp>
 #include <boost/filesystem/fstream.hpp>
+#include <boost/program_options.hpp>
+#include <boost/foreach.hpp>
 namespace fs = boost::filesystem;
+namespace po = boost::program_options;
+typedef std::ifstream::char_type char_t;
 
 namespace gr {
 
@@ -46,10 +52,7 @@ namespace gr {
 
   prefs::prefs()
   {
-    std::string config = _read_files(_sys_prefs_filenames());
-
-    // Convert the string into a map
-    _convert_to_map(config);
+    _read_files(_sys_prefs_filenames());
   }
 
   prefs::~prefs()
@@ -85,106 +88,39 @@ namespace gr {
     return fnames;
   }
 
-  std::string
+  void
   prefs::_read_files(const std::vector<std::string> &filenames)
   {
-    std::string config;
-
-    std::vector<std::string>::const_iterator sitr;
-    char tmp[1024];
-    for(sitr = filenames.begin(); sitr != filenames.end(); sitr++) {
-      fs::ifstream fin(*sitr);
-      while(!fin.eof()) {
-        fin.getline(tmp, 1024);
-        std::string t(tmp);
-        // ignore empty lines or lines of just comments
-        if((t.size() > 0) && (t[0] != '#')) {
-          // remove any comments in the line
-          size_t hash = t.find("#");
-
-          // Remove any white space unless it's between quotes
-          // Search if the string has any quotes in it
-          size_t quote1 = t.find("\"");
-          if(quote1 != std::string::npos) {
-            // If yes, find where the start and end quotes are.
-            // Note that this isn't robust if there are multiple
-            // quoted strings in the line; this will just take the
-            // first and last, and if there is only a single quote,
-            // this will treat the entire line after the quote as the
-            // quoted text.
-            // the inq variable is strips the quotes as well.
-            size_t quote2 = t.find_last_of("\"");
-            std::string sol = t.substr(0, quote1);
-            std::string inq = t.substr(quote1+1, quote2-quote1-1);
-            std::string eol = t.substr(quote2+1, t.size()-quote2-1);
-
-            // Remove all white space of the text before the first quote
-            sol.erase(std::remove_if(sol.begin(), sol.end(),
-                                     ::isspace), sol.end());
-
-            // Remove all white space of the text after the end quote
-            eol.erase(std::remove_if(eol.begin(), eol.end(),
-                                     ::isspace), eol.end());
-
-            // Pack the stripped start and end of lines with the part
-            // of the string in quotes (but without the quotes).
-            t = sol + inq + eol;
+    BOOST_FOREACH( std::string fname, filenames) {
+      std::ifstream infile(fname.c_str());
+      if(infile.good()) {
+        try {
+          po::basic_parsed_options<char_t> parsed = 
po::parse_config_file(infile, po::options_description(), true);
+          BOOST_FOREACH(po::basic_option<char_t> o, (parsed.options) ){
+            std::string okey = o.string_key;
+            size_t pos = okey.find(".");
+            std::string section, key;
+            if(pos != std::string::npos) {
+              section = okey.substr(0,pos);
+              key = okey.substr(pos+1);
+            } else {
+              section = "default";
+              key = okey;
+            }
+            std::transform(section.begin(), section.end(), section.begin(), 
::tolower);
+            std::transform(key.begin(), key.end(), key.begin(), ::tolower);
+            // value of a basic_option is always a std::vector<string>; we 
only allow single values, so:
+            std::string value = o.value[0];
+            d_config_map[section][key] = value;
           }
-          else {
-            // No quotes, just strip all white space
-            t.erase(std::remove_if(t.begin(), t.end(),
-                                   ::isspace), t.end());
-          }
-
-          // Use hash marks at the end of each segment as a delimiter
-          config += t.substr(0, hash) + '#';
+        } catch(const boost::program_options::invalid_config_file_syntax & e) {
+          std::cerr << "WARNING: Config file '" << fname << "' failed to 
parse:" << std::endl;
+          std::cerr << e.what() << std::endl;
+          std::cerr << "Skipping it" << std::endl;
         }
+      } else { // infile.good();
+        std::cerr << "WARNING: Config file '" << fname << "' could not be 
opened for reading." << std::endl;
       }
-      fin.close();
-    }
-
-    return config;
-  }
-
-  void
-  prefs::_convert_to_map(const std::string &conf)
-  {
-    // Convert the string into an map of maps
-    // Map is structured as {section name: map of options}
-    // And options map is simply: {option name: option value}
-    std::string sub = conf;
-    size_t sec_start = sub.find("[");
-    while(sec_start != std::string::npos) {
-      sub = sub.substr(sec_start);
-
-      size_t sec_end = sub.find("]");
-      if(sec_end == std::string::npos)
-        throw std::runtime_error("Config file error: Mismatched section 
label.\n");
-
-      std::string sec = sub.substr(1, sec_end-1);
-      size_t next_sec_start = sub.find("[", sec_end);
-      std::string subsec = sub.substr(sec_end+1, next_sec_start-sec_end-2);
-
-      std::transform(sec.begin(), sec.end(), sec.begin(), ::tolower);
-
-      std::map<std::string, std::string> options_map = d_config_map[sec];
-      size_t next_opt = 0;
-      size_t next_val = 0;
-      next_opt = subsec.find("#");
-      while(next_opt < subsec.size()-1) {
-        next_val = subsec.find("=", next_opt);
-        std::string option = subsec.substr(next_opt+1, next_val-next_opt-1);
-
-        next_opt = subsec.find("#", next_val);
-        std::string value = subsec.substr(next_val+1, next_opt-next_val-1);
-
-        std::transform(option.begin(), option.end(), option.begin(), 
::tolower);
-        options_map[option] = value;
-      }
-
-      d_config_map[sec] = options_map;
-
-      sec_start = sub.find("[", sec_end);
     }
   }
 
@@ -194,8 +130,7 @@ namespace gr {
     std::vector<std::string> filenames;
     filenames.push_back(configfile);
 
-    std::string config = _read_files(filenames);
-    _convert_to_map(config);
+    _read_files(filenames);
   }
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]