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 }