cline.c

Mon, 23 May 2011 16:42:44 +0200

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

cline project init

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdbool.h>
     4 #include <stdlib.h>
     5 #include <dirent.h>
     7 static int suffixc;
     8 static char** suffixv;
     9 static bool recursive;
    10 static bool includeSuffixes;
    12 bool testSuffix(char* filename)
    13 {
    14   bool ret = false;
    15   int tokenlen, fnamelen = strlen(filename);
    16   for (int t = 0 ; t < suffixc ; t++)
    17   {
    18     tokenlen = strlen(suffixv[t]);
    19     if (fnamelen >= tokenlen)
    20     {
    21       if (strncmp(filename+fnamelen-tokenlen, suffixv[t], tokenlen) == 0)
    22       {
    23         ret = true;
    24         break;
    25       }
    26     }
    27   }
    28   return ret ^ !includeSuffixes;
    29 }
    31 int scanDirectory(DIR *dir, const int spaces, char* currdir)
    32 {
    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   {
    41     if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
    42     {
    43       // Print occurence
    44       char entryname[strlen(entry->d_name)+spaces];
    45       for (int t = 0 ; t < spaces ; t++)
    46       {
    47         entryname[t]=' ';
    48       }
    49       entryname[spaces] = 0;
    50       strcat(entryname, entry->d_name);
    51       printf("%-60s", entryname);
    53       // Check for subdirectory
    54       char subdirname[(1+strlen(currdir)+strlen(entry->d_name))];
    55       strcpy(subdirname, currdir);
    56       strcat(subdirname, "/");
    57       strcat(subdirname, entry->d_name);
    58       if ((subdir = opendir(subdirname)) != NULL)
    59       {
    60         printf("\n");
    61         if (recursive)
    62         {
    63           lineSum += scanDirectory(subdir, spaces+1, subdirname);
    64         }
    65         closedir(subdir);
    66         continue;
    67       }
    69       // Count lines
    70       lines = 0;
    71       char filename[(1+strlen(currdir)+strlen(entry->d_name))];
    72       strcpy(filename, currdir);
    73       strcat(filename, "/");
    74       strcat(filename, entry->d_name);
    75       if (testSuffix(filename))
    76       {
    77         FILE *file = fopen(filename, "r");
    78         if (file == NULL)
    79         {
    80           perror("  File acces failed");
    81           continue;
    82         }
    84         do
    85         {
    86           a = fgetc(file);
    88           if (a == 10)
    89           {
    90             lines++;
    91           }
    92         } while (a != EOF);
    93         fclose(file);
    95         // Print line count
    96         printf("%14d lines\n", lines);
    98         lineSum += lines;
    99       }
   100       else
   101       {
   102         // Print hint
   103         printf("%20s\n", "no match");
   104       }
   105     }
   106   }
   107   return lineSum;
   108 }
   110 int main(int argc, char** argv)
   111 {
   112   // Help text
   113   const char* helpText = 
   114     "\nUsage:\n%s [-h|--help|(-s=<suffix>|-S=<suffix>)|(-r|-R)|<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  -s=<suffixes>       - only count files with these suffixes (separated"
   120     "\n                        by commas)"
   121     "\n  -S=<suffixes>       - count any file except those with these suffixes"
   122     "\n                        (separated by commas)"
   123     "\n  -R                  - excludes subdirectories"
   124     "\n  -r                  - includes subdirecotires"
   125     "\n\n"
   126     "The default call without any options is:"
   127     "\n  %s -r ./ -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 -s=.c\n";
   132   // Program name
   133   char* prgName = strrchr(argv[0], '/');
   134   if (prgName == NULL)
   135   {
   136     prgName = argv[0];
   137   }
   138   else
   139   {
   140     prgName++;
   141   }
   143   // Defaults
   144   char* _suffix = "";
   145   char* _directory = "./";
   147   // Get arguments
   148   char* directory;
   149   char* suffix;
   150   bool showHelp = false;
   151   recursive = true;
   152   includeSuffixes = false;
   153   char checked = 0;
   155   for (int t = 1 ; t < argc ; t++)
   156   {
   157     if (strncmp(argv[t], "-s=", 3) == 0)
   158     {
   159       if ((checked & 1) > 0)
   160       {
   161         printf(helpText, prgName, prgName, prgName);
   162         return -1;
   163       }
   164       includeSuffixes = true;
   165       suffix = argv[t]+3; 
   166       checked |= 1;
   167     }
   168     else if (strncmp(argv[t], "-S=", 3) == 0)
   169     {
   170       if ((checked & 1) > 0)
   171       {
   172         printf(helpText, prgName, prgName, prgName);
   173         return -1;
   174       }
   175       includeSuffixes = false;
   176       suffix = argv[t]+3;
   177       checked |= 1;
   178     }
   179     else if (strcmp(argv[t], "-h") == 0 || strcmp(argv[t], "--help") == 0)
   180     {
   181       if ((checked & 2) > 0)
   182       {
   183         printf(helpText, prgName, prgName, prgName);
   184         return -1;
   185       }
   186       checked |= 2;
   187       showHelp = true;
   188     }
   189     else if (strcmp(argv[t], "-r") == 0)
   190     {
   191       if ((checked & 4) > 0)
   192       {
   193         printf(helpText, prgName, prgName, prgName);
   194         return -1;
   195       }
   196       checked |= 4;
   197       recursive = true;
   198     }
   199     else if (strcmp(argv[t], "-R") == 0)
   200     {
   201       if ((checked & 4) > 0)
   202       {
   203         printf(helpText, prgName, prgName, prgName);
   204         return -1;
   205       }
   206       checked |= 4;
   207       recursive = false;
   208     }
   209     else
   210     {
   211       if ((checked & 8) > 0)
   212       {
   213         printf(helpText, prgName, prgName, prgName);
   214         return -1;
   215       }
   216       checked |= 8;      
   217       directory = argv[t];
   218     }
   219   }
   221   // Show help and quit
   222   if (showHelp)
   223   {
   224     printf(helpText, prgName, prgName, prgName);
   225     return 0;
   226   }
   228   // Default values
   229   if ((checked & 1) == 0)
   230   {
   231     suffix = _suffix;
   232   }
   234   if ((checked & 8) == 0)
   235   {
   236     directory = _directory;
   237   }
   239   // Find tokens
   240   char* finder;
   241   suffixc = 1;
   242   finder = strchr(suffix, ',');
   243   while (finder != NULL)
   244   {
   245     suffixc++;
   246     finder = strchr(finder+1, ',');
   247   }
   248   suffixv = (char**) malloc(sizeof(suffixv)*suffixc);
   249   if (suffixv == NULL)
   250   {
   251     fprintf(stderr, "Memory allocation failed.\n");
   252     return 1;
   253   }
   254   finder = strtok(suffix, ",");
   255   int c = 0;
   256   while (finder != NULL)
   257   {
   258     suffixv[c] = finder;
   259     c++;
   260     finder = strtok(NULL, ",");
   261   }
   263   // Open directory
   264   DIR *dir = opendir(directory);
   265   if (dir == NULL)
   266   {
   267     perror("Operation failed");
   268     free(suffixv);
   269     return 1;
   270   }
   272   // Scan directory
   273   int lines = scanDirectory(dir, 0, directory);
   275   // Print double line and line count
   276   for (int t = 0 ; t < 80 ; t++)
   277   {
   278     printf("=");
   279   }
   280   printf("\n%74d lines\n", lines);
   282   closedir(dir);
   283   free(suffixv);
   284   return 0;
   285 }

mercurial