diff options
author | vodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2005-09-14 15:09:06 +0000 |
---|---|---|
committer | vodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2005-09-14 15:09:06 +0000 |
commit | 94dfc57fdb01d9a85deb1283efbcb8ea5d2f60ff (patch) | |
tree | 7ab30763ab663235b114a7288627cb78adc7f705 | |
parent | 5dfcee2295cc09c2cc29bb882a5ed37cb59ff669 (diff) | |
download | busybox-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.c | 490 |
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 | |||
43 | typedef struct BB_KEYS { | 50 | typedef 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 | ||
51 | typedef struct FILE_LIST { | 58 | static bb_key_t *check_key(bb_key_t *k, const char *nk); |
52 | char *name; | 59 | static 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 */ |
58 | static void bb_error_d(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))); | 62 | static void bb_error_d(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))); |
59 | static char * bb_asprint(const char *format, ...) __attribute__ ((format (printf, 1, 2))); | 63 | static 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; |
66 | static llist_t *llist_add_to(llist_t *old_head, char *new_item); | ||
67 | static void *xrealloc(void *p, size_t size); | 70 | static void *xrealloc(void *p, size_t size); |
68 | static void *xmalloc(size_t size); | 71 | static void *xmalloc(size_t size); |
69 | static char *bb_xstrdup(const char *s); | 72 | static char *bb_xstrdup(const char *s); |
70 | static char *bb_simplify_path(const char *path); | 73 | static char *bb_simplify_path(const char *path); |
74 | /* error messages */ | ||
75 | static const char msg_enomem[] = "memory exhausted"; | ||
71 | 76 | ||
72 | /* for lexical analyzier */ | 77 | /* for lexical analyser */ |
73 | static bb_key_t *key_top; | 78 | static bb_key_t *key_top; |
74 | static llist_t *configs; | 79 | static llist_t *configs; |
75 | 80 | ||
81 | static int mode; | ||
82 | #define CONFIG_MODE 0 | ||
83 | #define SOURCES_MODE 1 | ||
84 | |||
76 | static void parse_inc(const char *include, const char *fname); | 85 | static void parse_inc(const char *include, const char *fname); |
77 | static void parse_conf_opt(char *opt, const char *val, size_t rsz); | 86 | static void parse_conf_opt(char *opt, const char *val, size_t rsz); |
78 | 87 | ||
79 | /* for speed triks */ | 88 | /* for speed tricks */ |
80 | static char first_chars[257]; /* + L_EOF */ | 89 | static char first_chars[257]; /* + L_EOF */ |
90 | /* trick for fast find "define", "include", "undef" */ | ||
91 | static char first_chars_diu[256]; | ||
81 | 92 | ||
82 | static int pagesizem1; | 93 | static int pagesizem1; |
83 | static size_t mema_id = 128; /* first allocated for id */ | 94 | static size_t mema_id = 128; /* first allocated for id */ |
84 | static char *id_s; | 95 | static char *id_s; |
85 | 96 | ||
86 | static bb_key_t *check_key(bb_key_t *k, const char *nk); | 97 | |
87 | static 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 */ | ||
121 | static void c_lex(const char *fname, long fsize) | 133 | static 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) | |||
409 | static void show_usage(void) __attribute__ ((noreturn)); | 427 | static void show_usage(void) __attribute__ ((noreturn)); |
410 | static void show_usage(void) | 428 | static 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 | ||
416 | static const char *kp; | 433 | static 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 | ||
448 | static inline char *store_include_fullpath(char *p_i, bb_key_t *li) | 465 | static 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) | |||
500 | static void parse_conf_opt(char *opt, const char *val, size_t recordsz) | 524 | static 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 | ||
590 | static int show_dep(int first, bb_key_t *k, const char *name) | 611 | static 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 | ||
609 | static llist_t *files; | ||
610 | static struct stat st_kp; | 630 | static struct stat st_kp; |
611 | 631 | static int dontgenerate_dep; | |
612 | static char *dir_and_entry; | ||
613 | 632 | ||
614 | static char * | 633 | static char * |
615 | filter_chd(const char *fe, const char *p, size_t dirlen) | 634 | parse_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 */ | ||
702 | static 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 | |||
682 | static void scan_dir_find_ch_files(char *p) | 713 | static 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 | ||
719 | int main(int argc, char **argv) | 750 | int 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 */ |
834 | static void bb_error_d(const char *s, ...) | 851 | static 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 | |||
846 | static 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 | |||
855 | static 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 | |||
862 | static char *bb_asprint(const char *format, ...) | 862 | static 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 | ||
877 | static llist_t *llist_add_to(llist_t *old_head, char *new_item) | 877 | /* partial libbb routine as is */ |
878 | static 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); | 887 | static 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 | ||
888 | static char *bb_xstrdup(const char *s) | 894 | static 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 | ||