Mon, 23 May 2011 16:42:44 +0200
cline project init
#include <stdio.h> #include <string.h> #include <stdbool.h> #include <stdlib.h> #include <dirent.h> static int suffixc; static char** suffixv; static bool recursive; static bool includeSuffixes; bool testSuffix(char* filename) { bool ret = false; int tokenlen, fnamelen = strlen(filename); for (int t = 0 ; t < suffixc ; t++) { tokenlen = strlen(suffixv[t]); if (fnamelen >= tokenlen) { if (strncmp(filename+fnamelen-tokenlen, suffixv[t], tokenlen) == 0) { ret = true; break; } } } return ret ^ !includeSuffixes; } int scanDirectory(DIR *dir, const int spaces, char* currdir) { DIR *subdir; char* subdirname; struct dirent *entry; int lines, digits, a; int lineSum = 0; while ((entry = readdir(dir)) != NULL) { if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { // Print occurence char entryname[strlen(entry->d_name)+spaces]; for (int t = 0 ; t < spaces ; t++) { entryname[t]=' '; } entryname[spaces] = 0; strcat(entryname, entry->d_name); printf("%-60s", entryname); // Check for subdirectory char subdirname[(1+strlen(currdir)+strlen(entry->d_name))]; strcpy(subdirname, currdir); strcat(subdirname, "/"); strcat(subdirname, entry->d_name); if ((subdir = opendir(subdirname)) != NULL) { printf("\n"); if (recursive) { lineSum += scanDirectory(subdir, spaces+1, subdirname); } closedir(subdir); continue; } // Count lines lines = 0; char filename[(1+strlen(currdir)+strlen(entry->d_name))]; strcpy(filename, currdir); strcat(filename, "/"); strcat(filename, entry->d_name); if (testSuffix(filename)) { FILE *file = fopen(filename, "r"); if (file == NULL) { perror(" File acces failed"); continue; } do { a = fgetc(file); if (a == 10) { lines++; } } while (a != EOF); fclose(file); // Print line count printf("%14d lines\n", lines); lineSum += lines; } else { // Print hint printf("%20s\n", "no match"); } } } return lineSum; } int main(int argc, char** argv) { // Help text const char* helpText = "\nUsage:\n%s [-h|--help|(-s=<suffix>|-S=<suffix>)|(-r|-R)|<directory>]" "\n\nCounts the line terminator characters (\\n) within all" " files in the specified\ndirectory." "\n\nOptions:" "\n -h, --help - this help text" "\n -s=<suffixes> - only count files with these suffixes (separated" "\n by commas)" "\n -S=<suffixes> - count any file except those with these suffixes" "\n (separated by commas)" "\n -R - excludes subdirectories" "\n -r - includes subdirecotires" "\n\n" "The default call without any options is:" "\n %s -r ./ -S=\n" "That means each file in each subdirectory is counted. If you want to count" "\nC source code in your working directory and its subdirectories, type:" "\n %s -s=.c\n"; // Program name char* prgName = strrchr(argv[0], '/'); if (prgName == NULL) { prgName = argv[0]; } else { prgName++; } // Defaults char* _suffix = ""; char* _directory = "./"; // Get arguments char* directory; char* suffix; bool showHelp = false; recursive = true; includeSuffixes = false; char checked = 0; for (int t = 1 ; t < argc ; t++) { if (strncmp(argv[t], "-s=", 3) == 0) { if ((checked & 1) > 0) { printf(helpText, prgName, prgName, prgName); return -1; } includeSuffixes = true; suffix = argv[t]+3; checked |= 1; } else if (strncmp(argv[t], "-S=", 3) == 0) { if ((checked & 1) > 0) { printf(helpText, prgName, prgName, prgName); return -1; } includeSuffixes = false; suffix = argv[t]+3; checked |= 1; } else if (strcmp(argv[t], "-h") == 0 || strcmp(argv[t], "--help") == 0) { if ((checked & 2) > 0) { printf(helpText, prgName, prgName, prgName); return -1; } checked |= 2; showHelp = true; } else if (strcmp(argv[t], "-r") == 0) { if ((checked & 4) > 0) { printf(helpText, prgName, prgName, prgName); return -1; } checked |= 4; recursive = true; } else if (strcmp(argv[t], "-R") == 0) { if ((checked & 4) > 0) { printf(helpText, prgName, prgName, prgName); return -1; } checked |= 4; recursive = false; } else { if ((checked & 8) > 0) { printf(helpText, prgName, prgName, prgName); return -1; } checked |= 8; directory = argv[t]; } } // Show help and quit if (showHelp) { printf(helpText, prgName, prgName, prgName); return 0; } // Default values if ((checked & 1) == 0) { suffix = _suffix; } if ((checked & 8) == 0) { directory = _directory; } // Find tokens char* finder; suffixc = 1; finder = strchr(suffix, ','); while (finder != NULL) { suffixc++; finder = strchr(finder+1, ','); } suffixv = (char**) malloc(sizeof(suffixv)*suffixc); if (suffixv == NULL) { fprintf(stderr, "Memory allocation failed.\n"); return 1; } finder = strtok(suffix, ","); int c = 0; while (finder != NULL) { suffixv[c] = finder; c++; finder = strtok(NULL, ","); } // Open directory DIR *dir = opendir(directory); if (dir == NULL) { perror("Operation failed"); free(suffixv); return 1; } // Scan directory int lines = scanDirectory(dir, 0, directory); // Print double line and line count for (int t = 0 ; t < 80 ; t++) { printf("="); } printf("\n%74d lines\n", lines); closedir(dir); free(suffixv); return 0; }