line sum per directory now displayed + directories without matching files are no longer displayed when -m is used + new buffering strategy replaces stream hack when -V is used

Wed, 22 May 2013 13:00:36 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 22 May 2013 13:00:36 +0200
changeset 44
9574a181ec26
parent 43
104e75d18ede
child 45
6114a2c28d28

line sum per directory now displayed + directories without matching files are no longer displayed when -m is used + new buffering strategy replaces stream hack when -V is used

Makefile file | annotate | diff | comparison | revisions
src/cline.c file | annotate | diff | comparison | revisions
src/cline.h file | annotate | diff | comparison | revisions
src/scanner.c file | annotate | diff | comparison | revisions
src/scanner.h file | annotate | diff | comparison | revisions
src/stream.c file | annotate | diff | comparison | revisions
src/stream.h file | annotate | diff | comparison | revisions
src/string_list.c file | annotate | diff | comparison | revisions
--- a/Makefile	Wed May 22 10:57:17 2013 +0200
+++ b/Makefile	Wed May 22 13:00:36 2013 +0200
@@ -37,11 +37,10 @@
 CONF = gcc
 #endif
 
-VERSION_PREFIX=1.0.
 SRCDIR=src
 BUILDDIR=build
 PREFIX=/usr
-OBJ = arguments.o bfile_heuristics.o cline.o regex_parser.o scanner.o settings.o stream.o string_list.o suffix_fnc.o
+OBJ = arguments.o bfile_heuristics.o cline.o regex_parser.o scanner.o settings.o string_list.o suffix_fnc.o
 BIN = $(BUILDDIR)/cline
 
 include $(CONF).mk
--- a/src/cline.c	Wed May 22 10:57:17 2013 +0200
+++ b/src/cline.c	Wed May 22 13:00:36 2013 +0200
@@ -33,7 +33,6 @@
 #include "scanner.h"
 #include "settings.h"
 #include "arguments.h"
-#include "stream.h"
 #include "regex_parser.h"
 
 void printHelpText() {
@@ -219,48 +218,65 @@
     }
   }
 
-  /* Configure output */
-  if (!settings->verbose) {
-    close_stdout();
-  }
-
   /* Find tokens */
   parseCSL(includeSuffix, settings->includeSuffixes);
   parseCSL(excludeSuffix, settings->excludeSuffixes);
 
   /* Scan directories */
   if (regex_compile_all(settings->regex)) {
-    int lines = 0;
+    /* Don't waste memory when only the total sum is needed */
+    string_list_t *output = settings->verbose ? new_string_list_t() : NULL;
+    char *outbuf;
+    
+    int lineSum = 0, lines;
     if (directories->count == 0) {
         add_string(directories, ".");
     }
     for (int t = 0 ; t < directories->count ; t++) {
-      if (t > 0) {
-          for (int u = 0 ; u < 79 ; u++) {
-              printf("-");
-          }
-          printf("\n");
+      lines = scanDirectory((scanner_t){directories->items[t], 0}, settings,
+          output);
+      lineSum += lines;
+      if (directories->count > 1 ) {
+        outbuf = (char*) malloc(81);
+        memset(outbuf, '-', 79);
+        outbuf[79] = '\n';
+        outbuf[80] = 0;
+        add_string(output, outbuf);
+        outbuf = (char*) malloc(81);
+        snprintf(outbuf, 81, "%-63s%10d lines\n", directories->items[t], lines);
+        add_string(output, outbuf);
+        outbuf = (char*) malloc(81);
+        memset(outbuf, '-', 79);
+        outbuf[79] = '\n';
+        outbuf[80] = 0;
+        add_string(output, outbuf);
       }
-      lines += scanDirectory((scanner_t){directories->items[t], 0}, settings);
     }
     destroy_string_list_t(directories);
 
-    /* Print double line and line count */
-    for (int t = 0 ; t < 79 ; t++) {
-      printf("=");
-    }
-    printf("\n%73d lines\n", lines);
+    /* Print result */
+    if (settings->verbose) {
+      for (int i = 0 ; i < output->count ; i++) {
+        printf("%s", output->items[i]);
+        free(output->items[i]);
+      }
+      
+      for (int t = 0 ; t < 79 ; t++) {
+        printf("=");
+      }
+      printf("\n%73d lines\n", lineSum);
 
-    if (settings->confusing_lnlen && settings->regex->pattern_list->count > 0) {
-      printf("\nSome files contain too long lines.\n"
-        "The regex parser currently supports a maximum line length of %d."
-        "\nThe result might be wrong.\n", REGEX_MAX_LINELENGTH);
+      if (settings->confusing_lnlen &&
+          settings->regex->pattern_list->count > 0) {
+
+        printf("\nSome files contain too long lines.\n"
+          "The regex parser currently supports a maximum line length of %d."
+          "\nThe result might be wrong.\n", REGEX_MAX_LINELENGTH);
+      }
+    } else {
+      printf("%d", lineSum);
     }
-
-    if (!settings->verbose) {
-      reopen_stdout();
-      printf("%d", lines);
-    }
+    destroy_string_list_t(output);
     destroy_settings_t(settings);
   }
 
--- a/src/cline.h	Wed May 22 10:57:17 2013 +0200
+++ b/src/cline.h	Wed May 22 13:00:36 2013 +0200
@@ -32,7 +32,7 @@
 #ifndef CLINE_H_
 #define CLINE_H_
 
-const char* VERSION="1.0.37";
+const char* VERSION="1.0.44";
 
 #include "stdinc.h"
 #include "settings.h"
--- a/src/scanner.c	Wed May 22 10:57:17 2013 +0200
+++ b/src/scanner.c	Wed May 22 13:00:36 2013 +0200
@@ -117,11 +117,13 @@
   return list;
 }
 
-int scanDirectory(scanner_t scanner, settings_t* settings) {
+int scanDirectory(scanner_t scanner, settings_t* settings,
+    string_list_t* output) {
 
   int lines, a;
   int lineSum = 0;
   bool bfile;
+  char *outbuf;
 
   filelist_t *filelist = buildFileList(scanner, settings, NULL);
 
@@ -129,11 +131,28 @@
 
     /* Scan subdirectories */
     if (!S_ISREG(filelist->st_mode)) {
-      printf("%*s\n", filelist->displayname_len+scanner.spaces,
+      if (settings->recursive && S_ISDIR(filelist->st_mode)) {
+        string_list_t *recoutput = new_string_list_t();
+        lines = scanDirectory(
+            (scanner_t) {filelist->filename, scanner.spaces+1},
+            settings, recoutput);
+        lineSum += 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, "", lines);
+          add_string(output, outbuf);
+          for (int i = 0 ; i < recoutput->count ; i++) {
+            add_string(output, recoutput->items[i]);
+          }
+        }
+        destroy_string_list_t(recoutput);
+      } else {
+        outbuf = (char*) malloc(81);
+        snprintf(outbuf, 81, "%*s\n", filelist->displayname_len+scanner.spaces,
           filelist->displayname);
-      if (settings->recursive && S_ISDIR(filelist->st_mode)) {
-        lineSum += scanDirectory(
-            (scanner_t) {filelist->filename, scanner.spaces+1}, settings);
+        add_string(output, outbuf);
       }
     } else {
       if ((settings->includeSuffixes->count == 0
@@ -149,8 +168,10 @@
 
         FILE *file = fopen(filelist->filename, "r");
         if (file == NULL) {
-          printf("%*s", filelist->displayname_len+scanner.spaces,
+          outbuf = (char*) malloc(81);
+          snprintf(outbuf, 81, "%*s", filelist->displayname_len+scanner.spaces,
               filelist->displayname);
+          add_string(output, outbuf);
           perror("  File acces failed");
         } else {
           do {
@@ -184,23 +205,30 @@
           /* Print and sum line count */
           if (bfile) {
             if (!settings->matchesOnly) {
-              printf("%*s%*s%19s\n", filelist->displayname_len+scanner.spaces,
+              outbuf = (char*) malloc(81);
+              snprintf(outbuf, 81,
+                  "%*s%*s%19s\n", filelist->displayname_len+scanner.spaces,
                   filelist->displayname,
                   60-filelist->displayname_len-scanner.spaces, "", "binary");
+              add_string(output, outbuf);
             }
           } else {
             lineSum += lines;
-            printf("%*s%*s%13d lines\n",
+            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, "", lines);
+            add_string(output, outbuf);
           }
         }
       } else {
         if (!settings->matchesOnly) {
           /* Print hint */
-          printf("%*s%*s%19s\n",
+          outbuf = (char*) malloc(81);
+          snprintf(outbuf, 81, "%*s%*s%19s\n",
               filelist->displayname_len+scanner.spaces, filelist->displayname,
               60-filelist->displayname_len-scanner.spaces, "", "no match");
+          add_string(output, outbuf);
         }
       }
     }
--- a/src/scanner.h	Wed May 22 10:57:17 2013 +0200
+++ b/src/scanner.h	Wed May 22 13:00:36 2013 +0200
@@ -34,6 +34,7 @@
 
 #include "stdinc.h"
 #include "settings.h"
+#include "string_list.h"
 
 typedef struct {
   char *dir;
@@ -44,7 +45,8 @@
 extern "C" {
 #endif
 
-int scanDirectory(scanner_t scanner, settings_t* settings);
+int scanDirectory(scanner_t scanner, settings_t* settings,
+        string_list_t* output);
 
 #ifdef _cplusplus
 }
--- a/src/stream.c	Wed May 22 10:57:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 
- * Copyright 2013 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. 
- *
- * stream.c
- *
- *  Created on: 20.09.2011
- *      Author: Mike
- */
-
-#include "stream.h"
-
-void close_stdout() {
-#ifdef _WIN32
-  _STREAM_STDOUT = dup(STDOUT_FILENO);
-#endif
-  stdout = freopen("/dev/null", "w", stdout);
-}
-
-void reopen_stdout() {
-#ifdef _WIN32
-  close(STDOUT_FILENO);
-  fdopen(dup(_STREAM_STDOUT), "wa");
-  close(_STREAM_STDOUT);
-#else
-  stdout = freopen("/dev/stdout", "w", stdout);
-#endif
-}
--- a/src/stream.h	Wed May 22 10:57:17 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 
- * Copyright 2013 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. 
- *
- * stream.h
- *
- *  Created on: 20.09.2011
- *      Author: Mike
- */
-
-#ifndef STREAM_H_
-#define STREAM_H_
-
-#include "stdinc.h"
-
-#ifdef _WIN32
-int _STREAM_STDOUT;
-#endif
-
-#ifdef _cplusplus
-extern "C" {
-#endif
-
-void close_stdout();
-void reopen_stdout();
-
-#ifdef _cplusplus
-extern "C" }
-#endif
-
-#endif /* STREAM_H_ */
--- a/src/string_list.c	Wed May 22 10:57:17 2013 +0200
+++ b/src/string_list.c	Wed May 22 13:00:36 2013 +0200
@@ -40,19 +40,28 @@
 }
 
 void destroy_string_list_t(string_list_t* list) {
-  if (list->items != NULL) {
-    free(list->items);
-  }
-  free(list);
-}
-
-void add_string(string_list_t* list, char* item) {
-  char** reallocated_list =
-    realloc(list->items, sizeof(char*) * (list->count + 1));
-  if (reallocated_list != NULL) {
-    list->items = reallocated_list;
-    list->items[list->count] = item;
-    list->count++;
+  if (list) {
+    if (list->items) {
+      free(list->items);
+    }
+    free(list);
   }
 }
 
+/* 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) {
+    char** reallocated_list =
+      realloc(list->items, sizeof(char*) * (list->count + 1));
+    if (reallocated_list != NULL) {
+      list->items = reallocated_list;
+      list->items[list->count] = item;
+      list->count++;
+    }
+  } else {
+    free(item);
+  }
+}
+

mercurial