diff --git a/simplecpp.cpp b/simplecpp.cpp index 7afc17ab..a163236c 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -1692,10 +1692,9 @@ namespace simplecpp { } /** base class for errors */ - struct Error { - Error(const Location &loc, const std::string &s) : location(loc), what(s) {} + struct Error : public std::runtime_error { + Error(const Location &loc, const std::string &s) : std::runtime_error(s), location(loc) {} const Location location; - const std::string what; }; /** Struct that is thrown when macro is expanded with wrong number of parameters */ @@ -1739,6 +1738,9 @@ namespace simplecpp { return tok; } + /** + * @throws Error thrown in case of __VA_OPT__ issues + */ bool parseDefine(const Token *nametoken) { nameTokDef = nametoken; variadic = false; @@ -3278,7 +3280,7 @@ static bool preprocessToken(simplecpp::TokenList &output, const simplecpp::Token simplecpp::Output out{ simplecpp::Output::SYNTAX_ERROR, err.location, - "failed to expand \'" + tok->str() + "\', " + err.what + "failed to expand \'" + tok->str() + "\', " + err.what() }; outputList->emplace_back(std::move(out)); } @@ -3507,23 +3509,12 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL else it->second = macro; } - } catch (const std::runtime_error &) { + } catch (const std::runtime_error &err) { if (outputList) { - simplecpp::Output err{ + simplecpp::Output out{ Output::SYNTAX_ERROR, rawtok->location, - "Failed to parse #define" - }; - outputList->emplace_back(std::move(err)); - } - output.clear(); - return; - } catch (const simplecpp::Macro::Error &err) { - if (outputList) { - simplecpp::Output out{ - simplecpp::Output::SYNTAX_ERROR, - err.location, - "Failed to parse #define, " + err.what + std::string("Failed to parse #define, ") + err.what() }; outputList->emplace_back(std::move(out)); } diff --git a/test.cpp b/test.cpp index fa94a266..3a4b273a 100644 --- a/test.cpp +++ b/test.cpp @@ -687,7 +687,7 @@ static void define_invalid_1() const char code[] = "#define A(\nB\n"; simplecpp::OutputList outputList; ASSERT_EQUALS("", preprocess(code, &outputList)); - ASSERT_EQUALS("file0,1,syntax_error,Failed to parse #define\n", toString(outputList)); + ASSERT_EQUALS("file0,1,syntax_error,Failed to parse #define, bad macro syntax\n", toString(outputList)); } static void define_invalid_2() @@ -695,7 +695,7 @@ static void define_invalid_2() const char code[] = "#define\nhas#"; simplecpp::OutputList outputList; ASSERT_EQUALS("", preprocess(code, &outputList)); - ASSERT_EQUALS("file0,1,syntax_error,Failed to parse #define\n", toString(outputList)); + ASSERT_EQUALS("file0,1,syntax_error,Failed to parse #define, bad macro syntax\n", toString(outputList)); } static void define_define_1() @@ -1094,6 +1094,15 @@ static void define_va_opt_8() ASSERT_EQUALS("", toString(outputList)); } +static void define_va_opt_9() +{ + simplecpp::DUI dui; + dui.defines.emplace_back("f(...)=__VA_OPT__"); + simplecpp::OutputList outputList; + ASSERT_EQUALS("", preprocess("", dui, &outputList)); + ASSERT_EQUALS("file0,0,dui_error,In definition of 'f': Missing opening parenthesis for __VA_OPT__\n", toString(outputList)); +} + static void define_ifdef() { const char code[] = "#define A(X) X\n" @@ -3599,6 +3608,7 @@ int main(int argc, char **argv) TEST_CASE(define_va_opt_6); TEST_CASE(define_va_opt_7); TEST_CASE(define_va_opt_8); + TEST_CASE(define_va_opt_9); // #632 TEST_CASE(pragma_backslash); // multiline pragma directive