Skip to content
Merged
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
22 changes: 22 additions & 0 deletions integration_test.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -481,3 +481,25 @@ def test_include_header_twice(tmpdir):

assert stderr == ''


def test_define(record_property, tmpdir): # #589
test_file = os.path.join(tmpdir, "test.cpp")
with open(test_file, 'w') as f:
f.write(
"""#define PREFIX_WITH_MACRO(test_name) Macro##test_name

TEST_P(PREFIX_WITH_MACRO(NamingTest), n) {}
""")

args = [
'-DTEST_P(A,B)=void __ ## A ## _ ## B ( )',
'test.cpp'
]

exitcode, stdout, stderr = simplecpp(args, cwd=tmpdir)
record_property("stdout", stdout)
record_property("stderr", stderr)

assert exitcode == 0
assert stderr == "test.cpp:1: syntax error: failed to expand 'TEST_P', Invalid ## usage when expanding 'TEST_P': Unexpected token ')'\n"
assert stdout == '\n'
2 changes: 1 addition & 1 deletion main.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -207,7 +207,7 @@ int main(int argc, char **argv)
std::cout << outputTokens.stringify(linenrs) << std::endl;

for (const simplecpp::Output &output : outputList) {
std::cerr << output.location.file() << ':' << output.location.line << ": ";
std::cerr << outputTokens.file(output.location) << ':' << output.location.line << ": ";
switch (output.type) {
case simplecpp::Output::ERROR:
std::cerr << "#error: ";
Expand Down
53 changes: 27 additions & 26 deletions simplecpp.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -182,8 +182,6 @@ static std::string replaceAll(std::string s, const std::string& from, const std:
return s;
}

const std::string simplecpp::Location::emptyFileName;

void simplecpp::Location::adjust(const std::string &str)
{
if (strpbrk(str.c_str(), "\r\n") == nullptr) {
Expand DownExpand Up@@ -422,7 +420,7 @@ class FileStream : public simplecpp::TokenList::Stream {
{
if (!file) {
files.push_back(filename);
throw simplecpp::Output(simplecpp::Output::FILE_NOT_FOUND, simplecpp::Location(files), "File is missing: " + filename);
throw simplecpp::Output(simplecpp::Output::FILE_NOT_FOUND, {}, "File is missing: " + filename);
}
init();
}
Expand DownExpand Up@@ -564,11 +562,11 @@ void simplecpp::TokenList::dump(bool linenrs) const
std::string simplecpp::TokenList::stringify(bool linenrs) const
{
std::ostringstream ret;
Location loc(files);
Location loc;
bool filechg = true;
for (const Token *tok = cfront(); tok; tok = tok->next) {
if (tok->location.line < loc.line || tok->location.fileIndex != loc.fileIndex) {
ret << "\n#line " << tok->location.line << " \"" << tok->location.file() << "\"\n";
ret << "\n#line " << tok->location.line << " \"" << file(tok->location) << "\"\n";
loc = tok->location;
filechg = true;
}
Expand DownExpand Up@@ -633,16 +631,16 @@ static bool isStringLiteralPrefix(const std::string &str)
str == "R" || str == "uR" || str == "UR" || str == "LR" || str == "u8R";
}

void simplecpp::TokenList::lineDirective(unsigned int fileIndex, unsigned int line, Location *location)
void simplecpp::TokenList::lineDirective(unsigned int fileIndex, unsigned int line, Location &location)
{
if (fileIndex != location->fileIndex || line >= location->line) {
location->fileIndex = fileIndex;
location->line = line;
if (fileIndex != location.fileIndex || line >= location.line) {
location.fileIndex = fileIndex;
location.line = line;
return;
}

if (line + 2 >= location->line) {
location->line = line;
if (line + 2 >= location.line) {
location.line = line;
while (cback()->op != '#')
deleteToken(back());
deleteToken(back());
Expand All@@ -660,10 +658,7 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename,

const Token *oldLastToken = nullptr;

Location location(files);
location.fileIndex = fileIndex(filename);
location.line = 1U;
location.col = 1U;
Location location(fileIndex(filename), 1, 1);
while (stream.good()) {
unsigned char ch = stream.readChar();
if (!stream.good())
Expand DownExpand Up@@ -732,7 +727,7 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename,
while (numtok->comment)
numtok = numtok->previous;
lineDirective(fileIndex(replaceAll(strtok->str().substr(1U, strtok->str().size() - 2U),"\\\\","\\")),
std::atol(numtok->str().c_str()), &location);
std::atol(numtok->str().c_str()), location);
}
// #line 3
else if (llNextToken->str() == "line" &&
Expand All@@ -741,7 +736,7 @@ void simplecpp::TokenList::readfile(Stream &stream, const std::string &filename,
const Token *numtok = cback();
while (numtok->comment)
numtok = numtok->previous;
lineDirective(location.fileIndex, std::atol(numtok->str().c_str()), &location);
lineDirective(location.fileIndex, std::atol(numtok->str().c_str()), location);
}
}
// #endfile
Expand DownExpand Up@@ -1478,6 +1473,12 @@ unsigned int simplecpp::TokenList::fileIndex(const std::string &filename)
return files.size() - 1U;
}

const std::string& simplecpp::TokenList::file(const Location& loc) const
{
static const std::string s_emptyFileName;
return loc.fileIndex < files.size() ? files[loc.fileIndex] : s_emptyFileName;
}


namespace simplecpp {
class Macro;
Expand DownExpand Up@@ -1885,7 +1886,7 @@ namespace simplecpp {
usageList.push_back(loc);

if (nameTokInst->str() == "__FILE__") {
output.push_back(new Token('\"'+loc.file()+'\"', loc));
output.push_back(new Token('\"'+output.file(loc)+'\"', loc));
return nameTokInst->next;
}
if (nameTokInst->str() == "__LINE__") {
Expand DownExpand Up@@ -2637,7 +2638,7 @@ static void simplifyHasInclude(simplecpp::TokenList &expr, const simplecpp::DUI
}
}

const std::string &sourcefile = tok->location.file();
const std::string &sourcefile = expr.file(tok->location);
const bool systemheader = (tok1 && tok1->op == '<');
std::string header;
if (systemheader) {
Expand DownExpand Up@@ -3179,7 +3180,7 @@ simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens,
if (outputList) {
simplecpp::Output err = {
simplecpp::Output::EXPLICIT_INCLUDE_NOT_FOUND,
Location(filenames),
{},
"Can not open include file '" + filename + "' that is explicitly included."
};
outputList->push_back(std::move(err));
Expand DownExpand Up@@ -3212,7 +3213,7 @@ simplecpp::FileDataCache simplecpp::load(const simplecpp::TokenList &rawtokens,
if (!rawtok || rawtok->str() != INCLUDE)
continue;

const std::string &sourcefile = rawtok->location.file();
const std::string &sourcefile = rawtokens.file(rawtok->location);

const Token * const htok = rawtok->nextSkipComments();
if (!sameline(rawtok, htok))
Expand DownExpand Up@@ -3369,7 +3370,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
if (outputList) {
simplecpp::Output err = {
Output::DUI_ERROR,
Location(files),
{},
"unknown standard specified: '" + dui.std + "'"
};
outputList->push_back(std::move(err));
Expand DownExpand Up@@ -3539,7 +3540,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL

const bool systemheader = (inctok->str()[0] == '<');
const std::string header(inctok->str().substr(1U, inctok->str().size() - 2U));
const FileData *const filedata = cache.get(rawtok->location.file(), header, dui, systemheader, files, outputList).first;
const FileData *const filedata = cache.get(rawtokens.file(rawtok->location), header, dui, systemheader, files, outputList).first;
if (filedata == nullptr) {
if (outputList) {
simplecpp::Output out = {
Expand DownExpand Up@@ -3632,7 +3633,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
tok = tok->next;
bool closingAngularBracket = false;
if (tok) {
const std::string &sourcefile = rawtok->location.file();
const std::string &sourcefile = rawtokens.file(rawtok->location);
const bool systemheader = (tok && tok->op == '<');
std::string header;

Expand DownExpand Up@@ -3740,7 +3741,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
macros.erase(tok->str());
}
} else if (ifstates.top() == True && rawtok->str() == PRAGMA && rawtok->next && rawtok->next->str() == ONCE && sameline(rawtok,rawtok->next)) {
pragmaOnce.insert(rawtok->location.file());
pragmaOnce.insert(rawtokens.file(rawtok->location));
}
if (ifstates.top() != True && rawtok->nextcond)
rawtok = rawtok->nextcond->previous;
Expand DownExpand Up@@ -3796,7 +3797,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
const std::list<Location>& temp = maybeUsedMacros[macro.name()];
usage.insert(usage.end(), temp.begin(), temp.end());
for (std::list<Location>::const_iterator usageIt = usage.begin(); usageIt != usage.end(); ++usageIt) {
MacroUsage mu(usageIt->files, macro.valueDefinedInCode());
MacroUsage mu(macro.valueDefinedInCode());
mu.macroName = macro.name();
mu.macroLocation = macro.defineLocation();
mu.useLocation = *usageIt;
Expand Down
33 changes: 12 additions & 21 deletions simplecpp.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -74,20 +74,16 @@ namespace simplecpp {
/**
* Location in source code
*/
class SIMPLECPP_LIB Location {
public:
explicit Location(const std::vector<std::string> &f) : files(f) {}
struct SIMPLECPP_LIB Location {
Location() = default;
Location(unsigned int fileIndex, unsigned int line, unsigned int col)
: fileIndex(fileIndex)
, line(line)
, col(col)
{}

Location(const Location &loc) = default;

Location &operator=(const Location &other) {
if (this != &other) {
fileIndex = other.fileIndex;
line = other.line;
col = other.col;
}
return *this;
}
Location &operator=(const Location &other) = default;
Comment on lines -82 to +86

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was lacking the assignment of files. I have no idea how that could have ever been a valid object - beside the fact that containing a reference is even problematic to begin with.


/** increment this location by string */
void adjust(const std::string &str);
Expand All@@ -104,16 +100,9 @@ namespace simplecpp {
return fileIndex == other.fileIndex && line == other.line;
}

const std::string& file() const {
return fileIndex < files.size() ? files[fileIndex] : emptyFileName;
}

const std::vector<std::string> &files;
unsigned int fileIndex{};
unsigned int line{1};
unsigned int col{};
private:
static const std::string emptyFileName;
};

/**
Expand DownExpand Up@@ -341,6 +330,8 @@ namespace simplecpp {
return files;
}

const std::string& file(const Location& loc) const;

private:
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList, int unused);

Expand All@@ -356,7 +347,7 @@ namespace simplecpp {
void constFoldQuestionOp(Token *&tok1);

std::string readUntil(Stream &stream, const Location &location, char start, char end, OutputList *outputList);
void lineDirective(unsigned int fileIndex, unsigned int line, Location *location);
void lineDirective(unsigned int fileIndex, unsigned int line, Location &location);

const Token* lastLineTok(int maxsize=1000) const;
const Token* isLastLinePreprocessor(int maxsize=1000) const;
Expand All@@ -370,7 +361,7 @@ namespace simplecpp {

/** Tracking how macros are used */
struct SIMPLECPP_LIB MacroUsage {
explicit MacroUsage(const std::vector<std::string> &f, bool macroValueKnown_) : macroLocation(f), useLocation(f), macroValueKnown(macroValueKnown_) {}
explicit MacroUsage(bool macroValueKnown_) : macroValueKnown(macroValueKnown_) {}
std::string macroName;
Location macroLocation;
Location useLocation;
Expand Down
2 changes: 1 addition & 1 deletion test.cpp
Original file line numberDiff line numberDiff line change
Expand Up@@ -3206,7 +3206,7 @@ static void stdValid()
static void assertToken(const std::string& s, bool name, bool number, bool comment, char op, int line)
{
const std::vector<std::string> f;
const simplecpp::Location l(f);
const simplecpp::Location l;
const simplecpp::Token t(s, l);
assertEquals(name, t.name, line);
assertEquals(number, t.number, line);
Expand Down
Loading