1010#include < cstring>
1111#include < exception>
1212#include < iostream>
13+ #include < list>
1314#include < sstream>
1415#include < stdexcept>
1516#include < string>
@@ -103,15 +104,15 @@ static std::string readfile(const char code[], std::size_t size, simplecpp::Outp
103104 return makeTokenList (code,size,files,std::string (),outputList).stringify ();
104105}
105106
106- static std::string preprocess (const char code[], const simplecpp::DUI &dui, simplecpp::OutputList *outputList, const std::string &file = std::string())
107+ static std::string preprocess (const char code[], const simplecpp::DUI &dui, simplecpp::OutputList *outputList, std::list<simplecpp::MacroUsage> *macroUsage = nullptr , std::list<simplecpp::IfCond> *ifCond = nullptr , const std::string &file = std::string())
107108{
108109 std::vector<std::string> files;
109110 simplecpp::FileDataCache cache;
110111 simplecpp::TokenList tokens = makeTokenList (code,files, file);
111112 if (dui.removeComments )
112113 tokens.removeComments ();
113114 simplecpp::TokenList tokens2 (files);
114- simplecpp::preprocess (tokens2, tokens, files, cache, dui, outputList);
115+ simplecpp::preprocess (tokens2, tokens, files, cache, dui, outputList, macroUsage, ifCond );
115116 simplecpp::cleanup (cache);
116117 return tokens2.stringify ();
117118}
@@ -123,7 +124,7 @@ static std::string preprocess(const char code[])
123124
124125static std::string preprocess (const char code[], const std::string &file)
125126{
126- return preprocess (code, simplecpp::DUI (), nullptr , file);
127+ return preprocess (code, simplecpp::DUI (), nullptr , nullptr , nullptr , file);
127128}
128129
129130static std::string preprocess (const char code[], const simplecpp::DUI &dui)
@@ -136,6 +137,16 @@ static std::string preprocess(const char code[], simplecpp::OutputList *outputLi
136137 return preprocess (code, simplecpp::DUI (), outputList);
137138}
138139
140+ static std::string preprocess (const char code[], std::list<simplecpp::IfCond> *ifCond)
141+ {
142+ return preprocess (code, simplecpp::DUI (), nullptr , nullptr , ifCond);
143+ }
144+
145+ static std::string preprocess (const char code[], std::list<simplecpp::MacroUsage> *macroUsage)
146+ {
147+ return preprocess (code, simplecpp::DUI (), nullptr , macroUsage);
148+ }
149+
139150static std::string toString (const simplecpp::OutputList &outputList)
140151{
141152 std::ostringstream ostr;
@@ -3461,6 +3472,70 @@ static void bad_macro_syntax() // #616
34613472 ASSERT_EQUALS (" bad macro syntax. macroname=\" value=1" , outputList.cbegin ()->msg );
34623473}
34633474
3475+ static void ifCond ()
3476+ {
3477+ {
3478+ const char code[] = " int i;" ;
3479+ std::list<simplecpp::IfCond> ifCond;
3480+ ASSERT_EQUALS (" int i ;" , preprocess (code, &ifCond));
3481+ ASSERT_EQUALS (0 , ifCond.size ());
3482+ }
3483+ {
3484+ const char code[] = " #if 0\n "
3485+ " # elif __GNUC__ == 1\n "
3486+ " # elif defined(__APPLE__)\n "
3487+ " #endif\n " ;
3488+ std::list<simplecpp::IfCond> ifCond;
3489+ ASSERT_EQUALS (" " , preprocess (code, &ifCond));
3490+ ASSERT_EQUALS (3 , ifCond.size ());
3491+ auto it = ifCond.cbegin ();
3492+ ASSERT_EQUALS (0 , it->location .fileIndex );
3493+ ASSERT_EQUALS (1 , it->location .line );
3494+ ASSERT_EQUALS (2 , it->location .col );
3495+ ASSERT_EQUALS (" 0" , it->E );
3496+ ASSERT_EQUALS (0 , it->result );
3497+ ++it;
3498+ ASSERT_EQUALS (0 , it->location .fileIndex );
3499+ ASSERT_EQUALS (2 , it->location .line );
3500+ ASSERT_EQUALS (3 , it->location .col );
3501+ ASSERT_EQUALS (" __GNUC__ == 1" , it->E );
3502+ ASSERT_EQUALS (0 , it->result );
3503+ ++it;
3504+ ASSERT_EQUALS (0 , it->location .fileIndex );
3505+ ASSERT_EQUALS (3 , it->location .line );
3506+ ASSERT_EQUALS (4 , it->location .col );
3507+ ASSERT_EQUALS (" 0" , it->E );
3508+ ASSERT_EQUALS (0 , it->result );
3509+ }
3510+ }
3511+
3512+ static void macroUsage ()
3513+ {
3514+ {
3515+ const char code[] = " int i;" ;
3516+ std::list<simplecpp::MacroUsage> macroUsage;
3517+ ASSERT_EQUALS (" int i ;" , preprocess (code, ¯oUsage));
3518+ ASSERT_EQUALS (0 , macroUsage.size ());
3519+ }
3520+ {
3521+ const char code[] = " #define DEF_1\n "
3522+ " #ifdef DEF_1\n "
3523+ " #endif\n " ;
3524+ std::list<simplecpp::MacroUsage> macroUsage;
3525+ ASSERT_EQUALS (" " , preprocess (code, ¯oUsage));
3526+ ASSERT_EQUALS (1 , macroUsage.size ());
3527+ auto it = macroUsage.cbegin ();
3528+ ASSERT_EQUALS (" DEF_1" , it->macroName );
3529+ ASSERT_EQUALS (0 , it->macroLocation .fileIndex );
3530+ ASSERT_EQUALS (1 , it->macroLocation .line );
3531+ ASSERT_EQUALS (9 , it->macroLocation .col );
3532+ ASSERT_EQUALS (true , it->macroValueKnown );
3533+ ASSERT_EQUALS (0 , it->useLocation .fileIndex );
3534+ ASSERT_EQUALS (2 , it->useLocation .line );
3535+ ASSERT_EQUALS (8 , it->useLocation .col );
3536+ }
3537+ }
3538+
34643539static void isAbsolutePath () {
34653540#ifdef _WIN32
34663541 ASSERT_EQUALS (true , simplecpp::isAbsolutePath (" C:\\ foo\\ bar" ));
@@ -3790,6 +3865,9 @@ int main(int argc, char **argv)
37903865
37913866 TEST_CASE (bad_macro_syntax);
37923867
3868+ TEST_CASE (ifCond);
3869+ TEST_CASE (macroUsage);
3870+
37933871 TEST_CASE (fuzz_crash);
37943872
37953873 TEST_CASE (leak);
0 commit comments