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
22namespace filesystem = boost::filesystem;
23
24//struct stop {
25// stop() { char c; std::cin >> c; }
26//} stop_;
27
28boost::regex whitespace("\\s*");
29boost::regex blank_line("\\A(?://.*$|\\s)*");
30
31boost::regex include_guard("#ifndef (\\w+)\n#define \\1\n");
32boost::regex base_unit("(\\w*_base_unit)(?:;| :)");
33
34std::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(s: contents, m&: include_guard_match, e: include_guard);
40 boost::smatch base_unit_match;
41 boost::regex_search(s: contents, m&: base_unit_match, e: 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(x: base_unit_match[1].str(), y: include_guard_match[1].str()));
44}
45
46int 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(x: get_base_unit_and_include_guard(path: 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
68boost::regex include_guard_regex("#if defined\\((\\w+)\\) && defined\\((\\w+)\\) &&\\\\");
69std::cout << __LINE__ << std::endl;
70boost::regex conversion_guard_regex(" !defined\\((\\w+)\\)");
71std::cout << __LINE__ << std::endl;
72boost::regex set_conversion_guard(" #define (\\w+)");
73std::cout << __LINE__ << std::endl;
74boost::regex include_conversion(" #include <boost/units/conversion.hpp>");
75std::cout << __LINE__ << std::endl;
76boost::regex include_absolute(" #include <boost/units/absolute.hpp>");
77std::cout << __LINE__ << std::endl;
78boost::regex define_conversion_factor(" BOOST_UNITS_DEFINE_CONVERSION_FACTOR\\(boost::units::(\\w+_base_unit), boost::units::(\\w+_base_unit), \\w+, (?:[\\d\\.e\\-/ ]*|one\\(\\))\\);");
79std::cout << __LINE__ << std::endl;
80boost::regex define_conversion_offset(" BOOST_UNITS_DEFINE_CONVERSION_OFFSET\\(boost::units::(\\w+_base_unit), boost::units::(\\w+_base_unit), \\w+, [\\d\\.e+\\* \\-/]*\\);");
81std::cout << __LINE__ << std::endl;
82boost::regex endif("#endif");
83std::cout << __LINE__ << std::endl;
84
85 while(std::getline(is&: conversions_file, str&: line)) {
86 ++line_count;
87 std::cout << "on line: " << line_count << std::endl;
88 if(boost::regex_match(s: line, m&: match, e: blank_line)) {
89 continue;
90 } else if(boost::regex_match(s: line, m&: match, e: 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(is&: conversions_file, str&: line)) { std::cerr << "unexpected end of file." << std::endl; return(1); } ++line_count;
97 if(!boost::regex_match(s: line, m&: match, e: 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(x: conversion_guard).second){ std::cerr << "error on line: " << line_count << std::endl; return(1); }
101
102 if(!std::getline(is&: conversions_file, str&: line)) { std::cerr << "unexpected end of file." << std::endl; return(1); } ++line_count;
103 if(!boost::regex_match(s: line, m&: match, e: set_conversion_guard)) { std::cerr << "error on line: " << line_count << std::endl; return(1); }
104std::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(is&: conversions_file, str&: line)) { std::cerr << "unexpected end of file." << std::endl; return(1); } ++line_count;
109 if(!boost::regex_match(s: line, m&: match, e: include_conversion)) { std::cerr << "error on line: " << line_count << std::endl; return(1); }
110std::cout << __LINE__ << std::endl;
111
112 if(!std::getline(is&: conversions_file, str&: line)) { std::cerr << "unexpected end of file." << std::endl; return(1); } ++line_count;
113 if(boost::regex_match(s: line, m&: match, e: include_absolute)) {
114 uses_absolute = true;
115 if(!std::getline(is&: conversions_file, str&: line)) { std::cerr << "unexpected end of file." << std::endl; return(1); } ++line_count;
116 }
117
118std::cout << __LINE__ << std::endl;
119 if(!boost::regex_match(s: line, m&: match, e: define_conversion_factor)) { std::cerr << "error on line: " << line_count << std::endl; return(1); }
120
121std::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 }
134std::cout << __LINE__ << std::endl;
135
136 if(!std::getline(is&: conversions_file, str&: line)) { std::cerr << "unexpected end of file." << std::endl; return(1); } ++line_count;
137std::cout << __LINE__ << std::endl;
138 if(boost::regex_match(s: line, m&: match, e: define_conversion_offset)) {
139 if(!uses_absolute) { std::cerr << "error on line: " << line_count << std::endl; return(1); }
140std::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(is&: conversions_file, str&: 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 }
146std::cout << __LINE__ << std::endl;
147
148
149 if(!boost::regex_match(s: line, m&: match, e: 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

source code of boost/libs/units/test/check_conversion_defs.cpp