bb_mkdep release. speed up *3, clearing, more comments
This commit is contained in:
parent
6943a9489e
commit
676e95ea3d
@ -1,2 +1 @@
|
|||||||
mkdep
|
bb_mkdep
|
||||||
split-include
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Another dependences for Makefile mashine generator
|
* Another dependences for Makefile fast mashine generator
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005 by Vladimir Oleynik <dzo@simtreas.ru>
|
* Copyright (C) 2005 by Vladimir Oleynik <dzo@simtreas.ru>
|
||||||
*
|
*
|
||||||
@ -19,6 +19,7 @@
|
|||||||
* -w (show warning if include files not found)
|
* -w (show warning if include files not found)
|
||||||
* -k include/config (default: INCLUDE_CONFIG_PATH)
|
* -k include/config (default: INCLUDE_CONFIG_PATH)
|
||||||
* -c include/config.h (configs, default: INCLUDE_CONFIG_KEYS_PATH)
|
* -c include/config.h (configs, default: INCLUDE_CONFIG_KEYS_PATH)
|
||||||
|
* dirs_for_scan (default ".")
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LOCAL_INCLUDE_PATH "include"
|
#define LOCAL_INCLUDE_PATH "include"
|
||||||
@ -47,9 +48,13 @@ typedef struct BB_KEYS {
|
|||||||
struct BB_KEYS *next;
|
struct BB_KEYS *next;
|
||||||
} bb_key_t;
|
} bb_key_t;
|
||||||
|
|
||||||
|
typedef struct FILE_LIST {
|
||||||
|
char *name;
|
||||||
|
char *ext; /* *.c or *.h, point to last char */
|
||||||
|
long size;
|
||||||
|
} file_list_t;
|
||||||
|
|
||||||
/* partial and simplify libbb routine */
|
/* partial and simplify libbb routine */
|
||||||
|
|
||||||
static 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)));
|
||||||
static char * bb_asprint(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
static char * bb_asprint(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
||||||
|
|
||||||
@ -66,15 +71,20 @@ 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;
|
||||||
|
static llist_t *configs;
|
||||||
|
|
||||||
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 */
|
/* for speed triks */
|
||||||
|
static char first_chars[257]; /* + L_EOF */
|
||||||
|
|
||||||
#define CHECK_ONLY 0
|
static int pagesizem1;
|
||||||
#define MAKE_NEW 1
|
static size_t mema_id = 128; /* first allocated for id */
|
||||||
static bb_key_t *find_already(bb_key_t *k, const char *nk, int flg_save_new);
|
static char *id_s;
|
||||||
|
|
||||||
|
static bb_key_t *check_key(bb_key_t *k, const char *nk);
|
||||||
|
static bb_key_t *make_new_key(bb_key_t *k, const char *nk);
|
||||||
|
|
||||||
#define yy_error_d(s) bb_error_d("%s:%d hmm, %s", fname, line, s)
|
#define yy_error_d(s) bb_error_d("%s:%d hmm, %s", fname, line, s)
|
||||||
|
|
||||||
@ -82,40 +92,41 @@ static bb_key_t *find_already(bb_key_t *k, const char *nk, int flg_save_new);
|
|||||||
#define S 0 /* start state */
|
#define S 0 /* start state */
|
||||||
#define STR '"' /* string */
|
#define STR '"' /* string */
|
||||||
#define CHR '\'' /* char */
|
#define CHR '\'' /* char */
|
||||||
#define REM '*' /* block comment */
|
#define REM '/' /* block comment */
|
||||||
|
#define BS '\\' /* back slash */
|
||||||
#define POUND '#' /* # */
|
#define POUND '#' /* # */
|
||||||
#define I 'i' /* #include preprocessor`s directive */
|
#define I 'i' /* #include preprocessor`s directive */
|
||||||
#define D 'd' /* #define preprocessor`s directive */
|
#define D 'd' /* #define preprocessor`s directive */
|
||||||
#define U 'u' /* #undef preprocessor`s directive */
|
#define U 'u' /* #undef preprocessor`s directive */
|
||||||
#define LI 'I' /* #include "... */
|
#define LI 'I' /* #include "... */
|
||||||
#define DK 'K' /* #define KEY... (config mode) */
|
#define DK 'K' /* #define KEY... (config mode) */
|
||||||
#define DV 'V' /* #define KEY "... or #define KEY '... */
|
#define DV 'V' /* #define KEY "VALUE or #define KEY 'VALUE */
|
||||||
#define NLC 'n' /* \+\n */
|
#define NLC 'n' /* \ and \n */
|
||||||
#define ANY '?' /* skip unparsed . */
|
#define ANY '*' /* any unparsed chars */
|
||||||
|
|
||||||
|
#define L_EOF 256
|
||||||
/* [A-Z_a-z] */
|
/* [A-Z_a-z] */
|
||||||
#define ID(c) ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_')
|
#define ID(c) ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_')
|
||||||
/* [A-Z_a-z0-9] */
|
/* [A-Z_a-z0-9] */
|
||||||
#define ISALNUM(c) (ID(c) || (c >= '0' && c <= '9'))
|
#define ISALNUM(c) (ID(c) || (c >= '0' && c <= '9'))
|
||||||
|
|
||||||
#define getc1() do { c = (optr >= oend) ? EOF : *optr++; } while(0)
|
#define getc1() do { c = (optr >= oend) ? L_EOF : *optr++; } while(0)
|
||||||
#define ungetc1() optr--
|
#define ungetc1() optr--
|
||||||
|
|
||||||
#define put_id(c) do { if(id_len == mema_id) \
|
#define put_id(c) do { if(id_len == local_mema_id) \
|
||||||
id = xrealloc(id, mema_id += 16); \
|
id = xrealloc(id, local_mema_id += 16); \
|
||||||
id[id_len++] = c; } while(0)
|
id[id_len++] = c; } while(0)
|
||||||
|
|
||||||
/* stupid C lexical analizator */
|
/* stupid C lexical analizator */
|
||||||
static void c_lex(const char *fname, int flg_config_include)
|
static void c_lex(const char *fname, long fsize)
|
||||||
{
|
{
|
||||||
int c = EOF; /* stupid initialize */
|
int c = L_EOF; /* stupid initialize */
|
||||||
int prev_state = EOF;
|
int prev_state = L_EOF;
|
||||||
int called;
|
int called;
|
||||||
int state;
|
int state;
|
||||||
int line;
|
int line;
|
||||||
static size_t mema_id;
|
char *id = id_s;
|
||||||
static char *id_s;
|
size_t local_mema_id = mema_id;
|
||||||
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;
|
||||||
@ -124,35 +135,20 @@ static void c_lex(const char *fname, int flg_config_include)
|
|||||||
int fd;
|
int fd;
|
||||||
char *map;
|
char *map;
|
||||||
int mapsize;
|
int mapsize;
|
||||||
{
|
|
||||||
/* stolen from mkdep by Linus Torvalds */
|
|
||||||
int pagesizem1 = getpagesize() - 1;
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
fd = open(fname, O_RDONLY);
|
fd = open(fname, O_RDONLY);
|
||||||
if(fd < 0) {
|
if(fd < 0) {
|
||||||
perror(fname);
|
perror(fname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fstat(fd, &st);
|
mapsize = (fsize+pagesizem1) & ~pagesizem1;
|
||||||
if (st.st_size == 0)
|
map = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
bb_error_d("%s is empty", fname);
|
if ((long) map == -1)
|
||||||
mapsize = st.st_size;
|
|
||||||
mapsize = (mapsize+pagesizem1) & ~pagesizem1;
|
|
||||||
map = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
||||||
if ((long) map == -1)
|
|
||||||
bb_error_d("%s: mmap: %m", fname);
|
bb_error_d("%s: mmap: %m", fname);
|
||||||
|
|
||||||
/* hereinafter is my */
|
optr = (unsigned char *)map;
|
||||||
optr = (unsigned char *)map;
|
oend = optr + fsize;
|
||||||
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;
|
||||||
|
|
||||||
@ -163,10 +159,7 @@ static void c_lex(const char *fname, int flg_config_include)
|
|||||||
if(state == LI) {
|
if(state == LI) {
|
||||||
parse_inc(id, fname);
|
parse_inc(id, fname);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/* #define KEY "[VAL]" */
|
||||||
if(val[0] == '\0')
|
|
||||||
yy_error_d("expected value");
|
|
||||||
*/
|
|
||||||
parse_conf_opt(id, val, (optr - start));
|
parse_conf_opt(id, val, (optr - start));
|
||||||
}
|
}
|
||||||
state = S;
|
state = S;
|
||||||
@ -180,7 +173,7 @@ static void c_lex(const char *fname, int flg_config_include)
|
|||||||
while(c == ' ' || c == '\t')
|
while(c == ' ' || c == '\t')
|
||||||
getc1();
|
getc1();
|
||||||
|
|
||||||
if(c == '\\') {
|
if(c == BS) {
|
||||||
getc1();
|
getc1();
|
||||||
if(c == '\n') {
|
if(c == '\n') {
|
||||||
/* \\\n eat continued */
|
/* \\\n eat continued */
|
||||||
@ -189,49 +182,50 @@ static void c_lex(const char *fname, int flg_config_include)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ungetc1();
|
ungetc1();
|
||||||
c = '\\';
|
c = BS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state == S) {
|
if(state == S) {
|
||||||
while(c <= ' ' && c != EOF) {
|
while(first_chars[c] == ANY) {
|
||||||
/* <S>[\000- ]+ */
|
/* <S>unparsed */
|
||||||
if(c == '\n')
|
if(c == '\n')
|
||||||
line++;
|
line++;
|
||||||
getc1();
|
getc1();
|
||||||
}
|
}
|
||||||
if(c == EOF) {
|
if(c == L_EOF) {
|
||||||
/* <S><<EOF>> */
|
/* <S><<EOF>> */
|
||||||
|
id_s = id;
|
||||||
|
mema_id = local_mema_id;
|
||||||
munmap(map, mapsize);
|
munmap(map, mapsize);
|
||||||
close(fd);
|
close(fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(c == '/') {
|
if(c == REM) {
|
||||||
/* <S>/ */
|
/* <S>/ */
|
||||||
getc1();
|
getc1(); /* eat <S>/ */
|
||||||
if(c == '/') {
|
if(c == REM) {
|
||||||
/* <S>"//"[^\n]* */
|
/* <S>"//"[^\n]* */
|
||||||
do getc1(); while(c != '\n' && c != EOF);
|
do getc1(); while(c != '\n' && c != L_EOF);
|
||||||
} else if(c == '*') {
|
} else if(c == '*') {
|
||||||
/* <S>[/][*] */
|
/* <S>[/][*] */
|
||||||
called = S;
|
called = S;
|
||||||
state = REM;
|
state = REM;
|
||||||
}
|
}
|
||||||
/* eat <S>/ */
|
} else if(c == POUND) {
|
||||||
} else if(c == '#') {
|
/* <S># */
|
||||||
/* <S>\"|\'|# */
|
|
||||||
start = optr - 1;
|
start = optr - 1;
|
||||||
state = c;
|
state = c;
|
||||||
} else if(c == STR || c == CHR) {
|
} else if(c == STR || c == CHR) {
|
||||||
/* <S>\"|\'|# */
|
/* <S>\"|\' */
|
||||||
val = NULL;
|
val = NULL;
|
||||||
called = S;
|
called = S;
|
||||||
state = c;
|
state = c;
|
||||||
} else if(ISALNUM(c)) {
|
} else if(c != BS) {
|
||||||
/* <S>[A-Z_a-z0-9] */
|
/* <S>[A-Z_a-z0-9] */
|
||||||
|
|
||||||
/* trick for fast drop id
|
/* trick for fast drop id
|
||||||
if key with this first char undefined */
|
if key with this first char undefined */
|
||||||
if(first_char_conf_opts[c] == 0) {
|
if(first_chars[c] == 0) {
|
||||||
/* skip <S>[A-Z_a-z0-9]+ */
|
/* skip <S>[A-Z_a-z0-9]+ */
|
||||||
do getc1(); while(ISALNUM(c));
|
do getc1(); while(ISALNUM(c));
|
||||||
} else {
|
} else {
|
||||||
@ -242,11 +236,11 @@ static void c_lex(const char *fname, int flg_config_include)
|
|||||||
getc1();
|
getc1();
|
||||||
} while(ISALNUM(c));
|
} while(ISALNUM(c));
|
||||||
put_id(0);
|
put_id(0);
|
||||||
find_already(key_top, id, CHECK_ONLY);
|
check_key(key_top, id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* <S>. */
|
/* <S>\\ */
|
||||||
prev_state = ANY;
|
prev_state = c;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -259,13 +253,13 @@ static void c_lex(const char *fname, int flg_config_include)
|
|||||||
if(called != S)
|
if(called != S)
|
||||||
yy_error_d("unexpected newline");
|
yy_error_d("unexpected newline");
|
||||||
line++;
|
line++;
|
||||||
} else if(c == EOF)
|
} else if(c == L_EOF)
|
||||||
yy_error_d("unexpected EOF");
|
yy_error_d("unexpected EOF");
|
||||||
getc1();
|
getc1();
|
||||||
}
|
}
|
||||||
/* <REM>[*] */
|
/* <REM>[*] */
|
||||||
getc1();
|
getc1();
|
||||||
if(c == '/') {
|
if(c == REM) {
|
||||||
/* <REM>[*][/] */
|
/* <REM>[*][/] */
|
||||||
state = called;
|
state = called;
|
||||||
break;
|
break;
|
||||||
@ -276,14 +270,14 @@ static void c_lex(const char *fname, int flg_config_include)
|
|||||||
if(state == STR || state == CHR) {
|
if(state == STR || state == CHR) {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
/* <STR,CHR>\n|<<EOF>> */
|
/* <STR,CHR>\n|<<EOF>> */
|
||||||
if(c == '\n' || c == EOF)
|
if(c == '\n' || c == L_EOF)
|
||||||
yy_error_d("unterminating");
|
yy_error_d("unterminating");
|
||||||
if(c == '\\') {
|
if(c == BS) {
|
||||||
/* <STR,CHR>\\ */
|
/* <STR,CHR>\\ */
|
||||||
getc1();
|
getc1();
|
||||||
if(c != '\\' && c != '\n' && c != state) {
|
if(c != BS && c != '\n' && c != state) {
|
||||||
/* another usage \ in str or char */
|
/* another usage \ in str or char */
|
||||||
if(c == EOF)
|
if(c == L_EOF)
|
||||||
yy_error_d("unexpected EOF");
|
yy_error_d("unexpected EOF");
|
||||||
if(val)
|
if(val)
|
||||||
put_id(c);
|
put_id(c);
|
||||||
@ -298,7 +292,7 @@ static void c_lex(const char *fname, int flg_config_include)
|
|||||||
} else if(c == state) {
|
} else if(c == state) {
|
||||||
/* <STR>\" or <CHR>\' */
|
/* <STR>\" or <CHR>\' */
|
||||||
if(called == DV)
|
if(called == DV)
|
||||||
put_id(c);
|
put_id(c); /* #define KEY "VALUE"<- */
|
||||||
state = called;
|
state = called;
|
||||||
break;
|
break;
|
||||||
} else if(val)
|
} else if(val)
|
||||||
@ -310,12 +304,12 @@ static void c_lex(const char *fname, int flg_config_include)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* begin preprocessor states */
|
/* begin preprocessor states */
|
||||||
if(c == EOF)
|
if(c == L_EOF)
|
||||||
yy_error_d("unexpected EOF");
|
yy_error_d("unexpected EOF");
|
||||||
if(c == '/') {
|
if(c == REM) {
|
||||||
/* <#.*>/ */
|
/* <#.*>/ */
|
||||||
getc1();
|
getc1();
|
||||||
if(c == '/')
|
if(c == REM)
|
||||||
yy_error_d("detect // in preprocessor line");
|
yy_error_d("detect // in preprocessor line");
|
||||||
if(c == '*') {
|
if(c == '*') {
|
||||||
/* <#.*>[/][*] */
|
/* <#.*>[/][*] */
|
||||||
@ -326,51 +320,55 @@ static void c_lex(const char *fname, int flg_config_include)
|
|||||||
/* hmm, #.*[/] */
|
/* hmm, #.*[/] */
|
||||||
yy_error_d("strange preprocessor line");
|
yy_error_d("strange preprocessor line");
|
||||||
}
|
}
|
||||||
if(state == '#') {
|
if(state == POUND) {
|
||||||
|
if(c != 'd' && c != 'u' && c != 'i') {
|
||||||
|
while(ISALNUM(c))
|
||||||
|
getc1();
|
||||||
|
state = S;
|
||||||
|
} else {
|
||||||
static const char * const preproc[] = {
|
static const char * const preproc[] = {
|
||||||
"define", "undef", "include", ""
|
"define", "undef", "include", ""
|
||||||
};
|
};
|
||||||
const char * const *str_type;
|
const char * const *str_type;
|
||||||
|
|
||||||
id_len = 0;
|
id_len = 0;
|
||||||
while(ISALNUM(c)) {
|
do { put_id(c); getc1(); } while(ISALNUM(c));
|
||||||
put_id(c);
|
|
||||||
getc1();
|
|
||||||
}
|
|
||||||
put_id(0);
|
put_id(0);
|
||||||
for(str_type = preproc; (state = **str_type); str_type++) {
|
for(str_type = preproc; (state = **str_type); str_type++) {
|
||||||
if(*id == state && strcmp(id, *str_type) == 0)
|
if(*id == state && strcmp(id, *str_type) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* to S if another #directive */
|
/* to S if another #directive */
|
||||||
ungetc1();
|
|
||||||
id_len = 0; /* common for save */
|
id_len = 0; /* common for save */
|
||||||
continue;
|
}
|
||||||
|
ungetc1();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if(state == I) {
|
if(state == I) {
|
||||||
if(c == STR) {
|
if(c == STR) {
|
||||||
/* <I>\" */
|
/* <I>\" */
|
||||||
val = id;
|
val = id;
|
||||||
state = STR;
|
|
||||||
called = LI;
|
called = LI;
|
||||||
continue;
|
state = STR;
|
||||||
|
} else {
|
||||||
|
/* another (may be wrong) #include ... */
|
||||||
|
ungetc1();
|
||||||
|
state = S;
|
||||||
}
|
}
|
||||||
/* another (may be wrong) #include ... */
|
|
||||||
ungetc1();
|
|
||||||
state = S;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(state == D || state == U) {
|
if(state == D || state == U) {
|
||||||
while(ISALNUM(c)) {
|
if(configs == NULL) {
|
||||||
if(flg_config_include) {
|
/* ignore depend with #define or #undef KEY */
|
||||||
/* save KEY from #"define"|"undef" ... */
|
while(ISALNUM(c))
|
||||||
put_id(c);
|
getc1();
|
||||||
}
|
|
||||||
getc1();
|
|
||||||
}
|
|
||||||
if(!flg_config_include) {
|
|
||||||
state = S;
|
state = S;
|
||||||
} else {
|
} else {
|
||||||
|
/* save KEY from #"define"|"undef" ... */
|
||||||
|
while(ISALNUM(c)) {
|
||||||
|
put_id(c);
|
||||||
|
getc1();
|
||||||
|
}
|
||||||
if(!id_len)
|
if(!id_len)
|
||||||
yy_error_d("expected identificator");
|
yy_error_d("expected identificator");
|
||||||
put_id(0);
|
put_id(0);
|
||||||
@ -386,7 +384,7 @@ static void c_lex(const char *fname, int flg_config_include)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(state == DK) {
|
if(state == DK) {
|
||||||
/* #define (config mode) */
|
/* #define KEY[ ] (config mode) */
|
||||||
val = id + id_len;
|
val = id + id_len;
|
||||||
if(c == STR || c == CHR) {
|
if(c == STR || c == CHR) {
|
||||||
/* define KEY "... or define KEY '... */
|
/* define KEY "... or define KEY '... */
|
||||||
@ -396,6 +394,7 @@ static void c_lex(const char *fname, int flg_config_include)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
while(ISALNUM(c)) {
|
while(ISALNUM(c)) {
|
||||||
|
/* VALUE */
|
||||||
put_id(c);
|
put_id(c);
|
||||||
getc1();
|
getc1();
|
||||||
}
|
}
|
||||||
@ -410,43 +409,51 @@ static void c_lex(const char *fname, int flg_config_include)
|
|||||||
static void show_usage(void) __attribute__ ((noreturn));
|
static void show_usage(void) __attribute__ ((noreturn));
|
||||||
static void show_usage(void)
|
static void show_usage(void)
|
||||||
{
|
{
|
||||||
bb_error_d("Usage: [-I local_include_path] [-dw] "
|
bb_error_d("Usage: [-I local_include_paths] [-dw] "
|
||||||
"[-k path_for_store_keys] [-s skip_file]");
|
"[-k path_for_store_keys] [-s skip_file] [dirs]");
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *kp;
|
static const char *kp;
|
||||||
|
static size_t kp_len;
|
||||||
static llist_t *Iop;
|
static llist_t *Iop;
|
||||||
static bb_key_t *Ifound;
|
static bb_key_t *Ifound;
|
||||||
static int noiwarning;
|
static int noiwarning;
|
||||||
static llist_t *configs;
|
|
||||||
|
|
||||||
static bb_key_t *find_already(bb_key_t *k, const char *nk, int flg_save_new)
|
static bb_key_t *check_key(bb_key_t *k, const char *nk)
|
||||||
|
{
|
||||||
|
bb_key_t *cur;
|
||||||
|
|
||||||
|
for(cur = k; cur; cur = cur->next) {
|
||||||
|
if(strcmp(cur->keyname, nk) == 0) {
|
||||||
|
cur->checked = 1;
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bb_key_t *make_new_key(bb_key_t *k, const char *nk)
|
||||||
{
|
{
|
||||||
bb_key_t *cur;
|
bb_key_t *cur;
|
||||||
|
size_t nk_size;
|
||||||
|
|
||||||
for(cur = k; cur; cur = cur->next) {
|
nk_size = strlen(nk) + 1;
|
||||||
if(strcmp(cur->keyname, nk) == 0) {
|
cur = xmalloc(sizeof(bb_key_t) + nk_size);
|
||||||
cur->checked = 1;
|
cur->keyname = memcpy(cur + 1, nk, nk_size);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(flg_save_new == CHECK_ONLY)
|
|
||||||
return NULL;
|
|
||||||
cur = xmalloc(sizeof(bb_key_t));
|
|
||||||
cur->keyname = bb_xstrdup(nk);
|
|
||||||
cur->checked = 1;
|
cur->checked = 1;
|
||||||
cur->next = k;
|
cur->next = k;
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int store_include_fullpath(char *p_i, bb_key_t *li)
|
static inline char *store_include_fullpath(char *p_i, bb_key_t *li)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int ok = 0;
|
char *ok;
|
||||||
|
|
||||||
if(stat(p_i, &st) == 0) {
|
if(stat(p_i, &st) == 0) {
|
||||||
li->stored_path = bb_simplify_path(p_i);
|
ok = li->stored_path = bb_simplify_path(p_i);
|
||||||
ok = 1;
|
} else {
|
||||||
|
ok = NULL;
|
||||||
}
|
}
|
||||||
free(p_i);
|
free(p_i);
|
||||||
return ok;
|
return ok;
|
||||||
@ -458,9 +465,11 @@ static void parse_inc(const char *include, const char *fname)
|
|||||||
char *p_i;
|
char *p_i;
|
||||||
llist_t *lo;
|
llist_t *lo;
|
||||||
|
|
||||||
if((li = find_already(Ifound, include, MAKE_NEW)) == NULL)
|
li = check_key(Ifound, include);
|
||||||
|
if(li)
|
||||||
return;
|
return;
|
||||||
Ifound = li;
|
Ifound = li = make_new_key(Ifound, include);
|
||||||
|
|
||||||
if(include[0] != '/') {
|
if(include[0] != '/') {
|
||||||
/* relative */
|
/* relative */
|
||||||
int w;
|
int w;
|
||||||
@ -490,9 +499,10 @@ static void parse_inc(const char *include, const char *fname)
|
|||||||
|
|
||||||
static void parse_conf_opt(char *opt, const char *val, size_t recordsz)
|
static void parse_conf_opt(char *opt, const char *val, size_t recordsz)
|
||||||
{
|
{
|
||||||
bb_key_t *cur = find_already(key_top, opt, MAKE_NEW);
|
bb_key_t *cur;
|
||||||
|
|
||||||
if(cur != NULL) {
|
cur = check_key(key_top, opt);
|
||||||
|
if(cur == NULL) {
|
||||||
/* new key, check old key if present after previous usage */
|
/* new key, check old key if present after previous usage */
|
||||||
char *s, *p;
|
char *s, *p;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@ -501,6 +511,9 @@ static void parse_conf_opt(char *opt, const char *val, size_t recordsz)
|
|||||||
static char *record_buf;
|
static char *record_buf;
|
||||||
static char *r_cmp;
|
static char *r_cmp;
|
||||||
static size_t r_sz;
|
static size_t r_sz;
|
||||||
|
ssize_t rw_ret;
|
||||||
|
|
||||||
|
cur = make_new_key(key_top, opt);
|
||||||
|
|
||||||
recordsz += 2; /* \n\0 */
|
recordsz += 2; /* \n\0 */
|
||||||
if(recordsz > r_sz) {
|
if(recordsz > r_sz) {
|
||||||
@ -509,12 +522,24 @@ static void parse_conf_opt(char *opt, const char *val, size_t recordsz)
|
|||||||
}
|
}
|
||||||
s = record_buf;
|
s = record_buf;
|
||||||
/* may be short count " " */
|
/* may be short count " " */
|
||||||
if(val)
|
if(val) {
|
||||||
recordsz = sprintf(s, "#define %s%s%s\n", opt, (*val ? " " : ""), val);
|
if(*val == '\0') {
|
||||||
else
|
cur->value = "";
|
||||||
|
recordsz = sprintf(s, "#define %s\n", opt);
|
||||||
|
} else {
|
||||||
|
cur->value = bb_xstrdup(val);
|
||||||
|
recordsz = sprintf(s, "#define %s %s\n", opt, val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cur->value = NULL;
|
||||||
recordsz = sprintf(s, "#undef %s\n", opt);
|
recordsz = sprintf(s, "#undef %s\n", opt);
|
||||||
first_char_conf_opts[((int)((unsigned char)(*opt)))] = *opt;
|
}
|
||||||
/* key converting [A-Z] -> [a-z] */
|
/* size_t -> ssize_t :( */
|
||||||
|
rw_ret = (ssize_t)recordsz;
|
||||||
|
/* trick, save first char KEY for do fast identify id */
|
||||||
|
first_chars[(int)*opt] = *opt;
|
||||||
|
|
||||||
|
/* 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';
|
||||||
@ -524,6 +549,7 @@ static void parse_conf_opt(char *opt, const char *val, size_t recordsz)
|
|||||||
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;
|
||||||
if(stat(opt, &st)) {
|
if(stat(opt, &st)) {
|
||||||
|
p += kp_len;
|
||||||
while(*++p) {
|
while(*++p) {
|
||||||
/* Auto-create directories. */
|
/* Auto-create directories. */
|
||||||
if (*p == '/') {
|
if (*p == '/') {
|
||||||
@ -535,9 +561,9 @@ static void parse_conf_opt(char *opt, const char *val, size_t recordsz)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* found */
|
/* found */
|
||||||
if(st.st_size == recordsz) {
|
if(st.st_size == (off_t)recordsz) {
|
||||||
fd = open(opt, O_RDONLY);
|
fd = open(opt, O_RDONLY);
|
||||||
if(fd < 0 || read(fd, r_cmp, recordsz) != recordsz)
|
if(fd < 0 || read(fd, r_cmp, recordsz) < rw_ret)
|
||||||
bb_error_d("%s: %m", opt);
|
bb_error_d("%s: %m", opt);
|
||||||
close(fd);
|
close(fd);
|
||||||
cmp_ok = memcmp(s, r_cmp, recordsz) == 0;
|
cmp_ok = memcmp(s, r_cmp, recordsz) == 0;
|
||||||
@ -545,57 +571,30 @@ static void parse_conf_opt(char *opt, const char *val, size_t recordsz)
|
|||||||
}
|
}
|
||||||
if(!cmp_ok) {
|
if(!cmp_ok) {
|
||||||
fd = open(opt, O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
fd = open(opt, O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
||||||
if(fd < 0 || write(fd, s, recordsz) != recordsz)
|
if(fd < 0 || write(fd, s, recordsz) < rw_ret)
|
||||||
bb_error_d("%s: %m", opt);
|
bb_error_d("%s: %m", opt);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
/* store only */
|
|
||||||
cur->checked = 0;
|
|
||||||
if(val) {
|
|
||||||
if(*val == '\0') {
|
|
||||||
cur->value = "";
|
|
||||||
} else {
|
|
||||||
cur->value = bb_xstrdup(val);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cur->value = NULL;
|
|
||||||
}
|
|
||||||
key_top = cur;
|
key_top = cur;
|
||||||
} else {
|
} else {
|
||||||
/* present already */
|
/* present already */
|
||||||
for(cur = key_top; cur; cur = cur->next) {
|
if((cur->value == NULL && val != NULL) ||
|
||||||
if(strcmp(cur->keyname, opt) == 0) {
|
(cur->value != NULL && val == NULL) ||
|
||||||
cur->checked = 0;
|
(cur->value != NULL && val != NULL && strcmp(cur->value, val)))
|
||||||
if(cur->value == NULL && val == NULL)
|
fprintf(stderr, "Warning: redefined %s\n", opt);
|
||||||
return;
|
|
||||||
if((cur->value == NULL && val != NULL) ||
|
|
||||||
(cur->value != NULL && val == NULL) ||
|
|
||||||
strcmp(cur->value, val))
|
|
||||||
fprintf(stderr, "Warning: redefined %s\n", opt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
/* store only */
|
||||||
|
cur->checked = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int show_dep(int first, bb_key_t *k, const char *a)
|
static int show_dep(int first, bb_key_t *k, const char *name)
|
||||||
{
|
{
|
||||||
bb_key_t *cur;
|
bb_key_t *cur;
|
||||||
|
|
||||||
for(cur = k; cur; cur = cur->next) {
|
for(cur = k; cur; cur = cur->next) {
|
||||||
if(cur->checked && cur->stored_path) {
|
if(cur->checked && cur->stored_path) {
|
||||||
if(first) {
|
if(first) {
|
||||||
const char *ext;
|
printf("\n%s:", name);
|
||||||
|
|
||||||
if(*a == '.' && a[1] == '/')
|
|
||||||
a += 2;
|
|
||||||
ext = strrchr(a, '.');
|
|
||||||
if(ext && ext[1] == 'c' && ext[2] == '\0') {
|
|
||||||
/* *.c -> *.o */
|
|
||||||
printf("\n%.*s.o:", (ext - a), a);
|
|
||||||
} else {
|
|
||||||
printf("\n%s:", a);
|
|
||||||
}
|
|
||||||
first = 0;
|
first = 0;
|
||||||
} else {
|
} else {
|
||||||
printf(" \\\n ");
|
printf(" \\\n ");
|
||||||
@ -608,50 +607,56 @@ static int show_dep(int first, bb_key_t *k, const char *a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static llist_t *files;
|
static llist_t *files;
|
||||||
|
static struct stat st_kp;
|
||||||
|
|
||||||
static llist_t *filter_chd(const char *fe, const char *p, llist_t *pdirs)
|
static char *dir_and_entry;
|
||||||
|
|
||||||
|
static char *
|
||||||
|
filter_chd(const char *fe, const char *p, size_t dirlen)
|
||||||
{
|
{
|
||||||
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;
|
file_list_t *f;
|
||||||
|
size_t df_sz;
|
||||||
|
static size_t dir_and_entry_sz;
|
||||||
|
|
||||||
if (*fe == '.')
|
if (*fe == '.')
|
||||||
return NULL;
|
return NULL;
|
||||||
fp = bb_asprint("%s/%s", p, fe);
|
|
||||||
|
df_sz = dirlen + strlen(fe) + 2; /* dir/file\0 */
|
||||||
|
if(df_sz > dir_and_entry_sz)
|
||||||
|
dir_and_entry = xrealloc(dir_and_entry, dir_and_entry_sz = df_sz);
|
||||||
|
fp = dir_and_entry;
|
||||||
|
sprintf(fp, "%s/%s", p, fe);
|
||||||
|
|
||||||
if(stat(fp, &st)) {
|
if(stat(fp, &st)) {
|
||||||
fprintf(stderr, "Warning: stat(%s): %m", fp);
|
fprintf(stderr, "Warning: stat(%s): %m", fp);
|
||||||
free(fp);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(S_ISREG(st.st_mode)) {
|
if(S_ISREG(st.st_mode)) {
|
||||||
const char *e = strrchr(fe, '.');
|
afp = fp + df_sz - 3;
|
||||||
|
if(*afp++ != '.' || (*afp != 'c' && *afp != 'h')) {
|
||||||
if(e == NULL || !((e[1]=='c' || e[1]=='h') && e[2]=='\0')) {
|
|
||||||
/* direntry is regular file, but is not *.[ch] */
|
/* direntry is regular file, but is not *.[ch] */
|
||||||
free(fp);
|
return NULL;
|
||||||
|
}
|
||||||
|
if (st.st_size == 0) {
|
||||||
|
fprintf(stderr, "Warning: %s is empty\n", fp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} 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(S_ISDIR(st.st_mode)) {
|
||||||
if (st.st_dev == st_kp.st_dev && st.st_ino == st_kp.st_ino) {
|
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 */
|
/* drop scan kp/ directory */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return llist_add_to(pdirs, fp);
|
/* buff is returned, begin of zero allocate */
|
||||||
|
dir_and_entry = NULL;
|
||||||
|
dir_and_entry_sz = 0;
|
||||||
|
return fp;
|
||||||
}
|
}
|
||||||
/* hmm, is device! */
|
/* hmm, is device! */
|
||||||
free(fp);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
afp = bb_simplify_path(fp);
|
afp = bb_simplify_path(fp);
|
||||||
@ -659,16 +664,18 @@ static llist_t *filter_chd(const char *fe, const char *p, llist_t *pdirs)
|
|||||||
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, st.st_size);
|
||||||
free(fp);
|
|
||||||
free(cfl->data);
|
free(cfl->data);
|
||||||
cfl->data = NULL;
|
cfl->data = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(fp);
|
|
||||||
/* direntry is *.[ch] regular file */
|
/* direntry is *.[ch] regular file */
|
||||||
files = llist_add_to(files, afp);
|
f = xmalloc(sizeof(file_list_t));
|
||||||
|
f->name = afp;
|
||||||
|
f->ext = strrchr(afp, '.') + 1;
|
||||||
|
f->size = st.st_size;
|
||||||
|
files = llist_add_to(files, (char *)f);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,6 +686,7 @@ static void scan_dir_find_ch_files(char *p)
|
|||||||
llist_t *d;
|
llist_t *d;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
|
size_t dirlen;
|
||||||
|
|
||||||
dirs = llist_add_to(NULL, p);
|
dirs = llist_add_to(NULL, p);
|
||||||
/* emulate recursive */
|
/* emulate recursive */
|
||||||
@ -688,10 +696,12 @@ static void scan_dir_find_ch_files(char *p)
|
|||||||
dir = opendir(dirs->data);
|
dir = opendir(dirs->data);
|
||||||
if (dir == NULL)
|
if (dir == NULL)
|
||||||
fprintf(stderr, "Warning: opendir(%s): %m", dirs->data);
|
fprintf(stderr, "Warning: opendir(%s): %m", dirs->data);
|
||||||
|
dirlen = strlen(dirs->data);
|
||||||
while ((de = readdir(dir)) != NULL) {
|
while ((de = readdir(dir)) != NULL) {
|
||||||
d = filter_chd(de->d_name, dirs->data, d_add);
|
char *found_dir = filter_chd(de->d_name, dirs->data, dirlen);
|
||||||
if(d)
|
|
||||||
d_add = d;
|
if(found_dir)
|
||||||
|
d_add = llist_add_to(d_add, found_dir);
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
if(dirs->data != p)
|
if(dirs->data != p)
|
||||||
@ -702,15 +712,10 @@ 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *pwd;
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int generate_dep = 1;
|
int generate_dep = 1;
|
||||||
@ -718,6 +723,22 @@ int main(int argc, char **argv)
|
|||||||
int i;
|
int i;
|
||||||
llist_t *fl;
|
llist_t *fl;
|
||||||
|
|
||||||
|
{
|
||||||
|
/* for bb_simplify_path */
|
||||||
|
/* libbb xgetcwd(), this program have not chdir() */
|
||||||
|
unsigned path_max = 512;
|
||||||
|
|
||||||
|
s = xmalloc (path_max);
|
||||||
|
#define PATH_INCR 32
|
||||||
|
while (getcwd (s, path_max) == NULL) {
|
||||||
|
if(errno != ERANGE)
|
||||||
|
bb_error_d("getcwd: %m");
|
||||||
|
path_max += PATH_INCR;
|
||||||
|
s = xrealloc (s, path_max);
|
||||||
|
}
|
||||||
|
pwd = s;
|
||||||
|
}
|
||||||
|
|
||||||
while ((i = getopt(argc, argv, "I:c:dk:w")) > 0) {
|
while ((i = getopt(argc, argv, "I:c:dk:w")) > 0) {
|
||||||
switch(i) {
|
switch(i) {
|
||||||
case 'I':
|
case 'I':
|
||||||
@ -742,9 +763,6 @@ int main(int argc, char **argv)
|
|||||||
show_usage();
|
show_usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(argc > optind)
|
|
||||||
show_usage();
|
|
||||||
|
|
||||||
/* defaults */
|
/* defaults */
|
||||||
if(kp == NULL)
|
if(kp == NULL)
|
||||||
kp = bb_simplify_path(INCLUDE_CONFIG_PATH);
|
kp = bb_simplify_path(INCLUDE_CONFIG_PATH);
|
||||||
@ -754,13 +772,57 @@ 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);
|
||||||
}
|
}
|
||||||
|
/* globals initialize */
|
||||||
|
/* for c_lex */
|
||||||
|
pagesizem1 = getpagesize() - 1;
|
||||||
|
id_s = xmalloc(mema_id);
|
||||||
|
for(i = 0; i < 256; i++) {
|
||||||
|
/* set unparsed chars for speed up of parser */
|
||||||
|
if(!ISALNUM(i) && i != CHR && i != STR &&
|
||||||
|
i != POUND && i != REM && i != BS)
|
||||||
|
first_chars[i] = ANY;
|
||||||
|
}
|
||||||
|
first_chars[i] = '-'; /* L_EOF */
|
||||||
|
|
||||||
|
kp_len = strlen(kp);
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* main loops */
|
||||||
|
argv += optind;
|
||||||
|
if(*argv) {
|
||||||
|
while(*argv)
|
||||||
|
scan_dir_find_ch_files(*argv++);
|
||||||
|
} else {
|
||||||
|
scan_dir_find_ch_files(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(fl = configs; fl; fl = fl->link) {
|
||||||
|
if(fl->data) {
|
||||||
|
/* configs.h placed outsize of scanned dirs or not "*.ch" */
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if(stat(fl->data, &st))
|
||||||
|
bb_error_d("stat(%s): %m", fl->data);
|
||||||
|
c_lex(fl->data, st.st_size);
|
||||||
|
free(fl->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(configs);
|
||||||
|
configs = NULL; /* flag read config --> parse sourses mode */
|
||||||
|
|
||||||
scan_dir_find_ch_files(".");
|
|
||||||
for(fl = files; fl; fl = fl->link) {
|
for(fl = files; fl; fl = fl->link) {
|
||||||
c_lex(fl->data, 0);
|
file_list_t *t = (file_list_t *)(fl->data);
|
||||||
|
c_lex(t->name, t->size);
|
||||||
if(generate_dep) {
|
if(generate_dep) {
|
||||||
i = show_dep(1, Ifound, fl->data);
|
if(t->ext[0] == 'c') {
|
||||||
i = show_dep(i, key_top, fl->data);
|
/* *.c -> *.o */
|
||||||
|
t->ext[0] = 'o';
|
||||||
|
}
|
||||||
|
i = show_dep(1, Ifound, t->name);
|
||||||
|
i = show_dep(i, key_top, t->name);
|
||||||
if(i == 0)
|
if(i == 0)
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
@ -768,6 +830,7 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* partial and simplify libbb routine */
|
||||||
static void bb_error_d(const char *s, ...)
|
static void bb_error_d(const char *s, ...)
|
||||||
{
|
{
|
||||||
va_list p;
|
va_list p;
|
||||||
@ -836,24 +899,10 @@ static char *bb_simplify_path(const char *path)
|
|||||||
char *s, *start, *p;
|
char *s, *start, *p;
|
||||||
|
|
||||||
if (path[0] == '/')
|
if (path[0] == '/')
|
||||||
start = bb_xstrdup(path);
|
start = bb_xstrdup(path);
|
||||||
else {
|
else {
|
||||||
static char *pwd;
|
/* is not libbb, but this program have not chdir() */
|
||||||
|
start = bb_asprint("%s/%s", pwd, path);
|
||||||
if(pwd == NULL) {
|
|
||||||
/* is not libbb, but this program have not chdir() */
|
|
||||||
unsigned path_max = 512;
|
|
||||||
char *cwd = xmalloc (path_max);
|
|
||||||
#define PATH_INCR 32
|
|
||||||
while (getcwd (cwd, path_max) == NULL) {
|
|
||||||
if(errno != ERANGE)
|
|
||||||
bb_error_d("getcwd: %m");
|
|
||||||
path_max += PATH_INCR;
|
|
||||||
cwd = xrealloc (cwd, path_max);
|
|
||||||
}
|
|
||||||
pwd = cwd;
|
|
||||||
}
|
|
||||||
start = bb_asprint("%s/%s", pwd, path);
|
|
||||||
}
|
}
|
||||||
p = s = start;
|
p = s = start;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user