universe@3: #include "cline.h" universe@3: #include "functions.h" universe@1: universe@6: suffix_list_t* new_suffix_list_t() { universe@6: suffix_list_t* suffixList = malloc(sizeof(suffix_list_t*)); universe@6: suffixList->count = 0; universe@6: suffixList->items = NULL; universe@6: } universe@6: universe@6: void destroy_suffix_list_t(suffix_list_t* list) { universe@6: while (--list->count >= 0) { universe@6: free(list->items[list->count]); universe@6: } universe@6: free(list); universe@6: } universe@6: universe@6: void add_suffix(suffix_list_t* list, char* item) { universe@6: char** reallocated_list = universe@6: realloc(list->items, sizeof(char**) * list->count + 1); universe@6: if (reallocated_list != NULL) { universe@6: list->items = reallocated_list; universe@6: list->items[list->count] = item; universe@6: list->count++; universe@6: } universe@6: } universe@6: 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->recursive = false; universe@5: settings->includeSuffixes = false; universe@5: settings->matchesOnly = false; universe@6: settings->suffixList = new_suffix_list_t(); universe@5: } universe@4: universe@4: return settings; universe@4: } universe@4: universe@4: void destroy_settings_t(settings_t* settings) { universe@6: destroy_suffix_list_t(settings->suffixList); 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@7: "So each file in the working directory is counted. If you want to count C" universe@7: "\nsource 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@8: int exit_with_help(char* prgName, settings_t* settings, int code) { universe@8: printHelpText(prgName); universe@8: destroy_settings_t(settings); universe@8: return code; universe@8: } universe@8: 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: // Get arguments universe@7: char* directory = "./"; universe@7: char* suffix = " "; universe@0: bool showHelp = false; universe@8: int 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@8: if (registerArgument(&checked, 6)) { universe@8: return exit_with_help(prgName, settings, 1); universe@0: } universe@3: settings->includeSuffixes = true; universe@1: t++; universe@1: if (t >= argc) { universe@8: return exit_with_help(prgName, settings, 1); universe@1: } universe@1: suffix = argv[t]; universe@0: } universe@1: // S universe@1: if ((argflags & 4) > 0) { universe@8: if (registerArgument(&checked, 6)) { universe@8: return exit_with_help(prgName, settings, 1); universe@0: } universe@3: settings->includeSuffixes = false; universe@1: t++; universe@1: if (t >= argc) { universe@8: return exit_with_help(prgName, settings, 1); universe@1: } universe@1: suffix = argv[t]; universe@0: } universe@1: // h universe@1: if ((argflags & 1) > 0 || strcmp(argv[t], "--help") == 0) { universe@8: if (registerArgument(&checked, 1)) { universe@8: return exit_with_help(prgName, settings, 1); universe@0: } universe@0: showHelp = true; universe@0: } universe@1: // r, R universe@1: if ((argflags & 24) > 0) { universe@8: if (registerArgument(&checked, 24)) { universe@8: return exit_with_help(prgName, settings, 1); universe@0: } universe@3: settings->recursive = true; universe@0: } universe@8: // m universe@1: if ((argflags & 32) > 0) { universe@8: if (registerArgument(&checked, 32)) { universe@8: return exit_with_help(prgName, settings, 1); universe@0: } universe@3: settings->matchesOnly = true; universe@0: } universe@6: // Path universe@1: if (argflags == 0) { universe@8: if (registerArgument(&checked, 1024)) { universe@8: return exit_with_help(prgName, settings, 1); universe@0: } universe@0: directory = argv[t]; universe@0: } universe@0: } universe@0: universe@0: // Show help and quit universe@1: if (showHelp) { universe@8: return exit_with_help(prgName, settings, 0); universe@0: } universe@0: universe@0: // Find tokens universe@6: char* finder = strtok(suffix, ","); universe@1: while (finder != NULL) { universe@6: add_suffix(settings->suffixList, finder); 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@7: destroy_settings_t(settings); 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@0: return 0; universe@0: }