diff options
| author | Martin Braun <martin.braun@ettus.com> | 2017-11-10 21:43:09 -0800 | 
|---|---|---|
| committer | Martin Braun <martin.braun@ettus.com> | 2018-02-01 06:35:37 +0100 | 
| commit | 4ebfea45f32cc845d7887e552e8c6084d8ef3067 (patch) | |
| tree | 03072dbab4870b9d648d154331d0ee7911da1b24 /host/lib | |
| parent | 21be43d40a0fe33af9597e77fb3465caa7079033 (diff) | |
| download | uhd-4ebfea45f32cc845d7887e552e8c6084d8ef3067.tar.gz uhd-4ebfea45f32cc845d7887e552e8c6084d8ef3067.tar.bz2 uhd-4ebfea45f32cc845d7887e552e8c6084d8ef3067.zip | |
lib: Add config_parser class
This class is not publicly exported. It is meant to read config files in
the INI format.
Reviewed-by: Brent Stapleton <brent.stapleton@ettus.com>
Diffstat (limited to 'host/lib')
| -rw-r--r-- | host/lib/include/uhdlib/utils/config_parser.hpp | 121 | ||||
| -rw-r--r-- | host/lib/utils/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/lib/utils/config_parser.cpp | 59 | 
3 files changed, 181 insertions, 0 deletions
| diff --git a/host/lib/include/uhdlib/utils/config_parser.hpp b/host/lib/include/uhdlib/utils/config_parser.hpp new file mode 100644 index 000000000..5d01aa8c4 --- /dev/null +++ b/host/lib/include/uhdlib/utils/config_parser.hpp @@ -0,0 +1,121 @@ +// +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0+ +// + +#ifndef INCLUDED_LIBUHD_CONFIG_PARSER_HPP +#define INCLUDED_LIBUHD_CONFIG_PARSER_HPP + +#include <uhd/exception.hpp> +#include <boost/property_tree/ptree.hpp> +#include <vector> + +namespace uhd { + +/*! Represent a config file (INI format) + * + * These files have the following format: + * ``` + * ; Comment + * [section] + * key=value + * ``` + * + * The API of this class was designed to match the ConfigParser class from + * Python https://docs.python.org/3/library/configparser.html, which we use in + * MPM. This does mean the API is somewhat different from typical C++ APIs, + * and does not name getters get_*. + */ +class config_parser +{ +public: +    /*! +     * \param path Path to the INI file +     * +     * \throws uhd::runtime_error if the parsing failed. +     */ +    config_parser(const std::string &path=""); + +    /*! Load another config file and update the current values. +     * +     * If a value exists in both the new and current file, the new value wins. +     */ +    void read_file(const std::string &path); + +    //! Return a list of sections +    std::vector<std::string> sections(); + +    //! Return a list of options (keys) in a section, or an empty list if +    //  section does not exist +    std::vector<std::string> options(const std::string §ion); + +    /*! Return the value of a key +     * +     * \param section The name of the section in which this key is +     * \param key Name of the key +     * \param def Default value, in case the key does not exist +     */ +    template <typename T> +    T get( +            const std::string §ion, +            const std::string &key, +            const T &def +    ) { +        try { +            const auto child = _pt.get_child(section); +            return child.get<T>(key, def); +        } catch (const boost::property_tree::ptree_bad_path &) { +            return def; +        } +    } + +    /*! Return the value of a key +     * +     * \param section The name of the section in which this key is +     * \param key Name of the key +     * +     * \throws uhd::key_error if the key or the section don't exist +     */ +    template <typename T> +    T get( +            const std::string §ion, +            const std::string &key +    ) { +        try { +            const auto child = _pt.get_child(section); +            return child.get<T>(key); +        } catch (const boost::property_tree::ptree_bad_path &) { +            throw uhd::key_error( +                std::string("[config_parser] Key ") + key + +                " not found in section " + section +            ); +        } +    } + +    template <typename T> +    void set( +            const std::string §ion, +            const std::string &key, +            const T &value +    ) { +        _pt.put<T>(section + "." + key, value); +    } + +private: +    template <typename T> +    static std::vector<std::string> _options(T key_bearing_iterable) +    { +        std::vector<std::string> sections; +        for (const auto& node : key_bearing_iterable) { +            sections.push_back(node.first); +        } +        return sections; +    } + +    boost::property_tree::ptree _pt; +}; + +} /* namespace uhd */ + +#endif /* INCLUDED_LIBUHD_CONFIG_PARSER_HPP */ diff --git a/host/lib/utils/CMakeLists.txt b/host/lib/utils/CMakeLists.txt index 91a579853..afaf99274 100644 --- a/host/lib/utils/CMakeLists.txt +++ b/host/lib/utils/CMakeLists.txt @@ -159,6 +159,7 @@ SET_SOURCE_FILES_PROPERTIES(  ########################################################################  LIBUHD_APPEND_SOURCES(      ${CMAKE_CURRENT_SOURCE_DIR}/csv.cpp +    ${CMAKE_CURRENT_SOURCE_DIR}/config_parser.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/eeprom_utils.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/gain_group.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/ihex.cpp diff --git a/host/lib/utils/config_parser.cpp b/host/lib/utils/config_parser.cpp new file mode 100644 index 000000000..a88a99a01 --- /dev/null +++ b/host/lib/utils/config_parser.cpp @@ -0,0 +1,59 @@ +// +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0+ +// + +#include <uhdlib/utils/config_parser.hpp> +#include <boost/format.hpp> +#include <boost/filesystem.hpp> +#include <boost/property_tree/ini_parser.hpp> + +using namespace uhd; + +config_parser::config_parser(const std::string &path) +{ +    if (not path.empty() and boost::filesystem::exists(path)) { +        try { +            boost::property_tree::ini_parser::read_ini(path, _pt); +        } catch (const boost::property_tree::ini_parser_error &) { +            throw uhd::runtime_error(str( +                boost::format("Unable to parse file %s") +                % path +            )); +        } +    } +} + +void config_parser::read_file(const std::string &path) +{ +    config_parser new_config(path); +    for (const auto& section : new_config.sections()) { +        for (const auto& key : new_config.options(section)) { +            set<std::string>( +                    section, +                    key, +                    new_config.get<std::string>(section, key) +            ); +        } +    } +} + +std::vector<std::string> config_parser::sections() +{ +    try { +        return _options(_pt); +    } catch (const boost::property_tree::ptree_bad_path &) { +        return std::vector<std::string>{}; +    } +} + +std::vector<std::string> config_parser::options(const std::string §ion) +{ +    try { +        return _options(_pt.get_child(section)); +    } catch (const boost::property_tree::ptree_bad_path &) { +        return std::vector<std::string>{}; +    } +} + | 
