cline.c

Thu, 02 Feb 2012 16:55:51 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 02 Feb 2012 16:55:51 +0100
changeset 29
fa625066ae52
parent 28
72a98cbcb9f1
child 30
d642fdb6745e
permissions
-rw-r--r--

fixed author note

     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* suffix = " ";
    79   int checked = 0;
    81   for (int t = 1 ; t < argc ; t++) {
    83     int argflags = checkArgument(argv[t], "hsSrRmvVbeE");
    85     /* s, S */
    86     if ((argflags & 6) > 0) {
    87       if (registerArgument(&checked, 6)) {
    88         return exit_with_help(settings, 1);
    89       }
    90       settings->includeSuffixes = (argflags & 2) > 0;
    91       t++;
    92       if (t >= argc) {
    93         return exit_with_help(settings, 1);
    94       }
    95       suffix = argv[t]; 
    96     }
    97     /* h */
    98     if ((argflags & 1) > 0 || strcmp(argv[t], "--help") == 0) {
    99       return exit_with_help(settings, 0);
   100     }
   101     /* r, R */
   102     if ((argflags & 24) > 0) {
   103       if (registerArgument(&checked, 24)) {
   104         return exit_with_help(settings, 1);
   105       }
   106       settings->recursive = true;
   107     }
   108     /* m */
   109     if ((argflags & 32) > 0) {
   110       if (registerArgument(&checked, 32)) {
   111         return exit_with_help(settings, 1);
   112       }
   113       settings->matchesOnly = true;
   114     }
   115     /* v */
   116     if ((argflags & 64) > 0 || strcmp(argv[t], "--version") == 0) {
   117       return exit_with_version(settings);
   118     }
   119     /* V */
   120     if ((argflags & 128) > 0) {
   121       if (registerArgument(&checked, 128)) {
   122         return exit_with_help(settings, 1);
   123       }
   124       settings->verbose = false;
   125     }
   126     /* b */
   127     if ((argflags & 256) > 0) {
   128       if (registerArgument(&checked, 256)) {
   129         return exit_with_help(settings, 1);
   130       }
   131       t++;
   132       if (t >= argc) {
   133         return exit_with_help(settings, 1);
   134       }
   135       if (strcasecmp(argv[t], "ignore") == 0) {
   136         settings->bfileHeuristics->level = BFILE_IGNORE;
   137       } else if (strcasecmp(argv[t], "low") == 0) {
   138         settings->bfileHeuristics->level = BFILE_LOW_ACCURACY;
   139       } else if (strcasecmp(argv[t], "medium") == 0) {
   140         settings->bfileHeuristics->level = BFILE_MEDIUM_ACCURACY;
   141       } else if (strcasecmp(argv[t], "high") == 0) {
   142         settings->bfileHeuristics->level = BFILE_HIGH_ACCURACY;
   143       } else {
   144         return exit_with_help(settings, 1);
   145       }
   146     }
   147     /* e */
   148     if ((argflags & 512) > 0) {
   149       if (t + 2 >= argc) {
   150         return exit_with_help(settings, 1);
   151       }
   152       t++; add_string(settings->regex->pattern_list, argv[t]);
   153       t++; add_string(settings->regex->pattern_list, argv[t]);
   154     }
   155     /* E */
   156     if ((argflags & 1024) > 0) {
   157       t++;
   158       if (t >= argc) {
   159         return exit_with_help(settings, 1);
   160       }
   161       add_string(settings->regex->pattern_list, argv[t]);
   162       add_string(settings->regex->pattern_list, "$");
   163     }
   164     /* Path */
   165     if (argflags == 0) {
   166       if (registerArgument(&checked, 1024)) {
   167         return exit_with_help(settings, 1);
   168       }
   169       directory = argv[t];
   170     }
   171   }
   173   /* Configure output */
   174   if (!settings->verbose) {
   175     close_stdout();
   176   }
   178   /* Find tokens */
   179   char* finder = strtok(suffix, ",");
   180   while (finder != NULL) {
   181     add_string(settings->suffixList, finder);
   182     finder = strtok(NULL, ",");
   183   }
   185   /* Scan directory */
   186   if (regex_compile_all(settings->regex)) {
   187     int lines = scanDirectory((scanner_t){directory, 0}, settings);
   188     destroy_settings_t(settings);
   190     /* Print double line and line count */
   191     for (int t = 0 ; t < 79 ; t++) {
   192       printf("=");
   193     }
   194     printf("\n%73d lines\n", lines);
   196     if (settings->confusing_lnlen && settings->regex->pattern_list->count > 0) {
   197       printf("\nSome files contain too long lines.\n"
   198         "The regex parser currently supports a maximum line length of %d."
   199         "\nThe result might be wrong.\n", REGEX_MAX_LINELENGTH);
   200     }
   202     if (!settings->verbose) {
   203       reopen_stdout();
   204       printf("%d", lines);
   205     }
   206   }
   208   fflush(stdout);
   209   fflush(stderr);
   210   return 0;
   211 }

mercurial