adds option to compute individual sums

Mon, 27 Jul 2020 17:19:56 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 27 Jul 2020 17:19:56 +0200
changeset 61
9c8d768f0244
parent 60
69be673a4fd0
child 62
7f5f9f43d0c0

adds option to compute individual sums

configure.ac file | annotate | diff | comparison | revisions
src/Makefile.am file | annotate | diff | comparison | revisions
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/suffix_fnc.c file | annotate | diff | comparison | revisions
src/suffix_fnc.h file | annotate | diff | comparison | revisions
--- a/configure.ac	Sat Jul 25 18:28:01 2020 +0200
+++ b/configure.ac	Mon Jul 27 17:19:56 2020 +0200
@@ -22,7 +22,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
 AC_PREREQ([2.69])
-AC_INIT(cline, 1.2, universe@uap-core.de)
+AC_INIT(cline, 1.3, universe@uap-core.de)
 AM_INIT_AUTOMAKE
 
 # Conditionals
--- a/src/Makefile.am	Sat Jul 25 18:28:01 2020 +0200
+++ b/src/Makefile.am	Mon Jul 27 17:19:56 2020 +0200
@@ -29,7 +29,7 @@
 
 bin_PROGRAMS = cline
 cline_SOURCES = arguments.c bfile_heuristics.c cline.c regex_parser.c \
-		scanner.c settings.c string_list.c suffix_fnc.c
+		scanner.c settings.c string_list.c
 
 EXTRA_DIST = arguments.h bfile_heuristics.h cline.h regex_parser.h scanner.h \
-	     settings.h stdinc.h string_list.h suffix_fnc.h
+	     settings.h stdinc.h string_list.h
--- a/src/cline.c	Sat Jul 25 18:28:01 2020 +0200
+++ b/src/cline.c	Mon Jul 27 17:19:56 2020 +0200
@@ -44,7 +44,8 @@
     "\n  -e <start> <end>    - Excludes lines between <start> and <end>"
     "\n                        You may use these options multiple times"
     "\n  -h, --help          - this help text"
-//  "\n  -i                  - print out individual sums per file extension"
+    "\n  -i                  - print out individual sums per file extension"
+    "\n                        (cannot be used together with -V)"
     "\n  -m                  - print information about matching files only"
     "\n  -s <suffixes>       - only count files with these suffixes (separated"
     "\n                        by commas)"
@@ -199,8 +200,13 @@
       add_string(settings->regex->pattern_list, argv[t]);
       add_string(settings->regex->pattern_list, "$");
     }
+    /* i */
     if ((argflags & 2048) > 0) {
-        settings->individual_sums = true;
+      // cannot be used together with -V
+      if (registerArgument(&checked, 128)) {
+        return exit_with_help(settings, 1);
+      }
+      settings->individual_sums = true;
     }
     if (argflags == 0) {
       /* SHORTCUTS */
@@ -226,7 +232,7 @@
 
   /* Scan directories */
   if (regex_compile_all(settings->regex)) {
-    scanresult_t result;
+    scanresult_t* result = new_scanresult_t(settings);
     /* Don't waste memory when only the total sum is needed */
     string_list_t *output = settings->verbose ? new_string_list_t() : NULL;
     char *outbuf;
@@ -237,8 +243,8 @@
     }
     for (int t = 0 ; t < directories->count ; t++) {
       scanDirectory((scanner_t){directories->items[t], 0}, settings,
-          output, &result);
-      total += result.directory;
+          output, result);
+      total += result->lines;
       if (directories->count > 1 ) {
         outbuf = (char*) malloc(81);
         memset(outbuf, '-', 79);
@@ -247,7 +253,7 @@
         add_string(output, outbuf);
         outbuf = (char*) malloc(81);
         snprintf(outbuf, 81, "%-63s%10d lines\n", directories->items[t],
-                result.directory);
+                result->lines);
         add_string(output, outbuf);
         outbuf = (char*) malloc(81);
         memset(outbuf, '-', 79);
@@ -265,6 +271,20 @@
         free(output->items[i]);
       }
       
+      if (result->ext) {
+        if (result->ext->count > 0) {
+          for (int t = 0 ; t < 79 ; t++) {
+            printf("=");
+          }
+          printf("\nIndividual sums:\n");
+          for (int t = 0 ; t < result->ext->count ; t++) {
+            printf(" %-62s%10d lines\n",
+                    result->ext->extensions[t],
+                    result->ext->lines[t]);
+          }
+        }
+      }
+      
       for (int t = 0 ; t < 79 ; t++) {
         printf("=");
       }
@@ -280,6 +300,7 @@
     } else {
       printf("%d", total);
     }
+    destroy_scanresult_t(result);
     destroy_string_list_t(output);
     destroy_settings_t(settings);
   }
--- a/src/scanner.c	Sat Jul 25 18:28:01 2020 +0200
+++ b/src/scanner.c	Mon Jul 27 17:19:56 2020 +0200
@@ -26,7 +26,6 @@
 
 
 #include "scanner.h"
-#include "suffix_fnc.h"
 #include "bfile_heuristics.h"
 #include "regex_parser.h"
 #include <sys/stat.h>
@@ -37,11 +36,82 @@
   char *displayname;
   int displayname_len;
   char *filename;
+  char *ext;
   int st_mode;
   filelist_t *next;
 };
 
-filelist_t *buildFileList(scanner_t scanner, settings_t* settings,
+static bool testSuffix(char* filename, string_list_t* list) {
+  bool ret = false;
+  int tokenlen, fnamelen = strlen(filename);
+  for (int t = 0 ; t < list->count ; t++) {
+    tokenlen = strlen(list->items[t]);
+    if (fnamelen >= tokenlen && tokenlen > 0) {
+      if (strncmp(filename+fnamelen-tokenlen,
+                  list->items[t], tokenlen) == 0) {
+        ret = true;
+        break;
+      }
+    }
+  }
+  return ret;
+}
+
+static void addLinesPerExtension(scanresult_ext_t* result,
+        char* ext, int lines) {
+  if (!result) return;
+  
+  if (!ext) ext = "w/o";
+  
+  for (int i = 0 ; i < result->count ; i++) {
+    if (strcasecmp(result->extensions[i], ext) == 0) {
+      result->lines[i] += lines;
+      return;
+    }
+  }
+  
+  if (result->count == result->capacity) {
+    int newcap = result->capacity+8;
+    char** extarr = realloc(result->extensions, newcap*sizeof(char*));
+    int* linesarr = realloc(result->lines, newcap*sizeof(int));
+    if (!extarr || !linesarr) {
+      fprintf(stderr, "Memory allocation error.\n");
+      abort();
+    }
+    result->extensions = extarr;
+    result->lines = linesarr;
+    result->capacity = newcap;
+  }
+  
+  result->extensions[result->count] = strdup(ext);
+  result->lines[result->count] = lines;
+  result->count++;
+}
+
+scanresult_t* new_scanresult_t(settings_t* settings) {
+  scanresult_t* result = calloc(1, sizeof(scanresult_t));
+  if (settings->individual_sums) {
+    result->ext = calloc(1, sizeof(scanresult_ext_t));
+  }
+  return result;
+}
+
+void destroy_scanresult_t(scanresult_t* result) {
+  if (result->ext) {
+    if (result->ext->count > 0) {
+      for (int i = 0 ; i < result->ext->count ; i++) {
+        free(result->ext->extensions[i]);
+      }
+      free(result->ext->extensions);
+      free(result->ext->lines);
+    }
+    free(result->ext);
+  }
+  free(result);
+}
+
+
+static filelist_t *buildFileList(scanner_t scanner, settings_t* settings,
     filelist_t* list) {
   
   DIR *dirf;
@@ -76,6 +146,9 @@
       memcpy(filename+dirnamelen+1, entry->d_name, newentry->displayname_len);
       filename[1+dirnamelen+newentry->displayname_len] = 0;
       newentry->filename = filename;
+      
+      /* Obtain file extension */
+      newentry->ext = strrchr(newentry->displayname, '.');
 
       /* Check for subdirectory */
       if (stat(filename, &statbuf) == 0) {
@@ -115,7 +188,7 @@
 void scanDirectory(scanner_t scanner, settings_t* settings,
     string_list_t* output, scanresult_t* result) {
 
-  result->directory = 0;
+  result->lines = 0;
   int a;
   bool bfile;
   char *outbuf;
@@ -129,16 +202,17 @@
       if (settings->recursive && S_ISDIR(filelist->st_mode)) {
         string_list_t *recoutput = new_string_list_t();
         scanresult_t recresult;
+        recresult.ext = result->ext;
         scanDirectory(
             (scanner_t) {filelist->filename, scanner.spaces+1},
             settings, recoutput, &recresult);
-        result->directory += recresult.directory;
+        result->lines += recresult.lines;
         if (!settings->matchesOnly || recoutput->count > 0) {
           outbuf = (char*) malloc(81);
           snprintf(outbuf, 81, "%*s/%*s%13d lines\n",
               filelist->displayname_len+scanner.spaces, filelist->displayname,
               60-filelist->displayname_len-scanner.spaces-1, "",
-              recresult.directory);
+              recresult.lines);
           add_string(output, outbuf);
           for (int i = 0 ; i < recoutput->count ; i++) {
             add_string(output, recoutput->items[i]);
@@ -211,7 +285,8 @@
               add_string(output, outbuf);
             }
           } else {
-            result->directory += lines;
+            addLinesPerExtension(result->ext, filelist->ext, lines);
+            result->lines += lines;
             outbuf = (char*) malloc(81);
             snprintf(outbuf, 81, "%*s%*s%13d lines\n",
                 filelist->displayname_len+scanner.spaces, filelist->displayname,
--- a/src/scanner.h	Sat Jul 25 18:28:01 2020 +0200
+++ b/src/scanner.h	Mon Jul 27 17:19:56 2020 +0200
@@ -37,7 +37,15 @@
 } scanner_t;
 
 typedef struct {
-  int directory;
+  int count;
+  int capacity;
+  char** extensions;
+  int* lines; 
+} scanresult_ext_t;
+
+typedef struct {
+  int lines;
+  scanresult_ext_t* ext;
 } scanresult_t;
 
 #ifdef _cplusplus
@@ -47,6 +55,10 @@
 void scanDirectory(scanner_t scanner, settings_t* settings,
         string_list_t* output, scanresult_t* result);
 
+scanresult_t* new_scanresult_t(settings_t* settings);
+void destroy_scanresult_t(scanresult_t*);
+
+
 #ifdef _cplusplus
 }
 #endif 
--- a/src/suffix_fnc.c	Sat Jul 25 18:28:01 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 
- * Copyright 2018 Mike Becker. All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "suffix_fnc.h"
-
-bool testSuffix(char* filename, string_list_t* list) {
-  bool ret = false;
-  int tokenlen, fnamelen = strlen(filename);
-  for (int t = 0 ; t < list->count ; t++) {
-    tokenlen = strlen(list->items[t]);
-    if (fnamelen >= tokenlen && tokenlen > 0) {
-      if (strncmp(filename+fnamelen-tokenlen,
-                  list->items[t], tokenlen) == 0) {
-        ret = true;
-        break;
-      }
-    }
-  }
-  return ret;
-}
-
--- a/src/suffix_fnc.h	Sat Jul 25 18:28:01 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 
- * Copyright 2018 Mike Becker. All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- *
- */
-
-#ifndef SUFFIX_FNC_H_
-#define SUFFIX_FNC_H_
-
-#include "stdinc.h"
-#include "string_list.h"
-
-bool testSuffix(char*, string_list_t*);
-
-#endif /* SUFFIX_FNC_H_ */

mercurial