1 // Boost.Units - A C++ library for zero-overhead dimensional analysis and
2 // unit/quantity manipulation and conversion
3 //
4 // Copyright (C) 2003-2008 Matthias Christian Schabel
5 // Copyright (C) 2007-2008 Steven Watanabe
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See
8 // accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 
11 #include <iterator>
12 #include <string>
13 #include <utility>
14 #include <set>
15 #include <map>
16 #include <iostream>
17 
18 #include <boost/filesystem.hpp>
19 #include <boost/filesystem/fstream.hpp>
20 #include <boost/regex.hpp>
21 
22 namespace filesystem = boost::filesystem;
23 
24 //struct stop {
25 //    stop() { char c; std::cin >> c; }
26 //} stop_;
27 
28 boost::regex whitespace("\\s*");
29 boost::regex blank_line("\\A(?://.*$|\\s)*");
30 
31 boost::regex include_guard("#ifndef (\\w+)\n#define \\1\n");
32 boost::regex base_unit("(\\w*_base_unit)(?:;| :)");
33 
get_base_unit_and_include_guard(const filesystem::path & path)34 std::pair<std::string, std::string> get_base_unit_and_include_guard(const filesystem::path& path) {
35     filesystem::ifstream in(path);
36     std::string contents(std::istreambuf_iterator<char>(in.rdbuf()), std::istreambuf_iterator<char>());
37     in.close();
38     boost::smatch include_guard_match;
39     boost::regex_search(contents, include_guard_match, include_guard);
40     boost::smatch base_unit_match;
41     boost::regex_search(contents, base_unit_match, base_unit);
42     std::cout << "creating map entry: " << base_unit_match[1].str() << " -> "<<  include_guard_match[1].str() << std::endl;
43     return(std::make_pair(base_unit_match[1].str(), include_guard_match[1].str()));
44 }
45 
main()46 int main() {
47     std::cout << "In main" << std::endl;
48     std::map<std::string, std::string> include_guards;
49     for(filesystem::directory_iterator begin(filesystem::path("../../../boost/units/systems/base_units")), end; begin != end; ++begin) {
50         if(begin->status().type() == filesystem::regular_file) {
51             std::cout << "reading file: " << begin->path() << std::endl;
52             include_guards.insert(get_base_unit_and_include_guard(begin->path()));
53         }
54     }
55 
56     std::cout << "reading conversions file" << std::endl;
57     filesystem::ifstream conversions_file(filesystem::path("../../../boost/units/systems/base_units/detail/conversions.hpp"));
58 
59     std::string line;
60     int line_count = 0;
61 
62     boost::smatch match;
63 
64     std::set<std::string> conversion_guards;
65 
66     try {
67 
68 boost::regex include_guard_regex("#if defined\\((\\w+)\\) && defined\\((\\w+)\\) &&\\\\");
69 std::cout << __LINE__ << std::endl;
70 boost::regex conversion_guard_regex("    !defined\\((\\w+)\\)");
71 std::cout << __LINE__ << std::endl;
72 boost::regex set_conversion_guard("    #define (\\w+)");
73 std::cout << __LINE__ << std::endl;
74 boost::regex include_conversion("    #include <boost/units/conversion.hpp>");
75 std::cout << __LINE__ << std::endl;
76 boost::regex include_absolute("    #include <boost/units/absolute.hpp>");
77 std::cout << __LINE__ << std::endl;
78 boost::regex define_conversion_factor("    BOOST_UNITS_DEFINE_CONVERSION_FACTOR\\(boost::units::(\\w+_base_unit), boost::units::(\\w+_base_unit), \\w+, (?:[\\d\\.e\\-/ ]*|one\\(\\))\\);");
79 std::cout << __LINE__ << std::endl;
80 boost::regex define_conversion_offset("    BOOST_UNITS_DEFINE_CONVERSION_OFFSET\\(boost::units::(\\w+_base_unit), boost::units::(\\w+_base_unit), \\w+, [\\d\\.e+\\* \\-/]*\\);");
81 std::cout << __LINE__ << std::endl;
82 boost::regex endif("#endif");
83 std::cout << __LINE__ << std::endl;
84 
85     while(std::getline(conversions_file, line)) {
86         ++line_count;
87         std::cout << "on line: " << line_count << std::endl;
88         if(boost::regex_match(line, match, blank_line)) {
89             continue;
90         } else if(boost::regex_match(line, match, include_guard_regex)) {
91             std::string guard1, guard2, unit1, unit2, conversion_guard;
92             bool uses_absolute = false;
93 
94             guard1 = match[1].str();
95             guard2 = match[2].str();
96             if(!std::getline(conversions_file, line)) { std::cerr << "unexpected end of file." << std::endl; return(1); } ++line_count;
97             if(!boost::regex_match(line, match, conversion_guard_regex)) { std::cerr << "error on line: " << line_count << std::endl; return(1); }
98 
99             conversion_guard = match[1].str();
100             if(!conversion_guards.insert(conversion_guard).second){ std::cerr << "error on line: " << line_count << std::endl; return(1); }
101 
102             if(!std::getline(conversions_file, line)) { std::cerr << "unexpected end of file." << std::endl; return(1); } ++line_count;
103             if(!boost::regex_match(line, match, set_conversion_guard)) { std::cerr << "error on line: " << line_count << std::endl; return(1); }
104 std::cout << __LINE__ << std::endl;
105 
106             if(match[1].str() != conversion_guard) { std::cerr << "error on line: " << line_count << std::endl; return(1); }
107 
108             if(!std::getline(conversions_file, line)) { std::cerr << "unexpected end of file." << std::endl; return(1); } ++line_count;
109             if(!boost::regex_match(line, match, include_conversion)) { std::cerr << "error on line: " << line_count << std::endl; return(1); }
110 std::cout << __LINE__ << std::endl;
111 
112             if(!std::getline(conversions_file, line)) { std::cerr << "unexpected end of file." << std::endl; return(1); } ++line_count;
113             if(boost::regex_match(line, match, include_absolute)) {
114                 uses_absolute = true;
115                 if(!std::getline(conversions_file, line)) { std::cerr << "unexpected end of file." << std::endl; return(1); } ++line_count;
116             }
117 
118 std::cout << __LINE__ << std::endl;
119             if(!boost::regex_match(line, match, define_conversion_factor)) { std::cerr << "error on line: " << line_count << std::endl; return(1); }
120 
121 std::cout << __LINE__ << ": " << line << std::endl;
122             unit1 = match[1].str();
123             unit2 = match[2].str();
124             if(!((include_guards[unit1] == guard1 && include_guards[unit2] == guard2) ||
125                 (include_guards[unit1] == guard2 && include_guards[unit2] == guard1))) {
126                     std::cerr << "guard1: " << guard1 << std::endl;
127                     std::cerr << "guard2: " << guard2 << std::endl;
128                     std::cerr << "unit1: " << unit1 << std::endl;
129                     std::cerr << "unit2: " << unit2 << std::endl;
130                     std::cerr << "include_guards[unit1]: " << include_guards[unit1] << std::endl;
131                     std::cerr << "include_guards[unit2]: " << include_guards[unit2] << std::endl;
132                     { std::cerr << "error on line: " << line_count << std::endl; return(1); }
133             }
134 std::cout << __LINE__ << std::endl;
135 
136             if(!std::getline(conversions_file, line)) { std::cerr << "unexpected end of file." << std::endl; return(1); } ++line_count;
137 std::cout << __LINE__ << std::endl;
138             if(boost::regex_match(line, match, define_conversion_offset)) {
139                 if(!uses_absolute) { std::cerr << "error on line: " << line_count << std::endl; return(1); }
140 std::cout << __LINE__ << std::endl;
141                 if(match[1].str() != unit1 || match[2].str() != unit2) { std::cerr << "error on line: " << line_count << std::endl; return(1); }
142                 if(!std::getline(conversions_file, line)) { std::cerr << "unexpected end of file." << std::endl; return(1); } ++line_count;
143             } else {
144                 if(uses_absolute) { std::cerr << "error on line: " << line_count << std::endl; return(1); }
145             }
146 std::cout << __LINE__ << std::endl;
147 
148 
149             if(!boost::regex_match(line, match, endif)) { std::cerr << "error on line: " << line_count << std::endl; return(1); }
150 
151         }
152     }
153 
154     } catch(std::exception& e) {
155         std::cerr << e.what() << std::endl;
156         return(1);
157     }
158 
159 }
160