| 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 25 */ |
25 */ |
| 26 |
26 |
| 27 #include "cline.h" |
27 #ifndef VERSION |
| |
28 #error "VERSION macro must be set by build system" |
| |
29 #endif |
| |
30 |
| |
31 #include "stdinc.h" |
| |
32 #include "settings.h" |
| 28 #include "scanner.h" |
33 #include "scanner.h" |
| 29 #include "settings.h" |
|
| 30 #include "arguments.h" |
34 #include "arguments.h" |
| 31 #include "regex_parser.h" |
35 #include "regex_parser.h" |
| 32 |
36 |
| 33 void printHelpText() { |
37 static void printHelpText() { |
| 34 printf( |
38 printf( |
| 35 "\nUsage:" |
39 "\nUsage:" |
| 36 "\n cline [Options] [Directories...]" |
40 "\n cline [Options] [Directories...]" |
| 37 "\n\nCounts the line terminator characters (\\n) within all" |
41 "\n\nCounts the line terminator characters (\\n) within all" |
| 38 " files in the specified\ndirectories." |
42 " files in the specified\ndirectories." |
| 39 "\n\nOptions:" |
43 "\n\nOptions:" |
| 40 "\n -b <level> - binary file heuristics level (default medium)" |
44 "\n -b <level> - binary file heuristics level (default medium)" |
| 41 "\n One of: ignore low medium high" |
45 "\n One of: ignore low medium high" |
| 42 "\n -c - Count non-whitespace characters instead of lines" |
46 "\n -c - Count non-whitespace characters instead of lines" |
| |
47 "\n -d - Report only directory sums" |
| 43 "\n -E <pattern> - Excludes any line matching the <pattern>" |
48 "\n -E <pattern> - Excludes any line matching the <pattern>" |
| 44 "\n -e <start> <end> - Excludes lines between <start> and <end>" |
49 "\n -e <start> <end> - Excludes lines between <start> and <end>" |
| 45 "\n You may use these options multiple times" |
50 "\n You may use these options multiple times" |
| 46 "\n -h, --help - this help text" |
51 "\n -h, --help - this help text" |
| 47 "\n -i - print out individual sums per file extension" |
52 "\n -i - print out individual sums per file extension" |
| 72 "\n\nExample (C without comments):" |
77 "\n\nExample (C without comments):" |
| 73 "\n cline -s .c,.h --exclude-cstyle-comments" |
78 "\n cline -s .c,.h --exclude-cstyle-comments" |
| 74 "\n"); |
79 "\n"); |
| 75 } |
80 } |
| 76 |
81 |
| 77 int exit_with_version(settings_t* settings) { |
82 static int exit_with_version(settings_t* settings) { |
| 78 printf("cline - Version: " VERSION "\n"); |
83 printf("cline - Version: " VERSION "\n"); |
| 79 destroy_settings_t(settings); |
84 destroy_settings_t(settings); |
| 80 return 0; |
85 return 0; |
| 81 } |
86 } |
| 82 |
87 |
| 83 int exit_with_help(settings_t* settings, int code) { |
88 static int exit_with_help(settings_t* settings, int code) { |
| 84 printf("cline - Version: " VERSION "\n"); |
89 printf("cline - Version: " VERSION "\n"); |
| 85 printHelpText(); |
90 printHelpText(); |
| 86 destroy_settings_t(settings); |
91 destroy_settings_t(settings); |
| 87 return code; |
92 return code; |
| 88 } |
93 } |
| |
94 |
| |
95 static const char * sepline_double = "===============================================================================\n"; |
| |
96 static const char * sepline_single = "-------------------------------------------------------------------------------\n"; |
| 89 |
97 |
| 90 int main(int argc, char** argv) { |
98 int main(int argc, char** argv) { |
| 91 |
99 |
| 92 /* Settings */ |
100 /* Settings */ |
| 93 settings_t *settings = new_settings_t(); |
101 settings_t *settings = new_settings_t(); |
| 201 add_string(settings->regex->pattern_list, "$"); |
209 add_string(settings->regex->pattern_list, "$"); |
| 202 } |
210 } |
| 203 /* i */ |
211 /* i */ |
| 204 if ((argflags & 2048) > 0) { |
212 if ((argflags & 2048) > 0) { |
| 205 /* cannot be used together with -V */ |
213 /* cannot be used together with -V */ |
| 206 if (registerArgument(&checked, 128)) { |
214 if ((checked & 128) > 0) { |
| 207 return exit_with_help(settings, 1); |
215 return exit_with_help(settings, 1); |
| 208 } |
216 } |
| 209 settings->individual_sums = true; |
217 settings->individual_sums = true; |
| 210 } |
218 } |
| |
219 /* c */ |
| 211 if ((argflags & 4096) > 0) { |
220 if ((argflags & 4096) > 0) { |
| 212 if (registerArgument(&checked, 4096)) { |
221 if (registerArgument(&checked, 4096)) { |
| 213 return exit_with_help(settings, 1); |
222 return exit_with_help(settings, 1); |
| 214 } |
223 } |
| 215 settings->count_chars = true; |
224 settings->count_chars = true; |
| 216 settings->regex->count_chars = true; |
225 settings->regex->count_chars = true; |
| |
226 } |
| |
227 /* d */ |
| |
228 if ((argflags & 8192) > 0) { |
| |
229 if (registerArgument(&checked, 8192)) { |
| |
230 return exit_with_help(settings, 1); |
| |
231 } |
| |
232 /* ignored together with -V */ |
| |
233 if ((checked & 128) == 0) { |
| |
234 settings->dirsOnly = true; |
| |
235 } |
| 217 } |
236 } |
| 218 if (argflags == 0) { |
237 if (argflags == 0) { |
| 219 /* SHORTCUTS */ |
238 /* SHORTCUTS */ |
| 220 if (strcmp(argv[t], "--exclude-cstyle-comments") == 0) { |
239 if (strcmp(argv[t], "--exclude-cstyle-comments") == 0) { |
| 221 add_string(settings->regex->pattern_list, "\\s*//"); |
240 add_string(settings->regex->pattern_list, "\\s*//"); |
| 245 char *outbuf; |
264 char *outbuf; |
| 246 const char* result_type = settings->count_chars ? "chars" : "lines"; |
265 const char* result_type = settings->count_chars ? "chars" : "lines"; |
| 247 |
266 |
| 248 unsigned total = 0; |
267 unsigned total = 0; |
| 249 if (directories->count == 0) { |
268 if (directories->count == 0) { |
| 250 add_string(directories, "."); |
269 add_string(directories, "./"); |
| 251 } |
270 } |
| 252 for (unsigned t = 0 ; t < directories->count ; t++) { |
271 for (unsigned t = 0 ; t < directories->count ; t++) { |
| 253 scanDirectory((scanner_t){directories->items[t], 0}, settings, |
272 scanDirectory((scanner_t){directories->items[t], 0}, settings, |
| 254 output, result); |
273 output, result); |
| 255 total += result->result; |
274 total += result->result; |
| 256 if (directories->count > 1 ) { |
275 if (directories->count > 1) { |
| 257 outbuf = (char*) malloc(81); |
276 add_string(output, strdup(sepline_single)); |
| 258 memset(outbuf, '-', 79); |
|
| 259 outbuf[79] = '\n'; |
|
| 260 outbuf[80] = 0; |
|
| 261 add_string(output, outbuf); |
|
| 262 outbuf = (char*) malloc(81); |
277 outbuf = (char*) malloc(81); |
| 263 snprintf(outbuf, 81, "%-63s%10u %s\n", directories->items[t], |
278 snprintf(outbuf, 81, "%-63s%10u %s\n", directories->items[t], |
| 264 result->result, result_type); |
279 result->result, result_type); |
| 265 add_string(output, outbuf); |
280 add_string(output, outbuf); |
| 266 outbuf = (char*) malloc(81); |
281 add_string(output, strdup(sepline_single)); |
| 267 memset(outbuf, '-', 79); |
|
| 268 outbuf[79] = '\n'; |
|
| 269 outbuf[80] = 0; |
|
| 270 add_string(output, outbuf); |
|
| 271 } |
282 } |
| 272 } |
283 } |
| 273 destroy_string_list_t(directories); |
284 destroy_string_list_t(directories); |
| 274 |
285 |
| 275 /* Print result */ |
286 /* Print result */ |
| 276 if (settings->verbose) { |
287 if (output != NULL) { |
| 277 for (int i = 0 ; i < output->count ; i++) { |
288 for (int i = 0 ; i < output->count ; i++) { |
| 278 printf("%s", output->items[i]); |
289 printf("%s", output->items[i]); |
| 279 free(output->items[i]); |
290 free(output->items[i]); |
| 280 } |
291 } |
| 281 |
292 |
| 282 if (result->ext) { |
293 if (result->ext) { |
| 283 if (result->ext->count > 0) { |
294 if (result->ext->count > 0) { |
| 284 for (unsigned t = 0 ; t < 79 ; t++) { |
295 fwrite(sepline_double, 1, 80, stdout); |
| 285 printf("="); |
|
| 286 } |
|
| 287 printf("\nIndividual sums:\n"); |
296 printf("\nIndividual sums:\n"); |
| 288 for (unsigned t = 0 ; t < result->ext->count ; t++) { |
297 for (unsigned t = 0 ; t < result->ext->count ; t++) { |
| 289 printf(" %-62s%10u %s\n", |
298 printf(" %-62s%10u %s\n", |
| 290 result->ext->extensions[t], |
299 result->ext->extensions[t], |
| 291 result->ext->result[t], |
300 result->ext->result[t], |
| 292 result_type); |
301 result_type); |
| 293 } |
302 } |
| 294 } |
303 } |
| 295 } |
304 } |
| 296 |
305 |
| 297 for (unsigned t = 0 ; t < 79 ; t++) { |
306 if (output->count > 0) { |
| 298 printf("="); |
307 fwrite(sepline_double, 1, 80, stdout); |
| 299 } |
308 printf("%73d %s\n", total, result_type); |
| 300 printf("\n%73d %s\n", total, result_type); |
309 } else { |
| |
310 /* If we only need to output a total, output it differently */ |
| |
311 printf("%d %s\n", total, result_type); |
| |
312 } |
| 301 |
313 |
| 302 if (settings->confusing_lnlen && |
314 if (settings->confusing_lnlen && |
| 303 settings->regex->pattern_list->count > 0) { |
315 settings->regex->pattern_list->count > 0) { |
| 304 |
316 |
| 305 printf("\nSome files contain too long lines.\n" |
317 printf("\nSome files contain too long lines.\n" |