Fri, 03 Jun 2022 20:05:15 +0200
new feature: count non-whitespace characters
--- a/src/arguments.c Fri Jun 03 18:13:46 2022 +0200 +++ b/src/arguments.c Fri Jun 03 20:05:15 2022 +0200 @@ -27,12 +27,12 @@ #include "arguments.h" int checkArgument(const char* arg, const char* expected) { - int len = strlen(expected); + size_t len = strlen(expected); int ret = 0; if (arg[0] == '-') { if (arg[1] != '-') { - for (int t = 0 ; t < len ; t++) { + for (size_t t = 0 ; t < len ; t++) { ret |= (strchr(arg, expected[t])?1:0) << t; } }
--- a/src/cline.c Fri Jun 03 18:13:46 2022 +0200 +++ b/src/cline.c Fri Jun 03 20:05:15 2022 +0200 @@ -39,6 +39,7 @@ "\n\nOptions:" "\n -b <level> - binary file heuristics level (default medium)" "\n One of: ignore low medium high" + "\n -c - Count non-whitespace characters instead of lines" "\n -E <pattern> - Excludes any line matching the <pattern>" "\n -e <start> <end> - Excludes lines between <start> and <end>" "\n You may use these options multiple times" @@ -63,11 +64,11 @@ "\nsource code in your working directory and its subdirectories, type:" "\n cline -rs .c\n" "\nIf you want to exclude comment lines, you may use the -e/-E option." - "\nAfter a line matches the regex pattern <start> any following line is" - "\nnot counted unless a line matches the <end> pattern. A line is still " - "\ncounted when it does not start or end with the respective patterns." - "\nPlease note, that cline does not remove whitespace characters as this" - "\nmight not be reasonable in some cases." + "\nAfter a line matches the regex pattern <start>, this and any following" + "\nline is not counted unless a line matches the <end> pattern. A line is" + "\nstill counted when it does not start or end with the respective pattern." + "\nPlease note, that cline does not trim the lines before matching against" + "\nthe pattern." "\n\nExample (C without comments):" "\n cline -s .c,.h --exclude-cstyle-comments" "\n"); @@ -107,7 +108,7 @@ for (int t = 1 ; t < argc ; t++) { - int argflags = checkArgument(argv[t], "hsSrRmvVbeEi"); + int argflags = checkArgument(argv[t], "hsSrRmvVbeEic"); int paropt = 0; /* h */ @@ -201,12 +202,19 @@ } /* i */ if ((argflags & 2048) > 0) { - // cannot be used together with -V + /* cannot be used together with -V */ if (registerArgument(&checked, 128)) { return exit_with_help(settings, 1); } settings->individual_sums = true; } + if ((argflags & 4096) > 0) { + if (registerArgument(&checked, 4096)) { + return exit_with_help(settings, 1); + } + settings->count_chars = true; + settings->regex->count_chars = true; + } if (argflags == 0) { /* SHORTCUTS */ if (strcmp(argv[t], "--exclude-cstyle-comments") == 0) { @@ -235,15 +243,16 @@ /* Don't waste memory when only the total sum is needed */ string_list_t *output = settings->verbose ? new_string_list_t() : NULL; char *outbuf; + const char* result_type = settings->count_chars ? "chars" : "lines"; - int total = 0; + unsigned total = 0; if (directories->count == 0) { add_string(directories, "."); } - for (int t = 0 ; t < directories->count ; t++) { + for (unsigned t = 0 ; t < directories->count ; t++) { scanDirectory((scanner_t){directories->items[t], 0}, settings, output, result); - total += result->lines; + total += result->result; if (directories->count > 1 ) { outbuf = (char*) malloc(81); memset(outbuf, '-', 79); @@ -251,8 +260,8 @@ outbuf[80] = 0; add_string(output, outbuf); outbuf = (char*) malloc(81); - snprintf(outbuf, 81, "%-63s%10d lines\n", directories->items[t], - result->lines); + snprintf(outbuf, 81, "%-63s%10u %s\n", directories->items[t], + result->result, result_type); add_string(output, outbuf); outbuf = (char*) malloc(81); memset(outbuf, '-', 79); @@ -272,32 +281,33 @@ if (result->ext) { if (result->ext->count > 0) { - for (int t = 0 ; t < 79 ; t++) { + for (unsigned t = 0 ; t < 79 ; t++) { printf("="); } printf("\nIndividual sums:\n"); - for (int t = 0 ; t < result->ext->count ; t++) { - printf(" %-62s%10d lines\n", - result->ext->extensions[t], - result->ext->lines[t]); + for (unsigned t = 0 ; t < result->ext->count ; t++) { + printf(" %-62s%10u %s\n", + result->ext->extensions[t], + result->ext->result[t], + result_type); } } } - for (int t = 0 ; t < 79 ; t++) { + for (unsigned t = 0 ; t < 79 ; t++) { printf("="); } - printf("\n%73d lines\n", total); + printf("\n%73d %s\n", total, result_type); if (settings->confusing_lnlen && settings->regex->pattern_list->count > 0) { printf("\nSome files contain too long lines.\n" - "The regex parser currently supports a maximum line length of %d." - "\nThe result might be wrong.\n", REGEX_MAX_LINELENGTH); + "The parser currently supports a maximum line length of %u." + "\nThe result might be wrong.\n", MAX_LINELENGTH); } } else { - printf("%d", total); + printf("%u", total); } destroy_scanresult_t(result); destroy_string_list_t(output);
--- a/src/regex_parser.c Fri Jun 03 18:13:46 2022 +0200 +++ b/src/regex_parser.c Fri Jun 03 20:05:15 2022 +0200 @@ -25,26 +25,28 @@ */ #include "regex_parser.h" +#include <ctype.h> regex_parser_t* new_regex_parser_t() { regex_parser_t* ret = malloc(sizeof(regex_parser_t)); if (ret != NULL) { ret->pattern_list = new_string_list_t(); - ret->matched_lines = 0; + ret->matched_counted = 0; ret->pattern_match = 0; ret->compiled_patterns = NULL; ret->compiled_pattern_count = 0; + ret->count_chars = false; } return ret; } void regex_parser_reset(regex_parser_t* parser) { - parser->pattern_match = parser->matched_lines = 0; + parser->pattern_match = parser->matched_counted = 0; } void regex_destcomppats(regex_parser_t* parser) { if (parser->compiled_patterns != NULL) { - for (int i = 0 ; i < parser->compiled_pattern_count ; i++) { + for (unsigned i = 0 ; i < parser->compiled_pattern_count ; i++) { if (parser->compiled_patterns[i] != NULL) { free(parser->compiled_patterns[i]); } @@ -65,13 +67,27 @@ return parser->pattern_match > 0; } +static unsigned regex_parser_count_chars(const char* input, + unsigned start, unsigned end) { + unsigned ret = 0; + for (unsigned i = start ; i < end ; i++) { + ret += isspace(input[i]) ? 0 : 1; + } + return ret; +} + int regex_parser_do(regex_parser_t* parser, char* input) { int err = REG_NOMATCH; if (parser->compiled_pattern_count > 0) { regmatch_t match; if (regex_parser_matching(parser)) { - parser->matched_lines++; + if (parser->count_chars) { + parser->matched_counted += + regex_parser_count_chars(input, 0, strlen(input)); + } else { + parser->matched_counted++; + } err = regexec(parser->compiled_patterns[parser->pattern_match], input, 1, &match, 0); @@ -80,25 +96,42 @@ } if (err == 0) { parser->pattern_match = 0; - /* do not match line, if it does not end with the pattern */ - if (match.rm_eo < strlen(input)) { - parser->matched_lines--; + size_t input_len = strlen(input); + if (match.rm_eo < input_len) { + if (parser->count_chars) { + /* do not exclude chars that occur after pattern end */ + parser->matched_counted -= + regex_parser_count_chars(input, match.rm_eo, input_len); + } else { + /* do not exclude line, if it does not end with the pattern */ + parser->matched_counted--; + } } } } else { - for (int i = 0 ; i < parser->compiled_pattern_count - 1 ; i += 2) { + for (unsigned i = 0 ; i < parser->compiled_pattern_count - 1 ; i += 2) { err = regexec(parser->compiled_patterns[i], input, 1, &match, 0); if (err > 0 && err != REG_NOMATCH) { fprintf(stderr, "Regex-Error: 0x%08x", err); } if (err == 0) { + /* a start pattern matches, start counting */ + parser->matched_counted = 0; + /* Check, if end pattern is also in this line */ parser->pattern_match = i+1; - parser->matched_lines = 0; - /* Check, if end pattern is also in this line */ regex_parser_do(parser, input); - /* do not match line, if it does not start with the pattern */ - if (match.rm_so > 0 && parser->matched_lines > 0) { - parser->matched_lines--; + /* If something was found, determine what exactly to exclude */ + if (parser->matched_counted > 0) { + if (parser->count_chars) { + /* do not exclude the characters before the pattern */ + parser->matched_counted -= + regex_parser_count_chars(input, 0, match.rm_so); + } else { + /* do not match line, if it does not start with the pattern */ + if (match.rm_so > 0) { + parser->matched_counted--; + } + } } break; } @@ -117,7 +150,7 @@ parser->compiled_pattern_count = pcount; regex_t* re; - for (int i = 0 ; i < pcount ; i++) { + for (unsigned i = 0 ; i < pcount ; i++) { re = malloc(sizeof(regex_t)); if (regcomp(re, parser->pattern_list->items[i], REG_EXTENDED) == 0) { parser->compiled_patterns[i] = re;
--- a/src/regex_parser.h Fri Jun 03 18:13:46 2022 +0200 +++ b/src/regex_parser.h Fri Jun 03 20:05:15 2022 +0200 @@ -27,7 +27,7 @@ #ifndef REGEX_PARSER_H_ #define REGEX_PARSER_H_ -#define REGEX_MAX_LINELENGTH 2048 +#define MAX_LINELENGTH 4096u #include <sys/types.h> #include <stdbool.h> @@ -40,7 +40,8 @@ size_t compiled_pattern_count; unsigned int pattern_match; /* save position of end pattern to match - NULL when a start pattern shall match first */ - unsigned int matched_lines; + unsigned int matched_counted; + bool count_chars; } regex_parser_t; #ifdef _cplusplus
--- a/src/scanner.c Fri Jun 03 18:13:46 2022 +0200 +++ b/src/scanner.c Fri Jun 03 20:05:15 2022 +0200 @@ -29,22 +29,23 @@ #include "bfile_heuristics.h" #include "regex_parser.h" #include <sys/stat.h> +#include <ctype.h> typedef struct filelist filelist_t; struct filelist { char *displayname; - int displayname_len; + unsigned displayname_len; char *filename; char *ext; - int st_mode; + unsigned st_mode; filelist_t *next; }; static bool testSuffix(char* filename, string_list_t* list) { bool ret = false; - int tokenlen, fnamelen = strlen(filename); - for (int t = 0 ; t < list->count ; t++) { + size_t tokenlen, fnamelen = strlen(filename); + for (size_t t = 0 ; t < list->count ; t++) { tokenlen = strlen(list->items[t]); if (fnamelen >= tokenlen && tokenlen > 0) { if (strncmp(filename+fnamelen-tokenlen, @@ -57,34 +58,34 @@ return ret; } -static void addLinesPerExtension(scanresult_ext_t* result, - char* ext, int lines) { +static void addResultPerExtension(scanresult_ext_t* result, + char* ext, unsigned value) { if (!result) return; if (!ext) ext = "w/o"; - for (int i = 0 ; i < result->count ; i++) { + for (unsigned i = 0 ; i < result->count ; i++) { if (strcasecmp(result->extensions[i], ext) == 0) { - result->lines[i] += lines; + result->result[i] += value; return; } } if (result->count == result->capacity) { - int newcap = result->capacity+8; + unsigned newcap = result->capacity+8; char** extarr = realloc(result->extensions, newcap*sizeof(char*)); - int* linesarr = realloc(result->lines, newcap*sizeof(int)); - if (!extarr || !linesarr) { + unsigned* resultarr = realloc(result->result, newcap*sizeof(unsigned)); + if (!extarr || !resultarr) { fprintf(stderr, "Memory allocation error.\n"); abort(); } result->extensions = extarr; - result->lines = linesarr; + result->result = resultarr; result->capacity = newcap; } result->extensions[result->count] = strdup(ext); - result->lines[result->count] = lines; + result->result[result->count] = value; result->count++; } @@ -99,21 +100,20 @@ void destroy_scanresult_t(scanresult_t* result) { if (result->ext) { if (result->ext->count > 0) { - for (int i = 0 ; i < result->ext->count ; i++) { + for (unsigned i = 0 ; i < result->ext->count ; i++) { free(result->ext->extensions[i]); } free(result->ext->extensions); - free(result->ext->lines); + free(result->ext->result); } free(result->ext); } free(result); } +static filelist_t *buildFileList(scanner_t scanner, settings_t* settings) { -static filelist_t *buildFileList(scanner_t scanner, settings_t* settings, - filelist_t* list) { - + filelist_t* list = NULL; DIR *dirf; struct dirent *entry; struct stat statbuf; @@ -159,7 +159,7 @@ } if (list) { - // create fake root to have a pointer on the true root + /* create fake root to have a pointer on the true root */ filelist_t root; root.next = list; filelist_t *parent = &root; @@ -188,12 +188,12 @@ void scanDirectory(scanner_t scanner, settings_t* settings, string_list_t* output, scanresult_t* result) { - result->lines = 0; - int a; + result->result = 0; bool bfile; char *outbuf; + const char *result_type = settings->count_chars ? "chars" : "lines"; - filelist_t *filelist = buildFileList(scanner, settings, NULL); + filelist_t *filelist = buildFileList(scanner, settings); while (filelist != NULL) { @@ -206,23 +206,24 @@ scanDirectory( (scanner_t) {filelist->filename, scanner.spaces+1}, settings, recoutput, &recresult); - result->lines += recresult.lines; + result->result += recresult.result; if (!settings->matchesOnly || recoutput->count > 0) { outbuf = (char*) malloc(81); - snprintf(outbuf, 81, "%*s/%*s%13d lines\n", + snprintf(outbuf, 81, "%*s/%*s%13u %s\n", filelist->displayname_len+scanner.spaces, filelist->displayname, 60-filelist->displayname_len-scanner.spaces-1, "", - recresult.lines); + recresult.result, result_type); add_string(output, outbuf); - for (int i = 0 ; i < recoutput->count ; i++) { + for (unsigned i = 0 ; i < recoutput->count ; i++) { add_string(output, recoutput->items[i]); } } destroy_string_list_t(recoutput); } else { outbuf = (char*) malloc(81); - snprintf(outbuf, 81, "%*s\n", filelist->displayname_len+scanner.spaces, - filelist->displayname); + snprintf(outbuf, 81, "%*s\n", + filelist->displayname_len+scanner.spaces, + filelist->displayname); add_string(output, outbuf); } } else { @@ -230,44 +231,55 @@ || testSuffix(filelist->displayname, settings->includeSuffixes)) && !testSuffix(filelist->displayname, settings->excludeSuffixes)) { - /* Count lines */ - int lines = 0; + /* Count */ + unsigned res_value = 0; bfile = false; bfile_reset(settings->bfileHeuristics); regex_parser_reset(settings->regex); - char line_buffer[REGEX_MAX_LINELENGTH]; - int line_buffer_offset = 0; + char line_buffer[MAX_LINELENGTH]; + unsigned line_buffer_pos = 0; FILE *file = fopen(filelist->filename, "r"); if (file == NULL) { outbuf = (char*) malloc(81); - snprintf(outbuf, 81, "%*s", filelist->displayname_len+scanner.spaces, - filelist->displayname); + snprintf(outbuf, 81, "%*s", + filelist->displayname_len+scanner.spaces, + filelist->displayname); add_string(output, outbuf); perror(" File acces failed"); } else { + int a; do { a = fgetc(file); bfile = bfile_check(settings->bfileHeuristics, a); + /* ignore carriage return completely */ + if (a == 13) continue; + if (a == 10 || a == EOF) { - line_buffer[line_buffer_offset] = 0; + line_buffer[line_buffer_pos] = 0; if (regex_parser_do(settings->regex, line_buffer) == 0) { - /* Only subtract lines when matching has finished */ + /* Subtract excluded lines/chars when matching has finished */ if (!regex_parser_matching(settings->regex)) { - lines -= settings->regex->matched_lines; + res_value -= settings->regex->matched_counted; } } - line_buffer_offset = 0; - lines++; + if (settings->count_chars) { + for (size_t i = 0 ; i < line_buffer_pos ; i++) { + if (!isspace(line_buffer[i])) res_value++; + } + } else { + res_value++; + } + line_buffer_pos = 0; } else { - if (line_buffer_offset < REGEX_MAX_LINELENGTH) { - line_buffer[line_buffer_offset] = a; - line_buffer_offset++; + if (line_buffer_pos < MAX_LINELENGTH) { + line_buffer[line_buffer_pos] = (char) a; + line_buffer_pos++; } else { - line_buffer[line_buffer_offset-1] = 0; + line_buffer[line_buffer_pos - 1] = 0; settings->confusing_lnlen = true; } } @@ -285,12 +297,17 @@ add_string(output, outbuf); } } else { - addLinesPerExtension(result->ext, filelist->ext, lines); - result->lines += lines; + addResultPerExtension(result->ext, filelist->ext, res_value); + result->result += res_value; outbuf = (char*) malloc(81); - snprintf(outbuf, 81, "%*s%*s%13d lines\n", - filelist->displayname_len+scanner.spaces, filelist->displayname, - 60-filelist->displayname_len-scanner.spaces, "", lines); + snprintf(outbuf, 81, "%*s%*s%13u %s\n", + filelist->displayname_len+scanner.spaces, + filelist->displayname, + 60-filelist->displayname_len-scanner.spaces, + "", + res_value, + result_type + ); add_string(output, outbuf); } }
--- a/src/scanner.h Fri Jun 03 18:13:46 2022 +0200 +++ b/src/scanner.h Fri Jun 03 20:05:15 2022 +0200 @@ -33,18 +33,18 @@ typedef struct { char *dir; - int spaces; + unsigned spaces; } scanner_t; typedef struct { - int count; - int capacity; + unsigned count; + unsigned capacity; char** extensions; - int* lines; + unsigned* result; } scanresult_ext_t; typedef struct { - int lines; + unsigned result; scanresult_ext_t* ext; } scanresult_t;
--- a/src/settings.c Fri Jun 03 18:13:46 2022 +0200 +++ b/src/settings.c Fri Jun 03 20:05:15 2022 +0200 @@ -42,7 +42,8 @@ settings->bfileHeuristics = new_bfile_heuristics_t(); settings->confusing_lnlen = false; settings->regex = new_regex_parser_t(); - settings->individual_sums = false; + settings->individual_sums = false; + settings->count_chars = false; } return settings;
--- a/src/settings.h Fri Jun 03 18:13:46 2022 +0200 +++ b/src/settings.h Fri Jun 03 20:05:15 2022 +0200 @@ -32,7 +32,7 @@ #include "bfile_heuristics.h" #include "regex_parser.h" -typedef struct _settings { +typedef struct settings_s { string_list_t* includeSuffixes; string_list_t* excludeSuffixes; regex_parser_t* regex; @@ -43,6 +43,7 @@ bool verbose; bool confusing_lnlen; /* this flag is set by the scanner */ bool individual_sums; + bool count_chars; } settings_t; #ifdef _cplusplus
--- a/src/string_list.h Fri Jun 03 18:13:46 2022 +0200 +++ b/src/string_list.h Fri Jun 03 20:05:15 2022 +0200 @@ -29,7 +29,7 @@ #include "stdinc.h" -typedef struct _string_list { +typedef struct string_list_s { size_t count; char** items; } string_list_t;
--- a/test/Makefile.am Fri Jun 03 18:13:46 2022 +0200 +++ b/test/Makefile.am Fri Jun 03 20:05:15 2022 +0200 @@ -22,5 +22,5 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. TESTS = $(check_SCRIPTS) -check_SCRIPTS = total.sh nocomments.sh codeonly.sh +check_SCRIPTS = total.sh total_chars.sh nocomments.sh codeonly.sh codeonly_chars.sh EXTRA_DIST = $(check_SCRIPTS) testfile.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/codeonly_chars.sh Fri Jun 03 20:05:15 2022 +0200 @@ -0,0 +1,44 @@ +#!/bin/sh +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright 2018 Mike Becker. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +echo -n "Verifying correctness of code only character count: " + +clineprg="$(pwd)/../src/cline" + +cd $srcdir +count=`$clineprg -Vcs testfile.c --exclude-cstyle-comments` +expected=50 + +if [ "$count" -eq "$expected" ]; then + echo "OK." + exit 0; +else + echo "FAIL! $count is not $expected" + exit 1; +fi
--- a/test/testfile.c Fri Jun 03 18:13:46 2022 +0200 +++ b/test/testfile.c Fri Jun 03 20:05:15 2022 +0200 @@ -4,7 +4,7 @@ // And add other stuff below. -int main(int argc, char* argv) { // comments behind code don't matter +int main(int argc, char** argv) { // comments behind code don't matter int zero /* in block comments we are genius enough to * detect, if there is still some code in the line
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/total_chars.sh Fri Jun 03 20:05:15 2022 +0200 @@ -0,0 +1,44 @@ +#!/bin/sh +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright 2018 Mike Becker. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +echo -n "Verifying correctness of total character count: " + +clineprg="$(pwd)/../src/cline" + +cd $srcdir +count=`$clineprg -Vcs testfile.c` +expected=334 + +if [ "$count" -eq "$expected" ]; then + echo "OK." + exit 0; +else + echo "FAIL! $count is not $expected" + exit 1; +fi