1.1 --- a/src/scanner.c Fri May 17 14:41:44 2013 +0200 1.2 +++ b/src/scanner.c Tue May 21 13:19:37 2013 +0200 1.3 @@ -36,16 +36,24 @@ 1.4 #include "regex_parser.h" 1.5 #include <sys/stat.h> 1.6 1.7 -int scanDirectory(scanner_t scanner, settings_t* settings) { 1.8 +typedef struct filelist filelist_t; 1.9 1.10 +struct filelist { 1.11 + char *displayname; 1.12 + int displayname_len; 1.13 + char *filename; 1.14 + int st_mode; 1.15 + filelist_t *next; 1.16 +}; 1.17 + 1.18 +filelist_t *buildFileList(scanner_t scanner, settings_t* settings, 1.19 + filelist_t* list) { 1.20 + 1.21 DIR *dirf; 1.22 struct dirent *entry; 1.23 - int entrynamelen; 1.24 - int lines, a; 1.25 - int lineSum = 0; 1.26 - bool bfile; 1.27 struct stat statbuf; 1.28 - 1.29 + filelist_t *listentry = list; 1.30 + 1.31 if ((dirf = opendir(scanner.dir)) == NULL) { 1.32 printf("%s", scanner.dir); 1.33 perror(" Directory access failed"); 1.34 @@ -54,31 +62,74 @@ 1.35 1.36 while ((entry = readdir(dirf)) != NULL) { 1.37 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { 1.38 + 1.39 + /* Create new filelist entry */ 1.40 + filelist_t *newentry = (filelist_t*) malloc(sizeof(filelist_t)); 1.41 + // TODO: don't just append - create a sorted list! 1.42 + if (listentry) { 1.43 + listentry->next = newentry; 1.44 + } 1.45 + listentry = newentry; 1.46 + if (!list) { 1.47 + list = listentry; 1.48 + } 1.49 + 1.50 + listentry->next = NULL; 1.51 + 1.52 + listentry->displayname_len = strlen(entry->d_name); 1.53 + listentry->displayname = (char*) malloc(listentry->displayname_len+1); 1.54 + memcpy(listentry->displayname, entry->d_name, listentry->displayname_len); 1.55 + listentry->displayname[listentry->displayname_len] = 0; 1.56 + 1.57 + listentry->st_mode = 0; 1.58 + 1.59 /* Construct absolute pathname string */ 1.60 - entrynamelen = strlen(entry->d_name); 1.61 - char filename[(1+strlen(scanner.dir)+entrynamelen)]; 1.62 - strcpy(filename, scanner.dir); 1.63 - strncat(filename, &settings->fileSeparator, 1); 1.64 - strcat(filename, entry->d_name); 1.65 + size_t dirnamelen = strlen(scanner.dir); 1.66 + char *filename = (char*) malloc(2+dirnamelen+listentry->displayname_len); 1.67 + memcpy(filename, scanner.dir, dirnamelen); 1.68 + filename[dirnamelen] = settings->fileSeparator; 1.69 + memcpy(filename+dirnamelen+1, entry->d_name, listentry->displayname_len); 1.70 + filename[1+dirnamelen+listentry->displayname_len] = 0; 1.71 + listentry->filename = filename; 1.72 1.73 /* Check for subdirectory */ 1.74 if (stat(filename, &statbuf) == 0) { 1.75 - if (!(statbuf.st_mode & S_IFREG)) { 1.76 - printf("%*s\n", entrynamelen+scanner.spaces, entry->d_name); 1.77 - if (settings->recursive && (statbuf.st_mode & S_IFDIR)) { 1.78 - lineSum += scanDirectory( 1.79 - (scanner_t) {filename, scanner.spaces+1}, settings); 1.80 - } 1.81 - continue; 1.82 - } 1.83 + listentry->st_mode = statbuf.st_mode; 1.84 } else { 1.85 perror(" Error in stat call"); 1.86 continue; 1.87 } 1.88 + } 1.89 + } 1.90 + 1.91 + closedir(dirf); 1.92 + 1.93 + return list; 1.94 +} 1.95 1.96 +int scanDirectory(scanner_t scanner, settings_t* settings) { 1.97 + 1.98 + int lines, a; 1.99 + int lineSum = 0; 1.100 + bool bfile; 1.101 + 1.102 + filelist_t *filelist = buildFileList(scanner, settings, NULL); 1.103 + 1.104 + while (filelist != NULL) { 1.105 + 1.106 + /* Scan subdirectories */ 1.107 + if (!(filelist->st_mode & S_IFREG)) { 1.108 + printf("%*s\n", filelist->displayname_len+scanner.spaces, 1.109 + filelist->displayname); 1.110 + if (settings->recursive && (filelist->st_mode & S_IFDIR)) { 1.111 + scanDirectory((scanner_t) {filelist->filename, scanner.spaces+1}, 1.112 + settings); 1.113 + } 1.114 + } else { 1.115 if ((settings->includeSuffixes->count == 0 1.116 - || testSuffix(filename, settings->includeSuffixes)) 1.117 - && !testSuffix(filename, settings->excludeSuffixes)) { 1.118 + || testSuffix(filelist->displayname, settings->includeSuffixes)) 1.119 + && !testSuffix(filelist->displayname, settings->excludeSuffixes)) { 1.120 + 1.121 /* Count lines */ 1.122 lines = 0; 1.123 bfile = false; 1.124 @@ -86,66 +137,70 @@ 1.125 char line_buffer[REGEX_MAX_LINELENGTH]; 1.126 int line_buffer_offset = 0; 1.127 1.128 - FILE *file = fopen(filename, "r"); 1.129 + FILE *file = fopen(filelist->filename, "r"); 1.130 if (file == NULL) { 1.131 - printf("%*s", entrynamelen+scanner.spaces, entry->d_name); 1.132 + printf("%*s", filelist->displayname_len+scanner.spaces, 1.133 + filelist->displayname); 1.134 perror(" File acces failed"); 1.135 - continue; 1.136 - } 1.137 + } else { 1.138 + do { 1.139 + a = fgetc(file); 1.140 1.141 - do { 1.142 - a = fgetc(file); 1.143 + bfile = bfile_check(settings->bfileHeuristics, a); 1.144 1.145 - bfile = bfile_check(settings->bfileHeuristics, a); 1.146 + if (a == 10 || a == EOF) { 1.147 + line_buffer[line_buffer_offset] = 0; 1.148 + if (regex_parser_do(settings->regex, line_buffer) == 0) { 1.149 + /* Only subtract lines when matching has finished */ 1.150 + if (!regex_parser_matching(settings->regex)) { 1.151 + lines -= settings->regex->matched_lines; 1.152 + } 1.153 + } 1.154 1.155 - if (a == 10 || a == EOF) { 1.156 - line_buffer[line_buffer_offset] = 0; 1.157 - if (regex_parser_do(settings->regex, line_buffer) == 0) { 1.158 - /* Only subtract lines when matching has finished */ 1.159 - if (!regex_parser_matching(settings->regex)) { 1.160 - lines -= settings->regex->matched_lines; 1.161 + line_buffer_offset = 0; 1.162 + lines++; 1.163 + } else { 1.164 + if (line_buffer_offset < REGEX_MAX_LINELENGTH) { 1.165 + line_buffer[line_buffer_offset] = a; 1.166 + line_buffer_offset++; 1.167 + } else { 1.168 + line_buffer[line_buffer_offset-1] = 0; 1.169 + settings->confusing_lnlen = true; 1.170 } 1.171 } 1.172 + } while (!bfile && a != EOF); 1.173 + fclose(file); 1.174 1.175 - line_buffer_offset = 0; 1.176 - lines++; 1.177 + /* Print and sum line count */ 1.178 + if (bfile) { 1.179 + if (!settings->matchesOnly) { 1.180 + printf("%*s%*s%19s\n", filelist->displayname_len+scanner.spaces, 1.181 + filelist->displayname, 1.182 + 60-filelist->displayname_len-scanner.spaces, "", "binary"); 1.183 + } 1.184 } else { 1.185 - if (line_buffer_offset < REGEX_MAX_LINELENGTH) { 1.186 - line_buffer[line_buffer_offset] = a; 1.187 - line_buffer_offset++; 1.188 - } else { 1.189 - line_buffer[line_buffer_offset-1] = 0; 1.190 - settings->confusing_lnlen = true; 1.191 - } 1.192 + lineSum += lines; 1.193 + printf("%*s%*s%13d lines\n", 1.194 + filelist->displayname_len+scanner.spaces, filelist->displayname, 1.195 + 60-filelist->displayname_len-scanner.spaces, "", lines); 1.196 } 1.197 - } while (!bfile && a != EOF); 1.198 - fclose(file); 1.199 - 1.200 - /* Print and sum line count */ 1.201 - if (bfile) { 1.202 - if (!settings->matchesOnly) { 1.203 - printf("%*s%*s%19s\n", 1.204 - entrynamelen+scanner.spaces, entry->d_name, 1.205 - 60-entrynamelen-scanner.spaces, "", "binary"); 1.206 - } 1.207 - } else { 1.208 - lineSum += lines; 1.209 - printf("%*s%*s%13d lines\n", 1.210 - entrynamelen+scanner.spaces, entry->d_name, 1.211 - 60-entrynamelen-scanner.spaces, "", lines); 1.212 } 1.213 } else { 1.214 if (!settings->matchesOnly) { 1.215 /* Print hint */ 1.216 printf("%*s%*s%19s\n", 1.217 - entrynamelen+scanner.spaces, entry->d_name, 1.218 - 60-entrynamelen-scanner.spaces, "", "no match"); 1.219 + filelist->displayname_len+scanner.spaces, filelist->displayname, 1.220 + 60-filelist->displayname_len-scanner.spaces, "", "no match"); 1.221 } 1.222 } 1.223 } 1.224 + 1.225 + free(filelist->filename); 1.226 + free(filelist->displayname); 1.227 + filelist_t *freethis = filelist; 1.228 + filelist = filelist->next; 1.229 + free(freethis); 1.230 } 1.231 1.232 - closedir(dirf); 1.233 - 1.234 return lineSum; 1.235 }