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 */
|
/* 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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user