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

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

mercurial