trunk: changeset 4

Sat, 19 Feb 2000 23:23:29 +0100

author
tuomov
date
Sat, 19 Feb 2000 23:23:29 +0100
changeset 1
6e704fc09528
parent 0
86b7f6f9c5c0
child 2
e14a1aba4c56

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);
 }
 
 
+
 /* */
 
 

mercurial