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