# HG changeset patch # User tuomov # Date 950999009 -3600 # Node ID 6e704fc09528b70de1fa899fab685947a0ce53b5 # Parent 86b7f6f9c5c0eb1bebdc477fe3ad07c9bded0eed trunk: changeset 4 - Added include support in config file parser - Added scatn() - Fixed remalloczero() - Fixed is_end() in numparser2.h -- EOF case was missing diff -r 86b7f6f9c5c0 -r 6e704fc09528 Makefile --- a/Makefile Tue Feb 15 18:57:52 2005 +0100 +++ b/Makefile Sat Feb 19 23:23:29 2000 +0100 @@ -49,7 +49,7 @@ libtu.a: $(OBJS) $(AR) $(AR_FLAGS) $@ $+ -%: %.c +%: %.c libtu.a $(CC) $(CC_FLAGS) $+ -L. -ltu -lm -o $@ %.o: %.c diff -r 86b7f6f9c5c0 -r 6e704fc09528 include/misc.h --- a/include/misc.h Tue Feb 15 18:57:52 2005 +0100 +++ b/include/misc.h Sat Feb 19 23:23:29 2000 +0100 @@ -25,11 +25,12 @@ #define FREE(X) ({if(X!=NULL) free(X);}) -extern void* malloczero(int size); -extern void* remalloczero(void *ptr, int oldsize, int newsize); +extern void* malloczero(size_t size); +extern void* remalloczero(void *ptr, size_t oldsize, size_t newsize); extern char* scopy(const char *p); extern char* scat(const char *p1, const char *p2); +extern char* scatn(const char *p1, ssize_t n1, const char *p2, ssize_t n2); extern char* scat3(const char *p1, const char *p2, const char *p3); extern const char* simple_basename(const char *name); diff -r 86b7f6f9c5c0 -r 6e704fc09528 include/parser.h --- a/include/parser.h Tue Feb 15 18:57:52 2005 +0100 +++ b/include/parser.h Sat Feb 19 23:23:29 2000 +0100 @@ -23,7 +23,7 @@ * * = 0 or more times any (must be the last, "sd*") * ? = optional ("?c") * : = conditional (":c:s") - * + * + = 1 or more times last (most be the last, "l+") * special entries: * * "#end" call this handler at the end of section. diff -r 86b7f6f9c5c0 -r 6e704fc09528 include/tokenizer.h --- a/include/tokenizer.h Tue Feb 15 18:57:52 2005 +0100 +++ b/include/tokenizer.h Sat Feb 19 23:23:29 2000 +0100 @@ -149,15 +149,26 @@ struct _ConfOpt; -typedef struct{ +typedef struct _Tokenizer_FInfo{ FILE *file; - const char *name; - int flags; + char *name; int line; int ungetc; +} Tokenizer_FInfo; + +typedef struct _Tokenizer{ + FILE *file; + char *name; + int line; + int ungetc; + + int flags; const struct _ConfOpt **optstack; int nest_lvl; void *user_data; + + int filestack_n; + Tokenizer_FInfo *filestack; } Tokenizer; @@ -167,4 +178,8 @@ extern bool tokz_get_token(Tokenizer *tokz, Token *tok); extern void tokz_warn_error(const Tokenizer *tokz, int line, int e); +extern bool tokz_pushf(Tokenizer *tokz, const char *fname); +extern bool tokz_pushf_file(Tokenizer *tokz, FILE *file); +extern bool tokz_popf(Tokenizer *tokz); + #endif /* __LIBTU_TOKENIZER_H */ diff -r 86b7f6f9c5c0 -r 6e704fc09528 misc.c --- a/misc.c Tue Feb 15 18:57:52 2005 +0100 +++ b/misc.c Sat Feb 19 23:23:29 2000 +0100 @@ -15,7 +15,7 @@ #include "include/misc.h" -void *malloczero(int size) +void *malloczero(size_t size) { void *p=malloc(size); @@ -26,7 +26,7 @@ } -void *remalloczero(void *ptr, int oldsize, int newsize) +void *remalloczero(void *ptr, size_t oldsize, size_t newsize) { void *p=NULL; @@ -38,7 +38,10 @@ memset(p, 0, newsize); - if(ptr!=NULL && oldsizenegative=TRUE; diff -r 86b7f6f9c5c0 -r 6e704fc09528 parser.c --- a/parser.c Tue Feb 15 18:57:52 2005 +0100 +++ b/parser.c Sat Feb 19 23:23:29 2000 +0100 @@ -32,6 +32,17 @@ /* */ +static bool opt_include(Tokenizer *tokz, int n, Token *toks); + + +static ConfOpt common_opts[]={ + {"include", "s", opt_include, NULL}, + {NULL, NULL, NULL, NULL} +}; + + +/* */ + static int read_statement(const ConfOpt **opt_ret, Token *tokens, int *ntok_ret, Tokenizer *tokz, @@ -71,10 +82,17 @@ break; } - if(!opt->optname){ - e=E_TOKZ_UNKNOWN_OPTION; - e_line=tok->line; - retval=P_ERROR; + if(opt->optname==NULL){ + /* common opt? include, etc. */ + for(opt=common_opts; opt->optname; opt++){ + if(strcmp(opt->optname, TOK_IDENT_VAL(tok))==0) + break; + } + if(opt->optname==NULL){ + e=E_TOKZ_UNKNOWN_OPTION; + e_line=tok->line; + retval=P_ERROR; + } } had_comma=2; @@ -295,7 +313,10 @@ break; case P_EOF: - if(tokz->nest_lvl>0){ + if(tokz_popf(tokz)){ + if(!had_error) + continue; + }else if(tokz->nest_lvl>0){ tokz_warn_error(tokz, 0, E_TOKZ_UNEXPECTED_EOF); had_error=TRUE; }else if(!had_error){ @@ -516,3 +537,39 @@ return TRUE; } + +/* */ + + +static bool opt_include(Tokenizer *tokz, int n, Token *toks) +{ + const char *fname=TOK_STRING_VAL(toks+1); + const char *lastndx; + char *tmpname; + bool retval; + + if(fname[0]=='/' || tokz->name==NULL) + goto thisdir; + + lastndx=strrchr(tokz->name, '/'); + + if(lastndx==NULL) + goto thisdir; + + tmpname=scatn(tokz->name, lastndx-tokz->name+1, fname, -1); + + if(tmpname==NULL){ + warn_err(); + return FALSE; + } + + retval=tokz_pushf(tokz, tmpname); + + free(tmpname); + + return retval; + +thisdir: + return tokz_pushf(tokz, fname); +} + diff -r 86b7f6f9c5c0 -r 6e704fc09528 tokenizer.c --- a/tokenizer.c Tue Feb 15 18:57:52 2005 +0100 +++ b/tokenizer.c Sat Feb 19 23:23:29 2000 +0100 @@ -571,7 +571,7 @@ { int c, c2, e; - assert(tokz->file); + assert(tokz->file!=NULL); tok_free(tok); @@ -680,30 +680,89 @@ } -Tokenizer *tokz_open(const char *fname) -{ - Tokenizer*tokz; - FILE*file; +/* + * File open + */ + +static bool do_tokz_pushf(Tokenizer *tokz) +{ + Tokenizer_FInfo *finfo; + + finfo=REALLOC_N(tokz->filestack, Tokenizer_FInfo, + tokz->filestack_n, tokz->filestack_n+1); + + if(finfo==NULL) + return FALSE; + + tokz->filestack=finfo; + finfo=&(finfo[tokz->filestack_n++]); + + finfo->file=tokz->file; + finfo->name=tokz->name; + finfo->line=tokz->line; + finfo->ungetc=tokz->ungetc; + + return TRUE; +} + + +bool tokz_pushf_file(Tokenizer *tokz, FILE *file) +{ + if(file==NULL) + return FALSE; + + if(tokz->file!=NULL){ + if(!do_tokz_pushf(tokz)){ + warn_err(); + return FALSE; + } + } + + tokz->file=file; + tokz->name=NULL; + tokz->line=1; + tokz->ungetc=-1; + + return TRUE; +} + + +bool tokz_pushf(Tokenizer *tokz, const char *fname) +{ + FILE *file; + char *fname_copy; file=fopen(fname, "r"); if(file==NULL){ warn_err_obj(fname); - return NULL; + return FALSE; } - tokz=tokz_open_file(file); + fname_copy=scopy(fname); - if(tokz==NULL) - fclose(file); - else - tokz->name=fname; + if(fname_copy==NULL){ + warn_err(); + goto err1; + } + + if(!tokz_pushf_file(tokz, file)) + goto err2; + + tokz->name=fname_copy; + + return TRUE; - return tokz; +err2: + free(fname_copy); +err1: + fclose(file); + return FALSE; } -Tokenizer *tokz_open_file(FILE *file) + +static Tokenizer *tokz_create() { Tokenizer*tokz; @@ -714,27 +773,110 @@ return NULL; } - tokz->file=file; + tokz->file=NULL; tokz->name=NULL; tokz->line=1; tokz->ungetc=-1; tokz->flags=0; tokz->optstack=NULL; tokz->nest_lvl=0; + tokz->filestack_n=0; + tokz->filestack=NULL; + + return tokz; +} + + +Tokenizer *tokz_open(const char *fname) +{ + Tokenizer *tokz; + + tokz=tokz_create(); + + if(!tokz_pushf(tokz, fname)){ + free(tokz); + return NULL; + } + + return tokz; +} + + +Tokenizer *tokz_open_file(FILE *file) +{ + Tokenizer *tokz; + + tokz=tokz_create(); + + if(!tokz_pushf_file(tokz, file)){ + free(tokz); + return NULL; + } return tokz; } +/* + * File close + */ + +static bool do_tokz_popf(Tokenizer *tokz, bool shrink) +{ + Tokenizer_FInfo *finfo; + + if(tokz->filestack_n<=0) + return FALSE; + + if(tokz->file!=NULL) + fclose(tokz->file); + if(tokz->name!=NULL) + free(tokz->name); + + finfo=&(tokz->filestack[--tokz->filestack_n]); + + tokz->file=finfo->file; + tokz->name=finfo->name; + tokz->line=finfo->line; + tokz->ungetc=finfo->ungetc; + + if(tokz->filestack_n==0){ + free(tokz->filestack); + tokz->filestack=NULL; + }else if(shrink){ + finfo=REALLOC_N(tokz->filestack, Tokenizer_FInfo, + tokz->filestack_n+1, tokz->filestack_n); + if(finfo==NULL) + warn_err(); + else + tokz->filestack=finfo; + } + + return TRUE; +} + + +bool tokz_popf(Tokenizer *tokz) +{ + return do_tokz_popf(tokz, TRUE); +} + + void tokz_close(Tokenizer *tokz) { + while(tokz->filestack_n>0) + do_tokz_popf(tokz, FALSE); + if(tokz->file!=NULL) fclose(tokz->file); + if(tokz->name!=NULL) + free(tokz->name); free(tokz); } + /* */