Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Boost.Wave: A Standard compliant C++ preprocessor library
|
Chris@16
|
3
|
Chris@16
|
4 http://www.boost.org/
|
Chris@16
|
5
|
Chris@16
|
6 Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
|
Chris@16
|
7 Software License, Version 1.0. (See accompanying file
|
Chris@16
|
8 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
9 =============================================================================*/
|
Chris@16
|
10
|
Chris@16
|
11 #if !defined(TIME_CONVERSION_HELPER_HPP_DA97E389_1797_43BA_82AE_B071064B3EF4_INCLUDED)
|
Chris@16
|
12 #define TIME_CONVERSION_HELPER_HPP_DA97E389_1797_43BA_82AE_B071064B3EF4_INCLUDED
|
Chris@16
|
13
|
Chris@16
|
14 #include <ctime>
|
Chris@16
|
15 #include <cstring>
|
Chris@16
|
16
|
Chris@16
|
17 #include <boost/config.hpp>
|
Chris@16
|
18 #include <boost/spirit/include/classic_core.hpp>
|
Chris@16
|
19 #include <boost/spirit/include/classic_symbols.hpp>
|
Chris@16
|
20 #include <boost/spirit/include/classic_assign_actor.hpp>
|
Chris@16
|
21 #include <boost/spirit/include/classic_push_back_actor.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 #if !defined(spirit_append_actor)
|
Chris@16
|
24 #define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor)
|
Chris@16
|
25 #define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor)
|
Chris@16
|
26 #endif // !defined(spirit_append_actor)
|
Chris@16
|
27
|
Chris@16
|
28 // this must occur after all of the includes and before any code appears
|
Chris@16
|
29 #ifdef BOOST_HAS_ABI_HEADERS
|
Chris@16
|
30 #include BOOST_ABI_PREFIX
|
Chris@16
|
31 #endif
|
Chris@16
|
32
|
Chris@16
|
33 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
34 namespace boost {
|
Chris@16
|
35 namespace wave {
|
Chris@16
|
36 namespace util {
|
Chris@16
|
37
|
Chris@16
|
38 namespace time_conversion {
|
Chris@16
|
39
|
Chris@16
|
40 using namespace std; // some systems have std::tm etc. in namespace std
|
Chris@16
|
41
|
Chris@16
|
42 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
43 // define, whether the rule's should generate some debug output
|
Chris@16
|
44 #define TRACE_CPP_TIME_CONVERSION \
|
Chris@16
|
45 (BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_TIME_CONVERSION) \
|
Chris@16
|
46 /**/
|
Chris@16
|
47
|
Chris@16
|
48 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
49 // Grammar for parsing a date/time string generated by the C++ compiler from
|
Chris@16
|
50 // __DATE__ and __TIME__
|
Chris@16
|
51 class time_conversion_grammar :
|
Chris@16
|
52 public boost::spirit::classic::grammar<time_conversion_grammar>
|
Chris@16
|
53 {
|
Chris@16
|
54 public:
|
Chris@16
|
55 time_conversion_grammar() : fYearIsCorrected(false)
|
Chris@16
|
56 {
|
Chris@16
|
57 using namespace std; // some systems have memset in std
|
Chris@16
|
58 memset (&time_stamp, 0, sizeof(tm));
|
Chris@16
|
59 BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME(*this, "time_conversion_grammar",
|
Chris@16
|
60 TRACE_CPP_TIME_CONVERSION);
|
Chris@16
|
61 }
|
Chris@16
|
62
|
Chris@16
|
63 template <typename ScannerT>
|
Chris@16
|
64 struct definition {
|
Chris@16
|
65
|
Chris@16
|
66 definition(time_conversion_grammar const &self)
|
Chris@16
|
67 {
|
Chris@16
|
68 using boost::spirit::classic::int_p;
|
Chris@16
|
69 using boost::spirit::classic::add;
|
Chris@16
|
70
|
Chris@16
|
71 char const *m[] = {
|
Chris@16
|
72 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
Chris@16
|
73 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
Chris@16
|
74 };
|
Chris@16
|
75
|
Chris@16
|
76 for (int i = 0; i < 12; ++i)
|
Chris@16
|
77 add (month, m[i], i);
|
Chris@16
|
78
|
Chris@16
|
79 time_rule // expected format is 'Dec 29 2001 11:23:59'
|
Chris@16
|
80 = month[spirit_assign_actor(self.time_stamp.tm_mon)]
|
Chris@16
|
81 >> int_p[spirit_assign_actor(self.time_stamp.tm_mday)]
|
Chris@16
|
82 >> int_p[spirit_assign_actor(self.time_stamp.tm_year)]
|
Chris@16
|
83 >> int_p[spirit_assign_actor(self.time_stamp.tm_hour)] >> ':'
|
Chris@16
|
84 >> int_p[spirit_assign_actor(self.time_stamp.tm_min)] >> ':'
|
Chris@16
|
85 >> int_p[spirit_assign_actor(self.time_stamp.tm_sec)]
|
Chris@16
|
86 ;
|
Chris@16
|
87
|
Chris@16
|
88 BOOST_SPIRIT_DEBUG_TRACE_RULE(time_rule, TRACE_CPP_TIME_CONVERSION);
|
Chris@16
|
89 }
|
Chris@16
|
90
|
Chris@16
|
91 boost::spirit::classic::rule<ScannerT> time_rule;
|
Chris@16
|
92 boost::spirit::classic::symbols<> month;
|
Chris@16
|
93
|
Chris@16
|
94 boost::spirit::classic::rule<ScannerT> const&
|
Chris@16
|
95 start() const { return time_rule; }
|
Chris@16
|
96 };
|
Chris@16
|
97
|
Chris@16
|
98 void correct_year()
|
Chris@16
|
99 {
|
Chris@16
|
100 if (!fYearIsCorrected) {
|
Chris@16
|
101 time_stamp.tm_year -= 1900;
|
Chris@16
|
102 fYearIsCorrected = true;
|
Chris@16
|
103 }
|
Chris@16
|
104 }
|
Chris@16
|
105
|
Chris@16
|
106 mutable tm time_stamp;
|
Chris@16
|
107 bool fYearIsCorrected;
|
Chris@16
|
108 };
|
Chris@16
|
109
|
Chris@16
|
110 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
111 // calculate the time of the compilation as a std::time_t to ensure correctness
|
Chris@16
|
112 // of the saved dfa table
|
Chris@16
|
113 class time_conversion_helper
|
Chris@16
|
114 {
|
Chris@16
|
115 public:
|
Chris@16
|
116 time_conversion_helper(char const *act_time) : compile_time(0)
|
Chris@16
|
117 {
|
Chris@16
|
118 using namespace boost::spirit::classic;
|
Chris@16
|
119
|
Chris@16
|
120 time_conversion_grammar g;
|
Chris@16
|
121 parse_info<> pi = parse (act_time, g, space_p);
|
Chris@16
|
122
|
Chris@16
|
123 if (pi.hit) {
|
Chris@16
|
124 g.correct_year();
|
Chris@16
|
125 compile_time = mktime(&g.time_stamp);
|
Chris@16
|
126 }
|
Chris@16
|
127 BOOST_ASSERT(0 != compile_time);
|
Chris@16
|
128 }
|
Chris@16
|
129
|
Chris@16
|
130 time_t get_time() const { return compile_time; }
|
Chris@16
|
131
|
Chris@16
|
132 private:
|
Chris@16
|
133 time_t compile_time;
|
Chris@16
|
134 };
|
Chris@16
|
135
|
Chris@16
|
136 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
137 #undef TRACE_CPP_TIME_CONVERSION
|
Chris@16
|
138 } // namespace time_conversion
|
Chris@16
|
139
|
Chris@16
|
140 // import time_conversion into the boost::wave::util namespace
|
Chris@16
|
141 using namespace time_conversion;
|
Chris@16
|
142
|
Chris@16
|
143 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
144 } // namespace util
|
Chris@16
|
145 } // namespace wave
|
Chris@16
|
146 } // namespace boost
|
Chris@16
|
147
|
Chris@16
|
148 // the suffix header occurs after all of the code
|
Chris@16
|
149 #ifdef BOOST_HAS_ABI_HEADERS
|
Chris@16
|
150 #include BOOST_ABI_SUFFIX
|
Chris@16
|
151 #endif
|
Chris@16
|
152
|
Chris@16
|
153 #endif // !defined(TIME_CONVERSION_HELPER_HPP_DA97E389_1797_43BA_82AE_B071064B3EF4_INCLUDED)
|