/*============================================================================= Boost.Wave: A Standard compliant C++ preprocessor library http://www.boost.org/ Copyright (c) 2001-2005 Hartmut Kaiser. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #include #include #include #include #include #include #if !defined(spirit_append_actor) #define spirit_append_actor(actor) boost::spirit::push_back_a(actor) #define spirit_assign_actor(actor) boost::spirit::assign_a(actor) #endif // !defined(spirit_append_actor) /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace wave { namespace util { namespace time_conversion { using namespace std; // some systems have std::tm etc. in namespace std /////////////////////////////////////////////////////////////////////////////// // define, whether the rule's should generate some debug output #define TRACE_CPP_TIME_CONVERSION \ (BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_TIME_CONVERSION) \ /**/ /////////////////////////////////////////////////////////////////////////////// // Grammar for parsing a date/time string generated by the C++ compiler from // __DATE__ and __TIME__ class time_conversion_grammar : public boost::spirit::grammar { public: time_conversion_grammar() : fYearIsCorrected(false) { using namespace std; // some systems have memset in std memset (&time_stamp, 0, sizeof(tm)); BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME(*this, "time_conversion_grammar", TRACE_CPP_TIME_CONVERSION); } template struct definition { definition(time_conversion_grammar const &self) { using boost::spirit::int_p; using boost::spirit::add; char const *m[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; for (int i = 0; i < 12; ++i) add (month, m[i], i); time_rule // expected format is 'Dec 29 2001 11:23:59' = month[spirit_assign_actor(self.time_stamp.tm_mon)] >> int_p[spirit_assign_actor(self.time_stamp.tm_mday)] >> int_p[spirit_assign_actor(self.time_stamp.tm_year)] >> int_p[spirit_assign_actor(self.time_stamp.tm_hour)] >> int_p[spirit_assign_actor(self.time_stamp.tm_min)] >> int_p[spirit_assign_actor(self.time_stamp.tm_sec)] ; BOOST_SPIRIT_DEBUG_TRACE_RULE(time_rule, TRACE_CPP_TIME_CONVERSION); } boost::spirit::rule time_rule; boost::spirit::symbols<> month; boost::spirit::rule const& start() const { return time_rule; } }; void correct_year() { if (!fYearIsCorrected) { time_stamp.tm_year -= 1900; fYearIsCorrected = true; } } mutable tm time_stamp; bool fYearIsCorrected; }; /////////////////////////////////////////////////////////////////////////////// // calculate the time of the compilation as a std::time_t to ensure correctness // of the saved dfa table class time_conversion_helper { public: time_conversion_helper(char const *act_time) : compile_time(0) { using namespace boost::spirit; time_conversion_grammar g; std::cout << "Parsing: " << act_time << std::endl; parse_info<> pi = parse (act_time, g, space_p | ch_p(':') | ch_p(',')); if (pi.hit) { g.correct_year(); compile_time = mktime(&g.time_stamp); std::cout << "Parsing succeeded!" << std::endl; } else { std::cout << "Parsing failed!" << std::endl; std::cout << "full: " << pi.full << std::endl; std::cout << "hit: " << pi.hit << std::endl; std::cout << "length: " << pi.length << std::endl; } } time_t get_time() const { return compile_time; } private: time_t compile_time; }; /////////////////////////////////////////////////////////////////////////////// #undef TRACE_CPP_TIME_CONVERSION } // namespace time_conversion // import time_conversion into the boost::wave::util namespace using namespace time_conversion; /////////////////////////////////////////////////////////////////////////////// } // namespace util } // namespace wave } // namespace boost int main() { boost::wave::util::time_conversion_helper const compilation_time(__DATE__ " " __TIME__); std::cout << compilation_time.get_time() << std::endl; return 0; }