static struct cdecl *do_parse(const char *str, int english_mode)
{
+ struct cdecl *decl = NULL;
YY_BUFFER_STATE state;
yyscan_t scanner;
- struct cdecl *decl;
#if YYDEBUG
extern int cdecl__yydebug;
return NULL;
state = cdecl__yy_scan_string(str, scanner);
- if (cdecl__yyparse(scanner, &decl) != 0)
+ if (cdecl__yyparse(scanner, &decl) != 0) {
+ /*
+ * If the input consists of a complete, valid declaration
+ * followed by some garbage, that parsed declaration will
+ * be output by the parser and we need to free it here.
+ */
+ cdecl__free(decl);
decl = NULL;
+ }
cdecl__yy_delete_buffer(state, scanner);
cdecl__yylex_destroy(scanner);
AT_SETUP([cdecl99 interactive mode])
AT_DATA([test.dat],
-[[explain int x;
+[[explain int () int
+explain int x;
quit
]])
-AT_CHECK([cdecl99 --quiet --interactive <test.dat], [0], [stdout])
+AT_CHECK([cdecl99 --quiet --interactive <test.dat], [0], [stdout], [ignore])
# If built with readline support, then the input commands (including their
# trailing newlines) will be captured by AT_CHECK. Otherwise, they are not:
# the output just directly follows the prompt, and the final prompt will
# not end with a newline. Attempt to paper over these differences.
-AT_CHECK([echo >>stdout; sed '/> [[eq]]/d; s/^> //; /^$/d' stdout], [0],
+AT_DATA([check.sed],
+[[/> [eq]/d
+:loop
+s/^> //
+t loop
+/^$/d
+]])
+
+AT_CHECK([echo >>stdout; sed -f check.sed stdout], [0],
[declare x as int
])