universe@1: #include "include.h" universe@1: #include "v2.h" universe@1: universe@1: universe@1: #ifdef _WIN32 universe@1: static char fileSeparator = '\\'; universe@1: #else universe@1: static char fileSeparator = '/'; universe@1: #endif /* _WIN32 */ universe@0: universe@0: static int suffixc; universe@0: static char** suffixv; universe@0: static bool recursive; universe@0: static bool includeSuffixes; universe@1: static bool matchesOnly; universe@0: universe@1: bool testSuffix(char* filename) { universe@0: bool ret = false; universe@0: int tokenlen, fnamelen = strlen(filename); universe@1: for (int t = 0 ; t < suffixc ; t++) { universe@0: tokenlen = strlen(suffixv[t]); universe@1: if (fnamelen >= tokenlen && tokenlen > 0) { universe@1: if (strncmp(filename+fnamelen-tokenlen, suffixv[t], tokenlen) == 0) { universe@0: ret = true; universe@0: break; universe@0: } universe@0: } universe@0: } universe@0: return ret ^ !includeSuffixes; universe@0: } universe@0: universe@1: int scanDirectory(DIR *dir, const int spaces, char* currdir) { 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@1: while ((entry = readdir(dir)) != NULL) { universe@1: if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { universe@0: // Print occurence universe@0: char entryname[strlen(entry->d_name)+spaces]; universe@1: for (int t = 0 ; t < spaces ; t++) { universe@0: entryname[t]=' '; universe@0: } universe@0: entryname[spaces] = 0; universe@0: strcat(entryname, entry->d_name); universe@0: universe@0: // Check for subdirectory universe@0: char subdirname[(1+strlen(currdir)+strlen(entry->d_name))]; universe@0: strcpy(subdirname, currdir); universe@1: strncat(subdirname, &fileSeparator, 1); universe@0: strcat(subdirname, entry->d_name); universe@1: if ((subdir = opendir(subdirname)) != NULL) { universe@1: printf("%-60s\n", entryname); universe@1: if (recursive) { 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@1: strncat(filename, &fileSeparator, 1); universe@0: strcat(filename, entry->d_name); universe@1: if (testSuffix(filename)) { universe@0: FILE *file = fopen(filename, "r"); universe@1: if (file == NULL) { universe@0: perror(" File acces failed"); universe@0: continue; universe@0: } universe@0: universe@1: do { universe@0: a = fgetc(file); universe@0: universe@1: if (a == 10) { universe@0: lines++; universe@0: } universe@0: } while (a != EOF); universe@0: fclose(file); universe@0: universe@0: // Print line count universe@1: #ifdef _WIN32 universe@1: printf("%-60s%13d lines\n", entryname, lines); universe@1: #else universe@1: printf("%-60s%14d lines\n", entryname, lines); universe@1: #endif /* _WIN32 */ universe@0: universe@0: lineSum += lines; universe@0: } universe@1: else { universe@1: if (!matchesOnly) { universe@1: // Print hint universe@1: #ifdef _WIN32 universe@1: printf("%-60s%19s\n", entryname, "no match"); universe@1: #else universe@1: printf("%-60s%20s\n", entryname, "no match"); universe@1: #endif /* _WIN32 */ universe@1: } universe@0: } universe@0: } universe@0: } universe@0: return lineSum; universe@0: } universe@0: universe@1: void printHelpText(const char* prgName) { universe@0: // Help text universe@0: const char* helpText = universe@1: "\nUsage:" universe@1: "\n %s [-hrm][-s suffix][]" universe@1: "\n %s [-hrm][-S suffix][]" 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@1: "\n -m - print information about matching files only" universe@1: "\n -s - only count files with these suffixes (separated" universe@0: "\n by commas)" universe@1: "\n -S - count any file except those with these suffixes" universe@0: "\n (separated by commas)" universe@1: "\n -r, -R - includes subdirectories" universe@0: "\n\n" universe@1: "The default call without any options is:" universe@1: "\n %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@1: "\n %s -rs .c\n"; universe@1: universe@1: printf(helpText, prgName, prgName, prgName, prgName); universe@1: } universe@1: universe@1: int main(int argc, char** argv) { universe@0: universe@0: // Program name universe@1: char* prgName = strrchr(argv[0], fileSeparator); universe@1: universe@1: if (prgName == NULL) { universe@0: prgName = argv[0]; universe@0: } universe@1: else { universe@0: prgName++; universe@0: } universe@0: universe@0: // Defaults universe@1: char* _suffix = " "; universe@1: char _directory[3]; universe@1: _directory[0] = '.'; universe@1: _directory[1] = fileSeparator; universe@1: _directory[2] = 0; universe@0: universe@0: // Get arguments universe@0: char* directory; universe@0: char* suffix; universe@0: bool showHelp = false; universe@1: recursive = false; universe@0: includeSuffixes = false; universe@0: char checked = 0; universe@0: universe@1: for (int t = 1 ; t < argc ; t++) { universe@1: universe@1: int argflags = checkArgument(argv[t], "hsSrRm"); universe@1: universe@1: // s universe@1: if ((argflags & 2) > 0) { universe@1: if ((checked & 1) > 0) { universe@1: printHelpText(prgName); universe@0: return -1; universe@0: } universe@0: includeSuffixes = true; universe@1: t++; universe@1: if (t >= argc) { universe@1: printHelpText(prgName); universe@1: return -1; universe@1: } universe@1: suffix = argv[t]; universe@0: checked |= 1; universe@0: } universe@1: // S universe@1: if ((argflags & 4) > 0) { universe@1: if ((checked & 1) > 0) { universe@1: printHelpText(prgName); universe@0: return -1; universe@0: } universe@0: includeSuffixes = false; universe@1: t++; universe@1: if (t >= argc) { universe@1: printHelpText(prgName); universe@1: return -1; universe@1: } universe@1: suffix = argv[t]; universe@0: checked |= 1; universe@0: } universe@1: // h universe@1: if ((argflags & 1) > 0 || strcmp(argv[t], "--help") == 0) { universe@1: if ((checked & 2) > 0) { universe@1: printHelpText(prgName); universe@0: return -1; universe@0: } universe@0: checked |= 2; universe@0: showHelp = true; universe@0: } universe@1: // r, R universe@1: if ((argflags & 24) > 0) { universe@1: if ((checked & 4) > 0) { universe@1: printHelpText(prgName); universe@0: return -1; universe@0: } universe@0: checked |= 4; universe@0: recursive = true; universe@0: } universe@1: if ((argflags & 32) > 0) { universe@1: if ((checked & 32) > 0) { universe@1: printHelpText(prgName); universe@0: return -1; universe@0: } universe@1: checked |= 32; universe@1: matchesOnly = true; universe@0: } universe@1: // other universe@1: if (argflags == 0) { universe@1: if ((checked & 8) > 0) { universe@1: printHelpText(prgName); universe@0: return -1; universe@0: } universe@1: checked |= 8; universe@0: directory = argv[t]; universe@0: } universe@0: } universe@0: universe@0: // Show help and quit universe@1: if (showHelp) { universe@1: printHelpText(prgName); universe@0: return 0; universe@0: } universe@0: universe@0: // Default values universe@1: if ((checked & 1) == 0) { universe@0: suffix = _suffix; universe@0: } universe@0: universe@1: if ((checked & 8) == 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@1: while (finder != NULL) { universe@0: suffixc++; universe@0: finder = strchr(finder+1, ','); universe@0: } universe@0: suffixv = (char**) malloc(sizeof(suffixv)*suffixc); universe@1: if (suffixv == NULL) { 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@1: while (finder != NULL) { 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@1: if (dir == NULL) { 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@1: #ifdef _WIN32 universe@1: const int columns = 79; universe@1: #else universe@1: const int columns = 80; universe@1: #endif /* _WIN32 */ universe@1: universe@1: for (int t = 0 ; t < columns ; t++) { universe@0: printf("="); universe@0: } universe@1: #ifdef _WIN32 universe@1: printf("\n%73d lines\n", lines); universe@1: #else universe@1: printf("\n%74d lines\n", lines); universe@1: #endif /* _WIN32 */ universe@0: universe@0: closedir(dir); universe@0: free(suffixv); universe@0: return 0; universe@0: }