Ticket #5588: path_resolver.patch

File path_resolver.patch, 9.5 KB (added by Filippov Aleksey <sarum9in@…>, 11 years ago)

path_resolver patch

  • new file property_tree/detail/info_parser_default_path_resolver.hpp

    diff --git a/property_tree/detail/info_parser_default_path_resolver.hpp b/property_tree/detail/info_parser_default_path_resolver.hpp
    new file mode 100644
    index 0000000..9d3cde4
    - +  
     1#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_DEFAULT_PATH_RESOLVER_HPP_INCLUDED
     2#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_DEFAULT_PATH_RESOLVER_HPP_INCLUDED
     3
     4namespace boost { namespace property_tree { namespace info_parser
     5{
     6    /*!
     7     * \brief Path resolver class implementation
     8     *
     9     * This implementation will not resolve
     10     * paths: it will simply return
     11     * path argument. It was created
     12     * for compatibility purposes.
     13     */
     14    class default_path_resolver
     15    {
     16    public:
     17        inline const std::string &resolve(const std::string &path)
     18        {
     19            return path;
     20        }
     21        inline void enter(const std::string &) {}
     22        inline void enter() {}
     23        inline void exit() {}
     24    };
     25} } }
     26
     27#endif
  • property_tree/detail/info_parser_read.hpp

    diff --git a/property_tree/detail/info_parser_read.hpp b/property_tree/detail/info_parser_read.hpp
    index b87c2cb..e07daba 100644
    a b namespace boost { namespace property_tree { namespace info_parser  
    175175    }
    176176
    177177    // Build ptree from info stream
    178     template<class Ptree, class Ch>
     178    template<class Ptree, class Ch, class PathResolver>
    179179    void read_info_internal(std::basic_istream<Ch> &stream,
    180180                            Ptree &pt,
    181181                            const std::string &filename,
     182                            PathResolver &path_resolver,
    182183                            int include_depth)
    183184    {
    184185        typedef std::basic_string<Ch> str_t;
    namespace boost { namespace property_tree { namespace info_parser  
    227228                        str_t s = read_string(text, NULL);
    228229                        std::string inc_name =
    229230                            convert_chtype<char, Ch>(s.c_str());
    230                         std::basic_ifstream<Ch> inc_stream(inc_name.c_str());
     231                        std::basic_ifstream<Ch> inc_stream(
     232                            path_resolver.resolve(inc_name.c_str()));
    231233                        if (!inc_stream.good())
    232234                            BOOST_PROPERTY_TREE_THROW(info_parser_error(
    233235                                "cannot open include file " + inc_name,
    234236                                filename, line_no));
     237                        path_resolver.enter(inc_name);
    235238                        read_info_internal(inc_stream, *stack.top(),
    236                                            inc_name, include_depth + 1);
     239                                           inc_name, path_resolver,
     240                                           include_depth + 1);
     241                        path_resolver.exit();
    237242                    } else {   // Unknown directive
    238243                        BOOST_PROPERTY_TREE_THROW(info_parser_error(
    239244                            "unknown directive", filename, line_no));
  • new file property_tree/detail/info_parser_relative_path_resolver.hpp

    diff --git a/property_tree/detail/info_parser_relative_path_resolver.hpp b/property_tree/detail/info_parser_relative_path_resolver.hpp
    new file mode 100644
    index 0000000..d4f3f7f
    - +  
     1#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_RELATIVE_PATH_RESOLVER_HPP_INCLUDED
     2#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_RELATIVE_PATH_RESOLVER_HPP_INCLUDED
     3
     4#include <boost/config.hpp>
     5
     6#include <stack>
     7
     8#include <boost/filesystem/path.hpp>
     9#include <boost/filesystem/operations.hpp>
     10
     11namespace boost { namespace property_tree { namespace info_parser
     12{
     13    /*!
     14     * \brief Path resolver class implementation
     15     * that resolves paths relatively
     16     *
     17     * This implementation will resolve paths
     18     * relative to base path (directory path of the file contains '#include' directive)
     19     *
     20     * \note The drawback of this implementation
     21     * is dependency on boost::filesystem library
     22     *
     23     */
     24    class relative_path_resolver
     25    {
     26        std::stack<boost::filesystem::path> stack;
     27        inline boost::filesystem::path resolve_(const boost::filesystem::path &path)
     28        {
     29            if (path.is_absolute())
     30                return path;
     31            else
     32            {
     33                if (stack.empty())
     34                    return boost::filesystem::absolute(boost::filesystem::current_path()/path);
     35                else
     36                    return boost::filesystem::absolute(stack.top()/path);
     37            }
     38        }
     39    public:
     40        inline std::string resolve(const boost::filesystem::path &path)
     41        {
     42            return resolve(path).string();
     43        }
     44        inline void enter(const boost::filesystem::path &path)
     45        {
     46            stack.push(resolve_(path).parent_path());
     47        }
     48        inline void enter()
     49        {
     50            if (stack.empty())
     51                stack.push(boost::filesystem::current_path());
     52            else
     53                // this case is unreachable
     54                // probably should not be used
     55                // TODO: should we use BOOST_ASSERT here?
     56                stack.push(stack.top());
     57        }
     58        inline void exit()
     59        {
     60            stack.pop();
     61        }
     62    };
     63} } }
     64
     65#endif
  • property_tree/info_parser.hpp

    diff --git a/property_tree/info_parser.hpp b/property_tree/info_parser.hpp
    index 683ddad..764ef8a 100644
    a b  
    1515#include <boost/property_tree/detail/info_parser_writer_settings.hpp>
    1616#include <boost/property_tree/detail/info_parser_read.hpp>
    1717#include <boost/property_tree/detail/info_parser_write.hpp>
     18#include <boost/property_tree/detail/info_parser_default_path_resolver.hpp>
    1819#include <istream>
    1920
    2021namespace boost { namespace property_tree { namespace info_parser
    namespace boost { namespace property_tree { namespace info_parser  
    2930    template<class Ptree, class Ch>
    3031    void read_info(std::basic_istream<Ch> &stream, Ptree &pt)
    3132    {
     33        default_path_resolver path_resolver;
     34        read_info(stream, pt, path_resolver);
     35    }
     36
     37    template<class Ptree, class Ch, class PathResolver>
     38    void read_info(std::basic_istream<Ch> &stream, Ptree &pt,
     39                   PathResolver &path_resolver)
     40    {
    3241        Ptree local;
    33         read_info_internal(stream, local, std::string(), 0);
     42        path_resolver.enter();
     43        read_info_internal(stream, local, std::string(), path_resolver, 0);
     44        path_resolver.exit();
    3445        pt.swap(local);
    3546    }
    3647
    namespace boost { namespace property_tree { namespace info_parser  
    4354    void read_info(std::basic_istream<Ch> &stream, Ptree &pt,
    4455                   const Ptree &default_ptree)
    4556    {
     57        default_path_resolver path_resolver;
     58        read_info(stream, pt, default_ptree, path_resolver);
     59    }
     60
     61    template<class Ptree, class Ch, class PathResolver>
     62    void read_info(std::basic_istream<Ch> &stream, Ptree &pt,
     63                   const Ptree &default_ptree, PathResolver &path_resolver)
     64    {
    4665        try {
    47             read_info(stream, pt);
     66            path_resolver.enter();
     67            read_info(stream, pt, path_resolver);
     68            path_resolver.exit();
    4869        } catch(file_parser_error &) {
    4970            pt = default_ptree;
    5071        }
    namespace boost { namespace property_tree { namespace info_parser  
    6283    void read_info(const std::string &filename, Ptree &pt,
    6384                   const std::locale &loc = std::locale())
    6485    {
     86        default_path_resolver path_resolver;
     87        read_info(filename, pt, path_resolver, loc);
     88    }
     89
     90    template<class Ptree, class PathResolver>
     91    void read_info(const std::string &filename, Ptree &pt,
     92                   PathResolver &path_resolver,
     93                   const std::locale &loc = std::locale())
     94    {
    6595        std::basic_ifstream<typename Ptree::key_type::value_type>
    6696            stream(filename.c_str());
    6797        if (!stream) {
    namespace boost { namespace property_tree { namespace info_parser  
    70100        }
    71101        stream.imbue(loc);
    72102        Ptree local;
    73         read_info_internal(stream, local, filename, 0);
     103        path_resolver.enter(filename);
     104        read_info_internal(stream, local, filename, path_resolver, 0);
     105        path_resolver.exit();
    74106        pt.swap(local);
    75107    }
    76108
    namespace boost { namespace property_tree { namespace info_parser  
    81113     * @note Replaces the existing contents. Strong exception guarantee.
    82114     * @param default_ptree If parsing fails, pt is set to a copy of this tree.
    83115     */
    84     template<class Ptree>
     116    template<class Ptree, class PathResolver>
     117    void read_info(const std::string &filename,
     118                   Ptree &pt,
     119                   const Ptree &default_ptree,
     120                   const std::locale &loc = std::locale())
     121    {
     122        default_path_resolver path_resolver;
     123        read_info(filename, pt, default_ptree, loc, path_resolver);
     124    }
     125
     126    template<class Ptree, class PathResolver>
    85127    void read_info(const std::string &filename,
    86128                   Ptree &pt,
    87129                   const Ptree &default_ptree,
     130                   PathResolver &path_resolver,
    88131                   const std::locale &loc = std::locale())
    89132    {
    90133        try {
    91             read_info(filename, pt, loc);
     134            read_info(filename, pt, path_resolver, loc);
    92135        } catch(file_parser_error &) {
    93136            pt = default_ptree;
    94137        }