| 86 const char *ext; |
86 const char *ext; |
| 87 unsigned st_mode; |
87 unsigned st_mode; |
| 88 struct filelist *next; |
88 struct filelist *next; |
| 89 }; |
89 }; |
| 90 |
90 |
| 91 static bool testSuffix(const char *filename, string_list *list) { |
91 static bool test_suffix(const char *filename, string_list *list) { |
| 92 bool ret = false; |
92 bool ret = false; |
| 93 size_t tokenlen, fnamelen = strlen(filename); |
93 size_t tokenlen, fnamelen = strlen(filename); |
| 94 for (size_t t = 0 ; t < list->count ; t++) { |
94 for (size_t t = 0 ; t < list->count ; t++) { |
| 95 tokenlen = strlen(list->items[t]); |
95 tokenlen = strlen(list->items[t]); |
| 96 if (fnamelen >= tokenlen && tokenlen > 0) { |
96 if (fnamelen >= tokenlen && tokenlen > 0) { |
| 102 } |
102 } |
| 103 } |
103 } |
| 104 return ret; |
104 return ret; |
| 105 } |
105 } |
| 106 |
106 |
| 107 static void addResultPerExtension(scanresult_ext *result, |
107 static void add_result_per_ext(scanresult_ext *result, |
| 108 const char *ext, unsigned value) { |
108 const char *ext, unsigned value) { |
| 109 if (!result) return; |
109 if (!result) return; |
| 110 |
110 |
| 111 if (!ext) ext = "w/o"; |
111 if (!ext) ext = "w/o"; |
| 112 |
112 |
| 113 for (unsigned i = 0 ; i < result->count ; i++) { |
113 for (unsigned i = 0 ; i < result->count ; i++) { |
| 186 |
186 |
| 187 /* Construct full pathname string */ |
187 /* Construct full pathname string */ |
| 188 size_t dirnamelen = strlen(scanner.dir); |
188 size_t dirnamelen = strlen(scanner.dir); |
| 189 char *filename = malloc(2 + dirnamelen + newentry->displayname_len); |
189 char *filename = malloc(2 + dirnamelen + newentry->displayname_len); |
| 190 memcpy(filename, scanner.dir, dirnamelen); |
190 memcpy(filename, scanner.dir, dirnamelen); |
| 191 if (filename[dirnamelen - 1] != settings->fileSeparator) { |
191 if (filename[dirnamelen - 1] != FILE_SEPARATOR) { |
| 192 filename[dirnamelen++] = settings->fileSeparator; |
192 filename[dirnamelen++] = FILE_SEPARATOR; |
| 193 } |
193 } |
| 194 memcpy(filename+dirnamelen, entry->d_name, newentry->displayname_len); |
194 memcpy(filename+dirnamelen, entry->d_name, newentry->displayname_len); |
| 195 filename[dirnamelen+newentry->displayname_len] = 0; |
195 filename[dirnamelen+newentry->displayname_len] = 0; |
| 196 newentry->filename = filename; |
196 newentry->filename = filename; |
| 197 |
197 |
| 232 |
232 |
| 233 return list; |
233 return list; |
| 234 } |
234 } |
| 235 |
235 |
| 236 static bool is_dir_excluded(settings *settings, const char *dir) { |
236 static bool is_dir_excluded(settings *settings, const char *dir) { |
| 237 const string_list * const list = settings->excludeDirs; |
237 const string_list * const list = settings->exclude_dirs; |
| 238 |
238 |
| 239 for (size_t i = 0 ; i < list->count ; i++) { |
239 for (size_t i = 0 ; i < list->count ; i++) { |
| 240 /* determine if the list item is a path or a name */ |
240 /* determine if the list item is a path or a name */ |
| 241 if (strchr(list->items[i], settings->fileSeparator) == NULL) { |
241 if (strchr(list->items[i], FILE_SEPARATOR) == NULL) { |
| 242 /* compare only the name */ |
242 /* compare only the name */ |
| 243 const char *dirpart = strrchr(dir, settings->fileSeparator); |
243 const char *dirpart = strrchr(dir, FILE_SEPARATOR); |
| 244 if (dirpart == NULL) { |
244 if (dirpart == NULL) { |
| 245 dirpart = dir; |
245 dirpart = dir; |
| 246 } else { |
246 } else { |
| 247 dirpart++; |
247 dirpart++; |
| 248 } |
248 } |
| 260 } |
260 } |
| 261 } |
261 } |
| 262 return false; |
262 return false; |
| 263 } |
263 } |
| 264 |
264 |
| 265 void scanDirectory(scanner scnr, settings *settings, |
265 void scan_dir(scanner scnr, settings *settings, |
| 266 string_list *output, scanresult *result) { |
266 string_list *output, scanresult *result) { |
| 267 |
267 |
| 268 result->result = 0; |
268 result->result = 0; |
| 269 bool bfile; |
269 bool bfile; |
| 270 char *outbuf; |
270 char *outbuf; |
| 271 const char *result_type = settings->count_chars ? "chars" : "lines"; |
271 const char *result_type = settings->count_chars ? "chars" : "lines"; |
| 272 |
272 |
| 273 struct filelist *filelist = buildFileList(scnr, settings); |
273 struct filelist *filelist = filelist_create(scnr); |
| 274 |
274 |
| 275 while (filelist != NULL) { |
275 while (filelist != NULL) { |
| 276 |
276 |
| 277 /* Scan subdirectories */ |
277 /* Scan subdirectories */ |
| 278 if (!S_ISREG(filelist->st_mode)) { |
278 if (!S_ISREG(filelist->st_mode)) { |
| 279 if (S_ISDIR(filelist->st_mode)) { |
279 if (S_ISDIR(filelist->st_mode)) { |
| 280 if (settings->recursive) { |
280 if (settings->recursive) { |
| 281 if (is_dir_excluded(settings, filelist->filename)) { |
281 if (is_dir_excluded(settings, filelist->filename)) { |
| 282 if (!settings->matchesOnly && settings->verbose) { |
282 if (!settings->matches_only && settings->verbose) { |
| 283 /* Print hint */ |
283 /* Print hint */ |
| 284 outbuf = malloc(81); |
284 outbuf = malloc(81); |
| 285 snprintf(outbuf, 81, "%*s%*s%19s\n", |
285 snprintf(outbuf, 81, "%*s%*s%19s\n", |
| 286 filelist->displayname_len + scnr.spaces, |
286 filelist->displayname_len + scnr.spaces, |
| 287 filelist->displayname, |
287 filelist->displayname, |
| 294 scanresult recresult = {0}; |
294 scanresult recresult = {0}; |
| 295 recresult.ext = result->ext; |
295 recresult.ext = result->ext; |
| 296 if (settings->verbose) { |
296 if (settings->verbose) { |
| 297 recoutput = new_string_list(); |
297 recoutput = new_string_list(); |
| 298 } |
298 } |
| 299 scanDirectory( |
299 scan_dir( |
| 300 (scanner) {filelist->filename, scnr.spaces+1}, |
300 (scanner) {filelist->filename, scnr.spaces+1}, |
| 301 settings, recoutput, &recresult); |
301 settings, recoutput, &recresult); |
| 302 result->result += recresult.result; |
302 result->result += recresult.result; |
| 303 if (settings->verbose && |
303 if (settings->verbose && |
| 304 (!settings->matchesOnly || recresult.result > 0)) { |
304 (!settings->matches_only || recresult.result > 0)) { |
| 305 outbuf = malloc(81); |
305 outbuf = malloc(81); |
| 306 snprintf(outbuf, 81, "%*s/%*s%13u %s\n", |
306 snprintf(outbuf, 81, "%*s/%*s%13u %s\n", |
| 307 filelist->displayname_len+scnr.spaces, filelist->displayname, |
307 filelist->displayname_len+scnr.spaces, filelist->displayname, |
| 308 60-filelist->displayname_len-scnr.spaces-1, "", |
308 60-filelist->displayname_len-scnr.spaces-1, "", |
| 309 recresult.result, result_type); |
309 recresult.result, result_type); |
| 313 } |
313 } |
| 314 } |
314 } |
| 315 destroy_string_list(recoutput); |
315 destroy_string_list(recoutput); |
| 316 } |
316 } |
| 317 } |
317 } |
| 318 } else if (!settings->matchesOnly && settings->verbose) { |
318 } else if (!settings->matches_only && settings->verbose) { |
| 319 outbuf = malloc(81); |
319 outbuf = malloc(81); |
| 320 snprintf(outbuf, 81, "%*s\n", |
320 snprintf(outbuf, 81, "%*s\n", |
| 321 filelist->displayname_len+scnr.spaces, |
321 filelist->displayname_len+scnr.spaces, |
| 322 filelist->displayname); |
322 filelist->displayname); |
| 323 add_string(output, outbuf); |
323 add_string(output, outbuf); |
| 324 } |
324 } |
| 325 } else { |
325 } else { |
| 326 if ((settings->includeSuffixes->count == 0 |
326 if ((settings->include_suffixes->count == 0 |
| 327 || testSuffix(filelist->displayname, settings->includeSuffixes)) |
327 || test_suffix(filelist->displayname, settings->include_suffixes)) |
| 328 && !testSuffix(filelist->displayname, settings->excludeSuffixes)) { |
328 && !test_suffix(filelist->displayname, settings->exclude_suffixes)) { |
| 329 |
329 |
| 330 /* Count */ |
330 /* Count */ |
| 331 unsigned res_value = 0; |
331 unsigned res_value = 0; |
| 332 bfile = false; |
332 bfile = false; |
| 333 bfile_reset(settings->bfileHeuristics); |
333 bfile_reset(settings->bfile); |
| 334 regex_parser_reset(settings->regex); |
334 regex_parser_reset(settings->regex); |
| 335 char line_buffer[MAX_LINELENGTH + 1]; |
335 char line_buffer[MAX_LINELENGTH + 1]; |
| 336 unsigned line_buffer_pos = 0; |
336 unsigned line_buffer_pos = 0; |
| 337 |
337 |
| 338 FILE *file = fopen(filelist->filename, "r"); |
338 FILE *file = fopen(filelist->filename, "r"); |
| 379 fclose(file); |
379 fclose(file); |
| 380 |
380 |
| 381 /* Print and sum line count */ |
381 /* Print and sum line count */ |
| 382 if (bfile) { |
382 if (bfile) { |
| 383 if (settings->verbose && |
383 if (settings->verbose && |
| 384 !settings->matchesOnly && !settings->dirsOnly) { |
384 !settings->matches_only && !settings->dirs_only) { |
| 385 outbuf = malloc(81); |
385 outbuf = malloc(81); |
| 386 snprintf(outbuf, 81, |
386 snprintf(outbuf, 81, |
| 387 "%*s%*s%19s\n", filelist->displayname_len+scnr.spaces, |
387 "%*s%*s%19s\n", filelist->displayname_len+scnr.spaces, |
| 388 filelist->displayname, |
388 filelist->displayname, |
| 389 60-filelist->displayname_len-scnr.spaces, "", "binary"); |
389 60-filelist->displayname_len-scnr.spaces, "", "binary"); |
| 390 add_string(output, outbuf); |
390 add_string(output, outbuf); |
| 391 } |
391 } |
| 392 } else { |
392 } else { |
| 393 addResultPerExtension(result->ext, filelist->ext, res_value); |
393 add_result_per_ext(result->ext, filelist->ext, res_value); |
| 394 result->result += res_value; |
394 result->result += res_value; |
| 395 if (settings->verbose && !settings->dirsOnly) { |
395 if (settings->verbose && !settings->dirs_only) { |
| 396 outbuf = malloc(81); |
396 outbuf = malloc(81); |
| 397 snprintf(outbuf, 81, "%*s%*s%13u %s\n", |
397 snprintf(outbuf, 81, "%*s%*s%13u %s\n", |
| 398 filelist->displayname_len+scnr.spaces, |
398 filelist->displayname_len+scnr.spaces, |
| 399 filelist->displayname, |
399 filelist->displayname, |
| 400 60-filelist->displayname_len-scnr.spaces, |
400 60-filelist->displayname_len-scnr.spaces, |
| 406 } |
406 } |
| 407 } |
407 } |
| 408 } |
408 } |
| 409 } else { |
409 } else { |
| 410 if (settings->verbose && |
410 if (settings->verbose && |
| 411 !settings->matchesOnly && !settings->dirsOnly) { |
411 !settings->matches_only && !settings->dirs_only) { |
| 412 /* Print hint */ |
412 /* Print hint */ |
| 413 outbuf = malloc(81); |
413 outbuf = malloc(81); |
| 414 snprintf(outbuf, 81, "%*s%*s%19s\n", |
414 snprintf(outbuf, 81, "%*s%*s%19s\n", |
| 415 filelist->displayname_len+scnr.spaces, filelist->displayname, |
415 filelist->displayname_len+scnr.spaces, filelist->displayname, |
| 416 60-filelist->displayname_len-scnr.spaces, "", "no match"); |
416 60-filelist->displayname_len-scnr.spaces, "", "no match"); |
| 428 } |
428 } |
| 429 |
429 |
| 430 char *make_path_absolute(const char *path) { |
430 char *make_path_absolute(const char *path) { |
| 431 static const char *cwd = NULL; |
431 static const char *cwd = NULL; |
| 432 static size_t cwdlen = 0; |
432 static size_t cwdlen = 0; |
| 433 #ifdef _WIN32 |
433 static const char fs = FILE_SEPARATOR; |
| 434 static char fs = '\\'; |
|
| 435 #else |
|
| 436 static char fs = '/'; |
|
| 437 #endif /* _WIN32 */ |
|
| 438 char *abspath; |
434 char *abspath; |
| 439 if (path_is_relative(path)) { |
435 if (path_is_relative(path)) { |
| 440 if (cwdlen == 0) { |
436 if (cwdlen == 0) { |
| 441 get_working_dir(&cwd, &cwdlen); |
437 get_working_dir(&cwd, &cwdlen); |
| 442 } |
438 } |