src/cline.c

changeset 79
e4592d0292e7
parent 66
be2084398c37
equal deleted inserted replaced
78:b3d267334140 79:e4592d0292e7
1 /* 1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 * Copyright 2018 Mike Becker. All rights reserved. 3 * Copyright 2018 Mike Becker. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
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();
106 char* excludeSuffix = NULL; 114 char* excludeSuffix = NULL;
107 int checked = 0; 115 int checked = 0;
108 116
109 for (int t = 1 ; t < argc ; t++) { 117 for (int t = 1 ; t < argc ; t++) {
110 118
111 int argflags = checkArgument(argv[t], "hsSrRmvVbeEic"); 119 int argflags = checkArgument(argv[t], "hsSrRmvVbeEicd");
112 int paropt = 0; 120 int paropt = 0;
113 121
114 /* h */ 122 /* h */
115 if ((argflags & 1) > 0 || strcmp(argv[t], "--help") == 0) { 123 if ((argflags & 1) > 0 || strcmp(argv[t], "--help") == 0) {
116 return exit_with_help(settings, 0); 124 return exit_with_help(settings, 0);
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"

mercurial