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