diff options
author | vodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2005-09-12 16:39:47 +0000 |
---|---|---|
committer | vodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2005-09-12 16:39:47 +0000 |
commit | 4165e8075871e4344a43b937c135013c3103cbb8 (patch) | |
tree | dd1c74abee945c95121fa2fd8eaff15b73048dee | |
parent | d3181e1cf79d78b20bf4205a5d8678556defba98 (diff) | |
download | busybox-w32-4165e8075871e4344a43b937c135013c3103cbb8.tar.gz busybox-w32-4165e8075871e4344a43b937c135013c3103cbb8.tar.bz2 busybox-w32-4165e8075871e4344a43b937c135013c3103cbb8.zip |
bb_mkdep speed up * 10!
git-svn-id: svn://busybox.net/trunk/busybox@11426 69ca8d6d-28ef-0310-b511-8ec308f3f277
-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 | ||