diff options
author | William S Fulton <wsf@fultondesigns.co.uk> | 2019-07-29 19:03:30 +0100 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2019-07-31 00:08:49 +0100 |
commit | b36ae64185cc6d293d9350126f51ab23c0c7e36a (patch) | |
tree | 2d187f1cc327650ab0cdf97e042bcd99611dc820 | |
parent | f69da524f071a754744636dcadfba275d1b00d02 (diff) | |
download | swig-b36ae64185cc6d293d9350126f51ab23c0c7e36a.tar.gz |
Remove all generated files on error.
Previously generated files were not removed,
potentially breaking Makefiles using file dependencies, especially when
-Werror (warnings as errors) was used.
-rw-r--r-- | CHANGES.current | 5 | ||||
-rw-r--r-- | Source/DOH/doh.h | 4 | ||||
-rw-r--r-- | Source/DOH/file.c | 75 | ||||
-rw-r--r-- | Source/Modules/main.cxx | 21 |
4 files changed, 101 insertions, 4 deletions
diff --git a/CHANGES.current b/CHANGES.current index 3b9634726..b7d7fa3df 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,11 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.0.1 (in progress) =========================== +2019-07-29: wsfulton + Remove all generated files on error. Previously generated files were not removed, + potentially breaking Makefiles using file dependencies, especially when -Werror + (warnings as errors) was used. + 2019-07-23: smithx [C#] #1530 #1532 Fix marshalling of std::wstring to C#. diff --git a/Source/DOH/doh.h b/Source/DOH/doh.h index 7cc279ebc..7fb64c058 100644 --- a/Source/DOH/doh.h +++ b/Source/DOH/doh.h @@ -302,11 +302,12 @@ extern char *DohStrchr(const DOHString_or_char *s1, int ch); * Files * ----------------------------------------------------------------------------- */ -extern DOHFile *DohNewFile(DOH *filename, const char *mode, DOHList *outfiles); +extern DOHFile *DohNewFile(DOHString *filename, const char *mode, DOHList *outfiles); extern DOHFile *DohNewFileFromFile(FILE *f); extern DOHFile *DohNewFileFromFd(int fd); extern void DohFileErrorDisplay(DOHString * filename); extern int DohCopyto(DOHFile * input, DOHFile * output); +extern void DohCloseAllOpenFiles(void); /* ----------------------------------------------------------------------------- @@ -425,6 +426,7 @@ extern void DohMemoryDebug(void); #define Strstr DohStrstr #define Strchr DohStrchr #define Copyto DohCopyto +#define CloseAllOpenFiles DohCloseAllOpenFiles #define Split DohSplit #define SplitLines DohSplitLines #define Setmark DohSetmark diff --git a/Source/DOH/file.c b/Source/DOH/file.c index 9fb661a36..570f84ed5 100644 --- a/Source/DOH/file.c +++ b/Source/DOH/file.c @@ -26,6 +26,73 @@ typedef struct { } DohFile; /* ----------------------------------------------------------------------------- + * open_files_list_instance + * open_files_list_add + * open_files_list_remove + * + * Singleton list containing all the files that have been opened by DohNewFile. + * Open file pointers are held in the list as strings so as to not affect the + * reference count of the underlying DOH objects. + * ----------------------------------------------------------------------------- */ + +static DOHList *open_files_list_instance() { + static DOHList *all_open_files = 0; + if (!all_open_files) + all_open_files = DohNewList(); + return all_open_files; +} + +static void open_files_list_add(DohFile *f) { + DOHList *all_open_files = open_files_list_instance(); + DOHString *sf = NewStringf("%p", f); + Append(all_open_files, sf); + Delete(sf); +} + +static void open_files_list_remove(DohFile *f) { + int i; + int removed = 0; + DOHList *all_open_files = open_files_list_instance(); + DOHString *sf = NewStringf("%p", f); + for (i = 0; i < DohLen(all_open_files); i++) { + DOHString *sf_i = Getitem(all_open_files, i); + if (Strcmp(sf, sf_i) == 0) { + DohDelitem(all_open_files, i); + removed = 1; + break; + } + } + Delete(sf); + assert(removed); +} + +/* ----------------------------------------------------------------------------- + * DohCloseAllOpenFiles() + * + * Close all opened files, to be called on program termination + * ----------------------------------------------------------------------------- */ + +void DohCloseAllOpenFiles() { + int i; + DOHList *all_open_files = open_files_list_instance(); + for (i = 0; i < DohLen(all_open_files); i++) { + DohFile *f = 0; + DOHString *sf = Getitem(all_open_files, i); + int check = sscanf(Char(sf), "%p", (void **)&f); + assert(check == 1); + if (f->closeondel) { + if (f->filep) { + check = fclose(f->filep); + assert(check == 0); + } + f->closeondel = 0; + f->filep = 0; + } + } + DohClear(all_open_files); +} + +/* ----------------------------------------------------------------------------- * DelFile() * ----------------------------------------------------------------------------- */ @@ -40,6 +107,7 @@ static void DelFile(DOH *fo) { close(f->fd); } #endif + open_files_list_remove(f); } DohFree(f); } @@ -209,8 +277,9 @@ static DohObjInfo DohFileType = { * If newfiles is non-zero, the filename is added to the list of new files. * ----------------------------------------------------------------------------- */ -DOH *DohNewFile(DOH *filename, const char *mode, DOHList *newfiles) { +DOH *DohNewFile(DOHString *filename, const char *mode, DOHList *newfiles) { DohFile *f; + DOH *obj; FILE *file; char *filen; @@ -229,7 +298,9 @@ DOH *DohNewFile(DOH *filename, const char *mode, DOHList *newfiles) { f->filep = file; f->fd = 0; f->closeondel = 1; - return DohObjMalloc(&DohFileType, f); + obj = DohObjMalloc(&DohFileType, f); + open_files_list_add(f); + return obj; } /* ----------------------------------------------------------------------------- diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index 294455772..72b765b40 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -23,6 +23,7 @@ #include "swigwarn.h" #include "cparse.h" #include <ctype.h> +#include <errno.h> #include <limits.h> // for INT_MAX // Global variables @@ -1381,7 +1382,10 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { int error_count = werror ? Swig_warn_count() : 0; error_count += Swig_error_count(); - return error_count; + if (error_count != 0) + SWIG_exit(error_count); + + return 0; } /* ----------------------------------------------------------------------------- @@ -1393,5 +1397,20 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { void SWIG_exit(int exit_code) { while (freeze) { } + + if (exit_code > 0) { + CloseAllOpenFiles(); + + /* Remove all generated files */ + if (all_output_files) { + for (int i = 0; i < Len(all_output_files); i++) { + String *filename = Getitem(all_output_files, i); + int removed = remove(Char(filename)); + if (removed == -1) + fprintf(stderr, "On exit, could not delete file %s: %s\n", Char(filename), strerror(errno)); + } + } + } + exit(exit_code); } |