• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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