diff --git a/driver/main.c b/driver/main.c index fbd8de4df..8d26cf1b2 100644 --- a/driver/main.c +++ b/driver/main.c @@ -263,6 +263,7 @@ static const char*my_tempfile(const char*str, FILE**fout) static int t_version_only(void) { remove(source_path); + free(source_path); fflush(0); snprintf(tmp, sizeof tmp, "%s%civlpp -V", pbase, sep); @@ -275,8 +276,11 @@ static int t_version_only(void) if ( ! getenv("IVERILOG_ICONFIG")) { remove(iconfig_path); + free(iconfig_path); remove(defines_path); + free(defines_path); remove(compiled_defines_path); + free(compiled_defines_path); } return 0; @@ -314,11 +318,15 @@ static int t_preprocess_only(void) rc = system(cmd); remove(source_path); + free(source_path); if ( ! getenv("IVERILOG_ICONFIG")) { remove(iconfig_path); + free(iconfig_path); remove(defines_path); + free(defines_path); remove(compiled_defines_path); + free(compiled_defines_path); } if (rc != 0) { @@ -332,6 +340,7 @@ static int t_preprocess_only(void) return -1; } + free(cmd); return 0; } @@ -410,9 +419,13 @@ static int t_compile() rc = system(cmd); if ( ! getenv("IVERILOG_ICONFIG")) { remove(source_path); + free(source_path); remove(iconfig_path); + free(iconfig_path); remove(defines_path); + free(defines_path); remove(compiled_defines_path); + free(compiled_defines_path); } #ifdef __MINGW32__ /* MinGW just returns the exit status, so return it! */ free(cmd); diff --git a/ivlpp/globals.h b/ivlpp/globals.h index bd3ab933b..623baa54a 100644 --- a/ivlpp/globals.h +++ b/ivlpp/globals.h @@ -1,7 +1,7 @@ #ifndef __globals_H #define __globals_H /* - * Copyright (c) 1999-2007 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -22,9 +22,11 @@ # include extern void reset_lexor(FILE*out, char*paths[]); +extern void destroy_lexor(); extern void load_precompiled_defines(FILE*src); extern void define_macro(const char*name, const char*value, int keyword, int argc); +extern void free_macros(); extern void dump_precompiled_defines(FILE*out); /* These variables contain the include directories to be searched when diff --git a/ivlpp/lexor.lex b/ivlpp/lexor.lex index a25e4dc5a..d0a086e2e 100644 --- a/ivlpp/lexor.lex +++ b/ivlpp/lexor.lex @@ -78,6 +78,9 @@ struct include_stack_t YY_BUFFER_STATE yybs; struct include_stack_t* next; + + /* A single line comment can be associated with this include. */ + char* comment; }; static void emit_pathline(struct include_stack_t* isp); @@ -295,9 +298,10 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif) /* Catch single-line comments that share the line with an include * directive. And while I'm at it, I might as well preserve the - * comment in the output stream. + * comment in the output stream. This will be printed after the + * file has been included. */ -"//"[^\r\n]* { ECHO; } +"//"[^\r\n]* { standby->comment = strdup(yytext); } /* These finish the include directive (EOF or EOL) so I revert the * lexor state and execute the inclusion. @@ -829,6 +833,21 @@ void define_macro(const char* name, const char* value, int keyword, int argc) } } +static void free_macro(struct define_t* def) +{ + if (def == 0) return; + free_macro(def->left); + free_macro(def->right); + free(def->name); + free(def->value); + free(def); +} + +void free_macros() +{ + free_macro(def_table); +} + /* * The do_define function accumulates the defined value in these * variables. When the define is over, the def_finish() function @@ -1418,6 +1437,7 @@ static void include_filename() standby->path = strdup(yytext+1); standby->path[strlen(standby->path)-1] = 0; standby->lineno = 0; + standby->comment = NULL; } static void do_include() @@ -1457,6 +1477,8 @@ static void do_include() if ((standby->file = fopen(path, "r"))) { + /* Free the original path before we overwrite it. */ + free(standby->path); standby->path = strdup(path); goto code_that_switches_buffers; } @@ -1468,6 +1490,9 @@ static void do_include() code_that_switches_buffers: + /* Clear the current files path from the search list. */ + include_dir[0] = 0; + if(depend_file) fprintf(depend_file, "%s\n", standby->path); @@ -1530,6 +1555,17 @@ static int load_next_input() /* Delete the current input buffers, and free the cell. */ yy_delete_buffer(YY_CURRENT_BUFFER); + /* If there was a comment for this include print it before we + * return to the previous input stream. This technically belongs + * to the previous stream, but it should not create any problems + * since it is only a comment. + */ + if (isp->comment) { + fprintf(yyout, "%s\n", isp->comment); + free(isp->comment); + isp->comment = NULL; + } + if (isp->file) { free(isp->path); @@ -1726,6 +1762,7 @@ void reset_lexor(FILE* out, char* paths[]) isp->ebs = 0; isp->lineno = 0; isp->stringify_flag = 0; + isp->comment = NULL; if (isp->file == 0) { @@ -1756,6 +1793,7 @@ void reset_lexor(FILE* out, char* paths[]) isp->next = 0; isp->lineno = 0; isp->stringify_flag = 0; + isp->comment = NULL; if (tail) tail->next = isp; @@ -1765,3 +1803,17 @@ void reset_lexor(FILE* out, char* paths[]) tail = isp; } } + +/* + * Modern version of flex (>=2.5.9) can clean up the scanner data. + */ +void destroy_lexor() +{ +# ifdef FLEX_SCANNER +# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5 +# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9 + yylex_destroy(); +# endif +# endif +# endif +} diff --git a/ivlpp/main.c b/ivlpp/main.c index cdf4e4297..a8d761ebc 100644 --- a/ivlpp/main.c +++ b/ivlpp/main.c @@ -189,12 +189,14 @@ static int flist_read_names(const char*path) add_source_file(cp); } + fclose(fd); return 0; } int main(int argc, char*argv[]) { int opt, idx; + unsigned lp; const char*flist_path = 0; unsigned flag_errors = 0; char*out_path = 0; @@ -368,6 +370,7 @@ int main(int argc, char*argv[]) start scanning. */ reset_lexor(out, source_list); if (yylex()) return -1; + destroy_lexor(); if(depend_file) { fclose(depend_file); @@ -378,5 +381,17 @@ int main(int argc, char*argv[]) fclose(precomp_out); } + /* Free the source and include directory lists. */ + for (lp = 0; lp < source_cnt; lp += 1) { + free(source_list[lp]); + } + free(source_list); + for (lp = 0; lp < include_cnt; lp += 1) { + free(include_dir[lp]); + } + free(include_dir); + + free_macros(); + return error_count; }