1 /*============================================================================= 2 Boost.Wave: A Standard compliant C++ preprocessor library 3 4 Definition of the predefined macros 5 6 http://www.boost.org/ 7 8 Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost 9 Software License, Version 1.0. (See accompanying file 10 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 11 =============================================================================*/ 12 13 #if !defined(BOOST_CPP_MACROMAP_PREDEF_HPP_HK041119) 14 #define BOOST_CPP_MACROMAP_PREDEF_HPP_HK041119 15 16 #include <cstdio> 17 #include <boost/assert.hpp> 18 19 #include <boost/wave/wave_config.hpp> 20 #include <boost/wave/wave_config_constant.hpp> 21 #include <boost/wave/token_ids.hpp> 22 #include <boost/wave/util/time_conversion_helper.hpp> // time_conversion_helper 23 24 // this must occur after all of the includes and before any code appears 25 #ifdef BOOST_HAS_ABI_HEADERS 26 #include BOOST_ABI_PREFIX 27 #endif 28 29 /////////////////////////////////////////////////////////////////////////////// 30 // 31 // This file contains the definition of functions needed for the management 32 // of static and dynamic predefined macros, such as __DATE__, __TIME__ etc. 33 // 34 // Note: __FILE__, __LINE__ and __INCLUDE_LEVEL__ are handled in the file 35 // cpp_macromap.hpp. 36 // 37 /////////////////////////////////////////////////////////////////////////////// 38 39 /////////////////////////////////////////////////////////////////////////////// 40 namespace boost { 41 namespace wave { 42 namespace util { 43 44 /////////////////////////////////////////////////////////////////////////// 45 class predefined_macros 46 { 47 typedef BOOST_WAVE_STRINGTYPE string_type; 48 49 public: 50 // list of static predefined macros 51 struct static_macros { 52 char const *name; 53 boost::wave::token_id token_id; 54 char const *value; 55 }; 56 57 // list of dynamic predefined macros 58 struct dynamic_macros { 59 char const *name; 60 boost::wave::token_id token_id; 61 string_type (predefined_macros:: *generator)() const; 62 }; 63 64 private: 65 boost::wave::util::time_conversion_helper compilation_time_; 66 string_type datestr_; // __DATE__ 67 string_type timestr_; // __TIME__ 68 string_type version_; // __SPIRIT_PP_VERSION__/__WAVE_VERSION__ 69 string_type versionstr_; // __SPIRIT_PP_VERSION_STR__/__WAVE_VERSION_STR__ 70 71 protected: reset_datestr()72 void reset_datestr() 73 { 74 static const char *const monthnames[] = { 75 "Jan", "Feb", "Mar", "Apr", "May", "Jun", 76 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 77 }; 78 79 // for some systems sprintf, time_t etc. is in namespace std 80 using namespace std; 81 82 time_t tt = time(0); 83 struct tm *tb = 0; 84 85 if (tt != (time_t)-1) { 86 char buffer[sizeof("\"Oct 11 1347\"")+1]; 87 88 tb = localtime (&tt); 89 sprintf (buffer, "\"%s %2d %4d\"", 90 monthnames[tb->tm_mon], tb->tm_mday, tb->tm_year + 1900); 91 datestr_ = buffer; 92 } 93 else { 94 datestr_ = "\"??? ?? ????\""; 95 } 96 } 97 reset_timestr()98 void reset_timestr() 99 { 100 // for some systems sprintf, time_t etc. is in namespace std 101 using namespace std; 102 103 time_t tt = time(0); 104 struct tm *tb = 0; 105 106 if (tt != (time_t)-1) { 107 char buffer[sizeof("\"12:34:56\"")+1]; 108 109 tb = localtime (&tt); 110 sprintf (buffer, "\"%02d:%02d:%02d\"", tb->tm_hour, 111 tb->tm_min, tb->tm_sec); 112 timestr_ = buffer; 113 } 114 else { 115 timestr_ = "\"??:??:??\""; 116 } 117 } 118 reset_version()119 void reset_version() 120 { 121 char buffer[sizeof("0x00000000")+1]; 122 123 // for some systems sprintf, time_t etc. is in namespace std 124 using namespace std; 125 126 // calculate the number of days since Dec 13 2001 127 // (the day the Wave project was started) 128 tm first_day; 129 130 using namespace std; // for some systems memset is in namespace std 131 memset (&first_day, 0, sizeof(tm)); 132 first_day.tm_mon = 11; // Dec 133 first_day.tm_mday = 13; // 13 134 first_day.tm_year = 101; // 2001 135 136 long seconds = long(difftime(compilation_time_.get_time(), mktime(&first_day))); 137 138 sprintf(buffer, "0x%02d%1d%1d%04ld", BOOST_WAVE_VERSION_MAJOR, 139 BOOST_WAVE_VERSION_MINOR, BOOST_WAVE_VERSION_SUBMINOR, 140 seconds/(3600*24)); 141 version_ = buffer; 142 } 143 reset_versionstr()144 void reset_versionstr() 145 { 146 char buffer[sizeof("\"00.00.00.0000 \"")+sizeof(BOOST_PLATFORM)+sizeof(BOOST_COMPILER)+4]; 147 148 // for some systems sprintf, time_t etc. is in namespace std 149 using namespace std; 150 151 // calculate the number of days since Dec 13 2001 152 // (the day the Wave project was started) 153 tm first_day; 154 155 memset (&first_day, 0, sizeof(tm)); 156 first_day.tm_mon = 11; // Dec 157 first_day.tm_mday = 13; // 13 158 first_day.tm_year = 101; // 2001 159 160 long seconds = long(difftime(compilation_time_.get_time(), mktime(&first_day))); 161 162 sprintf(buffer, "\"%d.%d.%d.%ld [%s/%s]\"", BOOST_WAVE_VERSION_MAJOR, 163 BOOST_WAVE_VERSION_MINOR, BOOST_WAVE_VERSION_SUBMINOR, 164 seconds/(3600*24), BOOST_PLATFORM, BOOST_COMPILER); 165 versionstr_ = buffer; 166 } 167 168 // dynamic predefined macros get_date() const169 string_type get_date() const { return datestr_; } // __DATE__ get_time() const170 string_type get_time() const { return timestr_; } // __TIME__ 171 172 // __SPIRIT_PP__/__WAVE__ get_version() const173 string_type get_version() const 174 { 175 char buffer[sizeof("0x0000")+1]; 176 177 using namespace std; // for some systems sprintf is in namespace std 178 sprintf(buffer, "0x%02d%1d%1d", BOOST_WAVE_VERSION_MAJOR, 179 BOOST_WAVE_VERSION_MINOR, BOOST_WAVE_VERSION_SUBMINOR); 180 return buffer; 181 } 182 183 // __WAVE_CONFIG__ get_config() const184 string_type get_config() const 185 { 186 char buffer[sizeof("0x00000000")+1]; 187 188 using namespace std; // for some systems sprintf is in namespace std 189 sprintf(buffer, "0x%08x", BOOST_WAVE_CONFIG); 190 return buffer; 191 } 192 193 public: predefined_macros()194 predefined_macros() 195 : compilation_time_(__DATE__ " " __TIME__) 196 { 197 reset(); 198 reset_version(); 199 reset_versionstr(); 200 } 201 reset()202 void reset() 203 { 204 reset_datestr(); 205 reset_timestr(); 206 } 207 208 // __SPIRIT_PP_VERSION__/__WAVE_VERSION__ get_fullversion() const209 string_type get_fullversion() const { return version_; } 210 211 // __SPIRIT_PP_VERSION_STR__/__WAVE_VERSION_STR__ get_versionstr() const212 string_type get_versionstr() const { return versionstr_; } 213 214 // C++ mode static_data_cpp(std::size_t i) const215 static_macros const& static_data_cpp(std::size_t i) const 216 { 217 static static_macros data[] = { 218 { "__STDC__", T_INTLIT, "1" }, 219 { "__cplusplus", T_INTLIT, "199711L" }, 220 { 0, T_EOF, 0 } 221 }; 222 BOOST_ASSERT(i < sizeof(data)/sizeof(data[0])); 223 return data[i]; 224 } 225 226 #if BOOST_WAVE_SUPPORT_CPP0X != 0 227 // C++11 mode static_data_cpp0x(std::size_t i) const228 static_macros const& static_data_cpp0x(std::size_t i) const 229 { 230 static static_macros data[] = { 231 { "__STDC__", T_INTLIT, "1" }, 232 { "__cplusplus", T_INTLIT, "201103L" }, 233 { "__STDC_VERSION__", T_INTLIT, "199901L" }, 234 { "__STDC_HOSTED__", T_INTLIT, "0" }, 235 { "__WAVE_HAS_VARIADICS__", T_INTLIT, "1" }, 236 { 0, T_EOF, 0 } 237 }; 238 BOOST_ASSERT(i < sizeof(data)/sizeof(data[0])); 239 return data[i]; 240 } 241 #endif 242 243 #if BOOST_WAVE_SUPPORT_CPP2A != 0 244 // C++20 mode static_data_cpp2a(std::size_t i) const245 static_macros const& static_data_cpp2a(std::size_t i) const 246 { 247 static static_macros data[] = { 248 { "__STDC__", T_INTLIT, "1" }, 249 { "__cplusplus", T_INTLIT, "202002L" }, 250 { "__STDC_VERSION__", T_INTLIT, "199901L" }, 251 { "__STDC_HOSTED__", T_INTLIT, "0" }, 252 { "__WAVE_HAS_VARIADICS__", T_INTLIT, "1" }, 253 { 0, T_EOF, 0 } 254 }; 255 BOOST_ASSERT(i < sizeof(data)/sizeof(data[0])); 256 return data[i]; 257 } 258 #endif 259 260 #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0 261 // C99 mode static_data_c99(std::size_t i) const262 static_macros const& static_data_c99(std::size_t i) const 263 { 264 static static_macros data[] = { 265 { "__STDC__", T_INTLIT, "1" }, 266 { "__STDC_VERSION__", T_INTLIT, "199901L" }, 267 { "__STDC_HOSTED__", T_INTLIT, "0" }, 268 { "__WAVE_HAS_VARIADICS__", T_INTLIT, "1" }, 269 { 0, T_EOF, 0 } 270 }; 271 BOOST_ASSERT(i < sizeof(data)/sizeof(data[0])); 272 return data[i]; 273 } 274 #endif 275 dynamic_data(std::size_t i) const276 dynamic_macros const& dynamic_data(std::size_t i) const 277 { 278 static dynamic_macros data[] = { 279 { "__DATE__", T_STRINGLIT, &predefined_macros::get_date }, 280 { "__TIME__", T_STRINGLIT, &predefined_macros::get_time }, 281 { "__SPIRIT_PP__", T_INTLIT, &predefined_macros::get_version }, 282 { "__SPIRIT_PP_VERSION__", T_INTLIT, &predefined_macros::get_fullversion }, 283 { "__SPIRIT_PP_VERSION_STR__", T_STRINGLIT, &predefined_macros::get_versionstr }, 284 { "__WAVE__", T_INTLIT, &predefined_macros::get_version }, 285 { "__WAVE_VERSION__", T_INTLIT, &predefined_macros::get_fullversion }, 286 { "__WAVE_VERSION_STR__", T_STRINGLIT, &predefined_macros::get_versionstr }, 287 { "__WAVE_CONFIG__", T_INTLIT, &predefined_macros::get_config }, 288 { 0, T_EOF, 0 } 289 }; 290 BOOST_ASSERT(i < sizeof(data)/sizeof(data[0])); 291 return data[i]; 292 } 293 }; // predefined_macros 294 295 /////////////////////////////////////////////////////////////////////////////// 296 } // namespace util 297 } // namespace wave 298 } // namespace boost 299 300 // the suffix header occurs after all of the code 301 #ifdef BOOST_HAS_ABI_HEADERS 302 #include BOOST_ABI_SUFFIX 303 #endif 304 305 #endif // !defined(BOOST_CPP_MACROMAP_PREDEF_HPP_HK041119) 306