# HG changeset patch # User Mike Becker # Date 1595863196 -7200 # Node ID 9c8d768f024491465ee46d43fd5fa94a768f6395 # Parent 69be673a4fd014f89eb8c944c81d95626c08762d adds option to compute individual sums diff -r 69be673a4fd0 -r 9c8d768f0244 configure.ac --- 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 diff -r 69be673a4fd0 -r 9c8d768f0244 src/Makefile.am --- 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 diff -r 69be673a4fd0 -r 9c8d768f0244 src/cline.c --- 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 - Excludes lines between and " "\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 - 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); } diff -r 69be673a4fd0 -r 9c8d768f0244 src/scanner.c --- 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 @@ -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, diff -r 69be673a4fd0 -r 9c8d768f0244 src/scanner.h --- 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 diff -r 69be673a4fd0 -r 9c8d768f0244 src/suffix_fnc.c --- 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; -} - diff -r 69be673a4fd0 -r 9c8d768f0244 src/suffix_fnc.h --- 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_ */