]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*============================================================================= |
2 | Copyright (c) 2013 Daniel James | |
3 | ||
4 | Use, modification and distribution is subject to the Boost Software | |
5 | License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
6 | http://www.boost.org/LICENSE_1_0.txt) | |
7 | =============================================================================*/ | |
8 | ||
9 | #include "dependency_tracker.hpp" | |
b32b8144 | 10 | #include "path.hpp" |
7c673cae FG |
11 | #include <boost/filesystem/operations.hpp> |
12 | #include <boost/filesystem/fstream.hpp> | |
13 | #include <boost/foreach.hpp> | |
14 | ||
15 | namespace quickbook | |
16 | { | |
7c673cae FG |
17 | static char const* control_escapes[16] = { |
18 | "\\000", "\\001", "\\002", "\\003", | |
19 | "\\004", "\\005", "\\006", "\\a", | |
20 | "\\b", "\\t", "\\n", "\\v", | |
21 | "\\f", "\\r", "\\016", "\\017" | |
22 | }; | |
23 | ||
24 | static std::string escaped_path(std::string const& generic) | |
25 | { | |
26 | std::string result; | |
27 | result.reserve(generic.size()); | |
28 | ||
29 | BOOST_FOREACH(char c, generic) | |
30 | { | |
31 | if (c >= 0 && c < 16) { | |
32 | result += control_escapes[(unsigned int) c]; | |
33 | } | |
34 | else if (c == '\\') { | |
35 | result += "\\\\"; | |
36 | } | |
37 | else if (c == 127) { | |
38 | result += "\\177"; | |
39 | } | |
40 | else { | |
41 | result += c; | |
42 | } | |
43 | } | |
44 | ||
45 | return result; | |
46 | } | |
47 | ||
48 | static std::string get_path(fs::path const& path, | |
49 | dependency_tracker::flags f) | |
50 | { | |
51 | std::string generic = quickbook::detail::path_to_generic(path); | |
52 | ||
53 | if (f & dependency_tracker::escaped) { | |
54 | generic = escaped_path(generic); | |
55 | } | |
56 | ||
57 | return generic; | |
58 | } | |
59 | ||
60 | dependency_tracker::dependency_tracker() : | |
61 | dependencies(), glob_dependencies(), | |
62 | last_glob(glob_dependencies.end()) {} | |
63 | ||
64 | bool dependency_tracker::add_dependency(fs::path const& f) { | |
65 | bool found = fs::exists(fs::status(f)); | |
b32b8144 | 66 | dependencies[f] |= found; |
7c673cae FG |
67 | return found; |
68 | } | |
69 | ||
70 | void dependency_tracker::add_glob(fs::path const& f) { | |
71 | std::pair<glob_list::iterator, bool> r = glob_dependencies.insert( | |
b32b8144 | 72 | std::make_pair(f, glob_list::mapped_type())); |
7c673cae FG |
73 | last_glob = r.first; |
74 | } | |
75 | ||
76 | void dependency_tracker::add_glob_match(fs::path const& f) { | |
77 | assert(last_glob != glob_dependencies.end()); | |
b32b8144 | 78 | last_glob->second.insert(f); |
7c673cae FG |
79 | } |
80 | ||
81 | void dependency_tracker::write_dependencies(fs::path const& file_out, | |
82 | flags f) | |
83 | { | |
84 | fs::ofstream out(file_out); | |
85 | ||
86 | if (out.fail()) { | |
87 | throw std::runtime_error( | |
88 | "Error opening dependency file " + | |
89 | quickbook::detail::path_to_generic(file_out)); | |
90 | } | |
91 | ||
92 | out.exceptions(std::ios::badbit); | |
93 | write_dependencies(out, f); | |
94 | } | |
95 | ||
96 | void dependency_tracker::write_dependencies(std::ostream& out, | |
97 | flags f) | |
98 | { | |
99 | if (f & checked) { | |
100 | BOOST_FOREACH(dependency_list::value_type const& d, dependencies) | |
101 | { | |
102 | out << (d.second ? "+ " : "- ") | |
103 | << get_path(d.first, f) << std::endl; | |
104 | } | |
105 | ||
106 | BOOST_FOREACH(glob_list::value_type const& g, glob_dependencies) | |
107 | { | |
108 | out << "g " | |
109 | << get_path(g.first, f) << std::endl; | |
110 | ||
111 | BOOST_FOREACH(fs::path const& p, g.second) | |
112 | { | |
113 | out << "+ " << get_path(p, f) << std::endl; | |
114 | } | |
115 | } | |
116 | } | |
117 | else { | |
118 | std::set<std::string> paths; | |
119 | ||
120 | BOOST_FOREACH(dependency_list::value_type const& d, dependencies) | |
121 | { | |
122 | if (d.second) { | |
123 | paths.insert(get_path(d.first, f)); | |
124 | } | |
125 | } | |
126 | ||
127 | BOOST_FOREACH(glob_list::value_type const& g, glob_dependencies) | |
128 | { | |
129 | BOOST_FOREACH(fs::path const& p, g.second) | |
130 | { | |
131 | paths.insert(get_path(p, f)); | |
132 | } | |
133 | } | |
134 | ||
135 | BOOST_FOREACH(std::string const& p, paths) | |
136 | { | |
137 | out << p << std::endl; | |
138 | } | |
139 | } | |
140 | } | |
141 | } |