src/scanner.c

changeset 41
c2e73e175341
parent 40
5938a9b74e8e
child 42
0402b9b41b0a
equal deleted inserted replaced
40:5938a9b74e8e 41:c2e73e175341
34 #include "suffix_fnc.h" 34 #include "suffix_fnc.h"
35 #include "bfile_heuristics.h" 35 #include "bfile_heuristics.h"
36 #include "regex_parser.h" 36 #include "regex_parser.h"
37 #include <sys/stat.h> 37 #include <sys/stat.h>
38 38
39 int scanDirectory(scanner_t scanner, settings_t* settings) { 39 typedef struct filelist filelist_t;
40 40
41 struct filelist {
42 char *displayname;
43 int displayname_len;
44 char *filename;
45 int st_mode;
46 filelist_t *next;
47 };
48
49 filelist_t *buildFileList(scanner_t scanner, settings_t* settings,
50 filelist_t* list) {
51
41 DIR *dirf; 52 DIR *dirf;
42 struct dirent *entry; 53 struct dirent *entry;
43 int entrynamelen;
44 int lines, a;
45 int lineSum = 0;
46 bool bfile;
47 struct stat statbuf; 54 struct stat statbuf;
48 55 filelist_t *listentry = list;
56
49 if ((dirf = opendir(scanner.dir)) == NULL) { 57 if ((dirf = opendir(scanner.dir)) == NULL) {
50 printf("%s", scanner.dir); 58 printf("%s", scanner.dir);
51 perror(" Directory access failed"); 59 perror(" Directory access failed");
52 return 0; 60 return 0;
53 } 61 }
54 62
55 while ((entry = readdir(dirf)) != NULL) { 63 while ((entry = readdir(dirf)) != NULL) {
56 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { 64 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
65
66 /* Create new filelist entry */
67 filelist_t *newentry = (filelist_t*) malloc(sizeof(filelist_t));
68 // TODO: don't just append - create a sorted list!
69 if (listentry) {
70 listentry->next = newentry;
71 }
72 listentry = newentry;
73 if (!list) {
74 list = listentry;
75 }
76
77 listentry->next = NULL;
78
79 listentry->displayname_len = strlen(entry->d_name);
80 listentry->displayname = (char*) malloc(listentry->displayname_len+1);
81 memcpy(listentry->displayname, entry->d_name, listentry->displayname_len);
82 listentry->displayname[listentry->displayname_len] = 0;
83
84 listentry->st_mode = 0;
85
57 /* Construct absolute pathname string */ 86 /* Construct absolute pathname string */
58 entrynamelen = strlen(entry->d_name); 87 size_t dirnamelen = strlen(scanner.dir);
59 char filename[(1+strlen(scanner.dir)+entrynamelen)]; 88 char *filename = (char*) malloc(2+dirnamelen+listentry->displayname_len);
60 strcpy(filename, scanner.dir); 89 memcpy(filename, scanner.dir, dirnamelen);
61 strncat(filename, &settings->fileSeparator, 1); 90 filename[dirnamelen] = settings->fileSeparator;
62 strcat(filename, entry->d_name); 91 memcpy(filename+dirnamelen+1, entry->d_name, listentry->displayname_len);
92 filename[1+dirnamelen+listentry->displayname_len] = 0;
93 listentry->filename = filename;
63 94
64 /* Check for subdirectory */ 95 /* Check for subdirectory */
65 if (stat(filename, &statbuf) == 0) { 96 if (stat(filename, &statbuf) == 0) {
66 if (!(statbuf.st_mode & S_IFREG)) { 97 listentry->st_mode = statbuf.st_mode;
67 printf("%*s\n", entrynamelen+scanner.spaces, entry->d_name);
68 if (settings->recursive && (statbuf.st_mode & S_IFDIR)) {
69 lineSum += scanDirectory(
70 (scanner_t) {filename, scanner.spaces+1}, settings);
71 }
72 continue;
73 }
74 } else { 98 } else {
75 perror(" Error in stat call"); 99 perror(" Error in stat call");
76 continue; 100 continue;
77 } 101 }
78 102 }
103 }
104
105 closedir(dirf);
106
107 return list;
108 }
109
110 int scanDirectory(scanner_t scanner, settings_t* settings) {
111
112 int lines, a;
113 int lineSum = 0;
114 bool bfile;
115
116 filelist_t *filelist = buildFileList(scanner, settings, NULL);
117
118 while (filelist != NULL) {
119
120 /* Scan subdirectories */
121 if (!(filelist->st_mode & S_IFREG)) {
122 printf("%*s\n", filelist->displayname_len+scanner.spaces,
123 filelist->displayname);
124 if (settings->recursive && (filelist->st_mode & S_IFDIR)) {
125 scanDirectory((scanner_t) {filelist->filename, scanner.spaces+1},
126 settings);
127 }
128 } else {
79 if ((settings->includeSuffixes->count == 0 129 if ((settings->includeSuffixes->count == 0
80 || testSuffix(filename, settings->includeSuffixes)) 130 || testSuffix(filelist->displayname, settings->includeSuffixes))
81 && !testSuffix(filename, settings->excludeSuffixes)) { 131 && !testSuffix(filelist->displayname, settings->excludeSuffixes)) {
132
82 /* Count lines */ 133 /* Count lines */
83 lines = 0; 134 lines = 0;
84 bfile = false; 135 bfile = false;
85 bfile_reset(settings->bfileHeuristics); 136 bfile_reset(settings->bfileHeuristics);
86 char line_buffer[REGEX_MAX_LINELENGTH]; 137 char line_buffer[REGEX_MAX_LINELENGTH];
87 int line_buffer_offset = 0; 138 int line_buffer_offset = 0;
88 139
89 FILE *file = fopen(filename, "r"); 140 FILE *file = fopen(filelist->filename, "r");
90 if (file == NULL) { 141 if (file == NULL) {
91 printf("%*s", entrynamelen+scanner.spaces, entry->d_name); 142 printf("%*s", filelist->displayname_len+scanner.spaces,
143 filelist->displayname);
92 perror(" File acces failed"); 144 perror(" File acces failed");
93 continue; 145 } else {
94 } 146 do {
95 147 a = fgetc(file);
96 do { 148
97 a = fgetc(file); 149 bfile = bfile_check(settings->bfileHeuristics, a);
98 150
99 bfile = bfile_check(settings->bfileHeuristics, a); 151 if (a == 10 || a == EOF) {
100 152 line_buffer[line_buffer_offset] = 0;
101 if (a == 10 || a == EOF) { 153 if (regex_parser_do(settings->regex, line_buffer) == 0) {
102 line_buffer[line_buffer_offset] = 0; 154 /* Only subtract lines when matching has finished */
103 if (regex_parser_do(settings->regex, line_buffer) == 0) { 155 if (!regex_parser_matching(settings->regex)) {
104 /* Only subtract lines when matching has finished */ 156 lines -= settings->regex->matched_lines;
105 if (!regex_parser_matching(settings->regex)) { 157 }
106 lines -= settings->regex->matched_lines; 158 }
159
160 line_buffer_offset = 0;
161 lines++;
162 } else {
163 if (line_buffer_offset < REGEX_MAX_LINELENGTH) {
164 line_buffer[line_buffer_offset] = a;
165 line_buffer_offset++;
166 } else {
167 line_buffer[line_buffer_offset-1] = 0;
168 settings->confusing_lnlen = true;
107 } 169 }
108 } 170 }
109 171 } while (!bfile && a != EOF);
110 line_buffer_offset = 0; 172 fclose(file);
111 lines++; 173
174 /* Print and sum line count */
175 if (bfile) {
176 if (!settings->matchesOnly) {
177 printf("%*s%*s%19s\n", filelist->displayname_len+scanner.spaces,
178 filelist->displayname,
179 60-filelist->displayname_len-scanner.spaces, "", "binary");
180 }
112 } else { 181 } else {
113 if (line_buffer_offset < REGEX_MAX_LINELENGTH) { 182 lineSum += lines;
114 line_buffer[line_buffer_offset] = a; 183 printf("%*s%*s%13d lines\n",
115 line_buffer_offset++; 184 filelist->displayname_len+scanner.spaces, filelist->displayname,
116 } else { 185 60-filelist->displayname_len-scanner.spaces, "", lines);
117 line_buffer[line_buffer_offset-1] = 0;
118 settings->confusing_lnlen = true;
119 }
120 } 186 }
121 } while (!bfile && a != EOF);
122 fclose(file);
123
124 /* Print and sum line count */
125 if (bfile) {
126 if (!settings->matchesOnly) {
127 printf("%*s%*s%19s\n",
128 entrynamelen+scanner.spaces, entry->d_name,
129 60-entrynamelen-scanner.spaces, "", "binary");
130 }
131 } else {
132 lineSum += lines;
133 printf("%*s%*s%13d lines\n",
134 entrynamelen+scanner.spaces, entry->d_name,
135 60-entrynamelen-scanner.spaces, "", lines);
136 } 187 }
137 } else { 188 } else {
138 if (!settings->matchesOnly) { 189 if (!settings->matchesOnly) {
139 /* Print hint */ 190 /* Print hint */
140 printf("%*s%*s%19s\n", 191 printf("%*s%*s%19s\n",
141 entrynamelen+scanner.spaces, entry->d_name, 192 filelist->displayname_len+scanner.spaces, filelist->displayname,
142 60-entrynamelen-scanner.spaces, "", "no match"); 193 60-filelist->displayname_len-scanner.spaces, "", "no match");
143 } 194 }
144 } 195 }
145 } 196 }
197
198 free(filelist->filename);
199 free(filelist->displayname);
200 filelist_t *freethis = filelist;
201 filelist = filelist->next;
202 free(freethis);
146 } 203 }
147
148 closedir(dirf);
149 204
150 return lineSum; 205 return lineSum;
151 } 206 }

mercurial