| 33 |
33 |
| 34 #ifdef _MSC_VER |
34 #ifdef _MSC_VER |
| 35 #include <windows.h> |
35 #include <windows.h> |
| 36 #include <shlwapi.h> |
36 #include <shlwapi.h> |
| 37 |
37 |
| 38 void get_working_dir(const char** out_ptr, size_t *out_len) { |
38 void get_working_dir(const char **out_ptr, size_t *out_len) { |
| 39 static char cwd[MAX_PATH]; |
39 static char cwd[MAX_PATH]; |
| 40 if (GetCurrentDirectoryA(MAX_PATH, cwd) == 0) { |
40 if (GetCurrentDirectoryA(MAX_PATH, cwd) == 0) { |
| 41 fprintf(stderr, "Could not get current working directory.\n"); |
41 fprintf(stderr, "Could not get current working directory.\n"); |
| 42 exit(1); |
42 exit(1); |
| 43 } |
43 } |
| 55 int pathcmp(const char *p1, const char *p2) { |
55 int pathcmp(const char *p1, const char *p2) { |
| 56 return strcasecmp(p1, p2); |
56 return strcasecmp(p1, p2); |
| 57 } |
57 } |
| 58 #else |
58 #else |
| 59 #include <unistd.h> |
59 #include <unistd.h> |
| 60 void get_working_dir(const char** out_ptr, size_t *out_len) { |
60 void get_working_dir(const char **out_ptr, size_t *out_len) { |
| 61 static char cwd[PATH_MAX]; |
61 static char cwd[PATH_MAX]; |
| 62 if (getcwd(cwd, sizeof(cwd)) == NULL) { |
62 if (getcwd(cwd, sizeof(cwd)) == NULL) { |
| 63 fprintf(stderr, "Could not get current working directory.\n"); |
63 fprintf(stderr, "Could not get current working directory.\n"); |
| 64 exit(1); |
64 exit(1); |
| 65 } |
65 } |
| 81 |
81 |
| 82 struct filelist { |
82 struct filelist { |
| 83 char *displayname; |
83 char *displayname; |
| 84 unsigned displayname_len; |
84 unsigned displayname_len; |
| 85 char *filename; |
85 char *filename; |
| 86 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(char* filename, string_list* list) { |
91 static bool testSuffix(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 addResultPerExtension(scanresult_ext *result, |
| 108 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++) { |
| 117 } |
117 } |
| 118 } |
118 } |
| 119 |
119 |
| 120 if (result->count == result->capacity) { |
120 if (result->count == result->capacity) { |
| 121 unsigned newcap = result->capacity+8; |
121 unsigned newcap = result->capacity+8; |
| 122 char** extarr = realloc(result->extensions, newcap*sizeof(char*)); |
122 char **extarr = realloc(result->extensions, newcap*sizeof(char*)); |
| 123 unsigned* resultarr = realloc(result->result, newcap*sizeof(unsigned)); |
123 unsigned *resultarr = realloc(result->result, newcap*sizeof(unsigned)); |
| 124 if (!extarr || !resultarr) { |
124 if (!extarr || !resultarr) { |
| 125 fprintf(stderr, "Memory allocation error.\n"); |
125 fprintf(stderr, "Memory allocation error.\n"); |
| 126 abort(); |
126 abort(); |
| 127 } |
127 } |
| 128 result->extensions = extarr; |
128 result->extensions = extarr; |
| 133 result->extensions[result->count] = strdup(ext); |
133 result->extensions[result->count] = strdup(ext); |
| 134 result->result[result->count] = value; |
134 result->result[result->count] = value; |
| 135 result->count++; |
135 result->count++; |
| 136 } |
136 } |
| 137 |
137 |
| 138 scanresult* new_scanresult(settings* settings) { |
138 scanresult *new_scanresult(settings *settings) { |
| 139 scanresult* result = calloc(1, sizeof(scanresult)); |
139 scanresult *result = calloc(1, sizeof(scanresult)); |
| 140 if (settings->individual_sums) { |
140 if (settings->individual_sums) { |
| 141 result->ext = calloc(1, sizeof(scanresult_ext)); |
141 result->ext = calloc(1, sizeof(scanresult_ext)); |
| 142 } |
142 } |
| 143 return result; |
143 return result; |
| 144 } |
144 } |
| 145 |
145 |
| 146 void destroy_scanresult(scanresult* result) { |
146 void destroy_scanresult(scanresult *result) { |
| 147 if (result->ext) { |
147 if (result->ext) { |
| 148 if (result->ext->count > 0) { |
148 if (result->ext->count > 0) { |
| 149 for (unsigned i = 0 ; i < result->ext->count ; i++) { |
149 for (unsigned i = 0 ; i < result->ext->count ; i++) { |
| 150 free(result->ext->extensions[i]); |
150 free(result->ext->extensions[i]); |
| 151 } |
151 } |
| 184 |
184 |
| 185 newentry->st_mode = 0; |
185 newentry->st_mode = 0; |
| 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] != settings->fileSeparator) { |
| 192 filename[dirnamelen++] = settings->fileSeparator; |
192 filename[dirnamelen++] = settings->fileSeparator; |
| 193 } |
193 } |
| 194 memcpy(filename+dirnamelen, entry->d_name, newentry->displayname_len); |
194 memcpy(filename+dirnamelen, entry->d_name, newentry->displayname_len); |
| 231 closedir(dirf); |
231 closedir(dirf); |
| 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->excludeDirs; |
| 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], settings->fileSeparator) == NULL) { |
| 249 if (pathcmp(list->items[i], dirpart) == 0) { |
249 if (pathcmp(list->items[i], dirpart) == 0) { |
| 250 return true; |
250 return true; |
| 251 } |
251 } |
| 252 } else { |
252 } else { |
| 253 /* compare the full paths */ |
253 /* compare the full paths */ |
| 254 char* absdir = make_path_absolute(dir); |
254 char *absdir = make_path_absolute(dir); |
| 255 if (pathcmp(list->items[i], absdir) == 0) { |
255 if (pathcmp(list->items[i], absdir) == 0) { |
| 256 free(absdir); |
256 free(absdir); |
| 257 return true; |
257 return true; |
| 258 } |
258 } |
| 259 free(absdir); |
259 free(absdir); |
| 260 } |
260 } |
| 261 } |
261 } |
| 262 return false; |
262 return false; |
| 263 } |
263 } |
| 264 |
264 |
| 265 void scanDirectory(scanner scnr, settings* settings, |
265 void scanDirectory(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"; |
| 433 #ifdef _WIN32 |
433 #ifdef _WIN32 |
| 434 static char fs = '\\'; |
434 static char fs = '\\'; |
| 435 #else |
435 #else |
| 436 static char fs = '/'; |
436 static char fs = '/'; |
| 437 #endif /* _WIN32 */ |
437 #endif /* _WIN32 */ |
| 438 char* abspath; |
438 char *abspath; |
| 439 if (path_is_relative(path)) { |
439 if (path_is_relative(path)) { |
| 440 if (cwdlen == 0) { |
440 if (cwdlen == 0) { |
| 441 get_working_dir(&cwd, &cwdlen); |
441 get_working_dir(&cwd, &cwdlen); |
| 442 } |
442 } |
| 443 size_t pathlen = strlen(path); |
443 size_t pathlen = strlen(path); |
| 455 } else { |
455 } else { |
| 456 abspath = strdup(path); |
456 abspath = strdup(path); |
| 457 } |
457 } |
| 458 /* make path canonical */ |
458 /* make path canonical */ |
| 459 size_t abspathlen = strlen(abspath); |
459 size_t abspathlen = strlen(abspath); |
| 460 char* canonical = malloc(abspathlen + 1); |
460 char *canonical = malloc(abspathlen + 1); |
| 461 size_t canonicallen = 0; |
461 size_t canonicallen = 0; |
| 462 for (size_t j = 0; j < abspathlen; j++) { |
462 for (size_t j = 0; j < abspathlen; j++) { |
| 463 canonical[canonicallen++] = abspath[j]; |
463 canonical[canonicallen++] = abspath[j]; |
| 464 if (abspath[j] == fs) { |
464 if (abspath[j] == fs) { |
| 465 /* collapse consecutive separators */ |
465 /* collapse consecutive separators */ |