src/scanner.c

changeset 66
be2084398c37
parent 61
9c8d768f0244
     1.1 --- a/src/scanner.c	Fri Jun 03 18:13:46 2022 +0200
     1.2 +++ b/src/scanner.c	Fri Jun 03 20:05:15 2022 +0200
     1.3 @@ -29,22 +29,23 @@
     1.4  #include "bfile_heuristics.h"
     1.5  #include "regex_parser.h"
     1.6  #include <sys/stat.h>
     1.7 +#include <ctype.h>
     1.8  
     1.9  typedef struct filelist filelist_t;
    1.10  
    1.11  struct filelist {
    1.12    char *displayname;
    1.13 -  int displayname_len;
    1.14 +  unsigned displayname_len;
    1.15    char *filename;
    1.16    char *ext;
    1.17 -  int st_mode;
    1.18 +  unsigned st_mode;
    1.19    filelist_t *next;
    1.20  };
    1.21  
    1.22  static bool testSuffix(char* filename, string_list_t* list) {
    1.23    bool ret = false;
    1.24 -  int tokenlen, fnamelen = strlen(filename);
    1.25 -  for (int t = 0 ; t < list->count ; t++) {
    1.26 +  size_t tokenlen, fnamelen = strlen(filename);
    1.27 +  for (size_t t = 0 ; t < list->count ; t++) {
    1.28      tokenlen = strlen(list->items[t]);
    1.29      if (fnamelen >= tokenlen && tokenlen > 0) {
    1.30        if (strncmp(filename+fnamelen-tokenlen,
    1.31 @@ -57,34 +58,34 @@
    1.32    return ret;
    1.33  }
    1.34  
    1.35 -static void addLinesPerExtension(scanresult_ext_t* result,
    1.36 -        char* ext, int lines) {
    1.37 +static void addResultPerExtension(scanresult_ext_t* result,
    1.38 +                                  char* ext, unsigned value) {
    1.39    if (!result) return;
    1.40    
    1.41    if (!ext) ext = "w/o";
    1.42    
    1.43 -  for (int i = 0 ; i < result->count ; i++) {
    1.44 +  for (unsigned i = 0 ; i < result->count ; i++) {
    1.45      if (strcasecmp(result->extensions[i], ext) == 0) {
    1.46 -      result->lines[i] += lines;
    1.47 +      result->result[i] += value;
    1.48        return;
    1.49      }
    1.50    }
    1.51    
    1.52    if (result->count == result->capacity) {
    1.53 -    int newcap = result->capacity+8;
    1.54 +    unsigned newcap = result->capacity+8;
    1.55      char** extarr = realloc(result->extensions, newcap*sizeof(char*));
    1.56 -    int* linesarr = realloc(result->lines, newcap*sizeof(int));
    1.57 -    if (!extarr || !linesarr) {
    1.58 +    unsigned* resultarr = realloc(result->result, newcap*sizeof(unsigned));
    1.59 +    if (!extarr || !resultarr) {
    1.60        fprintf(stderr, "Memory allocation error.\n");
    1.61        abort();
    1.62      }
    1.63      result->extensions = extarr;
    1.64 -    result->lines = linesarr;
    1.65 +    result->result = resultarr;
    1.66      result->capacity = newcap;
    1.67    }
    1.68    
    1.69    result->extensions[result->count] = strdup(ext);
    1.70 -  result->lines[result->count] = lines;
    1.71 +  result->result[result->count] = value;
    1.72    result->count++;
    1.73  }
    1.74  
    1.75 @@ -99,21 +100,20 @@
    1.76  void destroy_scanresult_t(scanresult_t* result) {
    1.77    if (result->ext) {
    1.78      if (result->ext->count > 0) {
    1.79 -      for (int i = 0 ; i < result->ext->count ; i++) {
    1.80 +      for (unsigned i = 0 ; i < result->ext->count ; i++) {
    1.81          free(result->ext->extensions[i]);
    1.82        }
    1.83        free(result->ext->extensions);
    1.84 -      free(result->ext->lines);
    1.85 +      free(result->ext->result);
    1.86      }
    1.87      free(result->ext);
    1.88    }
    1.89    free(result);
    1.90  }
    1.91  
    1.92 +static filelist_t *buildFileList(scanner_t scanner, settings_t* settings) {
    1.93  
    1.94 -static filelist_t *buildFileList(scanner_t scanner, settings_t* settings,
    1.95 -    filelist_t* list) {
    1.96 -  
    1.97 +  filelist_t* list = NULL;
    1.98    DIR *dirf;
    1.99    struct dirent *entry;
   1.100    struct stat statbuf;
   1.101 @@ -159,7 +159,7 @@
   1.102        }
   1.103        
   1.104        if (list) {
   1.105 -        // create fake root to have a pointer on the true root
   1.106 +        /* create fake root to have a pointer on the true root */
   1.107          filelist_t root;
   1.108          root.next = list;
   1.109          filelist_t *parent = &root;
   1.110 @@ -188,12 +188,12 @@
   1.111  void scanDirectory(scanner_t scanner, settings_t* settings,
   1.112      string_list_t* output, scanresult_t* result) {
   1.113  
   1.114 -  result->lines = 0;
   1.115 -  int a;
   1.116 +  result->result = 0;
   1.117    bool bfile;
   1.118    char *outbuf;
   1.119 +  const char *result_type = settings->count_chars ? "chars" : "lines";
   1.120  
   1.121 -  filelist_t *filelist = buildFileList(scanner, settings, NULL);
   1.122 +  filelist_t *filelist = buildFileList(scanner, settings);
   1.123  
   1.124    while (filelist != NULL) {
   1.125  
   1.126 @@ -206,23 +206,24 @@
   1.127          scanDirectory(
   1.128              (scanner_t) {filelist->filename, scanner.spaces+1},
   1.129              settings, recoutput, &recresult);
   1.130 -        result->lines += recresult.lines;
   1.131 +        result->result += recresult.result;
   1.132          if (!settings->matchesOnly || recoutput->count > 0) {
   1.133            outbuf = (char*) malloc(81);
   1.134 -          snprintf(outbuf, 81, "%*s/%*s%13d lines\n",
   1.135 +          snprintf(outbuf, 81, "%*s/%*s%13u %s\n",
   1.136                filelist->displayname_len+scanner.spaces, filelist->displayname,
   1.137                60-filelist->displayname_len-scanner.spaces-1, "",
   1.138 -              recresult.lines);
   1.139 +              recresult.result, result_type);
   1.140            add_string(output, outbuf);
   1.141 -          for (int i = 0 ; i < recoutput->count ; i++) {
   1.142 +          for (unsigned i = 0 ; i < recoutput->count ; i++) {
   1.143              add_string(output, recoutput->items[i]);
   1.144            }
   1.145          }
   1.146          destroy_string_list_t(recoutput);
   1.147        } else {
   1.148          outbuf = (char*) malloc(81);
   1.149 -        snprintf(outbuf, 81, "%*s\n", filelist->displayname_len+scanner.spaces,
   1.150 -          filelist->displayname);
   1.151 +        snprintf(outbuf, 81, "%*s\n",
   1.152 +                 filelist->displayname_len+scanner.spaces,
   1.153 +                 filelist->displayname);
   1.154          add_string(output, outbuf);
   1.155        }
   1.156      } else {
   1.157 @@ -230,44 +231,55 @@
   1.158          || testSuffix(filelist->displayname, settings->includeSuffixes))
   1.159          && !testSuffix(filelist->displayname, settings->excludeSuffixes)) {
   1.160  
   1.161 -        /* Count lines */
   1.162 -        int lines = 0;
   1.163 +        /* Count */
   1.164 +        unsigned res_value = 0;
   1.165          bfile = false;
   1.166          bfile_reset(settings->bfileHeuristics);
   1.167          regex_parser_reset(settings->regex);
   1.168 -        char line_buffer[REGEX_MAX_LINELENGTH];
   1.169 -        int line_buffer_offset = 0;
   1.170 +        char line_buffer[MAX_LINELENGTH];
   1.171 +        unsigned line_buffer_pos = 0;
   1.172  
   1.173          FILE *file = fopen(filelist->filename, "r");
   1.174          if (file == NULL) {
   1.175            outbuf = (char*) malloc(81);
   1.176 -          snprintf(outbuf, 81, "%*s", filelist->displayname_len+scanner.spaces,
   1.177 -              filelist->displayname);
   1.178 +          snprintf(outbuf, 81, "%*s",
   1.179 +                   filelist->displayname_len+scanner.spaces,
   1.180 +                   filelist->displayname);
   1.181            add_string(output, outbuf);
   1.182            perror("  File acces failed");
   1.183          } else {
   1.184 +          int a;
   1.185            do {
   1.186              a = fgetc(file);
   1.187  
   1.188              bfile = bfile_check(settings->bfileHeuristics, a);
   1.189  
   1.190 +            /* ignore carriage return completely */
   1.191 +            if (a == 13) continue;
   1.192 +
   1.193              if (a == 10 || a == EOF) {
   1.194 -              line_buffer[line_buffer_offset] = 0;
   1.195 +              line_buffer[line_buffer_pos] = 0;
   1.196                if (regex_parser_do(settings->regex, line_buffer) == 0) {
   1.197 -                /* Only subtract lines when matching has finished */
   1.198 +                /* Subtract excluded lines/chars when matching has finished */
   1.199                  if (!regex_parser_matching(settings->regex)) {
   1.200 -                  lines -= settings->regex->matched_lines;
   1.201 +                  res_value -= settings->regex->matched_counted;
   1.202                  }
   1.203                }
   1.204  
   1.205 -              line_buffer_offset = 0;
   1.206 -              lines++;
   1.207 +              if (settings->count_chars) {
   1.208 +                for (size_t i = 0 ; i < line_buffer_pos ; i++) {
   1.209 +                  if (!isspace(line_buffer[i])) res_value++;
   1.210 +                }
   1.211 +              } else {
   1.212 +                res_value++;
   1.213 +              }
   1.214 +              line_buffer_pos = 0;
   1.215              } else {
   1.216 -              if (line_buffer_offset < REGEX_MAX_LINELENGTH) {
   1.217 -                line_buffer[line_buffer_offset] = a;
   1.218 -                line_buffer_offset++;
   1.219 +              if (line_buffer_pos < MAX_LINELENGTH) {
   1.220 +                line_buffer[line_buffer_pos] = (char) a;
   1.221 +                line_buffer_pos++;
   1.222                } else {
   1.223 -                line_buffer[line_buffer_offset-1] = 0;
   1.224 +                line_buffer[line_buffer_pos - 1] = 0;
   1.225                  settings->confusing_lnlen = true;
   1.226                }
   1.227              }
   1.228 @@ -285,12 +297,17 @@
   1.229                add_string(output, outbuf);
   1.230              }
   1.231            } else {
   1.232 -            addLinesPerExtension(result->ext, filelist->ext, lines);
   1.233 -            result->lines += lines;
   1.234 +            addResultPerExtension(result->ext, filelist->ext, res_value);
   1.235 +            result->result += res_value;
   1.236              outbuf = (char*) malloc(81);
   1.237 -            snprintf(outbuf, 81, "%*s%*s%13d lines\n",
   1.238 -                filelist->displayname_len+scanner.spaces, filelist->displayname,
   1.239 -                60-filelist->displayname_len-scanner.spaces, "", lines);
   1.240 +            snprintf(outbuf, 81, "%*s%*s%13u %s\n",
   1.241 +                     filelist->displayname_len+scanner.spaces,
   1.242 +                     filelist->displayname,
   1.243 +                     60-filelist->displayname_len-scanner.spaces,
   1.244 +                     "",
   1.245 +                     res_value,
   1.246 +                     result_type
   1.247 +            );
   1.248              add_string(output, outbuf);
   1.249            }
   1.250          }

mercurial