src/scanner.c

changeset 99
094eff4cfc03
parent 97
7b0357fdb304
child 100
e72410a58188
equal deleted inserted replaced
98:09ad5d8ab860 99:094eff4cfc03
77 int pathcmp(const char *p1, const char *p2) { 77 int pathcmp(const char *p1, const char *p2) {
78 return strcmp(p1, p2); 78 return strcmp(p1, p2);
79 } 79 }
80 #endif 80 #endif
81 81
82 typedef struct filelist filelist_t;
83
84 struct filelist { 82 struct filelist {
85 char *displayname; 83 char *displayname;
86 unsigned displayname_len; 84 unsigned displayname_len;
87 char *filename; 85 char *filename;
88 char *ext; 86 char *ext;
89 unsigned st_mode; 87 unsigned st_mode;
90 filelist_t *next; 88 struct filelist *next;
91 }; 89 };
92 90
93 static bool testSuffix(char* filename, string_list_t* list) { 91 static bool testSuffix(char* filename, string_list* list) {
94 bool ret = false; 92 bool ret = false;
95 size_t tokenlen, fnamelen = strlen(filename); 93 size_t tokenlen, fnamelen = strlen(filename);
96 for (size_t t = 0 ; t < list->count ; t++) { 94 for (size_t t = 0 ; t < list->count ; t++) {
97 tokenlen = strlen(list->items[t]); 95 tokenlen = strlen(list->items[t]);
98 if (fnamelen >= tokenlen && tokenlen > 0) { 96 if (fnamelen >= tokenlen && tokenlen > 0) {
104 } 102 }
105 } 103 }
106 return ret; 104 return ret;
107 } 105 }
108 106
109 static void addResultPerExtension(scanresult_ext_t* result, 107 static void addResultPerExtension(scanresult_ext* result,
110 char* ext, unsigned value) { 108 char* ext, unsigned value) {
111 if (!result) return; 109 if (!result) return;
112 110
113 if (!ext) ext = "w/o"; 111 if (!ext) ext = "w/o";
114 112
135 result->extensions[result->count] = strdup(ext); 133 result->extensions[result->count] = strdup(ext);
136 result->result[result->count] = value; 134 result->result[result->count] = value;
137 result->count++; 135 result->count++;
138 } 136 }
139 137
140 scanresult_t* new_scanresult_t(settings_t* settings) { 138 scanresult* new_scanresult(settings* settings) {
141 scanresult_t* result = calloc(1, sizeof(scanresult_t)); 139 scanresult* result = calloc(1, sizeof(scanresult));
142 if (settings->individual_sums) { 140 if (settings->individual_sums) {
143 result->ext = calloc(1, sizeof(scanresult_ext_t)); 141 result->ext = calloc(1, sizeof(scanresult_ext));
144 } 142 }
145 return result; 143 return result;
146 } 144 }
147 145
148 void destroy_scanresult_t(scanresult_t* result) { 146 void destroy_scanresult(scanresult* result) {
149 if (result->ext) { 147 if (result->ext) {
150 if (result->ext->count > 0) { 148 if (result->ext->count > 0) {
151 for (unsigned i = 0 ; i < result->ext->count ; i++) { 149 for (unsigned i = 0 ; i < result->ext->count ; i++) {
152 free(result->ext->extensions[i]); 150 free(result->ext->extensions[i]);
153 } 151 }
157 free(result->ext); 155 free(result->ext);
158 } 156 }
159 free(result); 157 free(result);
160 } 158 }
161 159
162 static filelist_t *buildFileList(scanner_t scanner, settings_t* settings) { 160 static struct filelist *buildFileList(scanner scanner, settings* settings) {
163 161
164 filelist_t* list = NULL; 162 struct filelist* list = NULL;
165 DIR *dirf; 163 DIR *dirf;
166 struct dirent *entry; 164 struct dirent *entry;
167 struct stat statbuf; 165 struct stat statbuf;
168 166
169 if ((dirf = opendir(scanner.dir)) == NULL) { 167 if ((dirf = opendir(scanner.dir)) == NULL) {
174 172
175 while ((entry = readdir(dirf)) != NULL) { 173 while ((entry = readdir(dirf)) != NULL) {
176 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { 174 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
177 175
178 /* Create new filelist entry */ 176 /* Create new filelist entry */
179 filelist_t *newentry = (filelist_t*) malloc(sizeof(filelist_t)); 177 struct filelist *newentry = malloc(sizeof(struct filelist));
180 newentry->next = NULL; 178 newentry->next = NULL;
181 179
182 newentry->displayname_len = strlen(entry->d_name); 180 newentry->displayname_len = strlen(entry->d_name);
183 newentry->displayname = (char*) malloc(newentry->displayname_len+1); 181 newentry->displayname = (char*) malloc(newentry->displayname_len+1);
184 memcpy(newentry->displayname, entry->d_name, newentry->displayname_len); 182 memcpy(newentry->displayname, entry->d_name, newentry->displayname_len);
208 continue; 206 continue;
209 } 207 }
210 208
211 if (list) { 209 if (list) {
212 /* create fake root to have a pointer on the true root */ 210 /* create fake root to have a pointer on the true root */
213 filelist_t root; 211 struct filelist root;
214 root.next = list; 212 root.next = list;
215 filelist_t *parent = &root; 213 struct filelist *parent = &root;
216 while (parent->next && 214 while (parent->next &&
217 (strcasecmp(parent->next->displayname, newentry->displayname) < 0 || 215 (strcasecmp(parent->next->displayname, newentry->displayname) < 0 ||
218 (!S_ISDIR(newentry->st_mode) && S_ISDIR(parent->next->st_mode)) 216 (!S_ISDIR(newentry->st_mode) && S_ISDIR(parent->next->st_mode))
219 ) && 217 ) &&
220 (!S_ISDIR(newentry->st_mode) || S_ISDIR(parent->next->st_mode)) 218 (!S_ISDIR(newentry->st_mode) || S_ISDIR(parent->next->st_mode))
233 closedir(dirf); 231 closedir(dirf);
234 232
235 return list; 233 return list;
236 } 234 }
237 235
238 static bool is_dir_excluded(settings_t* settings, const char* dir) { 236 static bool is_dir_excluded(settings* settings, const char* dir) {
239 const string_list_t * const list = settings->excludeDirs; 237 const string_list * const list = settings->excludeDirs;
240 238
241 for (size_t i = 0 ; i < list->count ; i++) { 239 for (size_t i = 0 ; i < list->count ; i++) {
242 /* determine if the list item is a path or a name */ 240 /* determine if the list item is a path or a name */
243 if (strchr(list->items[i], settings->fileSeparator) == NULL) { 241 if (strchr(list->items[i], settings->fileSeparator) == NULL) {
244 /* compare only the name */ 242 /* compare only the name */
262 } 260 }
263 } 261 }
264 return false; 262 return false;
265 } 263 }
266 264
267 void scanDirectory(scanner_t scanner, settings_t* settings, 265 void scanDirectory(scanner scnr, settings* settings,
268 string_list_t* output, scanresult_t* result) { 266 string_list* output, scanresult* result) {
269 267
270 result->result = 0; 268 result->result = 0;
271 bool bfile; 269 bool bfile;
272 char *outbuf; 270 char *outbuf;
273 const char *result_type = settings->count_chars ? "chars" : "lines"; 271 const char *result_type = settings->count_chars ? "chars" : "lines";
274 272
275 filelist_t *filelist = buildFileList(scanner, settings); 273 struct filelist *filelist = buildFileList(scnr, settings);
276 274
277 while (filelist != NULL) { 275 while (filelist != NULL) {
278 276
279 /* Scan subdirectories */ 277 /* Scan subdirectories */
280 if (!S_ISREG(filelist->st_mode)) { 278 if (!S_ISREG(filelist->st_mode)) {
283 if (is_dir_excluded(settings, filelist->filename)) { 281 if (is_dir_excluded(settings, filelist->filename)) {
284 if (!settings->matchesOnly && settings->verbose) { 282 if (!settings->matchesOnly && settings->verbose) {
285 /* Print hint */ 283 /* Print hint */
286 outbuf = malloc(81); 284 outbuf = malloc(81);
287 snprintf(outbuf, 81, "%*s%*s%19s\n", 285 snprintf(outbuf, 81, "%*s%*s%19s\n",
288 filelist->displayname_len + scanner.spaces, 286 filelist->displayname_len + scnr.spaces,
289 filelist->displayname, 287 filelist->displayname,
290 60 - filelist->displayname_len - scanner.spaces, 288 60 - filelist->displayname_len - scnr.spaces,
291 "", "no match"); 289 "", "no match");
292 add_string(output, outbuf); 290 add_string(output, outbuf);
293 } 291 }
294 } else { 292 } else {
295 string_list_t *recoutput = settings->verbose ? new_string_list_t() : NULL; 293 string_list *recoutput = settings->verbose ? new_string_list() : NULL;
296 scanresult_t recresult; 294 scanresult recresult;
297 recresult.ext = result->ext; 295 recresult.ext = result->ext;
298 scanDirectory( 296 scanDirectory(
299 (scanner_t) {filelist->filename, scanner.spaces+1}, 297 (scanner) {filelist->filename, scnr.spaces+1},
300 settings, recoutput, &recresult); 298 settings, recoutput, &recresult);
301 result->result += recresult.result; 299 result->result += recresult.result;
302 if (settings->verbose && (!settings->matchesOnly || recresult.result > 0)) { 300 if (settings->verbose && (!settings->matchesOnly || recresult.result > 0)) {
303 outbuf = (char*) malloc(81); 301 outbuf = (char*) malloc(81);
304 snprintf(outbuf, 81, "%*s/%*s%13u %s\n", 302 snprintf(outbuf, 81, "%*s/%*s%13u %s\n",
305 filelist->displayname_len+scanner.spaces, filelist->displayname, 303 filelist->displayname_len+scnr.spaces, filelist->displayname,
306 60-filelist->displayname_len-scanner.spaces-1, "", 304 60-filelist->displayname_len-scnr.spaces-1, "",
307 recresult.result, result_type); 305 recresult.result, result_type);
308 add_string(output, outbuf); 306 add_string(output, outbuf);
309 for (unsigned i = 0 ; i < recoutput->count ; i++) { 307 for (unsigned i = 0 ; i < recoutput->count ; i++) {
310 add_string(output, recoutput->items[i]); 308 add_string(output, recoutput->items[i]);
311 } 309 }
312 } 310 }
313 destroy_string_list_t(recoutput); 311 destroy_string_list(recoutput);
314 } 312 }
315 } 313 }
316 } else if (!settings->matchesOnly && settings->verbose) { 314 } else if (!settings->matchesOnly && settings->verbose) {
317 outbuf = (char*) malloc(81); 315 outbuf = (char*) malloc(81);
318 snprintf(outbuf, 81, "%*s\n", 316 snprintf(outbuf, 81, "%*s\n",
319 filelist->displayname_len+scanner.spaces, 317 filelist->displayname_len+scnr.spaces,
320 filelist->displayname); 318 filelist->displayname);
321 add_string(output, outbuf); 319 add_string(output, outbuf);
322 } 320 }
323 } else { 321 } else {
324 if ((settings->includeSuffixes->count == 0 322 if ((settings->includeSuffixes->count == 0
379 /* Print and sum line count */ 377 /* Print and sum line count */
380 if (bfile) { 378 if (bfile) {
381 if (!settings->matchesOnly && !settings->dirsOnly && settings->verbose) { 379 if (!settings->matchesOnly && !settings->dirsOnly && settings->verbose) {
382 outbuf = (char*) malloc(81); 380 outbuf = (char*) malloc(81);
383 snprintf(outbuf, 81, 381 snprintf(outbuf, 81,
384 "%*s%*s%19s\n", filelist->displayname_len+scanner.spaces, 382 "%*s%*s%19s\n", filelist->displayname_len+scnr.spaces,
385 filelist->displayname, 383 filelist->displayname,
386 60-filelist->displayname_len-scanner.spaces, "", "binary"); 384 60-filelist->displayname_len-scnr.spaces, "", "binary");
387 add_string(output, outbuf); 385 add_string(output, outbuf);
388 } 386 }
389 } else { 387 } else {
390 addResultPerExtension(result->ext, filelist->ext, res_value); 388 addResultPerExtension(result->ext, filelist->ext, res_value);
391 result->result += res_value; 389 result->result += res_value;
392 if (!settings->dirsOnly && settings->verbose) { 390 if (!settings->dirsOnly && settings->verbose) {
393 outbuf = (char*) malloc(81); 391 outbuf = (char*) malloc(81);
394 snprintf(outbuf, 81, "%*s%*s%13u %s\n", 392 snprintf(outbuf, 81, "%*s%*s%13u %s\n",
395 filelist->displayname_len+scanner.spaces, 393 filelist->displayname_len+scnr.spaces,
396 filelist->displayname, 394 filelist->displayname,
397 60-filelist->displayname_len-scanner.spaces, 395 60-filelist->displayname_len-scnr.spaces,
398 "", 396 "",
399 res_value, 397 res_value,
400 result_type 398 result_type
401 ); 399 );
402 add_string(output, outbuf); 400 add_string(output, outbuf);
406 } else { 404 } else {
407 if (!settings->matchesOnly && !settings->dirsOnly && settings->verbose) { 405 if (!settings->matchesOnly && !settings->dirsOnly && settings->verbose) {
408 /* Print hint */ 406 /* Print hint */
409 outbuf = (char*) malloc(81); 407 outbuf = (char*) malloc(81);
410 snprintf(outbuf, 81, "%*s%*s%19s\n", 408 snprintf(outbuf, 81, "%*s%*s%19s\n",
411 filelist->displayname_len+scanner.spaces, filelist->displayname, 409 filelist->displayname_len+scnr.spaces, filelist->displayname,
412 60-filelist->displayname_len-scanner.spaces, "", "no match"); 410 60-filelist->displayname_len-scnr.spaces, "", "no match");
413 add_string(output, outbuf); 411 add_string(output, outbuf);
414 } 412 }
415 } 413 }
416 } 414 }
417 415
418 free(filelist->filename); 416 free(filelist->filename);
419 free(filelist->displayname); 417 free(filelist->displayname);
420 filelist_t *freethis = filelist; 418 struct filelist *freethis = filelist;
421 filelist = filelist->next; 419 filelist = filelist->next;
422 free(freethis); 420 free(freethis);
423 } 421 }
424 } 422 }
425 423

mercurial