Skip to content

Commit 47bc464

Browse files
authored
added support for built-in defines __DATE__ and __TIME__ (#251)
1 parent 2860eed commit 47bc464

2 files changed

Lines changed: 71 additions & 0 deletions

File tree

simplecpp.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <algorithm>
2626
#include <climits>
2727
#include <cstring>
28+
#include <ctime>
2829
#include <exception>
2930
#include <fstream>
3031
#include <iostream>
@@ -2867,6 +2868,28 @@ static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token
28672868
return true;
28682869
}
28692870

2871+
static void getLocaltime(struct tm &ltime) {
2872+
time_t t;
2873+
time(&t);
2874+
#ifndef _WIN32
2875+
localtime_r(&t, &ltime);
2876+
#else
2877+
localtime_s(&ltime, &t);
2878+
#endif
2879+
}
2880+
2881+
static std::string getDateDefine(struct tm *timep) {
2882+
char buf[] = "??? ?? ????";
2883+
strftime(buf, sizeof(buf), "%b %d %Y", timep);
2884+
return std::string("\"").append(buf).append("\"");
2885+
}
2886+
2887+
static std::string getTimeDefine(struct tm *timep) {
2888+
char buf[] = "??:??:??";
2889+
strftime(buf, sizeof(buf), "%T", timep);
2890+
return std::string("\"").append(buf).append("\"");
2891+
}
2892+
28702893
void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenList &rawtokens, std::vector<std::string> &files, std::map<std::string, simplecpp::TokenList *> &filedata, const simplecpp::DUI &dui, simplecpp::OutputList *outputList, std::list<simplecpp::MacroUsage> *macroUsage, std::list<simplecpp::IfCond> *ifCond)
28712894
{
28722895
std::map<std::string, std::size_t> sizeOfType(rawtokens.sizeOfType);
@@ -2909,6 +2932,10 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
29092932
macros.insert(std::make_pair("__FILE__", Macro("__FILE__", "__FILE__", files)));
29102933
macros.insert(std::make_pair("__LINE__", Macro("__LINE__", "__LINE__", files)));
29112934
macros.insert(std::make_pair("__COUNTER__", Macro("__COUNTER__", "__COUNTER__", files)));
2935+
struct tm ltime = {};
2936+
getLocaltime(ltime);
2937+
macros.insert(std::make_pair("__DATE__", Macro("__DATE__", getDateDefine(&ltime), files)));
2938+
macros.insert(std::make_pair("__TIME__", Macro("__TIME__", getTimeDefine(&ltime), files)));
29122939

29132940
if (dui.std == "c++11")
29142941
macros.insert(std::make_pair("__cplusplus", Macro("__cplusplus", "201103L", files)));

test.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,6 +2161,47 @@ static void preprocessSizeOf()
21612161
ASSERT_EQUALS("file0,1,syntax_error,failed to evaluate #if condition, invalid sizeof expression\n", toString(outputList));
21622162
}
21632163

2164+
static void timeDefine()
2165+
{
2166+
const char code[] = "__TIME__";
2167+
const std::string t = preprocess(code);
2168+
// "19:09:53"
2169+
ASSERT_EQUALS(10, t.size());
2170+
// TODO: split string and check proper ranges instead
2171+
ASSERT_EQUALS('"', t[0]);
2172+
ASSERT_EQUALS(true, isdigit(t[1]) != 0);
2173+
ASSERT_EQUALS(true, isdigit(t[2]) != 0);
2174+
ASSERT_EQUALS(':', t[3]);
2175+
ASSERT_EQUALS(true, isdigit(t[4]) != 0);
2176+
ASSERT_EQUALS(true, isdigit(t[5]) != 0);
2177+
ASSERT_EQUALS(':', t[6]);
2178+
ASSERT_EQUALS(true, isdigit(t[7]) != 0);
2179+
ASSERT_EQUALS(true, isdigit(t[8]) != 0);
2180+
ASSERT_EQUALS('"', t[9]);
2181+
}
2182+
2183+
static void dateDefine()
2184+
{
2185+
const char code[] = "__DATE__";
2186+
const std::string dt = preprocess(code);
2187+
// "\"Mar 11 2022\""
2188+
ASSERT_EQUALS(13, dt.size());
2189+
// TODO: split string and check proper ranges instead
2190+
ASSERT_EQUALS('"', dt[0]);
2191+
ASSERT_EQUALS(true, dt[1] >= 'A' && dt[1] <= 'Z'); // uppercase letter
2192+
ASSERT_EQUALS(true, dt[2] >= 'a' && dt[2] <= 'z'); // lowercase letter
2193+
ASSERT_EQUALS(true, dt[3] >= 'a' && dt[3] <= 'z'); // lowercase letter
2194+
ASSERT_EQUALS(' ', dt[4]);
2195+
ASSERT_EQUALS(true, isdigit(dt[5]) != 0);
2196+
ASSERT_EQUALS(true, isdigit(dt[6]) != 0);
2197+
ASSERT_EQUALS(' ', dt[7]);
2198+
ASSERT_EQUALS(true, isdigit(dt[8]) != 0);
2199+
ASSERT_EQUALS(true, isdigit(dt[9]) != 0);
2200+
ASSERT_EQUALS(true, isdigit(dt[10]) != 0);
2201+
ASSERT_EQUALS(true, isdigit(dt[11]) != 0);
2202+
ASSERT_EQUALS('"', dt[12]);
2203+
}
2204+
21642205
int main(int argc, char **argv)
21652206
{
21662207
TEST_CASE(backslash);
@@ -2342,5 +2383,8 @@ int main(int argc, char **argv)
23422383

23432384
TEST_CASE(preprocessSizeOf);
23442385

2386+
TEST_CASE(timeDefine);
2387+
TEST_CASE(dateDefine);
2388+
23452389
return numberOfFailedAssertions > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
23462390
}

0 commit comments

Comments
 (0)