bb_mkdep speed up * 10!

This commit is contained in:
"Vladimir N. Oleynik" 2005-09-12 16:39:47 +00:00
parent 5e60dc4a20
commit b1fe462116

View File

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