bb_mkdep speed up * 10!
This commit is contained in:
parent
5e60dc4a20
commit
b1fe462116
@ -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;
|
||||
if(val)
|
||||
sprintf(s, "#define %s%s%s\n", opt, (*val ? " " : ""), val);
|
||||
else
|
||||
sprintf(s, "#undef %s\n", opt);
|
||||
/* 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] */
|
||||
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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user