diff options
| author | "Vladimir N. Oleynik" <dzo@simtreas.ru> | 2005-09-14 15:09:06 +0000 |
|---|---|---|
| committer | "Vladimir N. Oleynik" <dzo@simtreas.ru> | 2005-09-14 15:09:06 +0000 |
| commit | 7573ac6edf19ed2ea39fcd420b80ee05e8796e1c (patch) | |
| tree | 7ab30763ab663235b114a7288627cb78adc7f705 /scripts | |
| parent | 2ee82723a8a90d7aefa445e288b1f3427d75301d (diff) | |
| download | busybox-w32-7573ac6edf19ed2ea39fcd420b80ee05e8796e1c.tar.gz busybox-w32-7573ac6edf19ed2ea39fcd420b80ee05e8796e1c.tar.bz2 busybox-w32-7573ac6edf19ed2ea39fcd420b80ee05e8796e1c.zip | |
bb_mkdep version 2.0. speed up *2, remove problem of find e2fsprogs/uu*.h, spelling corrections by Bernhard Fischer
Diffstat (limited to 'scripts')
| -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 | ||
