| 92 printHelpText(); |
92 printHelpText(); |
| 93 destroy_settings_t(settings); |
93 destroy_settings_t(settings); |
| 94 return code; |
94 return code; |
| 95 } |
95 } |
| 96 |
96 |
| |
97 static void normalize_excluded_dirs(settings_t *settings) { |
| |
98 /* normalize all paths */ |
| |
99 for (int i = 0 ; i < settings->excludeDirs->count ; i++) { |
| |
100 char *arg = strdup(settings->excludeDirs->items[i]); |
| |
101 if (strpbrk(arg, "/\\") == NULL) { |
| |
102 /* do not normalize names */ |
| |
103 settings->excludeDirs->items[i] = arg; |
| |
104 } else { |
| |
105 size_t arglen = strlen(arg); |
| |
106 /* fix file separators */ |
| |
107 char fs = settings->fileSeparator; |
| |
108 char badfs = settings->fileSeparator == '/' ? '\\' : '/'; |
| |
109 for (size_t j = 0 ; j < arglen ; j++) { |
| |
110 if (arg[j] == badfs) { |
| |
111 arg[j] = fs; |
| |
112 } |
| |
113 } |
| |
114 /* make path absolute */ |
| |
115 { |
| |
116 char *ap = make_path_absolute(arg); |
| |
117 free(arg); |
| |
118 arg = ap; |
| |
119 arglen = strlen(ap); |
| |
120 } |
| |
121 /* make path canonical */ |
| |
122 char *canonical = malloc(arglen+1); |
| |
123 size_t canonicallen = 0; |
| |
124 for (size_t j = 0 ; j < arglen ; j++) { |
| |
125 canonical[canonicallen++] = arg[j]; |
| |
126 if (arg[j] == fs) { |
| |
127 /* collapse consecutive separators */ |
| |
128 while (arg[j+1] == fs) j++; |
| |
129 } else if (arg[j] == '.') { |
| |
130 if (arg[j+1] == fs) { |
| |
131 /* skip '.' segments */ |
| |
132 canonicallen--; |
| |
133 j++; |
| |
134 } else if (arg[j+1] == '.' && arg[j+2] == fs) { |
| |
135 /* trace back '..' segment */ |
| |
136 canonicallen -= 2; |
| |
137 while (canonical[canonicallen-1] != fs) canonicallen--; |
| |
138 j+=2; |
| |
139 } |
| |
140 } |
| |
141 } |
| |
142 canonical[canonicallen] = '\0'; |
| |
143 settings->excludeDirs->items[i] = canonical; |
| |
144 free(arg); |
| |
145 } |
| |
146 } |
| |
147 |
| |
148 /* tell the string list to free the items */ |
| |
149 settings->excludeDirs->free_item = free; |
| |
150 } |
| |
151 |
| 97 static const char * sepline_double = "===============================================================================\n"; |
152 static const char * sepline_double = "===============================================================================\n"; |
| 98 static const char * sepline_single = "-------------------------------------------------------------------------------\n"; |
153 static const char * sepline_single = "-------------------------------------------------------------------------------\n"; |
| 99 |
154 |
| 100 int main(int argc, char** argv) { |
155 int main(int argc, char** argv) { |
| 101 |
156 |
| 240 if ((argflags & 16384) > 0) { |
295 if ((argflags & 16384) > 0) { |
| 241 t++; |
296 t++; |
| 242 if (!checkParamOpt(&paropt) || t >= argc) { |
297 if (!checkParamOpt(&paropt) || t >= argc) { |
| 243 return exit_with_help(settings, 1); |
298 return exit_with_help(settings, 1); |
| 244 } |
299 } |
| 245 // TODO: normalize argument before adding to dir list |
|
| 246 // this makes it more efficient to compare dir names later |
|
| 247 add_string(settings->excludeDirs, argv[t]); |
300 add_string(settings->excludeDirs, argv[t]); |
| 248 } |
301 } |
| 249 if (argflags == 0) { |
302 if (argflags == 0) { |
| 250 /* SHORTCUTS */ |
303 /* SHORTCUTS */ |
| 251 if (strcmp(argv[t], "--exclude-cstyle-comments") == 0) { |
304 if (strcmp(argv[t], "--exclude-cstyle-comments") == 0) { |
| 278 destroy_string_list_t(directories); |
331 destroy_string_list_t(directories); |
| 279 destroy_settings_t(settings); |
332 destroy_settings_t(settings); |
| 280 return 1; |
333 return 1; |
| 281 } |
334 } |
| 282 |
335 |
| |
336 /* Normalize paths for excluded directories */ |
| |
337 normalize_excluded_dirs(settings); |
| |
338 |
| 283 /* Scan directories */ |
339 /* Scan directories */ |
| 284 scanresult_t* result = new_scanresult_t(settings); |
340 scanresult_t* result = new_scanresult_t(settings); |
| 285 const char* result_type = settings->count_chars ? "chars" : "lines"; |
341 const char* result_type = settings->count_chars ? "chars" : "lines"; |
| 286 bool has_output = false; |
342 bool has_output = false; |
| 287 unsigned total = 0; |
343 unsigned total = 0; |
| 288 if (directories->count == 0) { |
344 if (directories->count == 0) { |
| 289 add_string(directories, "./"); |
345 add_string(directories, "."); |
| 290 } |
346 } |
| 291 for (unsigned t = 0 ; t < directories->count ; t++) { |
347 for (unsigned t = 0 ; t < directories->count ; t++) { |
| 292 /* Don't waste memory when only the total sum is needed */ |
348 /* Don't waste memory when only the total sum is needed */ |
| 293 string_list_t *output = NULL; |
349 string_list_t *output = NULL; |
| 294 if (settings->verbose) { |
350 if (settings->verbose) { |