diff -r 7b90dd17f0ba -r 634f476cb60f stage1_2/iec_flex.ll --- a/stage1_2/iec_flex.ll Mon Nov 26 16:38:15 2012 +0000 +++ b/stage1_2/iec_flex.ll Tue Nov 27 14:49:08 2012 +0000 @@ -247,6 +247,8 @@ * but first return to the stream an additional character to mark the end of the token. */ void unput_and_mark(const char c); + +void include_file(const char *include_filename); %} @@ -867,38 +869,8 @@ {file_include_pragma_beg} BEGIN(include_filename); {file_include_pragma_filename} { - /* got the include file name */ - int i; - - if (include_stack_ptr >= MAX_INCLUDE_DEPTH) { - fprintf(stderr, "Includes nested too deeply\n"); - exit( 1 ); - } - include_stack[include_stack_ptr].buffer_state = YY_CURRENT_BUFFER; - include_stack[include_stack_ptr].env = current_tracking; - include_stack[include_stack_ptr].filename = current_filename; - - for (i = 0, yyin = NULL; (INCLUDE_DIRECTORIES[i] != NULL) && (yyin == NULL); i++) { - char *full_name = strdup3(INCLUDE_DIRECTORIES[i], "/", yytext); - if (full_name == NULL) { - fprintf(stderr, "Out of memory!\n"); - exit( 1 ); - } - yyin = fopen(full_name, "r"); - free(full_name); - } - - if (!yyin) { - fprintf(stderr, "Error opening included file %s\n", yytext); - exit( 1 ); - } - - current_filename = strdup(yytext); - current_tracking = GetNewTracking(yyin); - include_stack_ptr++; - - /* switch input buffer to new file... */ - yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + /* set the internal state variables of lexical analyser to process a new include file */ + include_file(yytext); /* switch to whatever state was active before the include file */ yy_pop_state(); /* now process the new file... */ @@ -947,6 +919,8 @@ } {file_include_pragma_end} yy_pop_state(); + /* handle the artificial file includes created by include_string(), which do not end with a '}' */ +. unput_text(0); yy_pop_state(); /*********************************/ @@ -1690,6 +1664,79 @@ } + +/* set the internal state variables of lexical analyser to process a new include file */ +void handle_include_file_(FILE *filehandle, const char *filename) { + if (include_stack_ptr >= MAX_INCLUDE_DEPTH) { + fprintf(stderr, "Includes nested too deeply\n"); + exit( 1 ); + } + + yyin = filehandle; + + include_stack[include_stack_ptr].buffer_state = YY_CURRENT_BUFFER; + include_stack[include_stack_ptr].env = current_tracking; + include_stack[include_stack_ptr].filename = current_filename; + + current_filename = strdup(filename); + current_tracking = GetNewTracking(yyin); + include_stack_ptr++; + + /* switch input buffer to new file... */ + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); +} + + + +/* insert the code (in ) into the source code we are parsing. + * This is done by creating an artificial file with that new source code, and then 'including' the file + */ +void include_string(const char *source_code) { + FILE *tmp_file = tmpfile(); + + if(tmp_file == NULL) { + perror("Error creating temp file."); + exit(EXIT_FAILURE); + } + + fwrite((void *)source_code, 1, strlen(source_code), tmp_file); + rewind(tmp_file); + + /* now parse the tmp file, by asking flex to handle it as if it had been included with the (*#include ... *) pragma... */ + handle_include_file_(tmp_file, ""); +//fclose(tmp_file); /* do NOT close file. It must only be closed when we finish reading from it! */ +} + + + +/* Open an include file, and set the internal state variables of lexical analyser to process a new include file */ +void include_file(const char *filename) { + FILE *filehandle = NULL; + + for (int i = 0; (INCLUDE_DIRECTORIES[i] != NULL) && (filehandle == NULL); i++) { + char *full_name; + full_name = strdup3(INCLUDE_DIRECTORIES[i], "/", filename); + if (full_name == NULL) { + fprintf(stderr, "Out of memory!\n"); + exit( 1 ); + } + filehandle = fopen(full_name, "r"); + free(full_name); + } + + if (NULL == filehandle) { + fprintf(stderr, "Error opening included file %s\n", filename); + exit( 1 ); + } + + /* now process the new file... */ + handle_include_file_(filehandle, filename); +} + + + + + /* return all the text in the current token back to the input stream, except the first n chars. */ void unput_text(unsigned int n) { /* it seems that flex has a bug in that it will not correctly count the line numbers