universe@3: #include "cline.h" universe@3: #include "functions.h" universe@1: universe@3: settings_t* new_settings_t() { universe@3: settings_t *settings = malloc(sizeof(settings_t*)); universe@5: if (settings != NULL) { universe@5: #ifdef _WIN32 universe@5: settings->fileSeparator = '\\'; universe@5: #else universe@5: settings->fileSeparator = '/'; universe@5: #endif /* _WIN32 */ universe@5: settings->suffixc = 1; universe@5: settings->recursive = false; universe@5: settings->includeSuffixes = false; universe@5: settings->matchesOnly = false; universe@5: } universe@4: universe@4: return settings; universe@4: } universe@4: universe@4: void destroy_settings_t(settings_t* settings) { universe@4: if (settings->suffixv != NULL) { universe@4: free(settings->suffixv); universe@4: } universe@4: free(settings); 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@3: printf(helpText, prgName, prgName, prgName, prgName); universe@1: } universe@1: universe@1: int main(int argc, char** argv) { universe@0: universe@3: // Settings universe@3: settings_t *settings = new_settings_t(); universe@5: if (settings == NULL) { universe@5: fprintf(stderr, "Memory allocation failed.\n"); universe@5: return 1; universe@5: } universe@3: universe@0: // Program name universe@3: char* prgName = strrchr(argv[0], settings->fileSeparator); universe@1: universe@1: if (prgName == NULL) { universe@0: prgName = argv[0]; universe@3: } 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@3: _directory[1] = settings->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@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@5: destroy_settings_t(settings); universe@5: return 1; universe@0: } universe@3: settings->includeSuffixes = true; universe@1: t++; universe@1: if (t >= argc) { universe@1: printHelpText(prgName); universe@5: destroy_settings_t(settings); universe@5: 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@5: destroy_settings_t(settings); universe@5: return 1; universe@0: } universe@3: settings->includeSuffixes = false; universe@1: t++; universe@1: if (t >= argc) { universe@1: printHelpText(prgName); universe@5: destroy_settings_t(settings); universe@5: 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@5: destroy_settings_t(settings); universe@5: 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@5: destroy_settings_t(settings); universe@5: return 1; universe@0: } universe@0: checked |= 4; universe@3: settings->recursive = true; universe@0: } universe@1: if ((argflags & 32) > 0) { universe@1: if ((checked & 32) > 0) { universe@1: printHelpText(prgName); universe@5: destroy_settings_t(settings); universe@5: return 1; universe@0: } universe@1: checked |= 32; universe@3: settings->matchesOnly = true; universe@0: } universe@1: // other universe@1: if (argflags == 0) { universe@1: if ((checked & 8) > 0) { universe@1: printHelpText(prgName); universe@5: destroy_settings_t(settings); universe@5: 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@5: destroy_settings_t(settings); 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: finder = strchr(suffix, ','); universe@1: while (finder != NULL) { universe@3: settings->suffixc++; universe@0: finder = strchr(finder+1, ','); universe@0: } universe@3: settings->suffixv = (char**) malloc(sizeof(char**)*settings->suffixc); universe@3: if (settings->suffixv == NULL) { universe@0: fprintf(stderr, "Memory allocation failed.\n"); universe@5: destroy_settings_t(settings); universe@0: return 1; universe@0: } universe@0: finder = strtok(suffix, ","); universe@0: int c = 0; universe@1: while (finder != NULL) { universe@3: settings->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@4: destroy_settings_t(settings); universe@0: return 1; universe@0: } universe@0: universe@0: // Scan directory universe@3: int lines = scanDirectory(dir, 0, directory, settings); universe@4: closedir(dir); universe@0: universe@0: // Print double line and line count universe@1: #ifdef _WIN32 universe@3: const int columns = 79; universe@1: #else universe@3: 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@3: printf("\n%73d lines\n", lines); universe@1: #else universe@3: printf("\n%74d lines\n", lines); universe@1: #endif /* _WIN32 */ universe@0: universe@4: destroy_settings_t(settings); universe@0: return 0; universe@0: }