/* 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;
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);
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;
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;
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;
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);
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;
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);
}
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)
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) {
return 0;
}
-void bb_error_d(const char *s, ...)
+static void bb_error_d(const char *s, ...)
{
va_list p;
}
-void *xmalloc(size_t size)
+static void *xmalloc(size_t size)
{
void *p = malloc(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;
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;
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;
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;