aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277>2005-09-14 15:09:06 +0000
committervodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277>2005-09-14 15:09:06 +0000
commit94dfc57fdb01d9a85deb1283efbcb8ea5d2f60ff (patch)
tree7ab30763ab663235b114a7288627cb78adc7f705
parent5dfcee2295cc09c2cc29bb882a5ed37cb59ff669 (diff)
downloadbusybox-w32-94dfc57fdb01d9a85deb1283efbcb8ea5d2f60ff.tar.gz
busybox-w32-94dfc57fdb01d9a85deb1283efbcb8ea5d2f60ff.tar.bz2
busybox-w32-94dfc57fdb01d9a85deb1283efbcb8ea5d2f60ff.zip
bb_mkdep version 2.0. speed up *2, remove problem of find e2fsprogs/uu*.h, spelling corrections by Bernhard Fischer
git-svn-id: svn://busybox.net/trunk/busybox@11457 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--scripts/bb_mkdep.c490
1 files changed, 248 insertions, 242 deletions
diff --git a/scripts/bb_mkdep.c b/scripts/bb_mkdep.c
index ee8456778..b2e0995ce 100644
--- a/scripts/bb_mkdep.c
+++ b/scripts/bb_mkdep.c
@@ -1,31 +1,37 @@
1/* 1/*
2 * Another dependences for Makefile fast mashine generator 2 * Another fast dependencies generator for Makefiles, Version 2.0
3 * 3 *
4 * Copyright (C) 2005 by Vladimir Oleynik <dzo@simtreas.ru> 4 * Copyright (C) 2005 by Vladimir Oleynik <dzo@simtreas.ru>
5 * 5 *
6 * This programm do 6 * This program does:
7 * 1) find #define KEY VALUE or #undef KEY from include/config.h 7 * 1) find #define KEY VALUE or #undef KEY from include/config.h
8 * 2) save include/config/key*.h if changed after previous usage 8 * 2) save include/config/key*.h if changed after previous usage
9 * 3) recursive scan from "./" *.[ch] files, but skip scan include/config/... 9 * 3) recursive scan from "./" *.[ch] files, but skips scan of include/config/
10 * 4) find #include "*.h" and KEYs using, if not as #define and #undef 10 * 4) find #include "*.h" and KEYs using, if not as #define and #undef
11 * 5) generate depend to stdout 11 * 5) generate dependencies to stdout
12 * path/file.o: include/config/key*.h found_include_*.h 12 * path/file.o: include/config/key*.h found_include_*.h
13 * path/inc.h: include/config/key*.h found_included_include_*.h 13 * path/inc.h: include/config/key*.h found_included_include_*.h
14 * This programm do not generate dependences for #include <...> 14 * This programm does not generate dependencies for #include <...>
15 * 15 */
16 * Options:
17 * -I local_include_path (include`s paths, default: LOCAL_INCLUDE_PATH)
18 * -d (don`t generate depend)
19 * -w (show warning if include files not found)
20 * -k include/config (default: INCLUDE_CONFIG_PATH)
21 * -c include/config.h (configs, default: INCLUDE_CONFIG_KEYS_PATH)
22 * dirs_for_scan (default ".")
23*/
24 16
25#define LOCAL_INCLUDE_PATH "include" 17#define LOCAL_INCLUDE_PATH "include"
26#define INCLUDE_CONFIG_PATH LOCAL_INCLUDE_PATH"/config" 18#define INCLUDE_CONFIG_PATH LOCAL_INCLUDE_PATH"/config"
27#define INCLUDE_CONFIG_KEYS_PATH LOCAL_INCLUDE_PATH"/config.h" 19#define INCLUDE_CONFIG_KEYS_PATH LOCAL_INCLUDE_PATH"/config.h"
28 20
21#define bb_mkdep_full_options \
22"\nOptions:" \
23"\n\t-I local_include_path include paths, default: \"" LOCAL_INCLUDE_PATH "\"" \
24"\n\t-d don't generate depend" \
25"\n\t-w show warning if include files not found" \
26"\n\t-k include/config default: \"" INCLUDE_CONFIG_PATH "\"" \
27"\n\t-c include/config.h configs, default: \"" INCLUDE_CONFIG_KEYS_PATH "\"" \
28"\n\tdirs_to_scan default \".\""
29
30#define bb_mkdep_terse_options "Usage: [-I local_include_paths] [-dw] " \
31 "[-k path_for_stored_keys] [dirs]"
32
33
34
29#define _GNU_SOURCE 35#define _GNU_SOURCE
30#include <sys/types.h> 36#include <sys/types.h>
31#include <sys/stat.h> 37#include <sys/stat.h>
@@ -40,6 +46,7 @@
40#include <errno.h> 46#include <errno.h>
41#include <fcntl.h> 47#include <fcntl.h>
42 48
49
43typedef struct BB_KEYS { 50typedef struct BB_KEYS {
44 char *keyname; 51 char *keyname;
45 const char *value; 52 const char *value;
@@ -48,13 +55,10 @@ typedef struct BB_KEYS {
48 struct BB_KEYS *next; 55 struct BB_KEYS *next;
49} bb_key_t; 56} bb_key_t;
50 57
51typedef struct FILE_LIST { 58static bb_key_t *check_key(bb_key_t *k, const char *nk);
52 char *name; 59static bb_key_t *make_new_key(bb_key_t *k, const char *nk);
53 char *ext; /* *.c or *.h, point to last char */
54 long size;
55} file_list_t;
56 60
57/* partial and simplify libbb routine */ 61/* partial and simplified libbb routine */
58static void bb_error_d(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))); 62static void bb_error_d(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
59static char * bb_asprint(const char *format, ...) __attribute__ ((format (printf, 1, 2))); 63static char * bb_asprint(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
60 64
@@ -63,28 +67,34 @@ typedef struct llist_s {
63 char *data; 67 char *data;
64 struct llist_s *link; 68 struct llist_s *link;
65} llist_t; 69} llist_t;
66static llist_t *llist_add_to(llist_t *old_head, char *new_item);
67static void *xrealloc(void *p, size_t size); 70static void *xrealloc(void *p, size_t size);
68static void *xmalloc(size_t size); 71static void *xmalloc(size_t size);
69static char *bb_xstrdup(const char *s); 72static char *bb_xstrdup(const char *s);
70static char *bb_simplify_path(const char *path); 73static char *bb_simplify_path(const char *path);
74/* error messages */
75static const char msg_enomem[] = "memory exhausted";
71 76
72/* for lexical analyzier */ 77/* for lexical analyser */
73static bb_key_t *key_top; 78static bb_key_t *key_top;
74static llist_t *configs; 79static llist_t *configs;
75 80
81static int mode;
82#define CONFIG_MODE 0
83#define SOURCES_MODE 1
84
76static void parse_inc(const char *include, const char *fname); 85static void parse_inc(const char *include, const char *fname);
77static void parse_conf_opt(char *opt, const char *val, size_t rsz); 86static void parse_conf_opt(char *opt, const char *val, size_t rsz);
78 87
79/* for speed triks */ 88/* for speed tricks */
80static char first_chars[257]; /* + L_EOF */ 89static char first_chars[257]; /* + L_EOF */
90/* trick for fast find "define", "include", "undef" */
91static char first_chars_diu[256];
81 92
82static int pagesizem1; 93static int pagesizem1;
83static size_t mema_id = 128; /* first allocated for id */ 94static size_t mema_id = 128; /* first allocated for id */
84static char *id_s; 95static char *id_s;
85 96
86static bb_key_t *check_key(bb_key_t *k, const char *nk); 97
87static bb_key_t *make_new_key(bb_key_t *k, const char *nk);
88 98
89#define yy_error_d(s) bb_error_d("%s:%d hmm, %s", fname, line, s) 99#define yy_error_d(s) bb_error_d("%s:%d hmm, %s", fname, line, s)
90 100
@@ -95,9 +105,9 @@ static bb_key_t *make_new_key(bb_key_t *k, const char *nk);
95#define REM '/' /* block comment */ 105#define REM '/' /* block comment */
96#define BS '\\' /* back slash */ 106#define BS '\\' /* back slash */
97#define POUND '#' /* # */ 107#define POUND '#' /* # */
98#define I 'i' /* #include preprocessor`s directive */ 108#define I 'i' /* #include preprocessor's directive */
99#define D 'd' /* #define preprocessor`s directive */ 109#define D 'd' /* #define preprocessor's directive */
100#define U 'u' /* #undef preprocessor`s directive */ 110#define U 'u' /* #undef preprocessor's directive */
101#define LI 'I' /* #include "... */ 111#define LI 'I' /* #include "... */
102#define DK 'K' /* #define KEY... (config mode) */ 112#define DK 'K' /* #define KEY... (config mode) */
103#define DV 'V' /* #define KEY "VALUE or #define KEY 'VALUE */ 113#define DV 'V' /* #define KEY "VALUE or #define KEY 'VALUE */
@@ -117,7 +127,9 @@ static bb_key_t *make_new_key(bb_key_t *k, const char *nk);
117 id = xrealloc(id, local_mema_id += 16); \ 127 id = xrealloc(id, local_mema_id += 16); \
118 id[id_len++] = c; } while(0) 128 id[id_len++] = c; } while(0)
119 129
120/* stupid C lexical analizator */ 130
131
132/* stupid C lexical analyser */
121static void c_lex(const char *fname, long fsize) 133static void c_lex(const char *fname, long fsize)
122{ 134{
123 int c = L_EOF; /* stupid initialize */ 135 int c = L_EOF; /* stupid initialize */
@@ -136,6 +148,10 @@ static void c_lex(const char *fname, long fsize)
136 char *map; 148 char *map;
137 int mapsize; 149 int mapsize;
138 150
151 if(fsize == 0) {
152 fprintf(stderr, "Warning: %s is empty\n", fname);
153 return;
154 }
139 fd = open(fname, O_RDONLY); 155 fd = open(fname, O_RDONLY);
140 if(fd < 0) { 156 if(fd < 0) {
141 perror(fname); 157 perror(fname);
@@ -271,7 +287,7 @@ static void c_lex(const char *fname, long fsize)
271 for(;;) { 287 for(;;) {
272 /* <STR,CHR>\n|<<EOF>> */ 288 /* <STR,CHR>\n|<<EOF>> */
273 if(c == '\n' || c == L_EOF) 289 if(c == '\n' || c == L_EOF)
274 yy_error_d("unterminating"); 290 yy_error_d("unterminated");
275 if(c == BS) { 291 if(c == BS) {
276 /* <STR,CHR>\\ */ 292 /* <STR,CHR>\\ */
277 getc1(); 293 getc1();
@@ -310,7 +326,7 @@ static void c_lex(const char *fname, long fsize)
310 /* <#.*>/ */ 326 /* <#.*>/ */
311 getc1(); 327 getc1();
312 if(c == REM) 328 if(c == REM)
313 yy_error_d("detect // in preprocessor line"); 329 yy_error_d("detected // in preprocessor line");
314 if(c == '*') { 330 if(c == '*') {
315 /* <#.*>[/][*] */ 331 /* <#.*>[/][*] */
316 called = state; 332 called = state;
@@ -321,25 +337,27 @@ static void c_lex(const char *fname, long fsize)
321 yy_error_d("strange preprocessor line"); 337 yy_error_d("strange preprocessor line");
322 } 338 }
323 if(state == POUND) { 339 if(state == POUND) {
324 if(c != 'd' && c != 'u' && c != 'i') { 340 const unsigned char *p = optr - 1;
325 while(ISALNUM(c)) 341 /* tricks */
326 getc1(); 342 static const char * const preproc[] = {
327 state = S; 343 /* 0-4 */
328 } else { 344 "", "", "", "", "",
329 static const char * const preproc[] = { 345 /* 5 */ /* 6 */ /* 7 */
330 "define", "undef", "include", "" 346 "undef", "define", "include",
331 }; 347 };
332 const char * const *str_type; 348 size_t readed = 0;
349 size_t diu = first_chars_diu[c]; /* strlen and preproc ptr */
333 350
334 id_len = 0; 351 while(ISALNUM(c)) {
335 do { put_id(c); getc1(); } while(ISALNUM(c)); 352 readed++;
336 put_id(0); 353 getc1();
337 for(str_type = preproc; (state = **str_type); str_type++) { 354 }
338 if(*id == state && strcmp(id, *str_type) == 0) 355 /* have str begined with c, readed == strlen key and compared */
339 break; 356 if(diu != S && diu == readed && !memcmp(p, preproc[diu], diu)) {
340 } 357 state = *p;
341 /* to S if another #directive */
342 id_len = 0; /* common for save */ 358 id_len = 0; /* common for save */
359 } else {
360 state = S;
343 } 361 }
344 ungetc1(); 362 ungetc1();
345 continue; 363 continue;
@@ -358,7 +376,7 @@ static void c_lex(const char *fname, long fsize)
358 continue; 376 continue;
359 } 377 }
360 if(state == D || state == U) { 378 if(state == D || state == U) {
361 if(configs == NULL) { 379 if(mode == SOURCES_MODE) {
362 /* ignore depend with #define or #undef KEY */ 380 /* ignore depend with #define or #undef KEY */
363 while(ISALNUM(c)) 381 while(ISALNUM(c))
364 getc1(); 382 getc1();
@@ -370,7 +388,7 @@ static void c_lex(const char *fname, long fsize)
370 getc1(); 388 getc1();
371 } 389 }
372 if(!id_len) 390 if(!id_len)
373 yy_error_d("expected identificator"); 391 yy_error_d("expected identifier");
374 put_id(0); 392 put_id(0);
375 if(state == U) { 393 if(state == U) {
376 parse_conf_opt(id, NULL, (optr - start)); 394 parse_conf_opt(id, NULL, (optr - start));
@@ -409,8 +427,7 @@ static void c_lex(const char *fname, long fsize)
409static void show_usage(void) __attribute__ ((noreturn)); 427static void show_usage(void) __attribute__ ((noreturn));
410static void show_usage(void) 428static void show_usage(void)
411{ 429{
412 bb_error_d("Usage: [-I local_include_paths] [-dw] " 430 bb_error_d("%s\n%s\n", bb_mkdep_terse_options, bb_mkdep_full_options);
413 "[-k path_for_store_keys] [-s skip_file] [dirs]");
414} 431}
415 432
416static const char *kp; 433static const char *kp;
@@ -440,18 +457,18 @@ static bb_key_t *make_new_key(bb_key_t *k, const char *nk)
440 nk_size = strlen(nk) + 1; 457 nk_size = strlen(nk) + 1;
441 cur = xmalloc(sizeof(bb_key_t) + nk_size); 458 cur = xmalloc(sizeof(bb_key_t) + nk_size);
442 cur->keyname = memcpy(cur + 1, nk, nk_size); 459 cur->keyname = memcpy(cur + 1, nk, nk_size);
443 cur->checked = 1; 460 cur->checked = 0;
444 cur->next = k; 461 cur->next = k;
445 return cur; 462 return cur;
446} 463}
447 464
448static inline char *store_include_fullpath(char *p_i, bb_key_t *li) 465static inline char *store_include_fullpath(char *p_i, bb_key_t *li)
449{ 466{
450 struct stat st;
451 char *ok; 467 char *ok;
452 468
453 if(stat(p_i, &st) == 0) { 469 if(access(p_i, F_OK) == 0) {
454 ok = li->stored_path = bb_simplify_path(p_i); 470 ok = li->stored_path = bb_simplify_path(p_i);
471 li->checked = 1;
455 } else { 472 } else {
456 ok = NULL; 473 ok = NULL;
457 } 474 }
@@ -486,11 +503,18 @@ static void parse_inc(const char *include, const char *fname)
486 p_i = bb_asprint("%.*s/%s", w, p, include); 503 p_i = bb_asprint("%.*s/%s", w, p, include);
487 if(store_include_fullpath(p_i, li)) 504 if(store_include_fullpath(p_i, li))
488 return; 505 return;
489 } 506 for(lo = Iop; lo; lo = lo->link) {
490 for(lo = Iop; lo; lo = lo->link) { 507 p_i = bb_asprint("%s/%s", lo->data, include);
491 p_i = bb_asprint("%s/%s", lo->data, include); 508 if(store_include_fullpath(p_i, li))
492 if(store_include_fullpath(p_i, li)) 509 return;
510 }
511 } else {
512 /* absolute include pathname */
513 if(access(include, F_OK) == 0) {
514 li->stored_path = bb_xstrdup(include);
515 li->checked = 1;
493 return; 516 return;
517 }
494 } 518 }
495 li->stored_path = NULL; 519 li->stored_path = NULL;
496 if(noiwarning) 520 if(noiwarning)
@@ -500,91 +524,88 @@ static void parse_inc(const char *include, const char *fname)
500static void parse_conf_opt(char *opt, const char *val, size_t recordsz) 524static void parse_conf_opt(char *opt, const char *val, size_t recordsz)
501{ 525{
502 bb_key_t *cur; 526 bb_key_t *cur;
527 char *s, *p;
528 struct stat st;
529 int fd;
530 int cmp_ok = 0;
531 static char *record_buf;
532 static char *r_cmp;
533 static size_t r_sz;
534 ssize_t rw_ret;
503 535
504 cur = check_key(key_top, opt); 536 cur = check_key(key_top, opt);
505 if(cur == NULL) { 537 if(cur != NULL) {
506 /* new key, check old key if present after previous usage */ 538 /* present already */
507 char *s, *p; 539 cur->checked = 0; /* store only */
508 struct stat st; 540 if(cur->value == NULL && val == NULL)
509 int fd; 541 return;
510 int cmp_ok = 0; 542 if(cur->value != NULL && val != NULL && strcmp(cur->value, val) == 0)
511 static char *record_buf; 543 return;
512 static char *r_cmp; 544 fprintf(stderr, "Warning: redefined %s\n", opt);
513 static size_t r_sz; 545 }
514 ssize_t rw_ret; 546 /* new or redefined key, check old key if present after previous usage */
515 547 key_top = cur = make_new_key(key_top, opt);
516 cur = make_new_key(key_top, opt); 548
517 549 recordsz += 2; /* \n\0 */
518 recordsz += 2; /* \n\0 */ 550 if(recordsz > r_sz) {
519 if(recordsz > r_sz) { 551 record_buf = xrealloc(record_buf, r_sz=recordsz);
520 record_buf = xrealloc(record_buf, r_sz=recordsz); 552 r_cmp = xrealloc(r_cmp, recordsz);
521 r_cmp = xrealloc(r_cmp, recordsz); 553 }
522 } 554 s = record_buf;
523 s = record_buf; 555 /* may be short count " " */
524 /* may be short count " " */ 556 if(val) {
525 if(val) { 557 if(*val == '\0') {
526 if(*val == '\0') { 558 cur->value = "";
527 cur->value = ""; 559 recordsz = sprintf(s, "#define %s\n", opt);
528 recordsz = sprintf(s, "#define %s\n", opt);
529 } else {
530 cur->value = bb_xstrdup(val);
531 recordsz = sprintf(s, "#define %s %s\n", opt, val);
532 }
533 } else { 560 } else {
534 cur->value = NULL; 561 cur->value = bb_xstrdup(val);
535 recordsz = sprintf(s, "#undef %s\n", opt); 562 recordsz = sprintf(s, "#define %s %s\n", opt, val);
536 }
537 /* size_t -> ssize_t :( */
538 rw_ret = (ssize_t)recordsz;
539 /* trick, save first char KEY for do fast identify id */
540 first_chars[(int)*opt] = *opt;
541
542 /* key converting [A-Z_] -> [a-z/] */
543 for(p = opt; *p; p++) {
544 if(*p >= 'A' && *p <= 'Z')
545 *p = *p - 'A' + 'a';
546 else if(*p == '_')
547 *p = '/';
548 } 563 }
549 p = bb_asprint("%s/%s.h", kp, opt); 564 } else {
550 cur->stored_path = opt = p; 565 cur->value = NULL;
551 if(stat(opt, &st)) { 566 recordsz = sprintf(s, "#undef %s\n", opt);
552 p += kp_len; 567 }
553 while(*++p) { 568 /* size_t -> ssize_t :( */
554 /* Auto-create directories. */ 569 rw_ret = (ssize_t)recordsz;
555 if (*p == '/') { 570 /* trick, save first char KEY for do fast identify id */
556 *p = '\0'; 571 first_chars[(int)*opt] = *opt;
557 if (stat(opt, &st) != 0 && mkdir(opt, 0755) != 0) 572
558 bb_error_d("mkdir(%s): %m", opt); 573 /* key converting [A-Z_] -> [a-z/] */
559 *p = '/'; 574 for(p = opt; *p; p++) {
560 } 575 if(*p >= 'A' && *p <= 'Z')
576 *p = *p - 'A' + 'a';
577 else if(*p == '_')
578 *p = '/';
579 }
580 p = bb_asprint("%s/%s.h", kp, opt);
581 cur->stored_path = opt = p;
582 if(stat(opt, &st)) {
583 p += kp_len;
584 while(*++p) {
585 /* Auto-create directories. */
586 if (*p == '/') {
587 *p = '\0';
588 if (access(opt, F_OK) != 0 && mkdir(opt, 0755) != 0)
589 bb_error_d("mkdir(%s): %m", opt);
590 *p = '/';
561 } 591 }
562 } else {
563 /* found */
564 if(st.st_size == (off_t)recordsz) {
565 fd = open(opt, O_RDONLY);
566 if(fd < 0 || read(fd, r_cmp, recordsz) < rw_ret)
567 bb_error_d("%s: %m", opt);
568 close(fd);
569 cmp_ok = memcmp(s, r_cmp, recordsz) == 0;
570 }
571 }
572 if(!cmp_ok) {
573 fd = open(opt, O_WRONLY|O_CREAT|O_TRUNC, 0644);
574 if(fd < 0 || write(fd, s, recordsz) < rw_ret)
575 bb_error_d("%s: %m", opt);
576 close(fd);
577 } 592 }
578 key_top = cur;
579 } else { 593 } else {
580 /* present already */ 594 /* found */
581 if((cur->value == NULL && val != NULL) || 595 if(st.st_size == (off_t)recordsz) {
582 (cur->value != NULL && val == NULL) || 596 fd = open(opt, O_RDONLY);
583 (cur->value != NULL && val != NULL && strcmp(cur->value, val))) 597 if(fd < 0 || read(fd, r_cmp, recordsz) < rw_ret)
584 fprintf(stderr, "Warning: redefined %s\n", opt); 598 bb_error_d("%s: %m", opt);
599 close(fd);
600 cmp_ok = memcmp(s, r_cmp, recordsz) == 0;
601 }
602 }
603 if(!cmp_ok) {
604 fd = open(opt, O_WRONLY|O_CREAT|O_TRUNC, 0644);
605 if(fd < 0 || write(fd, s, recordsz) < rw_ret)
606 bb_error_d("%s: %m", opt);
607 close(fd);
585 } 608 }
586 /* store only */
587 cur->checked = 0;
588} 609}
589 610
590static int show_dep(int first, bb_key_t *k, const char *name) 611static int show_dep(int first, bb_key_t *k, const char *name)
@@ -606,20 +627,16 @@ static int show_dep(int first, bb_key_t *k, const char *name)
606 return first; 627 return first;
607} 628}
608 629
609static llist_t *files;
610static struct stat st_kp; 630static struct stat st_kp;
611 631static int dontgenerate_dep;
612static char *dir_and_entry;
613 632
614static char * 633static char *
615filter_chd(const char *fe, const char *p, size_t dirlen) 634parse_chd(const char *fe, const char *p, size_t dirlen)
616{ 635{
617 struct stat st; 636 struct stat st;
618 char *fp; 637 char *fp;
619 char *afp;
620 llist_t *cfl;
621 file_list_t *f;
622 size_t df_sz; 638 size_t df_sz;
639 static char *dir_and_entry;
623 static size_t dir_and_entry_sz; 640 static size_t dir_and_entry_sz;
624 641
625 if (*fe == '.') 642 if (*fe == '.')
@@ -636,49 +653,63 @@ filter_chd(const char *fe, const char *p, size_t dirlen)
636 return NULL; 653 return NULL;
637 } 654 }
638 if(S_ISREG(st.st_mode)) { 655 if(S_ISREG(st.st_mode)) {
639 afp = fp + df_sz - 3; 656 llist_t *cfl;
640 if(*afp++ != '.' || (*afp != 'c' && *afp != 'h')) { 657 char *e = fp + df_sz - 3;
658
659 if(*e++ != '.' || (*e != 'c' && *e != 'h')) {
641 /* direntry is regular file, but is not *.[ch] */ 660 /* direntry is regular file, but is not *.[ch] */
642 return NULL; 661 return NULL;
643 } 662 }
644 if (st.st_size == 0) { 663 for(cfl = configs; cfl; cfl = cfl->link) {
645 fprintf(stderr, "Warning: %s is empty\n", fp); 664 struct stat *config = (struct stat *)cfl->data;
646 return NULL; 665
647 } 666 if (st.st_dev == config->st_dev && st.st_ino == config->st_ino) {
648 } else { 667 /* skip already parsed configs.h */
649 if(S_ISDIR(st.st_mode)) {
650 if (st.st_dev == st_kp.st_dev && st.st_ino == st_kp.st_ino) {
651 /* drop scan kp/ directory */
652 return NULL; 668 return NULL;
653 } 669 }
654 /* buff is returned, begin of zero allocate */
655 dir_and_entry = NULL;
656 dir_and_entry_sz = 0;
657 return fp;
658 } 670 }
659 /* hmm, is device! */ 671 /* direntry is *.[ch] regular file and is not configs */
660 return NULL; 672 if(!dontgenerate_dep) {
661 } 673 int first;
662 afp = bb_simplify_path(fp); 674
663 for(cfl = configs; cfl; cfl = cfl->link) { 675 c_lex(fp, st.st_size);
664 if(cfl->data && strcmp(cfl->data, afp) == 0) { 676 fp = bb_simplify_path(fp);
665 /* parse configs.h */ 677 if(*e == 'c') {
666 free(afp); 678 /* *.c -> *.o */
667 c_lex(fp, st.st_size); 679 e = strrchr(fp, '.') + 1;
668 free(cfl->data); 680 *e = 'o';
669 cfl->data = NULL; 681 }
670 return NULL; 682 first = show_dep(1, Ifound, fp);
683 first = show_dep(first, key_top, fp);
684 if(first == 0)
685 putchar('\n');
686 free(fp);
671 } 687 }
688 return NULL;
689 } else if(S_ISDIR(st.st_mode)) {
690 if (st.st_dev == st_kp.st_dev && st.st_ino == st_kp.st_ino)
691 return NULL; /* drop scan kp/ directory */
692 /* direntry is directory. buff is returned, begin of zero allocate */
693 dir_and_entry = NULL;
694 dir_and_entry_sz = 0;
695 return fp;
672 } 696 }
673 /* direntry is *.[ch] regular file */ 697 /* hmm, direntry is device! */
674 f = xmalloc(sizeof(file_list_t));
675 f->name = afp;
676 f->ext = strrchr(afp, '.') + 1;
677 f->size = st.st_size;
678 files = llist_add_to(files, (char *)f);
679 return NULL; 698 return NULL;
680} 699}
681 700
701/* from libbb but inline for fast */
702static inline llist_t *llist_add_to(llist_t *old_head, char *new_item)
703{
704 llist_t *new_head;
705
706 new_head = xmalloc(sizeof(llist_t));
707 new_head->data = new_item;
708 new_head->link = old_head;
709
710 return(new_head);
711}
712
682static void scan_dir_find_ch_files(char *p) 713static void scan_dir_find_ch_files(char *p)
683{ 714{
684 llist_t *dirs; 715 llist_t *dirs;
@@ -698,7 +729,7 @@ static void scan_dir_find_ch_files(char *p)
698 fprintf(stderr, "Warning: opendir(%s): %m", dirs->data); 729 fprintf(stderr, "Warning: opendir(%s): %m", dirs->data);
699 dirlen = strlen(dirs->data); 730 dirlen = strlen(dirs->data);
700 while ((de = readdir(dir)) != NULL) { 731 while ((de = readdir(dir)) != NULL) {
701 char *found_dir = filter_chd(de->d_name, dirs->data, dirlen); 732 char *found_dir = parse_chd(de->d_name, dirs->data, dirlen);
702 733
703 if(found_dir) 734 if(found_dir)
704 d_add = llist_add_to(d_add, found_dir); 735 d_add = llist_add_to(d_add, found_dir);
@@ -718,7 +749,6 @@ static char *pwd;
718 749
719int main(int argc, char **argv) 750int main(int argc, char **argv)
720{ 751{
721 int generate_dep = 1;
722 char *s; 752 char *s;
723 int i; 753 int i;
724 llist_t *fl; 754 llist_t *fl;
@@ -733,8 +763,7 @@ int main(int argc, char **argv)
733 while (getcwd (s, path_max) == NULL) { 763 while (getcwd (s, path_max) == NULL) {
734 if(errno != ERANGE) 764 if(errno != ERANGE)
735 bb_error_d("getcwd: %m"); 765 bb_error_d("getcwd: %m");
736 path_max += PATH_INCR; 766 s = xrealloc (s, path_max += PATH_INCR);
737 s = xrealloc (s, path_max);
738 } 767 }
739 pwd = s; 768 pwd = s;
740 } 769 }
@@ -749,7 +778,7 @@ int main(int argc, char **argv)
749 configs = llist_add_to(configs, s); 778 configs = llist_add_to(configs, s);
750 break; 779 break;
751 case 'd': 780 case 'd':
752 generate_dep = 0; 781 dontgenerate_dep = 1;
753 break; 782 break;
754 case 'k': 783 case 'k':
755 if(kp) 784 if(kp)
@@ -763,16 +792,22 @@ int main(int argc, char **argv)
763 show_usage(); 792 show_usage();
764 } 793 }
765 } 794 }
766 /* defaults */ 795 /* default kp */
767 if(kp == NULL) 796 if(kp == NULL)
768 kp = bb_simplify_path(INCLUDE_CONFIG_PATH); 797 kp = bb_simplify_path(INCLUDE_CONFIG_PATH);
798 /* globals initialize */
799 kp_len = strlen(kp);
800 if(stat(kp, &st_kp))
801 bb_error_d("stat(%s): %m", kp);
802 if(!S_ISDIR(st_kp.st_mode))
803 bb_error_d("%s is not directory", kp);
804 /* defaults */
769 if(Iop == NULL) 805 if(Iop == NULL)
770 Iop = llist_add_to(Iop, LOCAL_INCLUDE_PATH); 806 Iop = llist_add_to(Iop, LOCAL_INCLUDE_PATH);
771 if(configs == NULL) { 807 if(configs == NULL) {
772 s = bb_simplify_path(INCLUDE_CONFIG_KEYS_PATH); 808 s = bb_simplify_path(INCLUDE_CONFIG_KEYS_PATH);
773 configs = llist_add_to(configs, s); 809 configs = llist_add_to(configs, s);
774 } 810 }
775 /* globals initialize */
776 /* for c_lex */ 811 /* for c_lex */
777 pagesizem1 = getpagesize() - 1; 812 pagesizem1 = getpagesize() - 1;
778 id_s = xmalloc(mema_id); 813 id_s = xmalloc(mema_id);
@@ -783,14 +818,25 @@ int main(int argc, char **argv)
783 first_chars[i] = ANY; 818 first_chars[i] = ANY;
784 } 819 }
785 first_chars[i] = '-'; /* L_EOF */ 820 first_chars[i] = '-'; /* L_EOF */
821 /* trick for fast find "define", "include", "undef" */
822 first_chars_diu[(int)'d'] = (char)6; /* strlen("define"); */
823 first_chars_diu[(int)'i'] = (char)7; /* strlen("include"); */
824 first_chars_diu[(int)'u'] = (char)5; /* strlen("undef"); */
786 825
787 kp_len = strlen(kp); 826 /* parse configs */
788 if(stat(kp, &st_kp)) 827 for(fl = configs; fl; fl = fl->link) {
789 bb_error_d("stat(%s): %m", kp); 828 struct stat st;
790 if(!S_ISDIR(st_kp.st_mode)) 829
791 bb_error_d("%s is not directory", kp); 830 if(stat(fl->data, &st))
831 bb_error_d("stat(%s): %m", fl->data);
832 c_lex(fl->data, st.st_size);
833 /* trick for fast comparing found files with configs */
834 fl->data = xrealloc(fl->data, sizeof(struct stat));
835 memcpy(fl->data, &st, sizeof(struct stat));
836 }
792 837
793 /* main loops */ 838 /* main loop */
839 mode = SOURCES_MODE;
794 argv += optind; 840 argv += optind;
795 if(*argv) { 841 if(*argv) {
796 while(*argv) 842 while(*argv)
@@ -798,39 +844,10 @@ int main(int argc, char **argv)
798 } else { 844 } else {
799 scan_dir_find_ch_files("."); 845 scan_dir_find_ch_files(".");
800 } 846 }
801
802 for(fl = configs; fl; fl = fl->link) {
803 if(fl->data) {
804 /* configs.h placed outsize of scanned dirs or not "*.ch" */
805 struct stat st;
806
807 if(stat(fl->data, &st))
808 bb_error_d("stat(%s): %m", fl->data);
809 c_lex(fl->data, st.st_size);
810 free(fl->data);
811 }
812 }
813 free(configs);
814 configs = NULL; /* flag read config --> parse sourses mode */
815
816 for(fl = files; fl; fl = fl->link) {
817 file_list_t *t = (file_list_t *)(fl->data);
818 c_lex(t->name, t->size);
819 if(generate_dep) {
820 if(t->ext[0] == 'c') {
821 /* *.c -> *.o */
822 t->ext[0] = 'o';
823 }
824 i = show_dep(1, Ifound, t->name);
825 i = show_dep(i, key_top, t->name);
826 if(i == 0)
827 putchar('\n');
828 }
829 }
830 return 0; 847 return 0;
831} 848}
832 849
833/* partial and simplify libbb routine */ 850/* partial and simplified libbb routine */
834static void bb_error_d(const char *s, ...) 851static void bb_error_d(const char *s, ...)
835{ 852{
836 va_list p; 853 va_list p;
@@ -842,23 +859,6 @@ static void bb_error_d(const char *s, ...)
842 exit(1); 859 exit(1);
843} 860}
844 861
845
846static void *xmalloc(size_t size)
847{
848 void *p = malloc(size);
849
850 if(p == NULL)
851 bb_error_d("memory exhausted");
852 return p;
853}
854
855static void *xrealloc(void *p, size_t size) {
856 p = realloc(p, size);
857 if(p == NULL)
858 bb_error_d("memory exhausted");
859 return p;
860}
861
862static char *bb_asprint(const char *format, ...) 862static char *bb_asprint(const char *format, ...)
863{ 863{
864 va_list p; 864 va_list p;
@@ -874,15 +874,21 @@ static char *bb_asprint(const char *format, ...)
874 return out; 874 return out;
875} 875}
876 876
877static llist_t *llist_add_to(llist_t *old_head, char *new_item) 877/* partial libbb routine as is */
878static void *xmalloc(size_t size)
878{ 879{
879 llist_t *new_head; 880 void *p = malloc(size);
880 881
881 new_head = xmalloc(sizeof(llist_t)); 882 if(p == NULL)
882 new_head->data = new_item; 883 bb_error_d(msg_enomem);
883 new_head->link = old_head; 884 return p;
885}
884 886
885 return(new_head); 887static void *xrealloc(void *p, size_t size) {
888 p = realloc(p, size);
889 if(p == NULL)
890 bb_error_d(msg_enomem);
891 return p;
886} 892}
887 893
888static char *bb_xstrdup(const char *s) 894static char *bb_xstrdup(const char *s)
@@ -890,7 +896,7 @@ static char *bb_xstrdup(const char *s)
890 char *r = strdup(s); 896 char *r = strdup(s);
891 897
892 if(r == NULL) 898 if(r == NULL)
893 bb_error_d("memory exhausted"); 899 bb_error_d(msg_enomem);
894 return r; 900 return r;
895} 901}
896 902