Boost C++ Libraries: Ticket #5588: property_tree INFO include directive https://svn.boost.org/trac10/ticket/5588 <p> When you use #include in C/C++ programs, preprocessor uses path relative to file, where you used '#include'. But in read_info realization '#include' finds file using path, relative to current work directory. So, when you create some complex config structure, you have to you absolute pathes or change current work directory to config file. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/5588 Trac 1.4.3 Sebastian Redl Mon, 21 Nov 2011 13:00:56 GMT <link>https://svn.boost.org/trac10/ticket/5588#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5588#comment:1</guid> <description> <p> Good point, but I can't fix this without introducing a dependency on Filesystem, which requires building. Not sure if I want to do that. </p> </description> <category>Ticket</category> </item> <item> <author>sarum9in@…</author> <pubDate>Mon, 21 Nov 2011 19:55:00 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5588#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5588#comment:2</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5588#comment:1" title="Comment 1">cornedbee</a>: </p> <blockquote class="citation"> <p> Good point, but I can't fix this without introducing a dependency on Filesystem, which requires building. Not sure if I want to do that. </p> </blockquote> <p> Nevertheless it is possible to reimplement read_info function in the following way: we can introduce template argument (some functor), that will perform path resolving. Also we can provide default path-resolver that will behave as current implementation. Path-resolver that depends on boost::filesystem can be placed into separate header. Only and only if user wants to use this path-resolver the boost::filesystem dependency will be introduced. </p> <p> If this idea seems good for you, I can try to create a patch. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Sebastian Redl</dc:creator> <pubDate>Tue, 22 Nov 2011 10:05:47 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5588#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5588#comment:3</guid> <description> <p> Sounds good to me. </p> </description> <category>Ticket</category> </item> <item> <author>Filippov Aleksey <sarum9in@…></author> <pubDate>Thu, 01 Dec 2011 23:01:08 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/5588 https://svn.boost.org/trac10/ticket/5588 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">path_resolver.patch</span> </li> </ul> <p> path_resolver patch </p> Ticket Filippov Aleksey <sarum9in@…> Thu, 01 Dec 2011 23:02:43 GMT <link>https://svn.boost.org/trac10/ticket/5588#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5588#comment:4</guid> <description> <p> While I was changing current implementation I went to the following architecture: </p> <p> We can implement event-like class that will receive the following events: enter(std::string) and exit(), also this class will provide a query method: resolve(std::string) -&gt; std::string. </p> <p> We can use this in the following way: let's introduce new template argument to every read_info function named <a class="missing wiki">PathResolver</a>. Such functions will accept <a class="missing wiki">PathResolver</a> instances as their last argument: </p> <pre class="wiki">template&lt;class Ptree, class Ch, class PathResolver&gt; void read_info(std::basic_istream&lt;Ch&gt; &amp;stream, Ptree &amp;pt, PathResolver &amp;path_resolver) { //... } </pre><p> We should also provide overloads with old interface for every such read_info function: </p> <pre class="wiki">template&lt;class Ptree, class Ch&gt; void read_info(std::basic_istream&lt;Ch&gt; &amp;stream, Ptree &amp;pt) { default_path_resolver pr; read_info(stream, pt, pr); } </pre><p> Let's reimplement read_info_internal in the following way: </p> <pre class="wiki">template&lt;class Ptree, class Ch, class PathResolver&gt; void read_info_internal(std::basic_istream&lt;Ch&gt; &amp;stream, Ptree &amp;pt, const std::string &amp;filename, PathResolver &amp;path_resolver, int include_depth) { //... std::basic_ifstream&lt;Ch&gt; inc_stream( path_resolver.resolve(inc_name.c_str())); //... path_resolver.enter(inc_name); read_info_internal(/*...*/); path_resolver.exit(); //... } </pre><p> There is a case when we do not know the real file name, for example if user passes std::istream-like object. In that case <a class="missing wiki">PathResolver</a> has to implement enter() method (without arguments). </p> <p> As you has noticed, I used non-const references in code. In my opinion it should be done in that way because <a class="missing wiki">PathResolver</a> can have inner state. It is much simplier and efficientlier to pass object by reference rather than implementing inner share-state for (<a class="missing wiki">PathResolver</a> path_resolver) signature or (const <a class="missing wiki">PathResolver</a> &amp;path_resolver) one. Please note, that my changes will not break any legacy code. I have provided old-style overloads with default_path_resolver. </p> <p> I do not think this changes are completed. I tried to show you only idea. My code is still unchecked and probably have bugs. </p> <p> One question I have: how user should access standard path resolvers? Should we export them like read_info functions to boost::property_tree namespace? Or should we do something else? </p> <p> P.S. In my opinion publishing code that is being at developing stage only to bugtracker is not a good idea. I have created public git repository to share my code, if you can't watch it through git, I have created a patch. </p> <p> git repository is located at <a class="ext-link" href="http://cs.istu.ru/gitweb/?p=boost.git;a=summary"><span class="icon">​</span>http://cs.istu.ru/gitweb/?p=boost.git;a=summary</a>. </p> </description> <category>Ticket</category> </item> </channel> </rss>