cline.c

Thu, 09 Feb 2012 15:56:18 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 09 Feb 2012 15:56:18 +0100
changeset 30
d642fdb6745e
parent 28
72a98cbcb9f1
child 31
27c3c1c6b768
permissions
-rw-r--r--

allow parallel use of -s and -S

     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\n"
    38     "The default call without any options is:"    
    39     "\n  cline ./\n\n"
    40     "So each file in the working directory is counted. If you want to count C"
    41     "\nsource code in your working directory and its subdirectories, type:"
    42     "\n  cline -rs .c\n"
    43     "\nIf you want to exclude comment lines, you may use the -e/-E option."
    44     "\nAfter a line matches the regex pattern <start> any following line is"
    45     "\nnot counted unless a line matches the <end> pattern. A line is still "
    46     "\ncounted when it does not start or end with the respective patterns."
    47     "\nPlease note, that cline does not remove whitespace characters as this"
    48     "\nmight not be reasonable in some cases."
    49     "\n\nExample (C comments):"
    50     "\n  cline -s .c,.h -E \"\\s*//\" -e \"\\s*/\\*\" \"\\*/\\s*\"";
    52   printf(helpText);
    53 }
    55 int exit_with_version(settings_t* settings) {
    56   printf("cline - Revision: %s", VERSION);
    57   destroy_settings_t(settings);
    58   return 0;
    59 }
    61 int exit_with_help(settings_t* settings, int code) {
    62   printHelpText();
    63   destroy_settings_t(settings);
    64   return code;
    65 }
    67 int main(int argc, char** argv) {
    69   /* Settings */
    70   settings_t *settings = new_settings_t();
    71   if (settings == NULL) {
    72     fprintf(stderr, "Memory allocation failed.\n");
    73     return 1;
    74   }
    76   /* Get arguments */
    77   char* directory = "./";
    78   char* includeSuffix = NULL;
    79   char* excludeSuffix = NULL;
    80   int checked = 0;
    82   for (int t = 1 ; t < argc ; t++) {
    84     int argflags = checkArgument(argv[t], "hsSrRmvVbeE");
    85     int paropt = 0;
    87     /* s */
    88     if ((argflags & 2) > 0) {
    89       if (!checkParamOpt(&paropt) || registerArgument(&checked, 2)) {
    90         return exit_with_help(settings, 1);
    91       }
    92       t++;
    93       if (t >= argc) {
    94         return exit_with_help(settings, 1);
    95       }
    96       includeSuffix = argv[t];
    97     }
    98     /* S */
    99     if ((argflags & 4) > 0) {
   100       if (!checkParamOpt(&paropt) || registerArgument(&checked, 4)) {
   101         return exit_with_help(settings, 1);
   102       }
   103       t++;
   104       if (t >= argc) {
   105         return exit_with_help(settings, 1);
   106       }
   107       excludeSuffix = argv[t];
   108     }
   109     /* h */
   110     if ((argflags & 1) > 0 || strcmp(argv[t], "--help") == 0) {
   111       return exit_with_help(settings, 0);
   112     }
   113     /* r, R */
   114     if ((argflags & 24) > 0) {
   115       if (registerArgument(&checked, 24)) {
   116         return exit_with_help(settings, 1);
   117       }
   118       settings->recursive = true;
   119     }
   120     /* m */
   121     if ((argflags & 32) > 0) {
   122       if (registerArgument(&checked, 32)) {
   123         return exit_with_help(settings, 1);
   124       }
   125       settings->matchesOnly = true;
   126     }
   127     /* v */
   128     if ((argflags & 64) > 0 || strcmp(argv[t], "--version") == 0) {
   129       return exit_with_version(settings);
   130     }
   131     /* V */
   132     if ((argflags & 128) > 0) {
   133       if (registerArgument(&checked, 128)) {
   134         return exit_with_help(settings, 1);
   135       }
   136       settings->verbose = false;
   137     }
   138     /* b */
   139     if ((argflags & 256) > 0) {
   140       if (!checkParamOpt(&paropt) || registerArgument(&checked, 256)) {
   141         return exit_with_help(settings, 1);
   142       }
   143       t++;
   144       if (t >= argc) {
   145         return exit_with_help(settings, 1);
   146       }
   147       if (strcasecmp(argv[t], "ignore") == 0) {
   148         settings->bfileHeuristics->level = BFILE_IGNORE;
   149       } else if (strcasecmp(argv[t], "low") == 0) {
   150         settings->bfileHeuristics->level = BFILE_LOW_ACCURACY;
   151       } else if (strcasecmp(argv[t], "medium") == 0) {
   152         settings->bfileHeuristics->level = BFILE_MEDIUM_ACCURACY;
   153       } else if (strcasecmp(argv[t], "high") == 0) {
   154         settings->bfileHeuristics->level = BFILE_HIGH_ACCURACY;
   155       } else {
   156         return exit_with_help(settings, 1);
   157       }
   158     }
   159     /* e */
   160     if ((argflags & 512) > 0) {
   161       if (!checkParamOpt(&paropt) || t + 2 >= argc) {
   162         return exit_with_help(settings, 1);
   163       }
   164       t++; add_string(settings->regex->pattern_list, argv[t]);
   165       t++; add_string(settings->regex->pattern_list, argv[t]);
   166     }
   167     /* E */
   168     if ((argflags & 1024) > 0) {
   169       t++;
   170       if (!checkParamOpt(&paropt) || t >= argc) {
   171         return exit_with_help(settings, 1);
   172       }
   173       add_string(settings->regex->pattern_list, argv[t]);
   174       add_string(settings->regex->pattern_list, "$");
   175     }
   176     /* Path */
   177     if (argflags == 0) {
   178       if (registerArgument(&checked, 1024)) {
   179         return exit_with_help(settings, 1);
   180       }
   181       directory = argv[t];
   182     }
   183   }
   185   /* Configure output */
   186   if (!settings->verbose) {
   187     close_stdout();
   188   }
   190   /* Find tokens */
   191   parseCSL(includeSuffix, settings->includeSuffixes);
   192   parseCSL(excludeSuffix, settings->excludeSuffixes);
   194   /* Scan directory */
   195   if (regex_compile_all(settings->regex)) {
   196     int lines = scanDirectory((scanner_t){directory, 0}, settings);
   197     destroy_settings_t(settings);
   199     /* Print double line and line count */
   200     for (int t = 0 ; t < 79 ; t++) {
   201       printf("=");
   202     }
   203     printf("\n%73d lines\n", lines);
   205     if (settings->confusing_lnlen && settings->regex->pattern_list->count > 0) {
   206       printf("\nSome files contain too long lines.\n"
   207         "The regex parser currently supports a maximum line length of %d."
   208         "\nThe result might be wrong.\n", REGEX_MAX_LINELENGTH);
   209     }
   211     if (!settings->verbose) {
   212       reopen_stdout();
   213       printf("%d", lines);
   214     }
   215   }
   217   fflush(stdout);
   218   fflush(stderr);
   219   return 0;
   220 }

mercurial