Tue, 21 May 2013 13:19:37 +0200
replaced direct scanning of directories with a two-step approach (first: create filename list, second: scan)
gcc.mk | file | annotate | diff | comparison | revisions | |
mingw.mk | file | annotate | diff | comparison | revisions | |
src/scanner.c | file | annotate | diff | comparison | revisions |
1.1 --- a/gcc.mk Fri May 17 14:41:44 2013 +0200 1.2 +++ b/gcc.mk Tue May 21 13:19:37 2013 +0200 1.3 @@ -27,5 +27,5 @@ 1.4 1.5 CC = gcc 1.6 LD = gcc 1.7 -CFLAGS = -Wall -std=gnu99 -O 1.8 +CFLAGS = -Wall -std=gnu99 -O2 1.9 LDFLAGS =
2.1 --- a/mingw.mk Fri May 17 14:41:44 2013 +0200 2.2 +++ b/mingw.mk Tue May 21 13:19:37 2013 +0200 2.3 @@ -27,5 +27,5 @@ 2.4 2.5 CC = gcc 2.6 LD = gcc 2.7 -CFLAGS = -Wall -std=gnu99 -O 2.8 +CFLAGS = -Wall -std=gnu99 -O2 2.9 LDFLAGS = -static -lregex
3.1 --- a/src/scanner.c Fri May 17 14:41:44 2013 +0200 3.2 +++ b/src/scanner.c Tue May 21 13:19:37 2013 +0200 3.3 @@ -36,16 +36,24 @@ 3.4 #include "regex_parser.h" 3.5 #include <sys/stat.h> 3.6 3.7 -int scanDirectory(scanner_t scanner, settings_t* settings) { 3.8 +typedef struct filelist filelist_t; 3.9 3.10 +struct filelist { 3.11 + char *displayname; 3.12 + int displayname_len; 3.13 + char *filename; 3.14 + int st_mode; 3.15 + filelist_t *next; 3.16 +}; 3.17 + 3.18 +filelist_t *buildFileList(scanner_t scanner, settings_t* settings, 3.19 + filelist_t* list) { 3.20 + 3.21 DIR *dirf; 3.22 struct dirent *entry; 3.23 - int entrynamelen; 3.24 - int lines, a; 3.25 - int lineSum = 0; 3.26 - bool bfile; 3.27 struct stat statbuf; 3.28 - 3.29 + filelist_t *listentry = list; 3.30 + 3.31 if ((dirf = opendir(scanner.dir)) == NULL) { 3.32 printf("%s", scanner.dir); 3.33 perror(" Directory access failed"); 3.34 @@ -54,31 +62,74 @@ 3.35 3.36 while ((entry = readdir(dirf)) != NULL) { 3.37 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { 3.38 + 3.39 + /* Create new filelist entry */ 3.40 + filelist_t *newentry = (filelist_t*) malloc(sizeof(filelist_t)); 3.41 + // TODO: don't just append - create a sorted list! 3.42 + if (listentry) { 3.43 + listentry->next = newentry; 3.44 + } 3.45 + listentry = newentry; 3.46 + if (!list) { 3.47 + list = listentry; 3.48 + } 3.49 + 3.50 + listentry->next = NULL; 3.51 + 3.52 + listentry->displayname_len = strlen(entry->d_name); 3.53 + listentry->displayname = (char*) malloc(listentry->displayname_len+1); 3.54 + memcpy(listentry->displayname, entry->d_name, listentry->displayname_len); 3.55 + listentry->displayname[listentry->displayname_len] = 0; 3.56 + 3.57 + listentry->st_mode = 0; 3.58 + 3.59 /* Construct absolute pathname string */ 3.60 - entrynamelen = strlen(entry->d_name); 3.61 - char filename[(1+strlen(scanner.dir)+entrynamelen)]; 3.62 - strcpy(filename, scanner.dir); 3.63 - strncat(filename, &settings->fileSeparator, 1); 3.64 - strcat(filename, entry->d_name); 3.65 + size_t dirnamelen = strlen(scanner.dir); 3.66 + char *filename = (char*) malloc(2+dirnamelen+listentry->displayname_len); 3.67 + memcpy(filename, scanner.dir, dirnamelen); 3.68 + filename[dirnamelen] = settings->fileSeparator; 3.69 + memcpy(filename+dirnamelen+1, entry->d_name, listentry->displayname_len); 3.70 + filename[1+dirnamelen+listentry->displayname_len] = 0; 3.71 + listentry->filename = filename; 3.72 3.73 /* Check for subdirectory */ 3.74 if (stat(filename, &statbuf) == 0) { 3.75 - if (!(statbuf.st_mode & S_IFREG)) { 3.76 - printf("%*s\n", entrynamelen+scanner.spaces, entry->d_name); 3.77 - if (settings->recursive && (statbuf.st_mode & S_IFDIR)) { 3.78 - lineSum += scanDirectory( 3.79 - (scanner_t) {filename, scanner.spaces+1}, settings); 3.80 - } 3.81 - continue; 3.82 - } 3.83 + listentry->st_mode = statbuf.st_mode; 3.84 } else { 3.85 perror(" Error in stat call"); 3.86 continue; 3.87 } 3.88 + } 3.89 + } 3.90 + 3.91 + closedir(dirf); 3.92 + 3.93 + return list; 3.94 +} 3.95 3.96 +int scanDirectory(scanner_t scanner, settings_t* settings) { 3.97 + 3.98 + int lines, a; 3.99 + int lineSum = 0; 3.100 + bool bfile; 3.101 + 3.102 + filelist_t *filelist = buildFileList(scanner, settings, NULL); 3.103 + 3.104 + while (filelist != NULL) { 3.105 + 3.106 + /* Scan subdirectories */ 3.107 + if (!(filelist->st_mode & S_IFREG)) { 3.108 + printf("%*s\n", filelist->displayname_len+scanner.spaces, 3.109 + filelist->displayname); 3.110 + if (settings->recursive && (filelist->st_mode & S_IFDIR)) { 3.111 + scanDirectory((scanner_t) {filelist->filename, scanner.spaces+1}, 3.112 + settings); 3.113 + } 3.114 + } else { 3.115 if ((settings->includeSuffixes->count == 0 3.116 - || testSuffix(filename, settings->includeSuffixes)) 3.117 - && !testSuffix(filename, settings->excludeSuffixes)) { 3.118 + || testSuffix(filelist->displayname, settings->includeSuffixes)) 3.119 + && !testSuffix(filelist->displayname, settings->excludeSuffixes)) { 3.120 + 3.121 /* Count lines */ 3.122 lines = 0; 3.123 bfile = false; 3.124 @@ -86,66 +137,70 @@ 3.125 char line_buffer[REGEX_MAX_LINELENGTH]; 3.126 int line_buffer_offset = 0; 3.127 3.128 - FILE *file = fopen(filename, "r"); 3.129 + FILE *file = fopen(filelist->filename, "r"); 3.130 if (file == NULL) { 3.131 - printf("%*s", entrynamelen+scanner.spaces, entry->d_name); 3.132 + printf("%*s", filelist->displayname_len+scanner.spaces, 3.133 + filelist->displayname); 3.134 perror(" File acces failed"); 3.135 - continue; 3.136 - } 3.137 + } else { 3.138 + do { 3.139 + a = fgetc(file); 3.140 3.141 - do { 3.142 - a = fgetc(file); 3.143 + bfile = bfile_check(settings->bfileHeuristics, a); 3.144 3.145 - bfile = bfile_check(settings->bfileHeuristics, a); 3.146 + if (a == 10 || a == EOF) { 3.147 + line_buffer[line_buffer_offset] = 0; 3.148 + if (regex_parser_do(settings->regex, line_buffer) == 0) { 3.149 + /* Only subtract lines when matching has finished */ 3.150 + if (!regex_parser_matching(settings->regex)) { 3.151 + lines -= settings->regex->matched_lines; 3.152 + } 3.153 + } 3.154 3.155 - if (a == 10 || a == EOF) { 3.156 - line_buffer[line_buffer_offset] = 0; 3.157 - if (regex_parser_do(settings->regex, line_buffer) == 0) { 3.158 - /* Only subtract lines when matching has finished */ 3.159 - if (!regex_parser_matching(settings->regex)) { 3.160 - lines -= settings->regex->matched_lines; 3.161 + line_buffer_offset = 0; 3.162 + lines++; 3.163 + } else { 3.164 + if (line_buffer_offset < REGEX_MAX_LINELENGTH) { 3.165 + line_buffer[line_buffer_offset] = a; 3.166 + line_buffer_offset++; 3.167 + } else { 3.168 + line_buffer[line_buffer_offset-1] = 0; 3.169 + settings->confusing_lnlen = true; 3.170 } 3.171 } 3.172 + } while (!bfile && a != EOF); 3.173 + fclose(file); 3.174 3.175 - line_buffer_offset = 0; 3.176 - lines++; 3.177 + /* Print and sum line count */ 3.178 + if (bfile) { 3.179 + if (!settings->matchesOnly) { 3.180 + printf("%*s%*s%19s\n", filelist->displayname_len+scanner.spaces, 3.181 + filelist->displayname, 3.182 + 60-filelist->displayname_len-scanner.spaces, "", "binary"); 3.183 + } 3.184 } else { 3.185 - if (line_buffer_offset < REGEX_MAX_LINELENGTH) { 3.186 - line_buffer[line_buffer_offset] = a; 3.187 - line_buffer_offset++; 3.188 - } else { 3.189 - line_buffer[line_buffer_offset-1] = 0; 3.190 - settings->confusing_lnlen = true; 3.191 - } 3.192 + lineSum += lines; 3.193 + printf("%*s%*s%13d lines\n", 3.194 + filelist->displayname_len+scanner.spaces, filelist->displayname, 3.195 + 60-filelist->displayname_len-scanner.spaces, "", lines); 3.196 } 3.197 - } while (!bfile && a != EOF); 3.198 - fclose(file); 3.199 - 3.200 - /* Print and sum line count */ 3.201 - if (bfile) { 3.202 - if (!settings->matchesOnly) { 3.203 - printf("%*s%*s%19s\n", 3.204 - entrynamelen+scanner.spaces, entry->d_name, 3.205 - 60-entrynamelen-scanner.spaces, "", "binary"); 3.206 - } 3.207 - } else { 3.208 - lineSum += lines; 3.209 - printf("%*s%*s%13d lines\n", 3.210 - entrynamelen+scanner.spaces, entry->d_name, 3.211 - 60-entrynamelen-scanner.spaces, "", lines); 3.212 } 3.213 } else { 3.214 if (!settings->matchesOnly) { 3.215 /* Print hint */ 3.216 printf("%*s%*s%19s\n", 3.217 - entrynamelen+scanner.spaces, entry->d_name, 3.218 - 60-entrynamelen-scanner.spaces, "", "no match"); 3.219 + filelist->displayname_len+scanner.spaces, filelist->displayname, 3.220 + 60-filelist->displayname_len-scanner.spaces, "", "no match"); 3.221 } 3.222 } 3.223 } 3.224 + 3.225 + free(filelist->filename); 3.226 + free(filelist->displayname); 3.227 + filelist_t *freethis = filelist; 3.228 + filelist = filelist->next; 3.229 + free(freethis); 3.230 } 3.231 3.232 - closedir(dirf); 3.233 - 3.234 return lineSum; 3.235 }