--- a/src/scanner.c Fri May 17 14:41:44 2013 +0200 +++ b/src/scanner.c Tue May 21 13:19:37 2013 +0200 @@ -36,16 +36,24 @@ #include "regex_parser.h" #include <sys/stat.h> -int scanDirectory(scanner_t scanner, settings_t* settings) { +typedef struct filelist filelist_t; +struct filelist { + char *displayname; + int displayname_len; + char *filename; + int st_mode; + filelist_t *next; +}; + +filelist_t *buildFileList(scanner_t scanner, settings_t* settings, + filelist_t* list) { + DIR *dirf; struct dirent *entry; - int entrynamelen; - int lines, a; - int lineSum = 0; - bool bfile; struct stat statbuf; - + filelist_t *listentry = list; + if ((dirf = opendir(scanner.dir)) == NULL) { printf("%s", scanner.dir); perror(" Directory access failed"); @@ -54,31 +62,74 @@ while ((entry = readdir(dirf)) != NULL) { if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { + + /* Create new filelist entry */ + filelist_t *newentry = (filelist_t*) malloc(sizeof(filelist_t)); + // TODO: don't just append - create a sorted list! + if (listentry) { + listentry->next = newentry; + } + listentry = newentry; + if (!list) { + list = listentry; + } + + listentry->next = NULL; + + listentry->displayname_len = strlen(entry->d_name); + listentry->displayname = (char*) malloc(listentry->displayname_len+1); + memcpy(listentry->displayname, entry->d_name, listentry->displayname_len); + listentry->displayname[listentry->displayname_len] = 0; + + listentry->st_mode = 0; + /* Construct absolute pathname string */ - entrynamelen = strlen(entry->d_name); - char filename[(1+strlen(scanner.dir)+entrynamelen)]; - strcpy(filename, scanner.dir); - strncat(filename, &settings->fileSeparator, 1); - strcat(filename, entry->d_name); + size_t dirnamelen = strlen(scanner.dir); + char *filename = (char*) malloc(2+dirnamelen+listentry->displayname_len); + memcpy(filename, scanner.dir, dirnamelen); + filename[dirnamelen] = settings->fileSeparator; + memcpy(filename+dirnamelen+1, entry->d_name, listentry->displayname_len); + filename[1+dirnamelen+listentry->displayname_len] = 0; + listentry->filename = filename; /* Check for subdirectory */ if (stat(filename, &statbuf) == 0) { - if (!(statbuf.st_mode & S_IFREG)) { - printf("%*s\n", entrynamelen+scanner.spaces, entry->d_name); - if (settings->recursive && (statbuf.st_mode & S_IFDIR)) { - lineSum += scanDirectory( - (scanner_t) {filename, scanner.spaces+1}, settings); - } - continue; - } + listentry->st_mode = statbuf.st_mode; } else { perror(" Error in stat call"); continue; } + } + } + + closedir(dirf); + + return list; +} +int scanDirectory(scanner_t scanner, settings_t* settings) { + + int lines, a; + int lineSum = 0; + bool bfile; + + filelist_t *filelist = buildFileList(scanner, settings, NULL); + + while (filelist != NULL) { + + /* Scan subdirectories */ + if (!(filelist->st_mode & S_IFREG)) { + printf("%*s\n", filelist->displayname_len+scanner.spaces, + filelist->displayname); + if (settings->recursive && (filelist->st_mode & S_IFDIR)) { + scanDirectory((scanner_t) {filelist->filename, scanner.spaces+1}, + settings); + } + } else { if ((settings->includeSuffixes->count == 0 - || testSuffix(filename, settings->includeSuffixes)) - && !testSuffix(filename, settings->excludeSuffixes)) { + || testSuffix(filelist->displayname, settings->includeSuffixes)) + && !testSuffix(filelist->displayname, settings->excludeSuffixes)) { + /* Count lines */ lines = 0; bfile = false; @@ -86,66 +137,70 @@ char line_buffer[REGEX_MAX_LINELENGTH]; int line_buffer_offset = 0; - FILE *file = fopen(filename, "r"); + FILE *file = fopen(filelist->filename, "r"); if (file == NULL) { - printf("%*s", entrynamelen+scanner.spaces, entry->d_name); + printf("%*s", filelist->displayname_len+scanner.spaces, + filelist->displayname); perror(" File acces failed"); - continue; - } + } else { + do { + a = fgetc(file); + + bfile = bfile_check(settings->bfileHeuristics, a); - do { - a = fgetc(file); - - bfile = bfile_check(settings->bfileHeuristics, a); + if (a == 10 || a == EOF) { + line_buffer[line_buffer_offset] = 0; + if (regex_parser_do(settings->regex, line_buffer) == 0) { + /* Only subtract lines when matching has finished */ + if (!regex_parser_matching(settings->regex)) { + lines -= settings->regex->matched_lines; + } + } - if (a == 10 || a == EOF) { - line_buffer[line_buffer_offset] = 0; - if (regex_parser_do(settings->regex, line_buffer) == 0) { - /* Only subtract lines when matching has finished */ - if (!regex_parser_matching(settings->regex)) { - lines -= settings->regex->matched_lines; + line_buffer_offset = 0; + lines++; + } else { + if (line_buffer_offset < REGEX_MAX_LINELENGTH) { + line_buffer[line_buffer_offset] = a; + line_buffer_offset++; + } else { + line_buffer[line_buffer_offset-1] = 0; + settings->confusing_lnlen = true; } } + } while (!bfile && a != EOF); + fclose(file); - line_buffer_offset = 0; - lines++; + /* Print and sum line count */ + if (bfile) { + if (!settings->matchesOnly) { + printf("%*s%*s%19s\n", filelist->displayname_len+scanner.spaces, + filelist->displayname, + 60-filelist->displayname_len-scanner.spaces, "", "binary"); + } } else { - if (line_buffer_offset < REGEX_MAX_LINELENGTH) { - line_buffer[line_buffer_offset] = a; - line_buffer_offset++; - } else { - line_buffer[line_buffer_offset-1] = 0; - settings->confusing_lnlen = true; - } + lineSum += lines; + printf("%*s%*s%13d lines\n", + filelist->displayname_len+scanner.spaces, filelist->displayname, + 60-filelist->displayname_len-scanner.spaces, "", lines); } - } while (!bfile && a != EOF); - fclose(file); - - /* Print and sum line count */ - if (bfile) { - if (!settings->matchesOnly) { - printf("%*s%*s%19s\n", - entrynamelen+scanner.spaces, entry->d_name, - 60-entrynamelen-scanner.spaces, "", "binary"); - } - } else { - lineSum += lines; - printf("%*s%*s%13d lines\n", - entrynamelen+scanner.spaces, entry->d_name, - 60-entrynamelen-scanner.spaces, "", lines); } } else { if (!settings->matchesOnly) { /* Print hint */ printf("%*s%*s%19s\n", - entrynamelen+scanner.spaces, entry->d_name, - 60-entrynamelen-scanner.spaces, "", "no match"); + filelist->displayname_len+scanner.spaces, filelist->displayname, + 60-filelist->displayname_len-scanner.spaces, "", "no match"); } } } + + free(filelist->filename); + free(filelist->displayname); + filelist_t *freethis = filelist; + filelist = filelist->next; + free(freethis); } - closedir(dirf); - return lineSum; }