cline.c

Mon, 23 May 2011 16:43:13 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 23 May 2011 16:43:13 +0200
changeset 1
34a5e235d16e
parent 0
518bfd1cc1e8
child 3
510d6b198dde
permissions
-rw-r--r--

cline version 2

     1 #include "include.h"
     2 #include "v2.h"
     5 #ifdef _WIN32
     6 static char fileSeparator = '\\';
     7 #else
     8 static char fileSeparator = '/';
     9 #endif /* _WIN32 */
    11 static int suffixc;
    12 static char** suffixv;
    13 static bool recursive;
    14 static bool includeSuffixes;
    15 static bool matchesOnly;
    17 bool testSuffix(char* filename) {
    18   bool ret = false;
    19   int tokenlen, fnamelen = strlen(filename);
    20   for (int t = 0 ; t < suffixc ; t++) {
    21     tokenlen = strlen(suffixv[t]);
    22     if (fnamelen >= tokenlen && tokenlen > 0) {
    23       if (strncmp(filename+fnamelen-tokenlen, suffixv[t], tokenlen) == 0) {
    24         ret = true;
    25         break;
    26       }
    27     }
    28   }
    29   return ret ^ !includeSuffixes;
    30 }
    32 int scanDirectory(DIR *dir, const int spaces, char* currdir) {
    33   DIR *subdir;
    34   char* subdirname;
    35   struct dirent *entry;
    36   int lines, digits, a;
    37   int lineSum = 0;
    39   while ((entry = readdir(dir)) != NULL) {
    40     if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
    41       // Print occurence
    42       char entryname[strlen(entry->d_name)+spaces];
    43       for (int t = 0 ; t < spaces ; t++) {
    44         entryname[t]=' ';
    45       }
    46       entryname[spaces] = 0;
    47       strcat(entryname, entry->d_name);
    49       // Check for subdirectory
    50       char subdirname[(1+strlen(currdir)+strlen(entry->d_name))];
    51       strcpy(subdirname, currdir);
    52       strncat(subdirname, &fileSeparator, 1);
    53       strcat(subdirname, entry->d_name);
    54       if ((subdir = opendir(subdirname)) != NULL) {
    55         printf("%-60s\n", entryname);
    56         if (recursive) {
    57           lineSum += scanDirectory(subdir, spaces+1, subdirname);
    58         }
    59         closedir(subdir);
    60         continue;
    61       }
    63       // Count lines
    64       lines = 0;
    65       char filename[(1+strlen(currdir)+strlen(entry->d_name))];
    66       strcpy(filename, currdir);
    67       strncat(filename, &fileSeparator, 1);
    68       strcat(filename, entry->d_name);
    69       if (testSuffix(filename)) {
    70         FILE *file = fopen(filename, "r");
    71         if (file == NULL) {
    72           perror("  File acces failed");
    73           continue;
    74         }
    76         do {
    77           a = fgetc(file);
    79           if (a == 10) {
    80             lines++;
    81           }
    82         } while (a != EOF);
    83         fclose(file);
    85         // Print line count
    86         #ifdef _WIN32
    87           printf("%-60s%13d lines\n", entryname, lines);
    88         #else
    89           printf("%-60s%14d lines\n", entryname, lines);
    90         #endif /* _WIN32 */
    92         lineSum += lines;
    93       }
    94       else {
    95         if (!matchesOnly) {
    96           // Print hint
    97           #ifdef _WIN32
    98             printf("%-60s%19s\n", entryname, "no match");
    99           #else
   100             printf("%-60s%20s\n", entryname, "no match");
   101           #endif /* _WIN32 */
   102         }
   103       }
   104     }
   105   }
   106   return lineSum;
   107 }
   109 void printHelpText(const char* prgName) {
   110   // Help text
   111   const char* helpText = 
   112     "\nUsage:"
   113     "\n      %s [-hrm][-s suffix][<directory>]"
   114     "\n      %s [-hrm][-S suffix][<directory>]"
   115     "\n\nCounts the line terminator characters (\\n) within all"
   116     " files in the specified\ndirectory."
   117     "\n\nOptions:"
   118     "\n  -h, --help          - this help text"
   119     "\n  -m                  - print information about matching files only"
   120     "\n  -s <suffixes>       - only count files with these suffixes (separated"
   121     "\n                        by commas)"
   122     "\n  -S <suffixes>       - count any file except those with these suffixes"
   123     "\n                        (separated by commas)"
   124     "\n  -r, -R              - includes subdirectories"
   125     "\n\n"
   126     "The default call without any options is:"    
   127     "\n  %s ./\n"
   128     "That means each file in each subdirectory is counted. If you want to count"
   129     "\nC source code in your working directory and its subdirectories, type:"
   130     "\n  %s -rs .c\n";
   132     printf(helpText, prgName, prgName, prgName, prgName);
   133 }
   135 int main(int argc, char** argv) {
   137   // Program name
   138   char* prgName = strrchr(argv[0], fileSeparator);
   140   if (prgName == NULL) {
   141     prgName = argv[0];
   142   }
   143   else {
   144     prgName++;
   145   }
   147   // Defaults
   148   char* _suffix = " ";
   149   char _directory[3];
   150   _directory[0] = '.';
   151   _directory[1] = fileSeparator;
   152   _directory[2] = 0;
   154   // Get arguments
   155   char* directory;
   156   char* suffix;
   157   bool showHelp = false;
   158   recursive = false;
   159   includeSuffixes = false;
   160   char checked = 0;
   162   for (int t = 1 ; t < argc ; t++) {
   164     int argflags = checkArgument(argv[t], "hsSrRm");
   166     // s
   167     if ((argflags & 2) > 0) {
   168       if ((checked & 1) > 0) {
   169         printHelpText(prgName);
   170         return -1;
   171       }
   172       includeSuffixes = true;
   173       t++;
   174       if (t >= argc) {
   175         printHelpText(prgName);
   176         return -1;
   177       }
   178       suffix = argv[t]; 
   179       checked |= 1;
   180     }
   181     // S
   182     if ((argflags & 4) > 0) {
   183       if ((checked & 1) > 0) {
   184         printHelpText(prgName);
   185         return -1;
   186       }
   187       includeSuffixes = false;
   188       t++;
   189       if (t >= argc) {
   190         printHelpText(prgName);
   191         return -1;
   192       }
   193       suffix = argv[t];
   194       checked |= 1;
   195     }
   196     // h
   197     if ((argflags & 1) > 0 || strcmp(argv[t], "--help") == 0) {
   198       if ((checked & 2) > 0) {
   199         printHelpText(prgName);
   200         return -1;
   201       }
   202       checked |= 2;
   203       showHelp = true;
   204     }
   205     // r, R
   206     if ((argflags & 24) > 0) {
   207       if ((checked & 4) > 0) {
   208         printHelpText(prgName);
   209         return -1;
   210       }
   211       checked |= 4;
   212       recursive = true;
   213     }
   214     if ((argflags & 32) > 0) {
   215       if ((checked & 32) > 0) {
   216         printHelpText(prgName);
   217         return -1;
   218       }
   219       checked |= 32;
   220       matchesOnly = true;
   221     }
   222     // other
   223     if (argflags == 0) {
   224       if ((checked & 8) > 0) {
   225         printHelpText(prgName);
   226         return -1;
   227       }
   228       checked |= 8;
   229       directory = argv[t];
   230     }
   231   }
   233   // Show help and quit
   234   if (showHelp) {
   235     printHelpText(prgName);
   236     return 0;
   237   }
   239   // Default values
   240   if ((checked & 1) == 0) {
   241     suffix = _suffix;
   242   }
   244   if ((checked & 8) == 0) {
   245     directory = _directory;
   246   }
   248   // Find tokens
   249   char* finder;
   250   suffixc = 1;
   251   finder = strchr(suffix, ',');
   252   while (finder != NULL) {
   253     suffixc++;
   254     finder = strchr(finder+1, ',');
   255   }
   256   suffixv = (char**) malloc(sizeof(suffixv)*suffixc);
   257   if (suffixv == NULL) {
   258     fprintf(stderr, "Memory allocation failed.\n");
   259     return 1;
   260   }
   261   finder = strtok(suffix, ",");
   262   int c = 0;
   263   while (finder != NULL) {
   264     suffixv[c] = finder;
   265     c++;
   266     finder = strtok(NULL, ",");
   267   }
   269   // Open directory
   270   DIR *dir = opendir(directory);
   271   if (dir == NULL) {
   272     perror("Operation failed");
   273     free(suffixv);
   274     return 1;
   275   }
   277   // Scan directory
   278   int lines = scanDirectory(dir, 0, directory);
   280   // Print double line and line count
   281   #ifdef _WIN32
   282      const int columns = 79;
   283   #else
   284      const int columns = 80;
   285   #endif /* _WIN32 */
   287   for (int t = 0 ; t < columns ; t++) {
   288     printf("=");
   289   }
   290   #ifdef _WIN32
   291      printf("\n%73d lines\n", lines);
   292   #else
   293      printf("\n%74d lines\n", lines);
   294   #endif /* _WIN32 */
   296   closedir(dir);
   297   free(suffixv);
   298   return 0;
   299 }

mercurial