Sat, 19 Feb 2000 23:23:29 +0100
trunk: changeset 4
- Added include support in config file parser
- Added scatn()
- Fixed remalloczero()
- Fixed is_end() in numparser2.h -- EOF case was missing
Makefile | file | annotate | diff | comparison | revisions | |
include/misc.h | file | annotate | diff | comparison | revisions | |
include/parser.h | file | annotate | diff | comparison | revisions | |
include/tokenizer.h | file | annotate | diff | comparison | revisions | |
misc.c | file | annotate | diff | comparison | revisions | |
numparser2.h | file | annotate | diff | comparison | revisions | |
parser.c | file | annotate | diff | comparison | revisions | |
tokenizer.c | file | annotate | diff | comparison | revisions |
--- 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
--- 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);
--- 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.
--- 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 */
--- 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 && oldsize<newsize) + if(newsize<oldsize) + oldsize=newsize; + + if(ptr!=NULL) memcpy(p, ptr, oldsize); } @@ -107,6 +110,32 @@ } +char *scatn(const char *s1, ssize_t l1, const char *s2, ssize_t l2) +{ + size_t tlen=1; + char *s; + + if(l1<0) + l1=strlen(s1); + + if(l2<0) + l2=strlen(s2); + + tlen+=l1+l2; + + s=(char*)malloc(tlen); + + if(s==NULL) + return NULL; + + memcpy(s, s1, l1); + memcpy(s+l1, s2, l2); + s[l1+l2]='\0'; + + return s; +} + + /* */
--- a/numparser2.h Tue Feb 15 18:57:52 2005 +0100 +++ b/numparser2.h Sat Feb 19 23:23:29 2000 +0100 @@ -92,7 +92,8 @@ static bool is_end(int c) { - return ((c!='.' && ispunct(c)) || isspace(c) || iscntrl(c)); + /* oops... EOF was missing */ + return (c==EOF || (c!='.' && ispunct(c)) || isspace(c) || iscntrl(c)); } @@ -140,7 +141,7 @@ int dm=1; int err=0; int tmp; - + if(c=='-' || c=='+'){ if(c=='-') num->negative=TRUE;
--- 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); +} +
--- 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); } + /* */