cline.c

Tue, 28 Aug 2012 16:44:32 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 28 Aug 2012 16:44:32 +0200
changeset 32
51d6e45a7592
parent 31
27c3c1c6b768
child 33
1a2d7298bc82
permissions
-rw-r--r--

changed version output slightly

     1 /*
     2  * cline.c
     3  *
     4  *  Created on: 23.05.2011
     5  *      Author: Mike
     6  */
     8 #include "cline.h"
     9 #include "scanner.h"
    10 #include "settings.h"
    11 #include "arguments.h"
    12 #include "stream.h"
    13 #include "regex_parser.h"
    15 void printHelpText() {
    16   const char* helpText = 
    17     "\nUsage:"
    18     "\n      cline [Options] [Directory]"
    19     "\n      cline [Options] [Directory]"
    20     "\n\nCounts the line terminator characters (\\n) within all"
    21     " files in the specified\ndirectory."
    22     "\n\nOptions:"
    23     "\n  -b <level>          - binary file heuristics level (default medium)"
    24     "\n                        One of: ignore low medium high"
    25     "\n  -E <pattern>        - Excludes any line matching the <pattern>"
    26     "\n  -e <start> <end>    - Excludes lines between <start> and <end>"
    27     "\n                        You may use these options multiple times"
    28     "\n  -h, --help          - this help text"
    29     "\n  -m                  - print information about matching files only"
    30     "\n  -s <suffixes>       - only count files with these suffixes (separated"
    31     "\n                        by commas)"
    32     "\n  -S <suffixes>       - count any file except those with these suffixes"
    33     "\n                        (separated by commas)"
    34     "\n  -r, -R              - includes subdirectories"
    35     "\n  -v, --version       - print out version information"
    36     "\n  -V                  - turn verbose output off, print the result only"
    37     "\n\nShortcuts:"
    38     "\n  --exclude-cstyle-comments"
    39     "\n = -E \"\\s*//\" -e \"\\s*/\\*\" \"\\*/\\s*\""
    40     "\n\n"
    41     "The default call without any options is:"    
    42     "\n  cline ./\n\n"
    43     "So each file in the working directory is counted. If you want to count C"
    44     "\nsource code in your working directory and its subdirectories, type:"
    45     "\n  cline -rs .c\n"
    46     "\nIf you want to exclude comment lines, you may use the -e/-E option."
    47     "\nAfter a line matches the regex pattern <start> any following line is"
    48     "\nnot counted unless a line matches the <end> pattern. A line is still "
    49     "\ncounted when it does not start or end with the respective patterns."
    50     "\nPlease note, that cline does not remove whitespace characters as this"
    51     "\nmight not be reasonable in some cases."
    52     "\n\nExample (C without comments):"
    53     "\n  cline -s .c,.h --exclude-cstyle-comments";
    55   printf(helpText);
    56 }
    58 int exit_with_version(settings_t* settings) {
    59   printf("cline - Revision: %s\n", VERSION);
    60   destroy_settings_t(settings);
    61   return 0;
    62 }
    64 int exit_with_help(settings_t* settings, int code) {
    65   printHelpText();
    66   destroy_settings_t(settings);
    67   return code;
    68 }
    70 int main(int argc, char** argv) {
    72   /* Settings */
    73   settings_t *settings = new_settings_t();
    74   if (settings == NULL) {
    75     fprintf(stderr, "Memory allocation failed.\n");
    76     return 1;
    77   }
    79   /* Get arguments */
    80   char* directory = "./";
    81   char* includeSuffix = NULL;
    82   char* excludeSuffix = NULL;
    83   int checked = 0;
    85   for (int t = 1 ; t < argc ; t++) {
    87     int argflags = checkArgument(argv[t], "hsSrRmvVbeE");
    88     int paropt = 0;
    90     /* s */
    91     if ((argflags & 2) > 0) {
    92       if (!checkParamOpt(&paropt) || registerArgument(&checked, 2)) {
    93         return exit_with_help(settings, 1);
    94       }
    95       t++;
    96       if (t >= argc) {
    97         return exit_with_help(settings, 1);
    98       }
    99       includeSuffix = argv[t];
   100     }
   101     /* S */
   102     if ((argflags & 4) > 0) {
   103       if (!checkParamOpt(&paropt) || registerArgument(&checked, 4)) {
   104         return exit_with_help(settings, 1);
   105       }
   106       t++;
   107       if (t >= argc) {
   108         return exit_with_help(settings, 1);
   109       }
   110       excludeSuffix = argv[t];
   111     }
   112     /* h */
   113     if ((argflags & 1) > 0 || strcmp(argv[t], "--help") == 0) {
   114       return exit_with_help(settings, 0);
   115     }
   116     /* r, R */
   117     if ((argflags & 24) > 0) {
   118       if (registerArgument(&checked, 24)) {
   119         return exit_with_help(settings, 1);
   120       }
   121       settings->recursive = true;
   122     }
   123     /* m */
   124     if ((argflags & 32) > 0) {
   125       if (registerArgument(&checked, 32)) {
   126         return exit_with_help(settings, 1);
   127       }
   128       settings->matchesOnly = true;
   129     }
   130     /* v */
   131     if ((argflags & 64) > 0 || strcmp(argv[t], "--version") == 0) {
   132       return exit_with_version(settings);
   133     }
   134     /* V */
   135     if ((argflags & 128) > 0) {
   136       if (registerArgument(&checked, 128)) {
   137         return exit_with_help(settings, 1);
   138       }
   139       settings->verbose = false;
   140     }
   141     /* b */
   142     if ((argflags & 256) > 0) {
   143       if (!checkParamOpt(&paropt) || registerArgument(&checked, 256)) {
   144         return exit_with_help(settings, 1);
   145       }
   146       t++;
   147       if (t >= argc) {
   148         return exit_with_help(settings, 1);
   149       }
   150       if (strcasecmp(argv[t], "ignore") == 0) {
   151         settings->bfileHeuristics->level = BFILE_IGNORE;
   152       } else if (strcasecmp(argv[t], "low") == 0) {
   153         settings->bfileHeuristics->level = BFILE_LOW_ACCURACY;
   154       } else if (strcasecmp(argv[t], "medium") == 0) {
   155         settings->bfileHeuristics->level = BFILE_MEDIUM_ACCURACY;
   156       } else if (strcasecmp(argv[t], "high") == 0) {
   157         settings->bfileHeuristics->level = BFILE_HIGH_ACCURACY;
   158       } else {
   159         return exit_with_help(settings, 1);
   160       }
   161     }
   162     /* e */
   163     if ((argflags & 512) > 0) {
   164       if (!checkParamOpt(&paropt) || t + 2 >= argc) {
   165         return exit_with_help(settings, 1);
   166       }
   167       t++; add_string(settings->regex->pattern_list, argv[t]);
   168       t++; add_string(settings->regex->pattern_list, argv[t]);
   169     }
   170     /* E */
   171     if ((argflags & 1024) > 0) {
   172       t++;
   173       if (!checkParamOpt(&paropt) || t >= argc) {
   174         return exit_with_help(settings, 1);
   175       }
   176       add_string(settings->regex->pattern_list, argv[t]);
   177       add_string(settings->regex->pattern_list, "$");
   178     }
   179     if (argflags == 0) {
   180       /* SHORTCUTS */
   181       /* exclude-cstyle-comments */
   182       if (strcmp(argv[t], "--exclude-cstyle-comments") == 0) {
   183         add_string(settings->regex->pattern_list, "\\s*//");
   184         add_string(settings->regex->pattern_list, "$");
   185         add_string(settings->regex->pattern_list, "\\s*/\\*");
   186         add_string(settings->regex->pattern_list, "\\*/\\s*");
   187       }
   188       /* Path */
   189       else if (registerArgument(&checked, 1024)) {
   190         return exit_with_help(settings, 1);
   191       }
   192       directory = argv[t];
   193     }
   194   }
   196   /* Configure output */
   197   if (!settings->verbose) {
   198     close_stdout();
   199   }
   201   /* Find tokens */
   202   parseCSL(includeSuffix, settings->includeSuffixes);
   203   parseCSL(excludeSuffix, settings->excludeSuffixes);
   205   /* Scan directory */
   206   if (regex_compile_all(settings->regex)) {
   207     int lines = scanDirectory((scanner_t){directory, 0}, settings);
   208     destroy_settings_t(settings);
   210     /* Print double line and line count */
   211     for (int t = 0 ; t < 79 ; t++) {
   212       printf("=");
   213     }
   214     printf("\n%73d lines\n", lines);
   216     if (settings->confusing_lnlen && settings->regex->pattern_list->count > 0) {
   217       printf("\nSome files contain too long lines.\n"
   218         "The regex parser currently supports a maximum line length of %d."
   219         "\nThe result might be wrong.\n", REGEX_MAX_LINELENGTH);
   220     }
   222     if (!settings->verbose) {
   223       reopen_stdout();
   224       printf("%d", lines);
   225     }
   226   }
   228   fflush(stdout);
   229   fflush(stderr);
   230   return 0;
   231 }

mercurial