Skip to content

Fix #422 (add precompiled headers functionality) #423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ int main(int argc, char **argv)
{
bool error = false;
const char *filename = nullptr;
bool precompile = false;
bool use_istream = false;

// Settings..
Expand Down Expand Up @@ -66,6 +67,12 @@ int main(int argc, char **argv)
quiet = true;
found = true;
break;
case 'p':
if (std::strcmp(arg, "-pc")==0) {
precompile = true;
found = true;
}
break;
case 'e':
error_only = true;
found = true;
Expand Down Expand Up @@ -102,6 +109,7 @@ int main(int argc, char **argv)
std::cout << " -q Quiet mode (no output)." << std::endl;
std::cout << " -is Use std::istream interface." << std::endl;
std::cout << " -e Output errors only." << std::endl;
std::cout << " -pc Precompile header." << std::endl;
std::exit(0);
}

Expand All @@ -123,15 +131,19 @@ int main(int argc, char **argv)
}
rawtokens->removeComments();
simplecpp::TokenList outputTokens(files);
std::map<std::string, simplecpp::TokenList*> filedata;
simplecpp::preprocess(outputTokens, *rawtokens, files, filedata, dui, &outputList);
simplecpp::cleanup(filedata);
if (precompile) {
std::cout << simplecpp::precompileHeader(*rawtokens, files, dui, &outputList);
} else {
std::map<std::string, simplecpp::TokenList*> filedata;
simplecpp::preprocess(outputTokens, *rawtokens, files, filedata, dui, &outputList);
simplecpp::cleanup(filedata);
}
delete rawtokens;
rawtokens = nullptr;

// Output
if (!quiet) {
if (!error_only)
if (!error_only && !precompile)
std::cout << outputTokens.stringify() << std::endl;

for (const simplecpp::Output &output : outputList) {
Expand Down
72 changes: 70 additions & 2 deletions simplecpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1681,6 +1681,13 @@ namespace simplecpp {
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.");
}
};

std::string dump() const {
std::string ret;
for (const Token *tok = nameTokDef; sameline(nameTokDef,tok); tok = tok->next)
ret += "\n" + toString(tok->location.col) + ":" + tok->str();
return ret.substr(1);
}
private:
/** Create new token where Token::macro is set for replaced tokens */
Token *newMacroToken(const TokenString &str, const Location &loc, bool replaced, const Token *expandedFromToken=nullptr) const {
Expand Down Expand Up @@ -3314,8 +3321,10 @@ static std::string getTimeDefine(const struct tm *timep)
return std::string("\"").append(buf).append("\"");
}

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)
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)
{
using namespace simplecpp;

#ifdef SIMPLECPP_WINDOWS
if (dui.clearIncludeCache)
nonExistingFilesCache.clear();
Expand Down Expand Up @@ -3347,7 +3356,6 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
std::vector<std::string> dummy;

const bool hasInclude = isCpp17OrLater(dui);
MacroMap macros;
for (std::list<std::string>::const_iterator it = dui.defines.begin(); it != dui.defines.end(); ++it) {
const std::string &macrostr = *it;
const std::string::size_type eq = macrostr.find('=');
Expand Down Expand Up @@ -3792,6 +3800,66 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
}
}

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)
{
MacroMap macroMap;
simplecppPreprocess(output,
rawtokens,
files,
filedata,
dui,
outputList,
macroUsage,
ifCond,
macroMap);
}


std::string simplecpp::precompileHeader(const TokenList &rawtokens, std::vector<std::string> &files, const DUI &dui, OutputList *outputList)
{
std::map<std::string, TokenList*> filedata;
simplecpp::TokenList output(files);
std::list<simplecpp::MacroUsage> macroUsage;
std::list<simplecpp::IfCond> ifCond;
simplecpp::MacroMap macroMap;
simplecppPreprocess(output,
rawtokens,
files,
filedata,
dui,
outputList,
&macroUsage,
&ifCond,
macroMap);

std::string ret;
ret = "files\n";
for (int i = 0; i < files.size(); ++i)
ret += toString(i) + ":" + files[i] + "\n";
ret += "tokens\n";
unsigned int fileIndex = 0;
unsigned int line = 0;
unsigned int col = 0;
for (const simplecpp::Token *tok = output.cfront(); tok; tok = tok->next) {
if (tok->location.fileIndex != fileIndex) {
fileIndex = tok->location.fileIndex;
ret += "f" + toString(fileIndex);
}
if (tok->location.line != line) {
line = tok->location.line;
ret += "l" + toString(line);
}
if (tok->location.col != col) {
col = tok->location.col;
ret += "c" + toString(col);
}
ret += ":" + tok->str() + "\n";
}
for (simplecpp::MacroMap::const_iterator it = macroMap.begin(); it != macroMap.end(); ++it)
ret += "[MACRO]\n" + it->second.dump() + "\n";
return ret;
}

void simplecpp::cleanup(std::map<std::string, TokenList*> &filedata)
{
for (std::map<std::string, TokenList*>::iterator it = filedata.begin(); it != filedata.end(); ++it)
Expand Down
10 changes: 10 additions & 0 deletions simplecpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,16 @@ namespace simplecpp {
*/
SIMPLECPP_LIB void preprocess(TokenList &output, const TokenList &rawtokens, std::vector<std::string> &files, std::map<std::string, TokenList*> &filedata, const DUI &dui, OutputList *outputList = nullptr, std::list<MacroUsage> *macroUsage = nullptr, std::list<IfCond> *ifCond = nullptr);

/**
* Precompile header
* @param rawtokens Raw tokenlist for top sourcefile
* @param files internal data of simplecpp
* @param dui defines, undefs, and include paths
* @param outputList output: list that will receive output messages
* @return precompiled header data
*/
SIMPLECPP_LIB std::string precompileHeader(const TokenList &rawtokens, std::vector<std::string> &files, const DUI &dui, OutputList *outputList = nullptr);

/**
* Deallocate data
*/
Expand Down
Loading