| 77 int pathcmp(const char *p1, const char *p2) { |
77 int pathcmp(const char *p1, const char *p2) { |
| 78 return strcmp(p1, p2); |
78 return strcmp(p1, p2); |
| 79 } |
79 } |
| 80 #endif |
80 #endif |
| 81 |
81 |
| 82 typedef struct filelist filelist_t; |
|
| 83 |
|
| 84 struct filelist { |
82 struct filelist { |
| 85 char *displayname; |
83 char *displayname; |
| 86 unsigned displayname_len; |
84 unsigned displayname_len; |
| 87 char *filename; |
85 char *filename; |
| 88 char *ext; |
86 char *ext; |
| 89 unsigned st_mode; |
87 unsigned st_mode; |
| 90 filelist_t *next; |
88 struct filelist *next; |
| 91 }; |
89 }; |
| 92 |
90 |
| 93 static bool testSuffix(char* filename, string_list_t* list) { |
91 static bool testSuffix(char* filename, string_list* list) { |
| 94 bool ret = false; |
92 bool ret = false; |
| 95 size_t tokenlen, fnamelen = strlen(filename); |
93 size_t tokenlen, fnamelen = strlen(filename); |
| 96 for (size_t t = 0 ; t < list->count ; t++) { |
94 for (size_t t = 0 ; t < list->count ; t++) { |
| 97 tokenlen = strlen(list->items[t]); |
95 tokenlen = strlen(list->items[t]); |
| 98 if (fnamelen >= tokenlen && tokenlen > 0) { |
96 if (fnamelen >= tokenlen && tokenlen > 0) { |
| 135 result->extensions[result->count] = strdup(ext); |
133 result->extensions[result->count] = strdup(ext); |
| 136 result->result[result->count] = value; |
134 result->result[result->count] = value; |
| 137 result->count++; |
135 result->count++; |
| 138 } |
136 } |
| 139 |
137 |
| 140 scanresult_t* new_scanresult_t(settings_t* settings) { |
138 scanresult* new_scanresult(settings* settings) { |
| 141 scanresult_t* result = calloc(1, sizeof(scanresult_t)); |
139 scanresult* result = calloc(1, sizeof(scanresult)); |
| 142 if (settings->individual_sums) { |
140 if (settings->individual_sums) { |
| 143 result->ext = calloc(1, sizeof(scanresult_ext_t)); |
141 result->ext = calloc(1, sizeof(scanresult_ext)); |
| 144 } |
142 } |
| 145 return result; |
143 return result; |
| 146 } |
144 } |
| 147 |
145 |
| 148 void destroy_scanresult_t(scanresult_t* result) { |
146 void destroy_scanresult(scanresult* result) { |
| 149 if (result->ext) { |
147 if (result->ext) { |
| 150 if (result->ext->count > 0) { |
148 if (result->ext->count > 0) { |
| 151 for (unsigned i = 0 ; i < result->ext->count ; i++) { |
149 for (unsigned i = 0 ; i < result->ext->count ; i++) { |
| 152 free(result->ext->extensions[i]); |
150 free(result->ext->extensions[i]); |
| 153 } |
151 } |
| 174 |
172 |
| 175 while ((entry = readdir(dirf)) != NULL) { |
173 while ((entry = readdir(dirf)) != NULL) { |
| 176 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { |
174 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { |
| 177 |
175 |
| 178 /* Create new filelist entry */ |
176 /* Create new filelist entry */ |
| 179 filelist_t *newentry = (filelist_t*) malloc(sizeof(filelist_t)); |
177 struct filelist *newentry = malloc(sizeof(struct filelist)); |
| 180 newentry->next = NULL; |
178 newentry->next = NULL; |
| 181 |
179 |
| 182 newentry->displayname_len = strlen(entry->d_name); |
180 newentry->displayname_len = strlen(entry->d_name); |
| 183 newentry->displayname = (char*) malloc(newentry->displayname_len+1); |
181 newentry->displayname = (char*) malloc(newentry->displayname_len+1); |
| 184 memcpy(newentry->displayname, entry->d_name, newentry->displayname_len); |
182 memcpy(newentry->displayname, entry->d_name, newentry->displayname_len); |
| 262 } |
260 } |
| 263 } |
261 } |
| 264 return false; |
262 return false; |
| 265 } |
263 } |
| 266 |
264 |
| 267 void scanDirectory(scanner_t scanner, settings_t* settings, |
265 void scanDirectory(scanner scnr, settings* settings, |
| 268 string_list_t* output, scanresult_t* result) { |
266 string_list* output, scanresult* result) { |
| 269 |
267 |
| 270 result->result = 0; |
268 result->result = 0; |
| 271 bool bfile; |
269 bool bfile; |
| 272 char *outbuf; |
270 char *outbuf; |
| 273 const char *result_type = settings->count_chars ? "chars" : "lines"; |
271 const char *result_type = settings->count_chars ? "chars" : "lines"; |
| 274 |
272 |
| 275 filelist_t *filelist = buildFileList(scanner, settings); |
273 struct filelist *filelist = buildFileList(scnr, settings); |
| 276 |
274 |
| 277 while (filelist != NULL) { |
275 while (filelist != NULL) { |
| 278 |
276 |
| 279 /* Scan subdirectories */ |
277 /* Scan subdirectories */ |
| 280 if (!S_ISREG(filelist->st_mode)) { |
278 if (!S_ISREG(filelist->st_mode)) { |
| 283 if (is_dir_excluded(settings, filelist->filename)) { |
281 if (is_dir_excluded(settings, filelist->filename)) { |
| 284 if (!settings->matchesOnly && settings->verbose) { |
282 if (!settings->matchesOnly && settings->verbose) { |
| 285 /* Print hint */ |
283 /* Print hint */ |
| 286 outbuf = malloc(81); |
284 outbuf = malloc(81); |
| 287 snprintf(outbuf, 81, "%*s%*s%19s\n", |
285 snprintf(outbuf, 81, "%*s%*s%19s\n", |
| 288 filelist->displayname_len + scanner.spaces, |
286 filelist->displayname_len + scnr.spaces, |
| 289 filelist->displayname, |
287 filelist->displayname, |
| 290 60 - filelist->displayname_len - scanner.spaces, |
288 60 - filelist->displayname_len - scnr.spaces, |
| 291 "", "no match"); |
289 "", "no match"); |
| 292 add_string(output, outbuf); |
290 add_string(output, outbuf); |
| 293 } |
291 } |
| 294 } else { |
292 } else { |
| 295 string_list_t *recoutput = settings->verbose ? new_string_list_t() : NULL; |
293 string_list *recoutput = settings->verbose ? new_string_list() : NULL; |
| 296 scanresult_t recresult; |
294 scanresult recresult; |
| 297 recresult.ext = result->ext; |
295 recresult.ext = result->ext; |
| 298 scanDirectory( |
296 scanDirectory( |
| 299 (scanner_t) {filelist->filename, scanner.spaces+1}, |
297 (scanner) {filelist->filename, scnr.spaces+1}, |
| 300 settings, recoutput, &recresult); |
298 settings, recoutput, &recresult); |
| 301 result->result += recresult.result; |
299 result->result += recresult.result; |
| 302 if (settings->verbose && (!settings->matchesOnly || recresult.result > 0)) { |
300 if (settings->verbose && (!settings->matchesOnly || recresult.result > 0)) { |
| 303 outbuf = (char*) malloc(81); |
301 outbuf = (char*) malloc(81); |
| 304 snprintf(outbuf, 81, "%*s/%*s%13u %s\n", |
302 snprintf(outbuf, 81, "%*s/%*s%13u %s\n", |
| 305 filelist->displayname_len+scanner.spaces, filelist->displayname, |
303 filelist->displayname_len+scnr.spaces, filelist->displayname, |
| 306 60-filelist->displayname_len-scanner.spaces-1, "", |
304 60-filelist->displayname_len-scnr.spaces-1, "", |
| 307 recresult.result, result_type); |
305 recresult.result, result_type); |
| 308 add_string(output, outbuf); |
306 add_string(output, outbuf); |
| 309 for (unsigned i = 0 ; i < recoutput->count ; i++) { |
307 for (unsigned i = 0 ; i < recoutput->count ; i++) { |
| 310 add_string(output, recoutput->items[i]); |
308 add_string(output, recoutput->items[i]); |
| 311 } |
309 } |
| 312 } |
310 } |
| 313 destroy_string_list_t(recoutput); |
311 destroy_string_list(recoutput); |
| 314 } |
312 } |
| 315 } |
313 } |
| 316 } else if (!settings->matchesOnly && settings->verbose) { |
314 } else if (!settings->matchesOnly && settings->verbose) { |
| 317 outbuf = (char*) malloc(81); |
315 outbuf = (char*) malloc(81); |
| 318 snprintf(outbuf, 81, "%*s\n", |
316 snprintf(outbuf, 81, "%*s\n", |
| 319 filelist->displayname_len+scanner.spaces, |
317 filelist->displayname_len+scnr.spaces, |
| 320 filelist->displayname); |
318 filelist->displayname); |
| 321 add_string(output, outbuf); |
319 add_string(output, outbuf); |
| 322 } |
320 } |
| 323 } else { |
321 } else { |
| 324 if ((settings->includeSuffixes->count == 0 |
322 if ((settings->includeSuffixes->count == 0 |
| 379 /* Print and sum line count */ |
377 /* Print and sum line count */ |
| 380 if (bfile) { |
378 if (bfile) { |
| 381 if (!settings->matchesOnly && !settings->dirsOnly && settings->verbose) { |
379 if (!settings->matchesOnly && !settings->dirsOnly && settings->verbose) { |
| 382 outbuf = (char*) malloc(81); |
380 outbuf = (char*) malloc(81); |
| 383 snprintf(outbuf, 81, |
381 snprintf(outbuf, 81, |
| 384 "%*s%*s%19s\n", filelist->displayname_len+scanner.spaces, |
382 "%*s%*s%19s\n", filelist->displayname_len+scnr.spaces, |
| 385 filelist->displayname, |
383 filelist->displayname, |
| 386 60-filelist->displayname_len-scanner.spaces, "", "binary"); |
384 60-filelist->displayname_len-scnr.spaces, "", "binary"); |
| 387 add_string(output, outbuf); |
385 add_string(output, outbuf); |
| 388 } |
386 } |
| 389 } else { |
387 } else { |
| 390 addResultPerExtension(result->ext, filelist->ext, res_value); |
388 addResultPerExtension(result->ext, filelist->ext, res_value); |
| 391 result->result += res_value; |
389 result->result += res_value; |
| 392 if (!settings->dirsOnly && settings->verbose) { |
390 if (!settings->dirsOnly && settings->verbose) { |
| 393 outbuf = (char*) malloc(81); |
391 outbuf = (char*) malloc(81); |
| 394 snprintf(outbuf, 81, "%*s%*s%13u %s\n", |
392 snprintf(outbuf, 81, "%*s%*s%13u %s\n", |
| 395 filelist->displayname_len+scanner.spaces, |
393 filelist->displayname_len+scnr.spaces, |
| 396 filelist->displayname, |
394 filelist->displayname, |
| 397 60-filelist->displayname_len-scanner.spaces, |
395 60-filelist->displayname_len-scnr.spaces, |
| 398 "", |
396 "", |
| 399 res_value, |
397 res_value, |
| 400 result_type |
398 result_type |
| 401 ); |
399 ); |
| 402 add_string(output, outbuf); |
400 add_string(output, outbuf); |
| 406 } else { |
404 } else { |
| 407 if (!settings->matchesOnly && !settings->dirsOnly && settings->verbose) { |
405 if (!settings->matchesOnly && !settings->dirsOnly && settings->verbose) { |
| 408 /* Print hint */ |
406 /* Print hint */ |
| 409 outbuf = (char*) malloc(81); |
407 outbuf = (char*) malloc(81); |
| 410 snprintf(outbuf, 81, "%*s%*s%19s\n", |
408 snprintf(outbuf, 81, "%*s%*s%19s\n", |
| 411 filelist->displayname_len+scanner.spaces, filelist->displayname, |
409 filelist->displayname_len+scnr.spaces, filelist->displayname, |
| 412 60-filelist->displayname_len-scanner.spaces, "", "no match"); |
410 60-filelist->displayname_len-scnr.spaces, "", "no match"); |
| 413 add_string(output, outbuf); |
411 add_string(output, outbuf); |
| 414 } |
412 } |
| 415 } |
413 } |
| 416 } |
414 } |
| 417 |
415 |
| 418 free(filelist->filename); |
416 free(filelist->filename); |
| 419 free(filelist->displayname); |
417 free(filelist->displayname); |
| 420 filelist_t *freethis = filelist; |
418 struct filelist *freethis = filelist; |
| 421 filelist = filelist->next; |
419 filelist = filelist->next; |
| 422 free(freethis); |
420 free(freethis); |
| 423 } |
421 } |
| 424 } |
422 } |
| 425 |
423 |