[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);
}