@@ -312,7 +312,7 @@ namespace tcpp
312312 using TOnIncludeCallback = std::function<TInputStreamUniquePtr(const std::string&, bool )>;
313313 using TSymTable = std::vector<TMacroDesc>;
314314 using TContextStack = std::list<std::string>;
315- using TDirectiveHandler = std::function<std::string (Preprocessor&, Lexer&, const std::string &)>;
315+ using TDirectiveHandler = std::function<TToken (Preprocessor&, Lexer&)>;
316316 using TDirectivesMap = std::unordered_map<std::string, TDirectiveHandler>;
317317
318318 typedef struct TPreprocessorConfigInfo
@@ -346,7 +346,8 @@ namespace tcpp
346346
347347 bool AddCustomDirectiveHandler (const std::string& directive, const TDirectiveHandler& handler) TCPP_NOEXCEPT;
348348
349- std::string Process () TCPP_NOEXCEPT;
349+ TTokensSequence Process () TCPP_NOEXCEPT;
350+ static std::string ToString (const TTokensSequence& tokens) TCPP_NOEXCEPT;
350351
351352 Preprocessor& operator = (const Preprocessor&) TCPP_NOEXCEPT = delete ;
352353
@@ -1150,20 +1151,20 @@ namespace tcpp
11501151 }
11511152
11521153
1153- std::string Preprocessor::Process () TCPP_NOEXCEPT
1154+ TTokensSequence Preprocessor::Process () TCPP_NOEXCEPT
11541155 {
11551156 TCPP_ASSERT (mpLexer);
11561157
1157- std::string processedStr ;
1158+ TTokensSequence processedTokens{} ;
11581159
1159- auto appendString = [&processedStr , this ](const std::string& str )
1160+ auto appendToken = [&processedTokens , this ](const TToken& token )
11601161 {
11611162 if (_shouldTokenBeSkipped ())
11621163 {
11631164 return ;
11641165 }
11651166
1166- processedStr. append (str );
1167+ processedTokens. emplace_back (token );
11671168 };
11681169
11691170 // \note first stage of preprocessing, expand macros and include directives
@@ -1231,7 +1232,7 @@ namespace tcpp
12311232 }
12321233 else
12331234 {
1234- appendString (currToken. mRawView );
1235+ appendToken (currToken);
12351236 }
12361237 }
12371238 break ;
@@ -1242,13 +1243,18 @@ namespace tcpp
12421243 }), mContextStack .end ());
12431244 break ;
12441245 case E_TOKEN_TYPE::CONCAT_OP:
1245- while (processedStr .back () == ' ' ) // \note Remove last character in the processed source if it was a whitespace
1246+ while (processedTokens .back (). mType == E_TOKEN_TYPE::SPACE)
12461247 {
1247- processedStr .erase (processedStr. length () - 1 );
1248+ processedTokens .erase (processedTokens. end () - 1 );
12481249 }
12491250
12501251 currToken = TrySkipWhitespaceTokensSequence ([this ] { return mpLexer->GetNextToken (); }, mpLexer->GetNextToken ());
1251- appendString (currToken.mRawView );
1252+
1253+ if (!_shouldTokenBeSkipped ())
1254+ {
1255+ processedTokens.back ().mRawView += currToken.mRawView ;
1256+ }
1257+
12521258 break ;
12531259 case E_TOKEN_TYPE::STRINGIZE_OP:
12541260 {
@@ -1258,15 +1264,17 @@ namespace tcpp
12581264 continue ;
12591265 }
12601266
1261- appendString (" \" " + (currToken = mpLexer->GetNextToken ()).mRawView + " \" " );
1267+ appendToken (TToken{ E_TOKEN_TYPE::QUOTES, " \" " });
1268+ appendToken ((currToken = mpLexer->GetNextToken ()));
1269+ appendToken (TToken{ E_TOKEN_TYPE::QUOTES, " \" " });
12621270 }
12631271 break ;
12641272 case E_TOKEN_TYPE::CUSTOM_DIRECTIVE:
12651273 {
12661274 auto customDirectiveIter = mCustomDirectivesHandlersMap .find (currToken.mRawView );
12671275 if (customDirectiveIter != mCustomDirectivesHandlersMap .cend ())
12681276 {
1269- appendString (customDirectiveIter->second (*this , *mpLexer, processedStr ));
1277+ appendToken (customDirectiveIter->second (*this , *mpLexer));
12701278 }
12711279 else
12721280 {
@@ -1280,7 +1288,7 @@ namespace tcpp
12801288 break ;
12811289 }
12821290
1283- appendString (currToken. mRawView );
1291+ appendToken (currToken);
12841292 break ;
12851293 }
12861294
@@ -1290,7 +1298,19 @@ namespace tcpp
12901298 }
12911299 }
12921300
1293- return processedStr;
1301+ return processedTokens;
1302+ }
1303+
1304+ std::string Preprocessor::ToString (const TTokensSequence& tokens) TCPP_NOEXCEPT
1305+ {
1306+ std::string output = EMPTY_STR_VALUE;
1307+
1308+ for (const TToken& currToken : tokens)
1309+ {
1310+ output.append (currToken.mRawView );
1311+ }
1312+
1313+ return output;
12941314 }
12951315
12961316 Preprocessor::TSymTable Preprocessor::GetSymbolsTable () const TCPP_NOEXCEPT
@@ -1695,7 +1715,7 @@ namespace tcpp
16951715 }
16961716
16971717 currToken = TrySkipWhitespaceTokensSequence(getNextTokenCallback(), getNextTokenCallback());
1698- appendString (currToken.mRawView);
1718+ appendToken (currToken.mRawView);
16991719#endif
17001720 break ;
17011721 case E_TOKEN_TYPE::STRINGIZE_OP:
0 commit comments