$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r77598 - in trunk/tools/quickbook: src test/python test/python/sub1 test/python/sub2
From: dnljms_at_[hidden]
Date: 2012-03-27 19:00:49
Author: danieljames
Date: 2012-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
New Revision: 77598
URL: http://svn.boost.org/trac/boost/changeset/77598
Log:
Quickbook: Further dependencies development. Refs #6691
- Include relevant locations on path where file wasn't found.
- Improve `include_search` while I'm at it.
- Normalize paths for non-existent files.
- Tests, not integrated with Boost.Build yet. Needs to check that
  python is available then run the script with the location of the
  quickbook executable.
Added:
   trunk/tools/quickbook/test/python/
   trunk/tools/quickbook/test/python/include_path.qbk   (contents, props changed)
   trunk/tools/quickbook/test/python/include_path.txt   (contents, props changed)
   trunk/tools/quickbook/test/python/missing_relative.qbk   (contents, props changed)
   trunk/tools/quickbook/test/python/missing_relative.txt   (contents, props changed)
   trunk/tools/quickbook/test/python/output-deps.py   (contents, props changed)
   trunk/tools/quickbook/test/python/sub1/
   trunk/tools/quickbook/test/python/sub1/a.qbk   (contents, props changed)
   trunk/tools/quickbook/test/python/sub2/
   trunk/tools/quickbook/test/python/sub2/b.qbk   (contents, props changed)
   trunk/tools/quickbook/test/python/svg_missing.qbk   (contents, props changed)
   trunk/tools/quickbook/test/python/svg_missing.txt   (contents, props changed)
Text files modified: 
   trunk/tools/quickbook/src/actions.cpp   |    39 +++++++++++++++++++++++++++------------ 
   trunk/tools/quickbook/src/quickbook.cpp |     4 ++--                                    
   trunk/tools/quickbook/src/state.cpp     |    22 +++++++++++++++++-----                  
   trunk/tools/quickbook/src/state.hpp     |     4 ++--                                    
   4 files changed, 48 insertions(+), 21 deletions(-)
Modified: trunk/tools/quickbook/src/actions.cpp
==============================================================================
--- trunk/tools/quickbook/src/actions.cpp	(original)
+++ trunk/tools/quickbook/src/actions.cpp	2012-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
@@ -936,7 +936,7 @@
            //
            // Now load the SVG file:
            //
-           state.add_loaded_file(img);
+           state.add_dependency(img);
            std::string svg_text;
            fs::ifstream fs(img);
            char c;
@@ -1860,29 +1860,33 @@
         };
 
         std::set<include_search_return> include_search(path_details const& details,
-                quickbook::state const& state)
+                quickbook::state& state, string_iterator pos)
         {
             std::set<include_search_return> result;
-            fs::path current = state.current_file->path.parent_path();
 
-            fs::path path(details.value);
+            fs::path path = detail::generic_to_path(details.value);
 
             // If the path is relative, try and resolve it.
             if (!path.has_root_directory() && !path.has_root_name())
             {
+                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(current / path))
+                if (fs::exists(local_path))
                 {
                     result.insert(include_search_return(
-                        current / path,
+                        local_path,
                         state.filename_relative.parent_path() / path));
                     return result;
                 }
 
-                // Search in each of the include path locations.
                 BOOST_FOREACH(fs::path full, include_path)
                 {
                     full /= path;
+                    state.add_dependency(full);
+
                     if (fs::exists(full))
                     {
                         result.insert(include_search_return(full, path));
@@ -1890,9 +1894,22 @@
                     }
                 }
             }
+            else
+            {
+                state.add_dependency(path);
+
+                if (fs::exists(path)) {
+                    result.insert(include_search_return(path, path));
+                    return result;
+                }
+            }
+
+            detail::outerr(state.current_file, pos)
+                << "Unable to find file: "
+                << details.value
+                << std::endl;
+            ++state.error_count;
 
-            result.insert(include_search_return(path,
-                state.filename_relative.parent_path() / path));
             return result;
         }
     }
@@ -1921,7 +1938,6 @@
                 qbk_version_n >= 106u ? file_state::scope_callables :
                 file_state::scope_macros);
 
-            state.add_loaded_file(paths.filename);
             state.current_file = load(paths.filename); // Throws load_error
             state.filename_relative = paths.filename_relative;
             state.imported = (load_type == block_tags::import);
@@ -1953,7 +1969,6 @@
 
         std::string ext = paths.filename.extension().generic_string();
         std::vector<template_symbol> storage;
-        state.add_loaded_file(paths.filename);
         // Throws load_error
         state.error_count +=
             load_snippets(paths.filename, storage, ext, load_type);
@@ -2004,7 +2019,7 @@
         path_details details = check_path(values.consume(), state);
         values.finish();
 
-        std::set<include_search_return> search = include_search(details, state);
+        std::set<include_search_return> search = include_search(details, state, first);
         std::set<include_search_return>::iterator i = search.begin();
         std::set<include_search_return>::iterator e = search.end();
         for (; i != e; ++i)
Modified: trunk/tools/quickbook/src/quickbook.cpp
==============================================================================
--- trunk/tools/quickbook/src/quickbook.cpp	(original)
+++ trunk/tools/quickbook/src/quickbook.cpp	2012-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
@@ -130,7 +130,7 @@
             set_macros(state);
 
             if (state.error_count == 0) {
-                state.add_loaded_file(filein_);
+                state.add_dependency(filein_);
                 state.current_file = load(filein_); // Throws load_error
 
                 parse_file(state);
@@ -146,7 +146,7 @@
             if (!deps_out_.empty())
             {
                 fs::ofstream deps_out(deps_out_);
-                BOOST_FOREACH(fs::path const& f, state.loaded_files)
+                BOOST_FOREACH(fs::path const& f, state.dependencies)
                     deps_out << detail::path_to_generic(f) << std::endl;
             }
 
Modified: trunk/tools/quickbook/src/state.cpp
==============================================================================
--- trunk/tools/quickbook/src/state.cpp	(original)
+++ trunk/tools/quickbook/src/state.cpp	2012-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
@@ -71,11 +71,23 @@
         return *grammar_;
     }
 
-    void state::add_loaded_file(fs::path const& f) {
-        boost::system::error_code ec;
-        fs::path p = fs::canonical(f, ec);
-        if (ec) p = fs::absolute(f);
-        loaded_files.insert(p);
+    void state::add_dependency(fs::path const& f) {
+        fs::path p = fs::absolute(f);
+        fs::path extra;
+        while (!fs::exists(fs::status(p))) {
+            fs::path name = p.filename();
+            p = p.parent_path();
+            if (name == "..") {
+                p = p.parent_path();
+            }
+            else if (name == ".") {
+            }
+            else {
+                extra = name / extra;
+            }
+        }
+        p = fs::canonical(p) / extra;
+        dependencies.insert(p);
     }
 
     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-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
@@ -50,7 +50,7 @@
         id_manager&             ids;
         value_builder           callouts;           // callouts are global as
         int                     callout_depth;      // they don't nest.
-        std::set<fs::path>      loaded_files;
+        std::set<fs::path>      dependencies;
 
     // state saved for files and templates.
         bool                    imported;
@@ -79,7 +79,7 @@
 
         // Call this before loading any file so that it will be included in the
         // list of dependencies.
-        void add_loaded_file(fs::path const&);
+        void add_dependency(fs::path const&);
 
         void start_list(char mark);
         void end_list(char mark);
Added: trunk/tools/quickbook/test/python/include_path.qbk
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/include_path.qbk	2012-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
@@ -0,0 +1,4 @@
+[quickbook 1.5]
+[article Include Path]
+[include a.qbk]
+[include b.qbk]
Added: trunk/tools/quickbook/test/python/include_path.txt
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/include_path.txt	2012-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
@@ -0,0 +1,6 @@
+include_path.qbk
+a.qbk
+sub1/a.qbk
+b.qbk
+sub1/b.qbk
+sub2/b.qbk
Added: trunk/tools/quickbook/test/python/missing_relative.qbk
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/missing_relative.qbk	2012-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
@@ -0,0 +1,5 @@
+[quickbook 1.5]
+[article Missing Relative]
+
+[include ../missing.qbk]
+[include missing-dir/x.qbk]
Added: trunk/tools/quickbook/test/python/missing_relative.txt
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/missing_relative.txt	2012-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
@@ -0,0 +1,3 @@
+missing_relative.qbk
+../missing.qbk
+missing-dir/x.qbk
Added: trunk/tools/quickbook/test/python/output-deps.py
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/output-deps.py	2012-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
@@ -0,0 +1,97 @@
+#!/usr/bin/env python
+
+import sys, os, subprocess, tempfile
+
+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')
+    failures += run_quickbook(quickbook_command, 'missing_relative.qbk',
+            deps_gold = 'missing_relative.txt')
+    failures += run_quickbook(quickbook_command, 'include_path.qbk',
+            deps_gold = 'include_path.txt',
+            input_path = ['sub1', 'sub2'])
+    print "Failures:",failures
+    exit(failures)
+
+def run_quickbook(quickbook_command, filename, output_gold = None,
+        deps_gold = None, input_path = []):
+    failures = 0
+
+    command = [quickbook_command, '--debug', filename]
+
+    output_filename = None
+    if output_gold or not deps_gold:
+        output_filename = temp_filename('.qbk')
+        command.extend(['--output-file', output_filename])
+
+    deps_filename = None
+    if deps_gold:
+        deps_filename = temp_filename('.txt')
+        command.extend(['--output-deps', deps_filename])
+
+    try:
+        for path in input_path:
+            command.extend(['-I', path])
+        print 'Running: ' + ' '.join(command)
+        print
+        exit_code = subprocess.call(command)
+        print
+        success = not exit_code
+
+        if output_filename:
+            output = load_file(output_filename)
+        else:
+            output = None
+
+        if deps_filename:
+            deps = load_file(deps_filename)
+        else:
+            deps = 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:
+            failures = failures + 1
+            print "Dependencies doesn't match:"
+            print "Gold:", gold_deps
+            print "Result:", test_deps
+            print
+
+    if output_gold:
+        gold = load_file(output_gold)
+        if output_gold != output:
+            failures = failures + 1
+            print "Output doesn't match:"
+            print
+            print output_gold
+            print
+            print gold
+            print
+
+    return failures
+
+def temp_filename(extension):
+    file = tempfile.mkstemp(suffix = extension)
+    os.close(file[0])
+    return file[1]
+
+def load_file(filename):
+    f = open(filename, 'r')
+    try:
+        return f.read()
+    finally:
+        f.close()
+
+    return None
+
+main(sys.argv[1:], os.path.dirname(sys.argv[0]))
Added: trunk/tools/quickbook/test/python/sub1/a.qbk
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/sub1/a.qbk	2012-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
@@ -0,0 +1 @@
+a
Added: trunk/tools/quickbook/test/python/sub2/b.qbk
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/sub2/b.qbk	2012-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
@@ -0,0 +1 @@
+b
Added: trunk/tools/quickbook/test/python/svg_missing.qbk
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/svg_missing.qbk	2012-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
@@ -0,0 +1,3 @@
+[article Dependencies for missing svg]
+
+[$missing.svg]
Added: trunk/tools/quickbook/test/python/svg_missing.txt
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/python/svg_missing.txt	2012-03-27 19:00:48 EDT (Tue, 27 Mar 2012)
@@ -0,0 +1,2 @@
+html/missing.svg
+svg_missing.qbk