Skip to content

Commit 0e22d0b

Browse files
committed
fixed cppcheck-opensource#24 - warn about <backslash><whitespace><newline>
1 parent cf9ff13 commit 0e22d0b

4 files changed

Lines changed: 43 additions & 3 deletions

File tree

main.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ int main(int argc, char **argv) {
7979
case simplecpp::Output::SYNTAX_ERROR:
8080
std::cerr << "syntax error: ";
8181
break;
82+
case simplecpp::Output::PORTABILITY_BACKSLASH:
83+
std::cerr << "portability: ";
84+
break;
8285
}
8386
std::cerr << output.msg << std::endl;
8487
}

simplecpp.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,16 @@ static std::string escapeString(const std::string &str) {
342342
return ostr.str();
343343
}
344344

345+
static void portabilityBackslash(simplecpp::OutputList *outputList, const std::vector<std::string> &files, const simplecpp::Location &location) {
346+
if (!outputList)
347+
return;
348+
simplecpp::Output err(files);
349+
err.type = simplecpp::Output::PORTABILITY_BACKSLASH;
350+
err.location = location;
351+
err.msg = "Combination 'backslash space newline' is not portable.";
352+
outputList->push_back(err);
353+
}
354+
345355
void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filename, OutputList *outputList)
346356
{
347357
std::stack<simplecpp::Location> loc;
@@ -363,6 +373,8 @@ void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filen
363373

364374
if (ch == '\n') {
365375
if (cback() && cback()->op == '\\') {
376+
if (location.col > cback()->location.col + 1U)
377+
portabilityBackslash(outputList, files, cback()->location);
366378
++multiline;
367379
deleteToken(back());
368380
} else {
@@ -415,6 +427,9 @@ void simplecpp::TokenList::readfile(std::istream &istr, const std::string &filen
415427
currentToken += ch;
416428
ch = readChar(istr, bom);
417429
}
430+
const std::string::size_type pos = currentToken.find_last_not_of(" \t");
431+
if (pos < currentToken.size() - 1U && currentToken[pos] == '\\')
432+
portabilityBackslash(outputList, files, location);
418433
if (currentToken[currentToken.size() - 1U] == '\\') {
419434
++multiline;
420435
currentToken.erase(currentToken.size() - 1U);

simplecpp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ struct SIMPLECPP_LIB Output {
158158
WARNING, /* #warning */
159159
MISSING_HEADER,
160160
INCLUDE_NESTED_TOO_DEEPLY,
161-
SYNTAX_ERROR
161+
SYNTAX_ERROR,
162+
PORTABILITY_BACKSLASH
162163
} type;
163164
Location location;
164165
std::string msg;

test.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ static void testcase(const std::string &name, void (*f)(), int argc, char **argv
3939

4040

4141

42-
static std::string readfile(const char code[], int sz=-1) {
42+
static std::string readfile(const char code[], int sz=-1, simplecpp::OutputList *outputList=nullptr) {
4343
std::istringstream istr(sz == -1 ? std::string(code) : std::string(code,sz));
4444
std::vector<std::string> files;
45-
return simplecpp::TokenList(istr,files).stringify();
45+
return simplecpp::TokenList(istr,files,std::string(),outputList).stringify();
4646
}
4747

4848
static std::string preprocess(const char code[], const simplecpp::DUI &dui, simplecpp::OutputList *outputList = NULL) {
@@ -81,13 +81,32 @@ static std::string toString(const simplecpp::OutputList &outputList) {
8181
case simplecpp::Output::Type::SYNTAX_ERROR:
8282
ostr << "syntax_error,";
8383
break;
84+
case simplecpp::Output::Type::PORTABILITY_BACKSLASH:
85+
ostr << "portability_backslash,";
86+
break;
8487
}
8588

8689
ostr << output.msg << '\n';
8790
}
8891
return ostr.str();
8992
}
9093

94+
void backslash() {
95+
// <backslash><space><newline> preprocessed differently
96+
simplecpp::OutputList outputList;
97+
98+
readfile("//123 \\\n456", -1, &outputList);
99+
ASSERT_EQUALS("", toString(outputList));
100+
readfile("//123 \\ \n456", -1, &outputList);
101+
ASSERT_EQUALS("file0,1,portability_backslash,Combination 'backslash space newline' is not portable.\n", toString(outputList));
102+
103+
outputList.clear();
104+
readfile("#define A \\\n123", -1, &outputList);
105+
ASSERT_EQUALS("", toString(outputList));
106+
readfile("#define A \\ \n123", -1, &outputList);
107+
ASSERT_EQUALS("file0,1,portability_backslash,Combination 'backslash space newline' is not portable.\n", toString(outputList));
108+
}
109+
91110
void builtin() {
92111
ASSERT_EQUALS("\"\" 1 0", preprocess("__FILE__ __LINE__ __COUNTER__"));
93112
ASSERT_EQUALS("\n\n3", preprocess("\n\n__LINE__"));
@@ -965,6 +984,8 @@ void simplifyPath() {
965984

966985

967986
int main(int argc, char **argv) {
987+
TEST_CASE(backslash);
988+
968989
TEST_CASE(builtin);
969990

970991
TEST_CASE(combineOperators_floatliteral);

0 commit comments

Comments
 (0)