diff options
-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 { /* partial and simplify libbb routine */ -void bb_error_d(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))); -char * bb_asprint(const char *format, ...) __attribute__ ((format (printf, 1, 2))); +static void bb_error_d(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))); +static char * bb_asprint(const char *format, ...) __attribute__ ((format (printf, 1, 2))); /* stolen from libbb as is */ typedef struct llist_s { char *data; struct llist_s *link; } llist_t; -llist_t *llist_add_to(llist_t *old_head, char *new_item); -void *xrealloc(void *p, size_t size); -void *xmalloc(size_t size); -char *bb_xstrdup(const char *s); -char *bb_simplify_path(const char *path); +static llist_t *llist_add_to(llist_t *old_head, char *new_item); +static void *xrealloc(void *p, size_t size); +static void *xmalloc(size_t size); +static char *bb_xstrdup(const char *s); +static char *bb_simplify_path(const char *path); /* for lexical analyzier */ static bb_key_t *key_top; @@ -70,6 +70,8 @@ static bb_key_t *key_top; static void parse_inc(const char *include, const char *fname); static void parse_conf_opt(char *opt, const char *val, size_t rsz); +static char first_char_conf_opts[256]; /* for speed */ + #define CHECK_ONLY 0 #define MAKE_NEW 1 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) int state; int line; static size_t mema_id; - char *id = xmalloc(mema_id=128); /* fist allocate */ + static char *id_s; + char *id; size_t id_len = 0; /* stupid initialize */ char *val = NULL; unsigned char *optr, *oend; @@ -145,6 +148,11 @@ static void c_lex(const char *fname, int flg_config_include) oend = optr + st.st_size; } + if(id_s == NULL) { + /* fist allocate */ + id_s = xmalloc(mema_id=128); + } + id = id_s; line = 1; called = state = S; @@ -220,14 +228,22 @@ static void c_lex(const char *fname, int flg_config_include) state = c; } else if(ISALNUM(c)) { /* <S>[A-Z_a-z0-9] */ - id_len = 0; - do { + + /* trick for fast drop id + if key with this first char undefined */ + if(first_char_conf_opts[c] == 0) { + /* skip <S>[A-Z_a-z0-9]+ */ + do getc1(); while(ISALNUM(c)); + } else { + id_len = 0; + do { /* <S>[A-Z_a-z0-9]+ */ put_id(c); getc1(); - } while(ISALNUM(c)); - put_id(0); - find_already(key_top, id, CHECK_ONLY); + } while(ISALNUM(c)); + put_id(0); + find_already(key_top, id, CHECK_ONLY); + } } else { /* <S>. */ prev_state = ANY; @@ -492,31 +508,32 @@ static void parse_conf_opt(char *opt, const char *val, size_t recordsz) r_cmp = xrealloc(r_cmp, recordsz); } s = record_buf; + /* may be short count " " */ if(val) - sprintf(s, "#define %s%s%s\n", opt, (*val ? " " : ""), val); + recordsz = sprintf(s, "#define %s%s%s\n", opt, (*val ? " " : ""), val); else - sprintf(s, "#undef %s\n", opt); - /* may be short count " " */ - recordsz = strlen(s); + recordsz = sprintf(s, "#undef %s\n", opt); + first_char_conf_opts[((int)((unsigned char)(*opt)))] = *opt; /* key converting [A-Z] -> [a-z] */ for(p = opt; *p; p++) { if(*p >= 'A' && *p <= 'Z') *p = *p - 'A' + 'a'; - if(*p == '_') - *p = '/'; + else if(*p == '_') + *p = '/'; } p = bb_asprint("%s/%s.h", kp, opt); cur->stored_path = opt = p; - while(*++p) { - /* Auto-create directories. */ - if (*p == '/') { - *p = '\0'; - if (stat(opt, &st) != 0 && mkdir(opt, 0755) != 0) - bb_error_d("mkdir(%s): %m", opt); - *p = '/'; + if(stat(opt, &st)) { + while(*++p) { + /* Auto-create directories. */ + if (*p == '/') { + *p = '\0'; + if (stat(opt, &st) != 0 && mkdir(opt, 0755) != 0) + bb_error_d("mkdir(%s): %m", opt); + *p = '/'; + } } - } - if(stat(opt, &st) == 0) { + } else { /* found */ if(st.st_size == recordsz) { fd = open(opt, O_RDONLY); @@ -594,11 +611,11 @@ static llist_t *files; static llist_t *filter_chd(const char *fe, const char *p, llist_t *pdirs) { - const char *e; struct stat st; char *fp; char *afp; llist_t *cfl; + static struct stat st_kp; if (*fe == '.') return NULL; @@ -608,40 +625,45 @@ static llist_t *filter_chd(const char *fe, const char *p, llist_t *pdirs) free(fp); return NULL; } - afp = bb_simplify_path(fp); - if(S_ISDIR(st.st_mode)) { - if(strcmp(kp, afp) == 0) { - /* is autogenerated to kp/key* by previous usage */ - free(afp); + if(S_ISREG(st.st_mode)) { + const char *e = strrchr(fe, '.'); + + if(e == NULL || !((e[1]=='c' || e[1]=='h') && e[2]=='\0')) { + /* direntry is regular file, but is not *.[ch] */ free(fp); - /* drop scan kp/ directory */ return NULL; } - free(afp); - return llist_add_to(pdirs, fp); - } - if(!S_ISREG(st.st_mode)) { + } else { + if(st_kp.st_ino == 0) { + /* first call */ + if(stat(kp, &st_kp)) + bb_error_d("stat(%s): %m", kp); + if(!S_ISDIR(st_kp.st_mode)) + bb_error_d("%s is not directory", kp); + } + if(S_ISDIR(st.st_mode)) { + if (st.st_dev == st_kp.st_dev && st.st_ino == st_kp.st_ino) { + /* is autogenerated to kp/key* by previous usage */ + free(fp); + /* drop scan kp/ directory */ + return NULL; + } + return llist_add_to(pdirs, fp); + } /* hmm, is device! */ - free(afp); - free(fp); - return NULL; - } - e = strrchr(fe, '.'); - if(e == NULL || !((e[1]=='c' || e[1]=='h') && e[2]=='\0')) { - /* direntry is not directory or *.[ch] */ - free(afp); free(fp); return NULL; } + afp = bb_simplify_path(fp); for(cfl = configs; cfl; cfl = cfl->link) { if(cfl->data && strcmp(cfl->data, afp) == 0) { - /* parse configs.h */ - free(afp); - c_lex(fp, 1); - free(fp); - free(cfl->data); - cfl->data = NULL; - return NULL; + /* parse configs.h */ + free(afp); + c_lex(fp, 1); + free(fp); + free(cfl->data); + cfl->data = NULL; + return NULL; } } free(fp); @@ -680,6 +702,13 @@ static void scan_dir_find_ch_files(char *p) } dirs = d_add; } + for(d = configs; d; d = d->link) { + if(d->data) { + /* configs.h placed outsize of "." */ + c_lex(d->data, 1); + free(d->data); + } + } } int main(int argc, char **argv) @@ -725,8 +754,8 @@ int main(int argc, char **argv) s = bb_simplify_path(INCLUDE_CONFIG_KEYS_PATH); configs = llist_add_to(configs, s); } - scan_dir_find_ch_files("."); + scan_dir_find_ch_files("."); for(fl = files; fl; fl = fl->link) { c_lex(fl->data, 0); if(generate_dep) { @@ -739,7 +768,7 @@ int main(int argc, char **argv) return 0; } -void bb_error_d(const char *s, ...) +static void bb_error_d(const char *s, ...) { va_list p; @@ -751,7 +780,7 @@ void bb_error_d(const char *s, ...) } -void *xmalloc(size_t size) +static void *xmalloc(size_t size) { void *p = malloc(size); @@ -760,14 +789,14 @@ void *xmalloc(size_t size) return p; } -void *xrealloc(void *p, size_t size) { +static void *xrealloc(void *p, size_t size) { p = realloc(p, size); if(p == NULL) bb_error_d("memory exhausted"); return p; } -char *bb_asprint(const char *format, ...) +static char *bb_asprint(const char *format, ...) { va_list p; int r; @@ -782,7 +811,7 @@ char *bb_asprint(const char *format, ...) return out; } -llist_t *llist_add_to(llist_t *old_head, char *new_item) +static llist_t *llist_add_to(llist_t *old_head, char *new_item) { llist_t *new_head; @@ -793,15 +822,16 @@ llist_t *llist_add_to(llist_t *old_head, char *new_item) return(new_head); } -char *bb_xstrdup(const char *s) +static char *bb_xstrdup(const char *s) { - char *r = strdup(s); - if(r == NULL) - bb_error_d("memory exhausted"); - return r; + char *r = strdup(s); + + if(r == NULL) + bb_error_d("memory exhausted"); + return r; } -char *bb_simplify_path(const char *path) +static char *bb_simplify_path(const char *path) { char *s, *start, *p; @@ -828,26 +858,26 @@ char *bb_simplify_path(const char *path) p = s = start; do { - if (*p == '/') { - if (*s == '/') { /* skip duplicate (or initial) slash */ - continue; - } else if (*s == '.') { - if (s[1] == '/' || s[1] == 0) { /* remove extra '.' */ - continue; - } else if ((s[1] == '.') && (s[2] == '/' || s[2] == 0)) { - ++s; - if (p > start) { - while (*--p != '/'); /* omit previous dir */ - } - continue; - } + if (*p == '/') { + if (*s == '/') { /* skip duplicate (or initial) slash */ + continue; + } else if (*s == '.') { + if (s[1] == '/' || s[1] == 0) { /* remove extra '.' */ + continue; + } else if ((s[1] == '.') && (s[2] == '/' || s[2] == 0)) { + ++s; + if (p > start) { + while (*--p != '/'); /* omit previous dir */ } + continue; + } } - *++p = *s; + } + *++p = *s; } while (*++s); - if ((p == start) || (*p != '/')) { /* not a trailing slash */ - ++p; /* so keep last character */ + if ((p == start) || (*p != '/')) { /* not a trailing slash */ + ++p; /* so keep last character */ } *p = 0; |