diff options
| author | "Vladimir N. Oleynik" <dzo@simtreas.ru> | 2005-09-12 16:39:47 +0000 |
|---|---|---|
| committer | "Vladimir N. Oleynik" <dzo@simtreas.ru> | 2005-09-12 16:39:47 +0000 |
| commit | b1fe4621169b2a7f2eea966932703596583a37b6 (patch) | |
| tree | dd1c74abee945c95121fa2fd8eaff15b73048dee /scripts | |
| parent | 5e60dc4a209b053e8fe5170bd143173941c4634c (diff) | |
| download | busybox-w32-b1fe4621169b2a7f2eea966932703596583a37b6.tar.gz busybox-w32-b1fe4621169b2a7f2eea966932703596583a37b6.tar.bz2 busybox-w32-b1fe4621169b2a7f2eea966932703596583a37b6.zip | |
bb_mkdep speed up * 10!
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/bb_mkdep.c | 194 |
1 files changed, 112 insertions, 82 deletions
diff --git a/scripts/bb_mkdep.c b/scripts/bb_mkdep.c index 408397332..68b3f5bce 100644 --- a/scripts/bb_mkdep.c +++ b/scripts/bb_mkdep.c | |||
| @@ -50,19 +50,19 @@ typedef struct BB_KEYS { | |||
| 50 | 50 | ||
| 51 | /* partial and simplify libbb routine */ | 51 | /* partial and simplify libbb routine */ |
| 52 | 52 | ||
| 53 | void bb_error_d(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))); | 53 | static void bb_error_d(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))); |
| 54 | char * bb_asprint(const char *format, ...) __attribute__ ((format (printf, 1, 2))); | 54 | static char * bb_asprint(const char *format, ...) __attribute__ ((format (printf, 1, 2))); |
| 55 | 55 | ||
| 56 | /* stolen from libbb as is */ | 56 | /* stolen from libbb as is */ |
| 57 | typedef struct llist_s { | 57 | typedef struct llist_s { |
| 58 | char *data; | 58 | char *data; |
| 59 | struct llist_s *link; | 59 | struct llist_s *link; |
| 60 | } llist_t; | 60 | } llist_t; |
| 61 | llist_t *llist_add_to(llist_t *old_head, char *new_item); | 61 | static llist_t *llist_add_to(llist_t *old_head, char *new_item); |
| 62 | void *xrealloc(void *p, size_t size); | 62 | static void *xrealloc(void *p, size_t size); |
| 63 | void *xmalloc(size_t size); | 63 | static void *xmalloc(size_t size); |
| 64 | char *bb_xstrdup(const char *s); | 64 | static char *bb_xstrdup(const char *s); |
| 65 | char *bb_simplify_path(const char *path); | 65 | static char *bb_simplify_path(const char *path); |
| 66 | 66 | ||
| 67 | /* for lexical analyzier */ | 67 | /* for lexical analyzier */ |
| 68 | static bb_key_t *key_top; | 68 | static bb_key_t *key_top; |
| @@ -70,6 +70,8 @@ static bb_key_t *key_top; | |||
| 70 | static void parse_inc(const char *include, const char *fname); | 70 | static void parse_inc(const char *include, const char *fname); |
| 71 | static void parse_conf_opt(char *opt, const char *val, size_t rsz); | 71 | static void parse_conf_opt(char *opt, const char *val, size_t rsz); |
| 72 | 72 | ||
| 73 | static char first_char_conf_opts[256]; /* for speed */ | ||
| 74 | |||
| 73 | #define CHECK_ONLY 0 | 75 | #define CHECK_ONLY 0 |
| 74 | #define MAKE_NEW 1 | 76 | #define MAKE_NEW 1 |
| 75 | static bb_key_t *find_already(bb_key_t *k, const char *nk, int flg_save_new); | 77 | static bb_key_t *find_already(bb_key_t *k, const char *nk, int flg_save_new); |
| @@ -112,7 +114,8 @@ static void c_lex(const char *fname, int flg_config_include) | |||
| 112 | int state; | 114 | int state; |
| 113 | int line; | 115 | int line; |
| 114 | static size_t mema_id; | 116 | static size_t mema_id; |
| 115 | char *id = xmalloc(mema_id=128); /* fist allocate */ | 117 | static char *id_s; |
| 118 | char *id; | ||
| 116 | size_t id_len = 0; /* stupid initialize */ | 119 | size_t id_len = 0; /* stupid initialize */ |
| 117 | char *val = NULL; | 120 | char *val = NULL; |
| 118 | unsigned char *optr, *oend; | 121 | unsigned char *optr, *oend; |
| @@ -145,6 +148,11 @@ static void c_lex(const char *fname, int flg_config_include) | |||
| 145 | oend = optr + st.st_size; | 148 | oend = optr + st.st_size; |
| 146 | } | 149 | } |
| 147 | 150 | ||
| 151 | if(id_s == NULL) { | ||
| 152 | /* fist allocate */ | ||
| 153 | id_s = xmalloc(mema_id=128); | ||
| 154 | } | ||
| 155 | id = id_s; | ||
| 148 | line = 1; | 156 | line = 1; |
| 149 | called = state = S; | 157 | called = state = S; |
| 150 | 158 | ||
| @@ -220,14 +228,22 @@ static void c_lex(const char *fname, int flg_config_include) | |||
| 220 | state = c; | 228 | state = c; |
| 221 | } else if(ISALNUM(c)) { | 229 | } else if(ISALNUM(c)) { |
| 222 | /* <S>[A-Z_a-z0-9] */ | 230 | /* <S>[A-Z_a-z0-9] */ |
| 223 | id_len = 0; | 231 | |
| 224 | do { | 232 | /* trick for fast drop id |
| 233 | if key with this first char undefined */ | ||
| 234 | if(first_char_conf_opts[c] == 0) { | ||
| 235 | /* skip <S>[A-Z_a-z0-9]+ */ | ||
| 236 | do getc1(); while(ISALNUM(c)); | ||
| 237 | } else { | ||
| 238 | id_len = 0; | ||
| 239 | do { | ||
| 225 | /* <S>[A-Z_a-z0-9]+ */ | 240 | /* <S>[A-Z_a-z0-9]+ */ |
| 226 | put_id(c); | 241 | put_id(c); |
| 227 | getc1(); | 242 | getc1(); |
| 228 | } while(ISALNUM(c)); | 243 | } while(ISALNUM(c)); |
| 229 | put_id(0); | 244 | put_id(0); |
| 230 | find_already(key_top, id, CHECK_ONLY); | 245 | find_already(key_top, id, CHECK_ONLY); |
| 246 | } | ||
| 231 | } else { | 247 | } else { |
| 232 | /* <S>. */ | 248 | /* <S>. */ |
| 233 | prev_state = ANY; | 249 | prev_state = ANY; |
| @@ -492,31 +508,32 @@ static void parse_conf_opt(char *opt, const char *val, size_t recordsz) | |||
| 492 | r_cmp = xrealloc(r_cmp, recordsz); | 508 | r_cmp = xrealloc(r_cmp, recordsz); |
| 493 | } | 509 | } |
| 494 | s = record_buf; | 510 | s = record_buf; |
| 511 | /* may be short count " " */ | ||
| 495 | if(val) | 512 | if(val) |
| 496 | sprintf(s, "#define %s%s%s\n", opt, (*val ? " " : ""), val); | 513 | recordsz = sprintf(s, "#define %s%s%s\n", opt, (*val ? " " : ""), val); |
| 497 | else | 514 | else |
| 498 | sprintf(s, "#undef %s\n", opt); | 515 | recordsz = sprintf(s, "#undef %s\n", opt); |
| 499 | /* may be short count " " */ | 516 | first_char_conf_opts[((int)((unsigned char)(*opt)))] = *opt; |
| 500 | recordsz = strlen(s); | ||
| 501 | /* key converting [A-Z] -> [a-z] */ | 517 | /* key converting [A-Z] -> [a-z] */ |
| 502 | for(p = opt; *p; p++) { | 518 | for(p = opt; *p; p++) { |
| 503 | if(*p >= 'A' && *p <= 'Z') | 519 | if(*p >= 'A' && *p <= 'Z') |
| 504 | *p = *p - 'A' + 'a'; | 520 | *p = *p - 'A' + 'a'; |
| 505 | if(*p == '_') | 521 | else if(*p == '_') |
| 506 | *p = '/'; | 522 | *p = '/'; |
| 507 | } | 523 | } |
| 508 | p = bb_asprint("%s/%s.h", kp, opt); | 524 | p = bb_asprint("%s/%s.h", kp, opt); |
| 509 | cur->stored_path = opt = p; | 525 | cur->stored_path = opt = p; |
| 510 | while(*++p) { | 526 | if(stat(opt, &st)) { |
| 511 | /* Auto-create directories. */ | 527 | while(*++p) { |
| 512 | if (*p == '/') { | 528 | /* Auto-create directories. */ |
| 513 | *p = '\0'; | 529 | if (*p == '/') { |
| 514 | if (stat(opt, &st) != 0 && mkdir(opt, 0755) != 0) | 530 | *p = '\0'; |
| 515 | bb_error_d("mkdir(%s): %m", opt); | 531 | if (stat(opt, &st) != 0 && mkdir(opt, 0755) != 0) |
| 516 | *p = '/'; | 532 | bb_error_d("mkdir(%s): %m", opt); |
| 533 | *p = '/'; | ||
| 534 | } | ||
| 517 | } | 535 | } |
| 518 | } | 536 | } else { |
| 519 | if(stat(opt, &st) == 0) { | ||
| 520 | /* found */ | 537 | /* found */ |
| 521 | if(st.st_size == recordsz) { | 538 | if(st.st_size == recordsz) { |
| 522 | fd = open(opt, O_RDONLY); | 539 | fd = open(opt, O_RDONLY); |
| @@ -594,11 +611,11 @@ static llist_t *files; | |||
| 594 | 611 | ||
| 595 | static llist_t *filter_chd(const char *fe, const char *p, llist_t *pdirs) | 612 | static llist_t *filter_chd(const char *fe, const char *p, llist_t *pdirs) |
| 596 | { | 613 | { |
| 597 | const char *e; | ||
| 598 | struct stat st; | 614 | struct stat st; |
| 599 | char *fp; | 615 | char *fp; |
| 600 | char *afp; | 616 | char *afp; |
| 601 | llist_t *cfl; | 617 | llist_t *cfl; |
| 618 | static struct stat st_kp; | ||
| 602 | 619 | ||
| 603 | if (*fe == '.') | 620 | if (*fe == '.') |
| 604 | return NULL; | 621 | return NULL; |
| @@ -608,40 +625,45 @@ static llist_t *filter_chd(const char *fe, const char *p, llist_t *pdirs) | |||
| 608 | free(fp); | 625 | free(fp); |
| 609 | return NULL; | 626 | return NULL; |
| 610 | } | 627 | } |
| 611 | afp = bb_simplify_path(fp); | 628 | if(S_ISREG(st.st_mode)) { |
| 612 | if(S_ISDIR(st.st_mode)) { | 629 | const char *e = strrchr(fe, '.'); |
| 613 | if(strcmp(kp, afp) == 0) { | 630 | |
| 614 | /* is autogenerated to kp/key* by previous usage */ | 631 | if(e == NULL || !((e[1]=='c' || e[1]=='h') && e[2]=='\0')) { |
| 615 | free(afp); | 632 | /* direntry is regular file, but is not *.[ch] */ |
| 616 | free(fp); | 633 | free(fp); |
| 617 | /* drop scan kp/ directory */ | ||
| 618 | return NULL; | 634 | return NULL; |
| 619 | } | 635 | } |
| 620 | free(afp); | 636 | } else { |
| 621 | return llist_add_to(pdirs, fp); | 637 | if(st_kp.st_ino == 0) { |
| 622 | } | 638 | /* first call */ |
| 623 | if(!S_ISREG(st.st_mode)) { | 639 | if(stat(kp, &st_kp)) |
| 640 | bb_error_d("stat(%s): %m", kp); | ||
| 641 | if(!S_ISDIR(st_kp.st_mode)) | ||
| 642 | bb_error_d("%s is not directory", kp); | ||
| 643 | } | ||
| 644 | if(S_ISDIR(st.st_mode)) { | ||
| 645 | if (st.st_dev == st_kp.st_dev && st.st_ino == st_kp.st_ino) { | ||
| 646 | /* is autogenerated to kp/key* by previous usage */ | ||
| 647 | free(fp); | ||
| 648 | /* drop scan kp/ directory */ | ||
| 649 | return NULL; | ||
| 650 | } | ||
| 651 | return llist_add_to(pdirs, fp); | ||
| 652 | } | ||
| 624 | /* hmm, is device! */ | 653 | /* hmm, is device! */ |
| 625 | free(afp); | ||
| 626 | free(fp); | ||
| 627 | return NULL; | ||
| 628 | } | ||
| 629 | e = strrchr(fe, '.'); | ||
| 630 | if(e == NULL || !((e[1]=='c' || e[1]=='h') && e[2]=='\0')) { | ||
| 631 | /* direntry is not directory or *.[ch] */ | ||
| 632 | free(afp); | ||
| 633 | free(fp); | 654 | free(fp); |
| 634 | return NULL; | 655 | return NULL; |
| 635 | } | 656 | } |
| 657 | afp = bb_simplify_path(fp); | ||
| 636 | for(cfl = configs; cfl; cfl = cfl->link) { | 658 | for(cfl = configs; cfl; cfl = cfl->link) { |
| 637 | if(cfl->data && strcmp(cfl->data, afp) == 0) { | 659 | if(cfl->data && strcmp(cfl->data, afp) == 0) { |
| 638 | /* parse configs.h */ | 660 | /* parse configs.h */ |
| 639 | free(afp); | 661 | free(afp); |
| 640 | c_lex(fp, 1); | 662 | c_lex(fp, 1); |
| 641 | free(fp); | 663 | free(fp); |
| 642 | free(cfl->data); | 664 | free(cfl->data); |
| 643 | cfl->data = NULL; | 665 | cfl->data = NULL; |
| 644 | return NULL; | 666 | return NULL; |
| 645 | } | 667 | } |
| 646 | } | 668 | } |
| 647 | free(fp); | 669 | free(fp); |
| @@ -680,6 +702,13 @@ static void scan_dir_find_ch_files(char *p) | |||
| 680 | } | 702 | } |
| 681 | dirs = d_add; | 703 | dirs = d_add; |
| 682 | } | 704 | } |
| 705 | for(d = configs; d; d = d->link) { | ||
| 706 | if(d->data) { | ||
| 707 | /* configs.h placed outsize of "." */ | ||
| 708 | c_lex(d->data, 1); | ||
| 709 | free(d->data); | ||
| 710 | } | ||
| 711 | } | ||
| 683 | } | 712 | } |
| 684 | 713 | ||
| 685 | int main(int argc, char **argv) | 714 | int main(int argc, char **argv) |
| @@ -725,8 +754,8 @@ int main(int argc, char **argv) | |||
| 725 | s = bb_simplify_path(INCLUDE_CONFIG_KEYS_PATH); | 754 | s = bb_simplify_path(INCLUDE_CONFIG_KEYS_PATH); |
| 726 | configs = llist_add_to(configs, s); | 755 | configs = llist_add_to(configs, s); |
| 727 | } | 756 | } |
| 728 | scan_dir_find_ch_files("."); | ||
| 729 | 757 | ||
| 758 | scan_dir_find_ch_files("."); | ||
| 730 | for(fl = files; fl; fl = fl->link) { | 759 | for(fl = files; fl; fl = fl->link) { |
| 731 | c_lex(fl->data, 0); | 760 | c_lex(fl->data, 0); |
| 732 | if(generate_dep) { | 761 | if(generate_dep) { |
| @@ -739,7 +768,7 @@ int main(int argc, char **argv) | |||
| 739 | return 0; | 768 | return 0; |
| 740 | } | 769 | } |
| 741 | 770 | ||
| 742 | void bb_error_d(const char *s, ...) | 771 | static void bb_error_d(const char *s, ...) |
| 743 | { | 772 | { |
| 744 | va_list p; | 773 | va_list p; |
| 745 | 774 | ||
| @@ -751,7 +780,7 @@ void bb_error_d(const char *s, ...) | |||
| 751 | } | 780 | } |
| 752 | 781 | ||
| 753 | 782 | ||
| 754 | void *xmalloc(size_t size) | 783 | static void *xmalloc(size_t size) |
| 755 | { | 784 | { |
| 756 | void *p = malloc(size); | 785 | void *p = malloc(size); |
| 757 | 786 | ||
| @@ -760,14 +789,14 @@ void *xmalloc(size_t size) | |||
| 760 | return p; | 789 | return p; |
| 761 | } | 790 | } |
| 762 | 791 | ||
| 763 | void *xrealloc(void *p, size_t size) { | 792 | static void *xrealloc(void *p, size_t size) { |
| 764 | p = realloc(p, size); | 793 | p = realloc(p, size); |
| 765 | if(p == NULL) | 794 | if(p == NULL) |
| 766 | bb_error_d("memory exhausted"); | 795 | bb_error_d("memory exhausted"); |
| 767 | return p; | 796 | return p; |
| 768 | } | 797 | } |
| 769 | 798 | ||
| 770 | char *bb_asprint(const char *format, ...) | 799 | static char *bb_asprint(const char *format, ...) |
| 771 | { | 800 | { |
| 772 | va_list p; | 801 | va_list p; |
| 773 | int r; | 802 | int r; |
| @@ -782,7 +811,7 @@ char *bb_asprint(const char *format, ...) | |||
| 782 | return out; | 811 | return out; |
| 783 | } | 812 | } |
| 784 | 813 | ||
| 785 | llist_t *llist_add_to(llist_t *old_head, char *new_item) | 814 | static llist_t *llist_add_to(llist_t *old_head, char *new_item) |
| 786 | { | 815 | { |
| 787 | llist_t *new_head; | 816 | llist_t *new_head; |
| 788 | 817 | ||
| @@ -793,15 +822,16 @@ llist_t *llist_add_to(llist_t *old_head, char *new_item) | |||
| 793 | return(new_head); | 822 | return(new_head); |
| 794 | } | 823 | } |
| 795 | 824 | ||
| 796 | char *bb_xstrdup(const char *s) | 825 | static char *bb_xstrdup(const char *s) |
| 797 | { | 826 | { |
| 798 | char *r = strdup(s); | 827 | char *r = strdup(s); |
| 799 | if(r == NULL) | 828 | |
| 800 | bb_error_d("memory exhausted"); | 829 | if(r == NULL) |
| 801 | return r; | 830 | bb_error_d("memory exhausted"); |
| 831 | return r; | ||
| 802 | } | 832 | } |
| 803 | 833 | ||
| 804 | char *bb_simplify_path(const char *path) | 834 | static char *bb_simplify_path(const char *path) |
| 805 | { | 835 | { |
| 806 | char *s, *start, *p; | 836 | char *s, *start, *p; |
| 807 | 837 | ||
| @@ -828,26 +858,26 @@ char *bb_simplify_path(const char *path) | |||
| 828 | p = s = start; | 858 | p = s = start; |
| 829 | 859 | ||
| 830 | do { | 860 | do { |
| 831 | if (*p == '/') { | 861 | if (*p == '/') { |
| 832 | if (*s == '/') { /* skip duplicate (or initial) slash */ | 862 | if (*s == '/') { /* skip duplicate (or initial) slash */ |
| 833 | continue; | 863 | continue; |
| 834 | } else if (*s == '.') { | 864 | } else if (*s == '.') { |
| 835 | if (s[1] == '/' || s[1] == 0) { /* remove extra '.' */ | 865 | if (s[1] == '/' || s[1] == 0) { /* remove extra '.' */ |
| 836 | continue; | 866 | continue; |
| 837 | } else if ((s[1] == '.') && (s[2] == '/' || s[2] == 0)) { | 867 | } else if ((s[1] == '.') && (s[2] == '/' || s[2] == 0)) { |
| 838 | ++s; | 868 | ++s; |
| 839 | if (p > start) { | 869 | if (p > start) { |
| 840 | while (*--p != '/'); /* omit previous dir */ | 870 | while (*--p != '/'); /* omit previous dir */ |
| 841 | } | ||
| 842 | continue; | ||
| 843 | } | ||
| 844 | } | 871 | } |
| 872 | continue; | ||
| 873 | } | ||
| 845 | } | 874 | } |
| 846 | *++p = *s; | 875 | } |
| 876 | *++p = *s; | ||
| 847 | } while (*++s); | 877 | } while (*++s); |
| 848 | 878 | ||
| 849 | if ((p == start) || (*p != '/')) { /* not a trailing slash */ | 879 | if ((p == start) || (*p != '/')) { /* not a trailing slash */ |
| 850 | ++p; /* so keep last character */ | 880 | ++p; /* so keep last character */ |
| 851 | } | 881 | } |
| 852 | *p = 0; | 882 | *p = 0; |
| 853 | 883 | ||
