--- a/stage1_2/iec_bison.yy Sat Dec 01 11:27:48 2012 +0000
+++ b/stage1_2/iec_bison.yy Sat Dec 01 11:30:16 2012 +0000
@@ -8265,8 +8265,9 @@
fprintf (stderr, "Out of memory. Bailing out!\n");
return -1;
}
-
- if(parse_file(libfilename) < 0) {
+
+ FILE *libfile = NULL;
+ if((libfile = parse_file(libfilename)) == NULL) {
char *errmsg = strdup2("Error opening library file ", libfilename);
perror(errmsg);
free(errmsg);
@@ -8279,7 +8280,8 @@
full_token_loc = full_token_loc_;
if (yyparse() != 0)
ERROR;
-
+ fclose(libfile);
+
if (yynerrs > 0) {
fprintf (stderr, "\n%d error(s) found in %s. Bailing out!\n", yynerrs /* global variable */, libfilename);
ERROR;
@@ -8299,8 +8301,8 @@
#if YYDEBUG
yydebug = 1;
#endif
-
- if(parse_file(filename) < 0) {
+ FILE *mainfile = NULL;
+ if ((mainfile = parse_file(filename)) == NULL) {
char *errmsg = strdup2("Error opening main file ", filename);
perror(errmsg);
free(errmsg);
@@ -8315,7 +8317,8 @@
fprintf (stderr, "\nParsing failed because of too many consecutive syntax errors. Bailing out!\n");
exit(EXIT_FAILURE);
}
-
+ fclose(mainfile);
+
if (yynerrs > 0) {
fprintf (stderr, "\n%d error(s) found. Bailing out!\n", yynerrs /* global variable */);
exit(EXIT_FAILURE);
--- a/stage1_2/iec_flex.ll Sat Dec 01 11:27:48 2012 +0000
+++ b/stage1_2/iec_flex.ll Sat Dec 01 11:30:16 2012 +0000
@@ -884,17 +884,28 @@
}
-<<EOF>> { /* NOTE: We must not change the value of include_stack_ptr
- * just yet. We must only decrement it if we are NOT
- * at the end of the main file.
- * If we have finished parsing the main file, then we
- * must leave include_stack_ptr at 0, in case the
- * parser is called once again with a new file.
- * (In fact, we currently do just that!)
+<<EOF>> { /* NOTE: Currently bison is incorrectly using END_OF_INPUT in many rules
+ * when checking for syntax errors in the input source code.
+ * This means that in reality flex will be asked to carry on reading the input
+ * even after it has reached the end of all (including the main) input files.
+ * In other owrds, we will be called to return more tokens, even after we have
+ * already returned an END_OF_INPUT token. In this case, we must carry on returning
+ * more END_OF_INPUT tokens.
+ *
+ * However, in the above case we will be asked to carry on reading more tokens
+ * from the main input file, after we have reached the end. For this to work
+ * correctly, we cannot close the main input file!
+ *
+ * This is why we WILL be called with include_stack_ptr == 0 multiple times,
+ * and why we must handle it as a special case
+ * that leaves the include_stack_ptr unchanged, and returns END_OF_INPUT once again.
+ *
+ * As a corollory, flex can never safely close the main input file, and we must ask
+ * bison to close it!
*/
- fclose(yyin);
- free(current_tracking);
if (include_stack_ptr == 0) {
+ // fclose(yyin); // Must not do this!!
+ // free(current_tracking); // Must not do this!!
/* yyterminate() terminates the scanner and returns a 0 to the
* scanner's caller, indicating "all done".
*
@@ -905,6 +916,8 @@
*/
yyterminate();
} else {
+ fclose(yyin);
+ free(current_tracking);
--include_stack_ptr;
yy_delete_buffer(YY_CURRENT_BUFFER);
yy_switch_to_buffer((include_stack[include_stack_ptr]).buffer_state);
@@ -1864,18 +1877,18 @@
/* Tell flex which file to parse. This function will not imediately start parsing the file.
* To parse the file, you then need to call yyparse()
*
- * Returns -1 on error opening the file (and a valid errno), or 0 on success.
- */
-int parse_file(const char *filename) {
+ * Returns NULL on error opening the file (and a valid errno), or 0 on success.
+ * Caller must close the file!
+ */
+FILE *parse_file(const char *filename) {
FILE *filehandle = NULL;
- if((filehandle = fopen(filename, "r")) == NULL)
- return -1;
-
- yyin = filehandle;
- current_filename = strdup(filename);
- current_tracking = GetNewTracking(yyin);
- return 0;
+ if((filehandle = fopen(filename, "r")) != NULL) {
+ yyin = filehandle;
+ current_filename = strdup(filename);
+ current_tracking = GetNewTracking(yyin);
+ }
+ return filehandle;
}
--- a/stage1_2/stage1_2_priv.hh Sat Dec 01 11:27:48 2012 +0000
+++ b/stage1_2/stage1_2_priv.hh Sat Dec 01 11:30:16 2012 +0000
@@ -126,10 +126,10 @@
/* Tell flex which file to parse. This function will not imediately start parsing the file.
* To parse the file, you then need to call yyparse()
*
- * Returns -1 on error opening the file (and a valid errno), or 0 on success.
- */
-int parse_file(const char *filename);
-
+ * Returns NULL on error opening the file (and a valid errno), or 0 on success.
+ * Caller must close the file!
+ */
+FILE *parse_file(const char *filename);