| 29 #include "bfile_heuristics.h" |
29 #include "bfile_heuristics.h" |
| 30 #include "regex_parser.h" |
30 #include "regex_parser.h" |
| 31 #include <sys/stat.h> |
31 #include <sys/stat.h> |
| 32 #include <ctype.h> |
32 #include <ctype.h> |
| 33 |
33 |
| |
34 #ifdef _MSC_VER |
| |
35 #include <windows.h> |
| |
36 #include <shlwapi.h> |
| |
37 |
| |
38 void get_working_dir(const char** out_ptr, size_t *out_len) { |
| |
39 static char cwd[MAX_PATH]; |
| |
40 if (GetCurrentDirectory(MAX_PATH, cwd) == 0) { |
| |
41 fprintf(stderr, "Could not get current working directory.\n"); |
| |
42 exit(1); |
| |
43 } |
| |
44 size_t len = strlen(cwd); |
| |
45 if (cwd[len - 1] != '/') { |
| |
46 cwd[len++] = '/'; |
| |
47 cwd[len] = '\0'; |
| |
48 } |
| |
49 *out_ptr = cwd; |
| |
50 *out_len = len; |
| |
51 } |
| |
52 bool path_is_relative(const char *path) { |
| |
53 return PathIsRelative(path); |
| |
54 } |
| |
55 int pathcmp(const char *p1, const char *p2) { |
| |
56 return strcasecmp(p1, p2); |
| |
57 } |
| |
58 #else |
| |
59 #include <unistd.h> |
| |
60 void get_working_dir(const char** out_ptr, size_t *out_len) { |
| |
61 static char cwd[PATH_MAX]; |
| |
62 if (getcwd(cwd, sizeof(cwd)) == NULL) { |
| |
63 fprintf(stderr, "Could not get current working directory.\n"); |
| |
64 exit(1); |
| |
65 } |
| |
66 size_t len = strlen(cwd); |
| |
67 if (cwd[len - 1] != '/') { |
| |
68 cwd[len++] = '/'; |
| |
69 cwd[len] = '\0'; |
| |
70 } |
| |
71 *out_ptr = cwd; |
| |
72 *out_len = len; |
| |
73 } |
| |
74 bool path_is_relative(const char *path) { |
| |
75 return path[0] != '/'; |
| |
76 } |
| |
77 int pathcmp(const char *p1, const char *p2) { |
| |
78 return strcmp(p1, p2); |
| |
79 } |
| |
80 #endif |
| |
81 |
| 34 typedef struct filelist filelist_t; |
82 typedef struct filelist filelist_t; |
| 35 |
83 |
| 36 struct filelist { |
84 struct filelist { |
| 37 char *displayname; |
85 char *displayname; |
| 38 unsigned displayname_len; |
86 unsigned displayname_len; |
| 183 closedir(dirf); |
231 closedir(dirf); |
| 184 |
232 |
| 185 return list; |
233 return list; |
| 186 } |
234 } |
| 187 |
235 |
| 188 static bool is_dir_excluded(string_list_t* list, char* dir) { |
236 static bool is_dir_excluded(settings_t* settings, const char* dir) { |
| 189 // TODO: implement |
237 const string_list_t * const list = settings->excludeDirs; |
| 190 // assume normalized dir names in list (cline.c will make sure of it) |
238 |
| 191 // remember to do case-insensitive comparison for WIN32 |
239 for (size_t i = 0 ; i < list->count ; i++) { |
| |
240 /* determine if the list item is a path or a name */ |
| |
241 if (strchr(list->items[i], settings->fileSeparator) == NULL) { |
| |
242 /* compare only the name */ |
| |
243 const char *dirpart = strrchr(dir, settings->fileSeparator); |
| |
244 if (dirpart == NULL) { |
| |
245 dirpart = dir; |
| |
246 } else { |
| |
247 dirpart++; |
| |
248 } |
| |
249 if (pathcmp(list->items[i], dirpart) == 0) { |
| |
250 return true; |
| |
251 } |
| |
252 } else { |
| |
253 /* compare the full paths */ |
| |
254 char* absdir = make_path_absolute(dir); |
| |
255 if (pathcmp(list->items[i], absdir) == 0) { |
| |
256 free(absdir); |
| |
257 return true; |
| |
258 } |
| |
259 free(absdir); |
| |
260 } |
| |
261 } |
| 192 return false; |
262 return false; |
| 193 } |
263 } |
| 194 |
264 |
| 195 void scanDirectory(scanner_t scanner, settings_t* settings, |
265 void scanDirectory(scanner_t scanner, settings_t* settings, |
| 196 string_list_t* output, scanresult_t* result) { |
266 string_list_t* output, scanresult_t* result) { |
| 206 |
276 |
| 207 /* Scan subdirectories */ |
277 /* Scan subdirectories */ |
| 208 if (!S_ISREG(filelist->st_mode)) { |
278 if (!S_ISREG(filelist->st_mode)) { |
| 209 if (S_ISDIR(filelist->st_mode)) { |
279 if (S_ISDIR(filelist->st_mode)) { |
| 210 if (settings->recursive) { |
280 if (settings->recursive) { |
| 211 if (is_dir_excluded(settings->excludeDirs, filelist->filename)) { |
281 if (is_dir_excluded(settings, filelist->filename)) { |
| 212 if (!settings->matchesOnly && settings->verbose) { |
282 if (!settings->matchesOnly && settings->verbose) { |
| 213 // TODO: print "no match" |
283 /* Print hint */ |
| |
284 outbuf = malloc(81); |
| |
285 snprintf(outbuf, 81, "%*s%*s%19s\n", |
| |
286 filelist->displayname_len + scanner.spaces, |
| |
287 filelist->displayname, |
| |
288 60 - filelist->displayname_len - scanner.spaces, |
| |
289 "", "no match"); |
| |
290 add_string(output, outbuf); |
| 214 } |
291 } |
| 215 } else { |
292 } else { |
| 216 string_list_t *recoutput = settings->verbose ? new_string_list_t() : NULL; |
293 string_list_t *recoutput = settings->verbose ? new_string_list_t() : NULL; |
| 217 scanresult_t recresult; |
294 scanresult_t recresult; |
| 218 recresult.ext = result->ext; |
295 recresult.ext = result->ext; |
| 341 filelist_t *freethis = filelist; |
418 filelist_t *freethis = filelist; |
| 342 filelist = filelist->next; |
419 filelist = filelist->next; |
| 343 free(freethis); |
420 free(freethis); |
| 344 } |
421 } |
| 345 } |
422 } |
| |
423 |
| |
424 char *make_path_absolute(const char *path) { |
| |
425 static const char *cwd = NULL; |
| |
426 static size_t cwdlen = 0; |
| |
427 #ifdef _WIN32 |
| |
428 static char fs = '\\'; |
| |
429 #else |
| |
430 static char fs = '/'; |
| |
431 #endif /* _WIN32 */ |
| |
432 if (path_is_relative(path)) { |
| |
433 if (cwdlen == 0) { |
| |
434 get_working_dir(&cwd, &cwdlen); |
| |
435 } |
| |
436 size_t pathlen = strlen(path); |
| |
437 char *result = malloc(pathlen+cwdlen+1); |
| |
438 const char *part = path; |
| |
439 size_t partlen = pathlen; |
| |
440 if (part[0] == '.' && part[1] == fs) { |
| |
441 part += 2; |
| |
442 partlen -= 2; |
| |
443 } |
| |
444 memcpy(result, cwd, cwdlen); |
| |
445 memcpy(result+cwdlen, part, partlen); |
| |
446 result[cwdlen+partlen] = '\0'; |
| |
447 return result; |
| |
448 } else { |
| |
449 return strdup(path); |
| |
450 } |
| |
451 } |