@@ -1681,6 +1681,13 @@ namespace simplecpp {
1681
1681
return invalidHashHash (loc, macroName, " Combining '\\ " + tokenA->str ()+ " ' and '" + strAB.substr (tokenA->str ().size ()) + " ' yields universal character '\\ " + strAB + " '. This is undefined behavior according to C standard chapter 5.1.1.2, paragraph 4." );
1682
1682
}
1683
1683
};
1684
+
1685
+ std::string dump () const {
1686
+ std::string ret;
1687
+ for (const Token *tok = nameTokDef; sameline (nameTokDef,tok); tok = tok->next )
1688
+ ret += " \n " + toString (tok->location .col ) + " :" + tok->str ();
1689
+ return ret.substr (1 );
1690
+ }
1684
1691
private:
1685
1692
/* * Create new token where Token::macro is set for replaced tokens */
1686
1693
Token *newMacroToken (const TokenString &str, const Location &loc, bool replaced, const Token *expandedFromToken=nullptr ) const {
@@ -3245,7 +3252,18 @@ std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::To
3245
3252
continue ;
3246
3253
3247
3254
std::ifstream f;
3248
- const std::string header2 = openHeader (f,dui,sourcefile,header,systemheader);
3255
+ std::string header2;
3256
+ if (filenames.size () == 1 ) {
3257
+ header2 = openHeader (f,dui,sourcefile,header + " .pch" ,systemheader);
3258
+ if (f.is_open ()) {
3259
+ const std::string header2WithoutPch = header2.substr (0 , header2.size () - 4 );
3260
+ TokenList *tokens = new TokenList (header2WithoutPch, filenames, outputList);
3261
+ ret[header2WithoutPch] = tokens;
3262
+ continue ;
3263
+ }
3264
+ }
3265
+ if (!f.is_open ())
3266
+ header2 = openHeader (f,dui,sourcefile,header,systemheader);
3249
3267
if (!f.is_open ())
3250
3268
continue ;
3251
3269
f.close ();
@@ -3314,8 +3332,82 @@ static std::string getTimeDefine(const struct tm *timep)
3314
3332
return std::string (" \" " ).append (buf).append (" \" " );
3315
3333
}
3316
3334
3317
- 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)
3335
+ static void loadPrecompiledHeader (simplecpp::TokenList& output,
3336
+ const std::string& pch,
3337
+ std::istream& f,
3338
+ std::vector<std::string>& files,
3339
+ std::map<std::string, simplecpp::TokenList *> &filedata,
3340
+ simplecpp::MacroMap& macros)
3341
+ {
3342
+ simplecpp::TokenList * const macroTokens = new simplecpp::TokenList (files);
3343
+ filedata[pch] = macroTokens;
3344
+ enum { FILES, TOKENS, MACROS } section = FILES;
3345
+ simplecpp::Location loc (files);
3346
+ std::string line;
3347
+ while (std::getline (f,line)) {
3348
+ if (line == " files" ) {
3349
+ section = FILES;
3350
+ continue ;
3351
+ }
3352
+ if (line == " tokens" ) {
3353
+ section = TOKENS;
3354
+ continue ;
3355
+ }
3356
+ if (line == " [MACRO]" ) {
3357
+ section = MACROS;
3358
+ loc.fileIndex = 1 ;
3359
+ loc.line = 1 ;
3360
+ if (macroTokens->cback ())
3361
+ loc.line = macroTokens->cback ()->location .line + 1 ;
3362
+ loc.col = 1 ;
3363
+ macroTokens->push_back (new simplecpp::Token (" #" , loc));
3364
+ loc.col = 2 ;
3365
+ macroTokens->push_back (new simplecpp::Token (" define" , loc));
3366
+ continue ;
3367
+ }
3368
+ if (section == FILES) {
3369
+ std::string::size_type pos = line.find (' :' );
3370
+ if (pos >= 1 && pos < line.size ())
3371
+ files.push_back (line.substr (pos+1 ));
3372
+ continue ;
3373
+ }
3374
+ if (section == TOKENS) {
3375
+ std::string::size_type pos = 0 ;
3376
+ while (pos < line.size () && line[pos] != ' :' ) {
3377
+ char c = line[pos++];
3378
+ int value = 0 ;
3379
+ while (pos < line.size () && std::isdigit (line[pos]))
3380
+ value = value * 10 + line[pos++] - ' 0' ;
3381
+ if (c == ' f' )
3382
+ loc.fileIndex = value;
3383
+ else if (c == ' l' )
3384
+ loc.line = value;
3385
+ else if (c == ' c' )
3386
+ loc.col = value;
3387
+ }
3388
+ if (pos + 1 < line.size () && line[pos] == ' :' )
3389
+ output.push_back (new simplecpp::Token (line.substr (pos + 1 ), loc));
3390
+ continue ;
3391
+ }
3392
+ if (section == MACROS) {
3393
+ const std::string::size_type pos = line.find (' :' );
3394
+ loc.col = std::atoi (line.substr (0 , pos).c_str ());
3395
+ macroTokens->push_back (new simplecpp::Token (line.substr (pos + 1 ), loc));
3396
+ }
3397
+ }
3398
+ for (const simplecpp::Token* tok = macroTokens->cfront (); tok; tok = tok->next ) {
3399
+ if (tok->op == ' #' && tok->next && tok->next ->str () == DEFINE) {
3400
+ simplecpp::Macro macro (tok, files);
3401
+ if (macro.name () != " __DATE__" && macro.name () != " __TIME__" )
3402
+ macros.insert (std::pair<simplecpp::TokenString,simplecpp::Macro>(macro.name (), macro));
3403
+ }
3404
+ }
3405
+ }
3406
+
3407
+ static void simplecppPreprocess (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, simplecpp::MacroMap& macros)
3318
3408
{
3409
+ using namespace simplecpp ;
3410
+
3319
3411
#ifdef SIMPLECPP_WINDOWS
3320
3412
if (dui.clearIncludeCache )
3321
3413
nonExistingFilesCache.clear ();
@@ -3347,7 +3439,6 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
3347
3439
std::vector<std::string> dummy;
3348
3440
3349
3441
const bool hasInclude = isCpp17OrLater (dui);
3350
- MacroMap macros;
3351
3442
for (std::list<std::string>::const_iterator it = dui.defines .begin (); it != dui.defines .end (); ++it) {
3352
3443
const std::string ¯ostr = *it;
3353
3444
const std::string::size_type eq = macrostr.find (' =' );
@@ -3534,6 +3625,13 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
3534
3625
if (header2.empty ()) {
3535
3626
// try to load file..
3536
3627
std::ifstream f;
3628
+ if (output.empty ()) {
3629
+ header2 = openHeader (f, dui, rawtok->location .file (), header + " .pch" , systemheader);
3630
+ if (f.is_open ()) {
3631
+ loadPrecompiledHeader (output, header + " .pch" , f, files, filedata, macros);
3632
+ continue ;
3633
+ }
3634
+ }
3537
3635
header2 = openHeader (f, dui, rawtok->location .file (), header, systemheader);
3538
3636
if (f.is_open ()) {
3539
3637
f.close ();
@@ -3792,6 +3890,66 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
3792
3890
}
3793
3891
}
3794
3892
3893
+ 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)
3894
+ {
3895
+ MacroMap macroMap;
3896
+ simplecppPreprocess (output,
3897
+ rawtokens,
3898
+ files,
3899
+ filedata,
3900
+ dui,
3901
+ outputList,
3902
+ macroUsage,
3903
+ ifCond,
3904
+ macroMap);
3905
+ }
3906
+
3907
+
3908
+ std::string simplecpp::precompileHeader (const TokenList &rawtokens, std::vector<std::string> &files, const DUI &dui, OutputList *outputList)
3909
+ {
3910
+ std::map<std::string, TokenList*> filedata;
3911
+ simplecpp::TokenList output (files);
3912
+ std::list<simplecpp::MacroUsage> macroUsage;
3913
+ std::list<simplecpp::IfCond> ifCond;
3914
+ simplecpp::MacroMap macroMap;
3915
+ simplecppPreprocess (output,
3916
+ rawtokens,
3917
+ files,
3918
+ filedata,
3919
+ dui,
3920
+ outputList,
3921
+ ¯oUsage,
3922
+ &ifCond,
3923
+ macroMap);
3924
+
3925
+ std::string ret;
3926
+ ret = " files\n " ;
3927
+ for (size_t i = 0 ; i < files.size (); ++i)
3928
+ ret += toString (i) + " :" + files[i] + " \n " ;
3929
+ ret += " tokens\n " ;
3930
+ unsigned int fileIndex = 0 ;
3931
+ unsigned int line = 0 ;
3932
+ unsigned int col = 0 ;
3933
+ for (const simplecpp::Token *tok = output.cfront (); tok; tok = tok->next ) {
3934
+ if (tok->location .fileIndex != fileIndex) {
3935
+ fileIndex = tok->location .fileIndex ;
3936
+ ret += " f" + toString (fileIndex);
3937
+ }
3938
+ if (tok->location .line != line) {
3939
+ line = tok->location .line ;
3940
+ ret += " l" + toString (line);
3941
+ }
3942
+ if (tok->location .col != col) {
3943
+ col = tok->location .col ;
3944
+ ret += " c" + toString (col);
3945
+ }
3946
+ ret += " :" + tok->str () + " \n " ;
3947
+ }
3948
+ for (simplecpp::MacroMap::const_iterator it = macroMap.begin (); it != macroMap.end (); ++it)
3949
+ ret += " [MACRO]\n " + it->second .dump () + " \n " ;
3950
+ return ret;
3951
+ }
3952
+
3795
3953
void simplecpp::cleanup (std::map<std::string, TokenList*> &filedata)
3796
3954
{
3797
3955
for (std::map<std::string, TokenList*>::iterator it = filedata.begin (); it != filedata.end (); ++it)
0 commit comments