Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77973 - in trunk/tools/quickbook: src test/python
From: dnljms_at_[hidden]
Date: 2012-04-14 13:33:16


Author: danieljames
Date: 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
New Revision: 77973
URL: http://svn.boost.org/trac/boost/changeset/77973

Log:
Quickbook: Deal with checked paths that aren't present. Refs #6691.

I think that the dependencies should just be files that were loaded, so
I changed it to do that, but added an extra (hidden for now) option to
list all paths that were checked, staring with a `+` for files that are
present, and `-` for files that are absent.

Also fixed a bug with the path resolver.
Added:
   trunk/tools/quickbook/test/python/include_path_deps.txt (contents, props changed)
      - copied, changed from r77972, /trunk/tools/quickbook/test/python/include_path.txt
   trunk/tools/quickbook/test/python/include_path_locs.txt (contents, props changed)
   trunk/tools/quickbook/test/python/missing_relative_deps.txt (contents, props changed)
   trunk/tools/quickbook/test/python/missing_relative_locs.txt (contents, props changed)
   trunk/tools/quickbook/test/python/svg_missing_deps.txt (contents, props changed)
   trunk/tools/quickbook/test/python/svg_missing_locs.txt (contents, props changed)
Removed:
   trunk/tools/quickbook/test/python/include_path.txt
   trunk/tools/quickbook/test/python/missing_relative.txt
   trunk/tools/quickbook/test/python/svg_missing.txt
Text files modified:
   trunk/tools/quickbook/src/actions.cpp | 22 ++++-----
   trunk/tools/quickbook/src/quickbook.cpp | 57 +++++++++++++++++++-----
   trunk/tools/quickbook/src/state.cpp | 24 +++++++++-
   trunk/tools/quickbook/src/state.hpp | 9 ++-
   trunk/tools/quickbook/test/python/include_path_deps.txt | 3 -
   trunk/tools/quickbook/test/python/missing_relative.qbk | 1
   trunk/tools/quickbook/test/python/output-deps.py | 92 +++++++++++++++++++++++++++++++--------
   7 files changed, 154 insertions(+), 54 deletions(-)

Modified: trunk/tools/quickbook/src/actions.cpp
==============================================================================
--- trunk/tools/quickbook/src/actions.cpp (original)
+++ trunk/tools/quickbook/src/actions.cpp 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
@@ -936,12 +936,14 @@
            //
            // Now load the SVG file:
            //
- state.add_dependency(img);
            std::string svg_text;
- fs::ifstream fs(img);
- char c;
- while(fs.get(c) && fs.good())
- svg_text.push_back(c);
+ if (state.add_dependency(img)) {
+ fs::ifstream fs(img);
+ std::stringstream buffer;
+ buffer << fs.rdbuf();
+ svg_text = buffer.str();
+ }
+
            //
            // Extract the svg header from the file:
            //
@@ -1871,10 +1873,9 @@
             {
                 fs::path local_path =
                     state.current_file->path.parent_path() / path;
- state.add_dependency(local_path);
 
                 // See if it can be found locally first.
- if (fs::exists(local_path))
+ if (state.add_dependency(local_path))
                 {
                     result.insert(include_search_return(
                         local_path,
@@ -1885,9 +1886,8 @@
                 BOOST_FOREACH(fs::path full, include_path)
                 {
                     full /= path;
- state.add_dependency(full);
 
- if (fs::exists(full))
+ if (state.add_dependency(full))
                     {
                         result.insert(include_search_return(full, path));
                         return result;
@@ -1896,9 +1896,7 @@
             }
             else
             {
- state.add_dependency(path);
-
- if (fs::exists(path)) {
+ if (state.add_dependency(path)) {
                     result.insert(include_search_return(path, path));
                     return result;
                 }

Modified: trunk/tools/quickbook/src/quickbook.cpp
==============================================================================
--- trunk/tools/quickbook/src/quickbook.cpp (original)
+++ trunk/tools/quickbook/src/quickbook.cpp 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
@@ -115,6 +115,7 @@
         fs::path const& filein_
       , fs::path const& fileout_
       , fs::path const& deps_out_
+ , fs::path const& locations_out_
       , fs::path const& xinclude_base_
       , int indent
       , int linewidth
@@ -145,11 +146,26 @@
 
             if (!deps_out_.empty())
             {
- fs::ofstream deps_out(deps_out_);
- BOOST_FOREACH(fs::path const& f, state.dependencies)
- deps_out << detail::path_to_generic(f) << std::endl;
+ fs::ofstream out(deps_out_);
+ BOOST_FOREACH(quickbook::state::dependency_list::value_type
+ const& d, state.dependencies)
+ {
+ if (d.second) {
+ out << detail::path_to_generic(d.first) << std::endl;
+ }
+ }
             }
 
+ if (!locations_out_.empty())
+ {
+ fs::ofstream out(locations_out_);
+ BOOST_FOREACH(quickbook::state::dependency_list::value_type
+ const& d, state.dependencies)
+ {
+ out << (d.second ? "+ " : "- ")
+ << detail::path_to_generic(d.first) << std::endl;
+ }
+ }
         }
         catch (load_error& e) {
             detail::outerr(filein_) << e.what() << std::endl;
@@ -271,6 +287,10 @@
             ("xinclude-base", PO_VALUE<input_string>(),
                 "Generate xincludes as if generating for this target "
                 "directory.")
+ ("output-checked-locations", PO_VALUE<input_string>(),
+ "Writes a file listing all the file locations that were "
+ "checked, starting with '+' if they were found, or '-' "
+ "if they weren't.")
         ;
 
         all.add(desc).add(hidden);
@@ -400,25 +420,36 @@
             fs::path filein = quickbook::detail::input_to_path(
                 vm["input-file"].as<input_string>());
             fs::path fileout;
- fs::path depsout;
+ fs::path deps_out;
+ fs::path locations_out;
+
+ bool default_output = true;
+
+ if (vm.count("output-deps"))
+ {
+ deps_out = quickbook::detail::input_to_path(
+ vm["output-deps"].as<input_string>());
+ default_output = false;
+ }
+
+ if (vm.count("output-checked-locations"))
+ {
+ locations_out = quickbook::detail::input_to_path(
+ vm["output-checked-locations"].as<input_string>());
+ default_output = false;
+ }
 
             if (vm.count("output-file"))
             {
                 fileout = quickbook::detail::input_to_path(
                     vm["output-file"].as<input_string>());
             }
- else if (!vm.count("output-deps"))
+ else if (default_output)
             {
                 fileout = filein;
                 fileout.replace_extension(".xml");
             }
 
- if (vm.count("output-deps"))
- {
- depsout = quickbook::detail::input_to_path(
- vm["output-deps"].as<input_string>());
- }
-
             fs::path xinclude_base;
             if (vm.count("xinclude-base"))
             {
@@ -459,8 +490,8 @@
 
             if (!error_count)
                 error_count += quickbook::parse_document(
- filein, fileout, depsout, xinclude_base,
- indent, linewidth, pretty_print);
+ filein, fileout, deps_out, locations_out,
+ xinclude_base, indent, linewidth, pretty_print);
 
             if (expect_errors)
             {

Modified: trunk/tools/quickbook/src/state.cpp
==============================================================================
--- trunk/tools/quickbook/src/state.cpp (original)
+++ trunk/tools/quickbook/src/state.cpp 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
@@ -71,23 +71,41 @@
         return *grammar_;
     }
 
- void state::add_dependency(fs::path const& f) {
+ bool state::add_dependency(fs::path const& f) {
         fs::path p = fs::absolute(f);
+ bool found = fs::exists(fs::status(p));
+
+ // Pop path sections from path until we find an existing
+ // path, adjusting for any dot path sections.
         fs::path extra;
+ int parent_count = 0;
         while (!fs::exists(fs::status(p))) {
             fs::path name = p.filename();
             p = p.parent_path();
             if (name == "..") {
- p = p.parent_path();
+ ++parent_count;
             }
             else if (name == ".") {
             }
+ else if (parent_count) {
+ --parent_count;
+ }
             else {
                 extra = name / extra;
             }
         }
+
+ // If there are any left over ".." sections, then add them
+ // on to the end of the real path, and trust Boost.Filesystem
+ // to sort them out.
+ while (parent_count) {
+ p = p / "..";
+ --parent_count;
+ }
+
         p = fs::canonical(p) / extra;
- dependencies.insert(p);
+ dependencies[p] |= found;
+ return found;
     }
 
     file_state::file_state(quickbook::state& state, scope_flags scope)

Modified: trunk/tools/quickbook/src/state.hpp
==============================================================================
--- trunk/tools/quickbook/src/state.hpp (original)
+++ trunk/tools/quickbook/src/state.hpp 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
@@ -10,7 +10,7 @@
 #if !defined(BOOST_SPIRIT_ACTIONS_CLASS_HPP)
 #define BOOST_SPIRIT_ACTIONS_CLASS_HPP
 
-#include <set>
+#include <map>
 #include <boost/scoped_ptr.hpp>
 #include "parsers.hpp"
 #include "values_parse.hpp"
@@ -37,6 +37,7 @@
     ///////////////////////////////////////////////////////////////////////////
 
         typedef std::vector<std::string> string_list;
+ typedef std::map<fs::path, bool> dependency_list;
 
         static int const max_template_depth = 100;
 
@@ -50,7 +51,7 @@
         id_manager& ids;
         value_builder callouts; // callouts are global as
         int callout_depth; // they don't nest.
- std::set<fs::path> dependencies;
+ dependency_list dependencies;
 
     // state saved for files and templates.
         bool imported;
@@ -78,8 +79,8 @@
     ///////////////////////////////////////////////////////////////////////////
 
         // Call this before loading any file so that it will be included in the
- // list of dependencies.
- void add_dependency(fs::path const&);
+ // list of dependencies. Returns true if file exists.
+ bool add_dependency(fs::path const&);
 
         void start_list(char mark);
         void end_list(char mark);

Deleted: trunk/tools/quickbook/test/python/include_path.txt
==============================================================================
--- trunk/tools/quickbook/test/python/include_path.txt 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
+++ (empty file)
@@ -1,6 +0,0 @@
-include_path.qbk
-a.qbk
-sub1/a.qbk
-b.qbk
-sub1/b.qbk
-sub2/b.qbk

Copied: trunk/tools/quickbook/test/python/include_path_deps.txt (from r77972, /trunk/tools/quickbook/test/python/include_path.txt)
==============================================================================
--- /trunk/tools/quickbook/test/python/include_path.txt (original)
+++ trunk/tools/quickbook/test/python/include_path_deps.txt 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
@@ -1,6 +1,3 @@
 include_path.qbk
-a.qbk
 sub1/a.qbk
-b.qbk
-sub1/b.qbk
 sub2/b.qbk

Added: trunk/tools/quickbook/test/python/include_path_locs.txt
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/include_path_locs.txt 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
@@ -0,0 +1,6 @@
++ include_path.qbk
+- a.qbk
++ sub1/a.qbk
+- b.qbk
+- sub1/b.qbk
++ sub2/b.qbk

Modified: trunk/tools/quickbook/test/python/missing_relative.qbk
==============================================================================
--- trunk/tools/quickbook/test/python/missing_relative.qbk (original)
+++ trunk/tools/quickbook/test/python/missing_relative.qbk 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
@@ -3,3 +3,4 @@
 
 [include ../missing.qbk]
 [include missing-dir/x.qbk]
+[include missing-dir/../../x.qbk]

Deleted: trunk/tools/quickbook/test/python/missing_relative.txt
==============================================================================
--- trunk/tools/quickbook/test/python/missing_relative.txt 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
+++ (empty file)
@@ -1,3 +0,0 @@
-missing_relative.qbk
-../missing.qbk
-missing-dir/x.qbk

Added: trunk/tools/quickbook/test/python/missing_relative_deps.txt
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/missing_relative_deps.txt 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
@@ -0,0 +1 @@
+missing_relative.qbk

Added: trunk/tools/quickbook/test/python/missing_relative_locs.txt
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/missing_relative_locs.txt 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
@@ -0,0 +1,4 @@
++ missing_relative.qbk
+- ../missing.qbk
+- missing-dir/x.qbk
+- missing-dir/../../x.qbk

Modified: trunk/tools/quickbook/test/python/output-deps.py
==============================================================================
--- trunk/tools/quickbook/test/python/output-deps.py (original)
+++ trunk/tools/quickbook/test/python/output-deps.py 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
@@ -1,31 +1,40 @@
 #!/usr/bin/env python
 
-import sys, os, subprocess, tempfile
+import sys, os, subprocess, tempfile, re
 
 def main(args, directory):
     if len(args) != 1:
         print "Usage: output-deps.py quickbook-command"
         exit(1)
     quickbook_command = args[0]
+
     failures = 0
     failures += run_quickbook(quickbook_command, 'svg_missing.qbk',
- deps_gold = 'svg_missing.txt')
+ deps_gold = 'svg_missing_deps.txt')
+ failures += run_quickbook(quickbook_command, 'svg_missing.qbk',
+ locations_gold = 'svg_missing_locs.txt')
     failures += run_quickbook(quickbook_command, 'missing_relative.qbk',
- deps_gold = 'missing_relative.txt')
+ deps_gold = 'missing_relative_deps.txt',
+ locations_gold = 'missing_relative_locs.txt')
     failures += run_quickbook(quickbook_command, 'include_path.qbk',
- deps_gold = 'include_path.txt',
+ deps_gold = 'include_path_deps.txt',
+ locations_gold = 'include_path_locs.txt',
             input_path = ['sub1', 'sub2'])
- print "Failures:",failures
- exit(failures)
+
+ if failures == 0:
+ print "Success"
+ else:
+ print "Failures:",failures
+ exit(failures)
 
 def run_quickbook(quickbook_command, filename, output_gold = None,
- deps_gold = None, input_path = []):
+ deps_gold = None, locations_gold = None, input_path = []):
     failures = 0
 
     command = [quickbook_command, '--debug', filename]
 
     output_filename = None
- if output_gold or not deps_gold:
+ if output_gold:
         output_filename = temp_filename('.qbk')
         command.extend(['--output-file', output_filename])
 
@@ -34,6 +43,11 @@
         deps_filename = temp_filename('.txt')
         command.extend(['--output-deps', deps_filename])
 
+ locations_filename = None
+ if locations_gold:
+ locations_filename = temp_filename('.txt')
+ command.extend(['--output-checked-locations', locations_filename])
+
     try:
         for path in input_path:
             command.extend(['-I', path])
@@ -49,37 +63,77 @@
             output = None
 
         if deps_filename:
- deps = load_file(deps_filename)
+ deps = load_dependencies(deps_filename)
         else:
             deps = None
+
+ if locations_filename:
+ locations = load_locations(locations_filename)
+ else:
+ locations = None
     finally:
         if output_filename: os.unlink(output_filename)
         if deps_filename: os.unlink(deps_filename)
 
     if deps_gold:
- gold_deps = set(os.path.realpath(x) for x in
- load_file(deps_gold).strip().split('\n'))
- test_deps = set(deps.strip().split('\n'))
- if test_deps != gold_deps:
+ gold = load_dependencies(deps_gold, adjust_paths = True)
+ if deps != gold:
             failures = failures + 1
- print "Dependencies doesn't match:"
- print "Gold:", gold_deps
- print "Result:", test_deps
+ print "Dependencies don't match:"
+ print "Gold:", gold
+ print "Result:", deps
+ print
+
+ if locations_gold:
+ gold = load_locations(locations_gold, adjust_paths = True)
+ if locations != gold:
+ failures = failures + 1
+ print "Dependencies don't match:"
+ print "Gold:", gold
+ print "Result:", locations
             print
 
     if output_gold:
         gold = load_file(output_gold)
- if output_gold != output:
+ if gold != output:
             failures = failures + 1
             print "Output doesn't match:"
             print
- print output_gold
- print
             print gold
             print
+ print output
+ print
 
     return failures
 
+def load_dependencies(filename, adjust_paths = False):
+ dependencies = set()
+ f = open(filename, 'r')
+ for path in f:
+ if adjust_paths:
+ path = os.path.realpath(path)
+ if path in dependencies:
+ raise Exception("Duplicate path (%1s) in %2s" % (path, filename))
+ dependencies.add(path)
+ return dependencies
+
+def load_locations(filename, adjust_paths = False):
+ line_matcher = re.compile("^([+-]) (.*)$")
+ dependencies = {}
+ f = open(filename, 'r')
+ for line in f:
+ m = line_matcher.match(line)
+ if not m:
+ raise Exception("Invalid dependency file: %1s" % filename)
+ found = m.group(1) == '+'
+ path = m.group(2)
+ if adjust_paths:
+ path = os.path.realpath(path)
+ if path in dependencies:
+ raise Exception("Duplicate path (%1s) in %2s" % (path, filename))
+ dependencies[path] = found
+ return dependencies
+
 def temp_filename(extension):
     file = tempfile.mkstemp(suffix = extension)
     os.close(file[0])

Deleted: trunk/tools/quickbook/test/python/svg_missing.txt
==============================================================================
--- trunk/tools/quickbook/test/python/svg_missing.txt 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
+++ (empty file)
@@ -1,2 +0,0 @@
-html/missing.svg
-svg_missing.qbk

Added: trunk/tools/quickbook/test/python/svg_missing_deps.txt
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/svg_missing_deps.txt 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
@@ -0,0 +1 @@
+svg_missing.qbk

Added: trunk/tools/quickbook/test/python/svg_missing_locs.txt
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/svg_missing_locs.txt 2012-04-14 13:33:14 EDT (Sat, 14 Apr 2012)
@@ -0,0 +1,2 @@
+- html/missing.svg
++ svg_missing.qbk


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk