Suppress syntax error after skip_balanced() fails
In this situation, skip_balanced() reports a useful error such as
(the '}' part varies depending what we're trying to skip over):
Error: Missing '}'. Reached end of input.
We now exit after such failures which avoids reporting a second more
generic error like:
Error: Syntax error in input(1).
or:
Error: Syntax error in input(3).
Fixes #2606
diff --git a/CHANGES.current b/CHANGES.current
index 9c2413e..88560cf 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,17 @@
Version 4.2.0 (in progress)
===========================
+2023-05-23: olly
+ #2606 Improve error output when SWIG reaches EOF while looking for
+ a closing delimiter. This is reported with an error like:
+
+ Error: Missing '}'. Reached end of input.
+
+ We now exit after reporting this and so no longer report a second
+ more generic error like:
+
+ Error: Syntax error in input(1).
+
2023-05-22: mmomtchev
[Javascript] #2600 Improve test coverage by adding _runme.js files
for 22 test cases.
diff --git a/Examples/test-suite/errors/c_missing_rbrace.stderr b/Examples/test-suite/errors/c_missing_rbrace.stderr
index 28fdd26..7cadc07 100644
--- a/Examples/test-suite/errors/c_missing_rbrace.stderr
+++ b/Examples/test-suite/errors/c_missing_rbrace.stderr
@@ -1,2 +1 @@
c_missing_rbrace.i:3: Error: Missing '}'. Reached end of input.
-c_missing_rbrace.i:3: Error: Syntax error in input(1).
diff --git a/Examples/test-suite/errors/cpp_missing_rparenthesis.stderr b/Examples/test-suite/errors/cpp_missing_rparenthesis.stderr
index cc97f5c..5b826aa 100644
--- a/Examples/test-suite/errors/cpp_missing_rparenthesis.stderr
+++ b/Examples/test-suite/errors/cpp_missing_rparenthesis.stderr
@@ -1,2 +1 @@
cpp_missing_rparenthesis.i:5: Error: Missing ')'. Reached end of input.
-cpp_missing_rparenthesis.i:5: Error: Syntax error in input(3).
diff --git a/Source/CParse/cparse.h b/Source/CParse/cparse.h
index a7a40c7..0a53a0b 100644
--- a/Source/CParse/cparse.h
+++ b/Source/CParse/cparse.h
@@ -34,7 +34,7 @@
extern void Swig_cparse_cplusplusout(int);
extern void scanner_file(File *);
extern void scanner_next_token(int);
- extern void skip_balanced(int startchar, int endchar);
+ extern int skip_balanced(int startchar, int endchar);
extern String *get_raw_text_balanced(int startchar, int endchar);
extern void skip_decl(void);
extern void scanner_check_typedef(void);
diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c
index 2eb3f97..3395131 100644
--- a/Source/CParse/cscanner.c
+++ b/Source/CParse/cscanner.c
@@ -163,15 +163,17 @@
*
* Skips a piece of code enclosed in begin/end symbols such as '{...}' or
* (...). Ignores symbols inside comments or strings.
+ *
+ * Returns 0 if successfully skipped, -1 if EOF found first.
* ----------------------------------------------------------------------------- */
-void skip_balanced(int startchar, int endchar) {
+int skip_balanced(int startchar, int endchar) {
int start_line = Scanner_line(scan);
Clear(scanner_ccode);
if (Scanner_skip_balanced(scan,startchar,endchar) < 0) {
Swig_error(cparse_file, start_line, "Missing '%c'. Reached end of input.\n", endchar);
- return;
+ return -1;
}
cparse_line = Scanner_line(scan);
@@ -180,7 +182,7 @@
Append(scanner_ccode, Scanner_text(scan));
if (endchar == '}')
num_brace--;
- return;
+ return 0;
}
/* -----------------------------------------------------------------------------
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index f9622be..a8d0630 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -2116,15 +2116,15 @@
------------------------------------------------------------ */
except_directive : EXCEPT LPAREN identifier RPAREN LBRACE {
- skip_balanced('{','}');
- $$ = 0;
Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
+ $$ = 0;
}
| EXCEPT LBRACE {
- skip_balanced('{','}');
- $$ = 0;
Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
+ $$ = 0;
}
| EXCEPT LPAREN identifier RPAREN SEMI {
@@ -2175,7 +2175,7 @@
| FRAGMENT LPAREN fname COMMA kwargs RPAREN LBRACE {
Hash *p = $5;
String *code;
- skip_balanced('{','}');
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
$$ = new_node("fragment");
Setattr($$,"value",Getattr($3,"value"));
Setattr($$,"type",Getattr($3,"type"));
@@ -2286,10 +2286,11 @@
| INLINE LBRACE {
String *cpps;
int start_line = cparse_line;
- skip_balanced('{','}');
if (Namespaceprefix) {
Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n");
-
+ }
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
+ if (Namespaceprefix) {
$$ = 0;
} else {
String *code;
@@ -2335,7 +2336,7 @@
}
| INSERT LPAREN idstring RPAREN LBRACE {
String *code;
- skip_balanced('{','}');
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
$$ = new_node("insert");
Setattr($$,"section",$3);
Delitem(scanner_ccode,0);
@@ -3336,8 +3337,8 @@
* to wrap.
*/
| storage_class AUTO declarator cpp_const LBRACE {
- skip_balanced('{','}');
Swig_warning(WARN_CPP14_AUTO, cparse_file, cparse_line, "Unable to deduce return type for '%s'.\n", $3.id);
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
}
;
@@ -3373,7 +3374,7 @@
}
}
| LBRACE {
- skip_balanced('{','}');
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
$$ = 0;
}
| error {
@@ -3436,20 +3437,20 @@
;
lambda_introducer : LBRACKET {
- skip_balanced('[',']');
+ if (skip_balanced('[',']') < 0) Exit(EXIT_FAILURE);
$$ = 0;
}
;
lambda_template : LESSTHAN {
- skip_balanced('<','>');
+ if (skip_balanced('<','>') < 0) Exit(EXIT_FAILURE);
$$ = 0;
}
| empty { $$ = 0; }
;
lambda_body : LBRACE {
- skip_balanced('{','}');
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
$$ = 0;
}
@@ -3457,7 +3458,7 @@
$$ = 0;
}
| LPAREN {
- skip_balanced('(',')');
+ if (skip_balanced('(',')') < 0) Exit(EXIT_FAILURE);
} SEMI {
$$ = 0;
}
@@ -4903,7 +4904,7 @@
/* isolated catch clause. */
cpp_catch_decl : CATCH LPAREN parms RPAREN LBRACE {
- skip_balanced('{','}');
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
$$ = 0;
}
;
@@ -4911,7 +4912,7 @@
/* static_assert(bool, const char*); (C++11)
* static_assert(bool); (C++17) */
cpp_static_assert : STATIC_ASSERT LPAREN {
- skip_balanced('(',')');
+ if (skip_balanced('(',')') < 0) Exit(EXIT_FAILURE);
$$ = 0;
}
;
@@ -4983,7 +4984,7 @@
$$.final = $1.final;
}
| cpp_const LBRACE {
- skip_balanced('{','}');
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
$$.val = 0;
$$.qualifier = $1.qualifier;
$$.refqualifier = $1.refqualifier;
@@ -5018,7 +5019,7 @@
$$.final = $1.final;
}
| cpp_const LBRACE {
- skip_balanced('{','}');
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
$$.val = 0;
$$.qualifier = $1.qualifier;
$$.refqualifier = $1.refqualifier;
@@ -5313,7 +5314,7 @@
}
}
| EQUAL LBRACE {
- skip_balanced('{','}');
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
$$.val = NewString(scanner_ccode);
$$.rawval = 0;
$$.type = T_INT;
@@ -6266,7 +6267,7 @@
| error RPAREN {
// Avoid a parse error if we can't parse the expression decltype() is applied to.
$$ = 0;
- skip_balanced('(',')');
+ if (skip_balanced('(',')') < 0) Exit(EXIT_FAILURE);
Clear(scanner_ccode);
}
;
@@ -6928,7 +6929,7 @@
}
| type LPAREN {
String *qty;
- skip_balanced('(',')');
+ if (skip_balanced('(',')') < 0) Exit(EXIT_FAILURE);
qty = Swig_symbol_type_qualify($1,0);
if (SwigType_istemplate(qty)) {
String *nstr = SwigType_namestr(qty);
@@ -7192,15 +7193,15 @@
Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
}
| cpp_const ctor_initializer LBRACE {
- skip_balanced('{','}');
+ if ($1.qualifier)
+ Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
$$.have_parms = 0;
$$.defarg = 0;
$$.throws = $1.throws;
$$.throwf = $1.throwf;
$$.nexcept = $1.nexcept;
$$.final = $1.final;
- if ($1.qualifier)
- Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
}
| LPAREN parms RPAREN SEMI {
Clear(scanner_ccode);
@@ -7213,7 +7214,7 @@
$$.final = 0;
}
| LPAREN parms RPAREN LBRACE {
- skip_balanced('{','}');
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
$$.parms = $2;
$$.have_parms = 1;
$$.defarg = 0;
@@ -7253,7 +7254,7 @@
;
mem_initializer : idcolon LPAREN {
- skip_balanced('(',')');
+ if (skip_balanced('(',')') < 0) Exit(EXIT_FAILURE);
Clear(scanner_ccode);
}
/* Uniform initialization in C++11.
@@ -7265,7 +7266,7 @@
};
*/
| idcolon LBRACE {
- skip_balanced('{','}');
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
Clear(scanner_ccode);
}
;
@@ -7416,7 +7417,7 @@
$$ = $1;
}
| LBRACE {
- skip_balanced('{','}');
+ if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
$$ = NewString(scanner_ccode);
}
| HBLOCK {