Track temp files and remove them on close
authorRobert Pengelly <robertapengelly@hotmail.com>
Tue, 26 May 2026 18:46:16 +0000 (19:46 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Tue, 26 May 2026 18:46:16 +0000 (19:46 +0100)
lib.c
lib.h
parse.c

diff --git a/lib.c b/lib.c
index 2b7b1258329f1656937bc6bcc578b4780ee5a181..c7051ac577570dbdbb52dd7d50203b28fa65b669 100755 (executable)
--- a/lib.c
+++ b/lib.c
@@ -627,7 +627,7 @@ int is_pragma_igored (const char *filename) {
 
 }
 
-FILE *open_scc_temp_file (char *name, size_t name_size) {
+FILE *scc_tmpfile (void) {
 
     char *temp_path, *template;
     int fd;
@@ -639,26 +639,27 @@ FILE *open_scc_temp_file (char *name, size_t name_size) {
     template = xmalloc (strlen (temp_path) + 1 + 10 + 1);
     sprintf (template, "%s/sccXXXXXX", temp_path);
     
-    if (!(fd = mkstemp (template))) {
+    if ((fd = mkstemp (template)) < 0) {
         return 0;
     }
     
-    (void) name;
-    (void) name_size;
-    
     return fdopen (fd, "w+b");
 
 }
 
-FILE *scc_tmpfile (void) {
-
-    char name[64];
-    return open_scc_temp_file (name, sizeof (name));
-
+int scc_close (FILE *fp) {
+    return fclose (fp);
 }
+
 #elif       defined (_WIN32)
 # include       <windows.h>
 
+# ifndef    MAX_PATH
+#  define       MAX_PATH                206
+# endif
+
+# include       "hashtab.h"
+
 struct pragma_entry {
 
     DWORD    dwVolumeSerialNumber;
@@ -738,11 +739,26 @@ int is_pragma_igored (const char *filename) {
 
 }
 
-FILE *open_scc_temp_file (char *name, size_t name_size) {
+struct temp_file {
+
+    char *name, *path;
+    FILE *fp;
+
+};
+
+static struct hashtab hashtab_tmpfiles = { 0 };
+
+FILE *scc_tmpfile (void) {
 
     char temp_path[MAX_PATH + 1] = { 0 };
     char full_path[MAX_PATH + 1] = { 0 };
     
+    struct hashtab_name *key;
+    struct temp_file *tmp;
+    
+    char *name;
+    FILE *fp;
+    
     if (!GetTempPath (MAX_PATH + 1, temp_path)) {
         return 0;
     }
@@ -751,20 +767,91 @@ FILE *open_scc_temp_file (char *name, size_t name_size) {
         return 0;
     }
     
-    (void) name;
-    (void) name_size;
+    if ((name = strrchr (full_path, '\\'))) {
+        name++;
+    } else {
+        name = full_path;
+    }
     
-    return fopen (full_path, "w+b");
+    if ((fp = fopen (full_path, "w+b"))) {
+        
+        if (!(key = hashtab_get_key (&hashtab_tmpfiles, name))) {
+        
+            if (!((key = hashtab_alloc_name (xstrdup (name))))) {
+            
+                remove (full_path);
+                fclose (fp);
+                
+                return 0;
+            
+            }
+        
+        }
+        
+        tmp = xmalloc (sizeof (*tmp));
+        tmp->fp = fp;
+        
+        tmp->path = xstrdup (full_path);
+        tmp->name = xstrdup (name);
+        
+        hashtab_put (&hashtab_tmpfiles, key, tmp);
+        return fp;
+    
+    }
+    
+    return 0;
 
 }
 
-FILE *scc_tmpfile (void) {
+int scc_close (FILE *fp) {
 
-    char name[64];
-    return open_scc_temp_file (name, sizeof (name));
+    struct hashtab_entry *entry;
+    struct temp_file *tmp;
+    
+    int ret, i;
+    
+    for (i = 0; i < hashtab_tmpfiles.capacity; i++) {
+    
+        if (!(entry = &hashtab_tmpfiles.entries[i])) {
+            continue;
+        }
+        
+        if (!entry->key || !entry->value) {
+            continue;
+        }
+        
+        tmp = (struct temp_file *) entry->value;
+        
+        if (tmp->fp == fp) {
+        
+            if ((ret = fclose (fp))) {
+                return ret;
+            }
+            
+            remove (tmp->path);
+            
+            hashtab_remove (&hashtab_tmpfiles, hashtab_get_key (&hashtab_tmpfiles, tmp->name));
+            return 0;
+        
+        }
+    
+    }
+    
+    return 0;
 
 }
 #else
+# include       "hashtab.h"
+
+struct temp_file {
+
+    FILE *fp;
+    char name[1];
+
+};
+
+static struct hashtab hashtab_tmpfiles = { 0 };
+
 char *get_current_directory (void) {
     return xstrdup ("");
 }
@@ -789,16 +876,17 @@ int is_pragma_igored (const char *filename) {
 
 }
 
-FILE *open_scc_temp_file (char *name, size_t name_size) {
+FILE *scc_tmpfile (void) {
 
     static unsigned long temp_id = 1;
+    
+    char name[64];
     unsigned long i;
     
-    FILE *fp;
+    struct hashtab_name *key;
+    struct temp_file *tmp;
     
-    if (!name || name_size == 0) {
-        return 0;
-    }
+    FILE *fp;
     
     for (i = 0; i < 1000; i++) {
     
@@ -811,31 +899,72 @@ FILE *open_scc_temp_file (char *name, size_t name_size) {
         
         }
         
-        fp = fopen (name, "w+b");
+        if ((fp = fopen (name, "w+b"))) {
+            
+            if (!(key = hashtab_get_key (&hashtab_tmpfiles, name))) {
+            
+                if (!((key = hashtab_alloc_name (xstrdup (name))))) {
+                
+                    remove (name);
+                    fclose (fp);
+                    
+                    continue;
+                
+                }
+            
+            }
+            
+            tmp = xmalloc (sizeof (*tmp) + strlen (name) + 1);
+            sprintf (tmp->name, "%s", name);
+            
+            tmp->fp = fp;
         
-        if (fp) {
+            hashtab_put (&hashtab_tmpfiles, key, tmp);
             return fp;
+        
         }
     
     }
     
-    name[0] = 0;
     return 0;
 
 }
 
-FILE *scc_tmpfile (void) {
+int scc_close (FILE *fp) {
 
-    char name[64];
-    FILE *fp;
-
-    fp = open_scc_temp_file (name, sizeof (name));
-
-    if (fp && name[0]) {
-        remove (name);
+    struct hashtab_entry *entry;
+    struct temp_file *tmp;
+    
+    int ret, i;
+    
+    for (i = 0; i < hashtab_tmpfiles.capacity; i++) {
+    
+        if (!(entry = &hashtab_tmpfiles.entries[i])) {
+            continue;
+        }
+        
+        if (!entry->key || !entry->value) {
+            continue;
+        }
+        
+        tmp = (struct temp_file *) entry->value;
+        
+        if (tmp->fp == fp) {
+        
+            if ((ret = fclose (fp))) {
+                return ret;
+            }
+            
+            remove (tmp->name);
+            
+            hashtab_remove (&hashtab_tmpfiles, hashtab_get_key (&hashtab_tmpfiles, tmp->name));
+            return 0;
+        
+        }
+    
     }
-
-    return fp;
+    
+    return 0;
 
 }
 #endif
@@ -874,7 +1003,7 @@ void print_include_stack (void) {
     
     for (i = state->vec_hist.length - 1; i >= 0; i--) {
         
-        entry = state->vec_hist.data[i];
+        entry = (struct hist_entry *) state->vec_hist.data[i];
         printf ("from %s:%lu", entry->filename, entry->line_number);
         
         if (i > 0) {
diff --git a/lib.h b/lib.h
index dab1343ea05790e22524ed01e2ef5b64732f3608..afaf50c9371508a5995a41ad40562d504841b2bb 100755 (executable)
--- a/lib.h
+++ b/lib.h
@@ -49,8 +49,10 @@ void print_include_stack (void);
 char *get_current_directory (void);
 int is_pragma_igored (const char *filename);
 
+#include    <stddef.h>
 #include    <stdio.h>
-FILE *open_scc_temp_file (char *name, size_t name_size);
+
 FILE *scc_tmpfile (void);
+int scc_close (FILE *fp);
 
 #endif      /* _LIB_H */
diff --git a/parse.c b/parse.c
index 9317f5f6b31a20f221f54c0c025f7b3ef28156b2..59633677dc090138eb4927d897701a50cb2ecffb 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -5622,7 +5622,7 @@ static void finish_inline_buffer (FILE **tmp, FILE **saved, int optimize) {
     
     }
     
-    fclose (*tmp);
+    scc_close (*tmp);
     
     *tmp = 0;
     *saved = 0;
@@ -24367,7 +24367,7 @@ static void emit_call_pointer_in_reg_now (const char *fn_reg, const char *result
             
             if (arg_tmp_ofp) {
             
-                fclose (arg_tmp_ofp);
+                scc_close (arg_tmp_ofp);
                 arg_tmp_ofp = 0;
             
             }
@@ -24396,7 +24396,7 @@ static void emit_call_pointer_in_reg_now (const char *fn_reg, const char *result
                     fputc (ch, state->ofp);
                 }
                 
-                fclose (arg_tmp_ofps[i]);
+                scc_close (arg_tmp_ofps[i]);
                 arg_tmp_ofps[i] = 0;
             
             }
@@ -24444,7 +24444,7 @@ static void emit_call_pointer_in_reg_now (const char *fn_reg, const char *result
         for (i = 0; i < argc; i++) {
         
             if (arg_tmp_ofps[i]) {
-                fclose (arg_tmp_ofps[i]);
+                scc_close (arg_tmp_ofps[i]);
             }
         
         }
@@ -24794,7 +24794,7 @@ static void emit_call_identifier_to_reg_now (const char *name, const char *reg,
             
             if (arg_tmp_ofp) {
             
-                fclose (arg_tmp_ofp);
+                scc_close (arg_tmp_ofp);
                 arg_tmp_ofp = 0;
             
             }
@@ -24869,7 +24869,7 @@ static void emit_call_identifier_to_reg_now (const char *name, const char *reg,
             for (i = 0; i < argc; i++) {
             
                 if (arg_tmp_ofps[i]) {
-                    fclose (arg_tmp_ofps[i]);
+                    scc_close (arg_tmp_ofps[i]);
                 }
             
             }
@@ -24913,7 +24913,7 @@ static void emit_call_identifier_to_reg_now (const char *name, const char *reg,
                         fputc (ch, state->ofp);
                     }
                     
-                    fclose (arg_tmp_ofps[i]);
+                    scc_close (arg_tmp_ofps[i]);
                     arg_tmp_ofps[i] = 0;
                 
                 }
@@ -25004,7 +25004,7 @@ static void emit_call_identifier_to_reg_now (const char *name, const char *reg,
         for (i = 0; i < argc; i++) {
         
             if (arg_tmp_ofps[i]) {
-                fclose (arg_tmp_ofps[i]);
+                scc_close (arg_tmp_ofps[i]);
             }
         
         }
@@ -25459,7 +25459,7 @@ static void parse_switch_statement (void) {
     
         body_text = read_tmp_file_text (body_tmp);
         
-        fclose (body_tmp);
+        scc_close (body_tmp);
         body_tmp = 0;
         
         state->ofp = saved_ofp;
@@ -29689,7 +29689,7 @@ static int parse_identifier_assignment_statement (void) {
                             }
                             
                             if (arg_tmp_ofp) {
-                                fclose (arg_tmp_ofp);
+                                scc_close (arg_tmp_ofp);
                             }
                             
                             argc++;
@@ -29717,7 +29717,7 @@ static int parse_identifier_assignment_statement (void) {
                                     fputc (ch, state->ofp);
                                 }
                                 
-                                fclose (arg_tmp_ofps[i]);
+                                scc_close (arg_tmp_ofps[i]);
                                 arg_tmp_ofps[i] = 0;
                             
                             }
@@ -32892,7 +32892,7 @@ static void parse_for_statement (void) {
         if (step_tmp) {
         
             replay_tmp_file_to_output (step_tmp, state->ofp);
-            fclose (step_tmp);
+            scc_close (step_tmp);
             
             step_tmp = 0;
         
@@ -32903,7 +32903,7 @@ static void parse_for_statement (void) {
     }
     
     if (step_tmp) {
-        fclose (step_tmp);
+        scc_close (step_tmp);
     }
     
     emit_statement_label (break_label);
@@ -35628,7 +35628,6 @@ static void parse_function_body (const char *name, int storage_class, int is_inl
     
     char *inline_asm_text = 0;
     char *function_asm_text = 0;
-    char function_tmp_name[64];
     
     int capture_inline_body = 0;
     int capture_function_body = 0;
@@ -35646,7 +35645,6 @@ static void parse_function_body (const char *name, int storage_class, int is_inl
     int old_function_has_return_statement;
     
     char *function_filename_copy = 0;
-    function_tmp_name[0] = 0;
     
     /**
      * Inline definitions are compiled into a temporary assembler buffer so
@@ -35689,7 +35687,7 @@ static void parse_function_body (const char *name, int storage_class, int is_inl
     
     if (capture_function_body) {
     
-        function_tmp = open_scc_temp_file (function_tmp_name, sizeof (function_tmp_name));
+        function_tmp = scc_tmpfile ();
         
         if (!function_tmp) {
             capture_function_body = 0;
@@ -35827,15 +35825,8 @@ static void parse_function_body (const char *name, int storage_class, int is_inl
         
         }
         
-        fclose (function_tmp);
+        scc_close (function_tmp);
         function_tmp = 0;
-        
-        if (function_tmp_name[0]) {
-        
-            remove (function_tmp_name);
-            function_tmp_name[0] = 0;
-        
-        }
     
     }