diff --git a/lib/config/config_lexer.ll b/lib/config/config_lexer.ll index abe0a34c6..372dfc6d3 100644 --- a/lib/config/config_lexer.ll +++ b/lib/config/config_lexer.ll @@ -252,9 +252,9 @@ in return T_IN; \> return T_GREATER_THAN; } -\( { yyextra->m_IgnoreNewlines++; return '('; } -\) { yyextra->m_IgnoreNewlines--; return ')'; } -[\r\n]+ { yycolumn -= strlen(yytext) - 1; if (!yyextra->m_IgnoreNewlines) { return T_NEWLINE; } } +\( { yyextra->m_IgnoreNewlines.push(true); return '('; } +\) { yyextra->m_IgnoreNewlines.pop(); return ')'; } +[\r\n]+ { yycolumn -= strlen(yytext) - 1; if (!yyextra->m_IgnoreNewlines.top()) { return T_NEWLINE; } } <> { if (!yyextra->m_Eof) { yyextra->m_Eof = true; return T_NEWLINE; } else { yyterminate(); } } . return yytext[0]; diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index fd4e1995a..54e1c6dc8 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -258,9 +258,13 @@ Expression *ConfigCompiler::Compile(void) //yydebug = 1; + m_IgnoreNewlines.push(false); + if (yyparse(&llist, this) != 0) return NULL; + m_IgnoreNewlines.pop(); + std::vector dlist; typedef std::pair EListItem; int num = 0; @@ -733,11 +737,13 @@ rterm_array: '[' rterm_scope_require_side_effect: '{' { + context->m_IgnoreNewlines.push(false); context->m_OpenBraces++; } statements '}' { context->m_OpenBraces--; + context->m_IgnoreNewlines.pop(); std::vector dlist; typedef std::pair EListItem; int num = 0; @@ -754,11 +760,13 @@ rterm_scope_require_side_effect: '{' rterm_scope: '{' { + context->m_IgnoreNewlines.push(false); context->m_OpenBraces++; } statements '}' { context->m_OpenBraces--; + context->m_IgnoreNewlines.pop(); std::vector dlist; typedef std::pair EListItem; int num = 0; diff --git a/lib/config/configcompiler.cpp b/lib/config/configcompiler.cpp index 6d7edccf2..f0cca61c2 100644 --- a/lib/config/configcompiler.cpp +++ b/lib/config/configcompiler.cpp @@ -39,7 +39,7 @@ std::vector ConfigCompiler::m_IncludeSearchDirs; * @param zone The zone. */ ConfigCompiler::ConfigCompiler(const String& path, std::istream *input, const String& zone) - : m_Path(path), m_Input(input), m_Zone(zone), m_Eof(false), m_OpenBraces(0), m_IgnoreNewlines(0) + : m_Path(path), m_Input(input), m_Zone(zone), m_Eof(false), m_OpenBraces(0) { InitializeScanner(); } diff --git a/lib/config/configcompiler.hpp b/lib/config/configcompiler.hpp index aa438473e..47a6299b9 100644 --- a/lib/config/configcompiler.hpp +++ b/lib/config/configcompiler.hpp @@ -120,13 +120,13 @@ public: bool m_Eof; int m_OpenBraces; - int m_IgnoreNewlines; std::ostringstream m_LexBuffer; CompilerDebugInfo m_LocationBegin; std::stack m_RuleLists; ConfigType::Ptr m_Type; + std::stack m_IgnoreNewlines; std::stack m_Apply; std::stack m_ObjectAssign; std::stack m_SeenAssign; diff --git a/test/config-ops.cpp b/test/config-ops.cpp index 6468e3177..c34a901e0 100644 --- a/test/config-ops.cpp +++ b/test/config-ops.cpp @@ -203,6 +203,10 @@ BOOST_AUTO_TEST_CASE(simple) expr = ConfigCompiler::CompileText("", "\"\\'test\""); BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError); delete expr; + + expr = ConfigCompiler::CompileText("", "({ a = 3\nb = 3 })"); + BOOST_CHECK(expr->Evaluate(frame).GetValue().IsObjectType()); + delete expr; } BOOST_AUTO_TEST_CASE(advanced)