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" |