greatly improve memory usage - fixes #634

Thu, 10 Apr 2025 21:29:56 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 10 Apr 2025 21:29:56 +0200
changeset 82
44b3332dfe03
parent 81
54515e5d60f5
child 83
5c9e268aa6d8

greatly improve memory usage - fixes #634

src/cline.c file | annotate | diff | comparison | revisions
src/scanner.c file | annotate | diff | comparison | revisions
src/scanner.h file | annotate | diff | comparison | revisions
src/string_list.c file | annotate | diff | comparison | revisions
--- a/src/cline.c	Wed Apr 09 21:47:07 2025 +0200
+++ b/src/cline.c	Thu Apr 10 21:29:56 2025 +0200
@@ -261,77 +261,78 @@
   parseCSL(includeSuffix, settings->includeSuffixes);
   parseCSL(excludeSuffix, settings->excludeSuffixes);
 
+  /* Compiler regular expressions, if any specified */
+  if (!regex_compile_all(settings->regex)) {
+    return 1;
+  }
+
   /* Scan directories */
-  if (regex_compile_all(settings->regex)) {
-    scanresult_t* result = new_scanresult_t(settings);
+  scanresult_t* result = new_scanresult_t(settings);
+  const char* result_type = settings->count_chars ? "chars" : "lines";
+  bool has_output = false;
+  unsigned total = 0;
+  if (directories->count == 0) {
+      add_string(directories, "./");
+  }
+  for (unsigned t = 0 ; t < directories->count ; t++) {
     /* Don't waste memory when only the total sum is needed */
     string_list_t *output = settings->verbose ? new_string_list_t() : NULL;
-    char *outbuf;
-    const char* result_type = settings->count_chars ? "chars" : "lines";
-    
-    unsigned total = 0;
-    if (directories->count == 0) {
-        add_string(directories, "./");
-    }
-    for (unsigned t = 0 ; t < directories->count ; t++) {
-      scanDirectory((scanner_t){directories->items[t], 0}, settings,
-          output, result);
-      total += result->result;
-      if (directories->count > 1) {
-        add_string(output, strdup(sepline_single));
-        outbuf = (char*) malloc(81);
-        snprintf(outbuf, 81, "%-63s%10u %s\n", directories->items[t],
-                result->result, result_type);
-        add_string(output, outbuf);
-        add_string(output, strdup(sepline_single));
-      }
-    }
-    destroy_string_list_t(directories);
-
-    /* Print result */
-    if (output != NULL) {
+    scanDirectory((scanner_t){directories->items[t], 0}, settings, output, result);
+    total += result->result;
+    if (settings->verbose) {
+      has_output |= output->count > 0;
       for (int i = 0 ; i < output->count ; i++) {
         printf("%s", output->items[i]);
         free(output->items[i]);
       }
-      
-      if (result->ext) {
-        if (result->ext->count > 0) {
-          fwrite(sepline_double, 1, 80, stdout);
-          printf("\nIndividual sums:\n");
-          for (unsigned t = 0 ; t < result->ext->count ; t++) {
-            printf(" %-62s%10u %s\n",
-                   result->ext->extensions[t],
-                   result->ext->result[t],
-                   result_type);
-          }
+      destroy_string_list_t(output);
+      if (directories->count > 1) {
+        has_output = true;
+        fputs(sepline_single, stdout);
+        printf("%-63s%10u %s\n", directories->items[t],
+          result->result, result_type);
+        fputs(sepline_single, stdout);
+      }
+    }
+  }
+  destroy_string_list_t(directories);
+
+  /* Print result */
+  if (settings->verbose) {
+    if (result->ext) {
+      if (result->ext->count > 0) {
+        has_output = true;
+        fwrite(sepline_double, 1, 80, stdout);
+        printf("\nIndividual sums:\n");
+        for (unsigned t = 0 ; t < result->ext->count ; t++) {
+          printf(" %-62s%10u %s\n",
+                 result->ext->extensions[t],
+                 result->ext->result[t],
+                 result_type);
         }
       }
+    }
 
-      if (output->count > 0) {
-        fwrite(sepline_double, 1, 80, stdout);
-        printf("%73d %s\n", total, result_type);
-      } else {
-        /* If we only need to output a total, output it differently */
-        printf("%d %s\n", total, result_type);
-      }
-
-      if (settings->confusing_lnlen &&
-          settings->regex->pattern_list->count > 0) {
+    if (has_output) {
+      fwrite(sepline_double, 1, 80, stdout);
+      printf("%73d %s\n", total, result_type);
+    } else {
+      /* If there was not any output so far, skip formatting */
+      printf("%d %s\n", total, result_type);
+    }
 
-        printf("\nSome files contain too long lines.\n"
-          "The parser currently supports a maximum line length of %u."
-          "\nThe result might be wrong.\n", MAX_LINELENGTH);
-      }
-    } else {
-      printf("%u", total);
+    if (settings->confusing_lnlen &&
+        settings->regex->pattern_list->count > 0) {
+
+      printf("\nSome files contain too long lines.\n"
+        "The parser currently supports a maximum line length of %u."
+        "\nThe result might be wrong.\n", MAX_LINELENGTH);
     }
-    destroy_scanresult_t(result);
-    destroy_string_list_t(output);
-    destroy_settings_t(settings);
+  } else {
+    printf("%u", total);
   }
+  destroy_scanresult_t(result);
+  destroy_settings_t(settings);
 
-  fflush(stdout);
-  fflush(stderr);
   return 0;
 }
--- a/src/scanner.c	Wed Apr 09 21:47:07 2025 +0200
+++ b/src/scanner.c	Thu Apr 10 21:29:56 2025 +0200
@@ -201,14 +201,14 @@
     if (!S_ISREG(filelist->st_mode)) {
       if (S_ISDIR(filelist->st_mode)) {
         if (settings->recursive) {
-          string_list_t *recoutput = new_string_list_t();
+          string_list_t *recoutput = settings->verbose ? new_string_list_t() : NULL;
           scanresult_t recresult;
           recresult.ext = result->ext;
           scanDirectory(
               (scanner_t) {filelist->filename, scanner.spaces+1},
               settings, recoutput, &recresult);
           result->result += recresult.result;
-          if (!settings->matchesOnly || recresult.result > 0) {
+          if (settings->verbose && (!settings->matchesOnly || recresult.result > 0)) {
             outbuf = (char*) malloc(81);
             snprintf(outbuf, 81, "%*s/%*s%13u %s\n",
                 filelist->displayname_len+scanner.spaces, filelist->displayname,
@@ -221,7 +221,7 @@
           }
           destroy_string_list_t(recoutput);
         }
-      } else if (!settings->matchesOnly) {
+      } else if (!settings->matchesOnly && settings->verbose) {
         outbuf = (char*) malloc(81);
         snprintf(outbuf, 81, "%*s\n",
                  filelist->displayname_len+scanner.spaces,
@@ -243,11 +243,7 @@
 
         FILE *file = fopen(filelist->filename, "r");
         if (file == NULL) {
-          outbuf = (char*) malloc(81);
-          snprintf(outbuf, 81, "%*s",
-                   filelist->displayname_len+scanner.spaces,
-                   filelist->displayname);
-          add_string(output, outbuf);
+          fprintf(stderr, "Error: %s", filelist->displayname);
           perror("  File acces failed");
         } else {
           int a;
@@ -290,7 +286,7 @@
 
           /* Print and sum line count */
           if (bfile) {
-            if (!settings->matchesOnly && !settings->dirsOnly) {
+            if (!settings->matchesOnly && !settings->dirsOnly && settings->verbose) {
               outbuf = (char*) malloc(81);
               snprintf(outbuf, 81,
                   "%*s%*s%19s\n", filelist->displayname_len+scanner.spaces,
@@ -301,7 +297,7 @@
           } else {
             addResultPerExtension(result->ext, filelist->ext, res_value);
             result->result += res_value;
-            if (!settings->dirsOnly) {
+            if (!settings->dirsOnly && settings->verbose) {
               outbuf = (char*) malloc(81);
               snprintf(outbuf, 81, "%*s%*s%13u %s\n",
                        filelist->displayname_len+scanner.spaces,
@@ -316,7 +312,7 @@
           }
         }
       } else {
-        if (!settings->matchesOnly && !settings->dirsOnly) {
+        if (!settings->matchesOnly && !settings->dirsOnly && settings->verbose) {
           /* Print hint */
           outbuf = (char*) malloc(81);
           snprintf(outbuf, 81, "%*s%*s%19s\n",
--- a/src/scanner.h	Wed Apr 09 21:47:07 2025 +0200
+++ b/src/scanner.h	Thu Apr 10 21:29:56 2025 +0200
@@ -27,7 +27,6 @@
 #ifndef SCANNER_H_
 #define SCANNER_H_
 
-#include "stdinc.h"
 #include "settings.h"
 #include "string_list.h"
 
--- a/src/string_list.c	Wed Apr 09 21:47:07 2025 +0200
+++ b/src/string_list.c	Thu Apr 10 21:29:56 2025 +0200
@@ -46,24 +46,18 @@
   }
 }
 
-/* Adds an item to the list, if a NULL-list is specified, the item will
- * be freed. This way a NULL-list can be used as garbage bin.
- */
 void add_string(string_list_t* list, char* item) {
-  if (list) {
-    if (list->count < list->capacity) {
-      list->items[list->count++] = item;
-      return;
-    }
-    size_t newCapacity = list->capacity * 2;
-    char** reallocated_list =
-      realloc(list->items, sizeof(char*) * newCapacity);
-    assert(reallocated_list != NULL);
-    list->capacity = newCapacity;
-    list->items = reallocated_list;
+  assert(list != NULL);
+  if (list->count < list->capacity) {
     list->items[list->count++] = item;
-  } else {
-    free(item);
+    return;
   }
+  size_t newCapacity = list->capacity * 2;
+  char** reallocated_list =
+    realloc(list->items, sizeof(char*) * newCapacity);
+  assert(reallocated_list != NULL);
+  list->capacity = newCapacity;
+  list->items = reallocated_list;
+  list->items[list->count++] = item;
 }
 

mercurial