diff --git a/Makefile b/Makefile index 631e551..823bf2b 100644 --- a/Makefile +++ b/Makefile @@ -40,6 +40,7 @@ dist: $(PACKAGE)-$(VERSION)/include/System/plugin.h \ $(PACKAGE)-$(VERSION)/include/System/string.h \ $(PACKAGE)-$(VERSION)/include/System/token.h \ + $(PACKAGE)-$(VERSION)/include/System/variable.h \ $(PACKAGE)-$(VERSION)/include/System/Makefile \ $(PACKAGE)-$(VERSION)/include/System/project.conf \ $(PACKAGE)-$(VERSION)/src/array.c \ @@ -53,6 +54,7 @@ dist: $(PACKAGE)-$(VERSION)/src/plugin.c \ $(PACKAGE)-$(VERSION)/src/string.c \ $(PACKAGE)-$(VERSION)/src/token.c \ + $(PACKAGE)-$(VERSION)/src/variable.c \ $(PACKAGE)-$(VERSION)/src/Makefile \ $(PACKAGE)-$(VERSION)/src/token.h \ $(PACKAGE)-$(VERSION)/src/project.conf \ diff --git a/include/System.h b/include/System.h index 71d937d..aa89775 100644 --- a/include/System.h +++ b/include/System.h @@ -28,5 +28,6 @@ # include "System/parser.h" # include "System/plugin.h" # include "System/string.h" +# include "System/variable.h" #endif /* !LIBSYSTEM_SYSTEM_H */ diff --git a/include/System/Makefile b/include/System/Makefile index 433d352..172e441 100644 --- a/include/System/Makefile +++ b/include/System/Makefile @@ -38,6 +38,8 @@ install: $(INSTALL) -m 0644 -- string.h $(DESTDIR)$(INCLUDEDIR)/System/string.h $(MKDIR) $(DESTDIR)$(INCLUDEDIR)/System $(INSTALL) -m 0644 -- token.h $(DESTDIR)$(INCLUDEDIR)/System/token.h + $(MKDIR) $(DESTDIR)$(INCLUDEDIR)/System + $(INSTALL) -m 0644 -- variable.h $(DESTDIR)$(INCLUDEDIR)/System/variable.h uninstall: $(RM) -- $(DESTDIR)$(INCLUDEDIR)/System/array.h @@ -52,5 +54,6 @@ uninstall: $(RM) -- $(DESTDIR)$(INCLUDEDIR)/System/plugin.h $(RM) -- $(DESTDIR)$(INCLUDEDIR)/System/string.h $(RM) -- $(DESTDIR)$(INCLUDEDIR)/System/token.h + $(RM) -- $(DESTDIR)$(INCLUDEDIR)/System/variable.h .PHONY: all clean distclean install uninstall diff --git a/include/System/parser.h b/include/System/parser.h index 9d4fdaf..5111dd0 100644 --- a/include/System/parser.h +++ b/include/System/parser.h @@ -46,6 +46,8 @@ int parser_remove_callback(Parser * parser, ParserCallback callback); int parser_add_filter(Parser * parser, ParserFilter filter, void * data); int parser_remove_filter(Parser * parser, ParserFilter filter); +int parser_inject(Parser * parser, char const * string); + int parser_scan(Parser * parser); int parser_scan_filter(Parser * parser); diff --git a/include/System/project.conf b/include/System/project.conf index 6c2b489..9005855 100644 --- a/include/System/project.conf +++ b/include/System/project.conf @@ -1,4 +1,4 @@ -includes=array.h,buffer.h,config.h,error.h,event.h,file.h,hash.h,object.h,parser.h,plugin.h,string.h,token.h +includes=array.h,buffer.h,config.h,error.h,event.h,file.h,hash.h,object.h,parser.h,plugin.h,string.h,token.h,variable.h dist=Makefile [array.h] @@ -36,3 +36,6 @@ install=$(INCLUDEDIR)/System [token.h] install=$(INCLUDEDIR)/System + +[variable.h] +install=$(INCLUDEDIR)/System diff --git a/include/System/string.h b/include/System/string.h index 504d667..5e1f149 100644 --- a/include/System/string.h +++ b/include/System/string.h @@ -1,5 +1,5 @@ /* $Id$ */ -/* Copyright (c) 2009 Pierre Pronchery */ +/* Copyright (c) 2011 Pierre Pronchery */ /* This file is part of DeforaOS System libSystem */ /* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -49,4 +49,6 @@ String ** string_explode(String const * string, String const * separator); String * string_find(String const * string, String const * key); ssize_t string_index(String const * string, String const * key); +int string_replace(String ** string, String const * what, String const * by); + #endif /* !LIBSYSTEM_STRING_H */ diff --git a/src/Makefile b/src/Makefile index 15acebf..c5a46aa 100644 --- a/src/Makefile +++ b/src/Makefile @@ -18,7 +18,7 @@ INSTALL = install all: $(TARGETS) -libSystem_OBJS = array.o buffer.o config.o error.o event.o hash.o object.o parser.o plugin.o string.o token.o +libSystem_OBJS = array.o buffer.o config.o error.o event.o hash.o object.o parser.o plugin.o string.o token.o variable.o libSystem_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) libSystem_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) @@ -62,6 +62,9 @@ string.o: string.c token.o: token.c token.h $(CC) $(libSystem_CFLAGS) -c token.c +variable.o: variable.c + $(CC) $(libSystem_CFLAGS) -c variable.c + clean: $(RM) -- $(libSystem_OBJS) diff --git a/src/config.c b/src/config.c index 5b2a930..d564d22 100644 --- a/src/config.c +++ b/src/config.c @@ -213,6 +213,7 @@ int config_load(Config * config, char const * filename) string_delete(section); return error_set_code(1, "%s: %s", filename, strerror(errno)); } + /* FIXME unescape backslashes (eg allow multiple lines) */ for(line = 0; (c = fgetc(fp)) != EOF; line++) if(c == '#') while((c = fgetc(fp)) != EOF && c != '\n'); @@ -425,6 +426,7 @@ void _save_foreach_section(void const * key, void * value, void * data) if(*fp == NULL) return; + /* FIXME escape lines with a backslash */ if(val == NULL || fprintf(*fp, "%s=%s\n", var, val) >= 0) return; fclose(*fp); diff --git a/src/parser.c b/src/parser.c index 7cc5751..f5e1cdb 100644 --- a/src/parser.c +++ b/src/parser.c @@ -35,6 +35,7 @@ typedef struct _ParserCallbackData ParserCallbackData; struct _Parser { /* parsing sources */ + char * inject; char * filename; FILE * fp; char * string; @@ -45,7 +46,6 @@ struct _Parser unsigned int line; unsigned int col; int last; - unsigned int lookahead; ParserFilter scanner; @@ -80,21 +80,28 @@ int parser_scan_filter(Parser * parser) int c = parser->last; size_t i; ParserFilterData * pfd; - int l; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(%p)\n", __func__, parser); #endif - if(parser->lookahead) - parser->lookahead--; + if(parser->inject) + { + c = parser->inject[0]; + if((i = strlen(parser->inject)) > 1) + memmove(parser->inject, &parser->inject[1], i); + else + { + string_delete(parser->inject); + parser->inject = NULL; + } + } else if(parser->scanner(&c, parser) != 0) return EOF; /* FIXME report error */ for(i = 0; i < parser->filters_cnt; i++) { pfd = &parser->filters[i]; - if((l = pfd->filter(&c, pfd->data)) < 0) + if(pfd->filter(&c, pfd->data) != 0) return EOF; - parser->lookahead += l; } parser->last = c; return c; @@ -181,6 +188,7 @@ static Parser * _new_do(ParserFilter scanner) if((parser = object_new(sizeof(*parser))) == NULL) return NULL; + parser->inject = NULL; parser->filename = NULL; parser->fp = NULL; parser->string = NULL; @@ -189,7 +197,6 @@ static Parser * _new_do(ParserFilter scanner) parser->line = 1; parser->col = 1; parser->last = EOF; - parser->lookahead = 0; parser->scanner = scanner; parser->filters = NULL; parser->filters_cnt = 0; @@ -231,6 +238,7 @@ int parser_delete(Parser * parser) fprintf(stderr, "DEBUG: %s(%p) \"%s\"\n", __func__, parser, parser->filename); #endif + free(parser->inject); if(parser->fp != NULL && fclose(parser->fp) != 0) ret = error_set_code(1, "%s: %s", parser->filename, @@ -282,6 +290,15 @@ int parser_get_token(Parser * parser, Token ** token) } +#if 0 +/* parser_set_lookahead */ +void parser_set_lookahead(Parser * parser, unsigned int lookahead) +{ + parser->lookahead = lookahead; +} +#endif + + /* useful */ /* parser_add_callback */ int parser_add_callback(Parser * parser, ParserCallback callback, void * data) @@ -318,6 +335,30 @@ int parser_add_filter(Parser * parser, ParserFilter filter, void * data) } +/* parser_inject */ +int parser_inject(Parser * parser, char const * string) +{ + int c; + char buf[2] = "\0"; + + if(string == NULL || string[0] == '\0') + return 0; /* don't bother */ + c = parser->last; + parser->last = string[0]; + if(parser->inject == NULL) + { + if((parser->inject = string_new(&string[1])) == NULL) + return -1; + } + else if(string_append(&parser->inject, &string[1]) != 0) + return -1; + buf[0] = c; + if(c != EOF && string_append(&parser->inject, buf) != 0) + return -1; + return 0; +} + + /* parser_remove_callback */ int parser_remove_callback(Parser * parser, ParserCallback callback) /* FIXME untested */ diff --git a/src/project.conf b/src/project.conf index 4786595..ffdc414 100644 --- a/src/project.conf +++ b/src/project.conf @@ -7,7 +7,7 @@ dist=Makefile,token.h [libSystem] type=library -sources=array.c,buffer.c,config.c,error.c,event.c,hash.c,object.c,parser.c,plugin.c,string.c,token.c +sources=array.c,buffer.c,config.c,error.c,event.c,hash.c,object.c,parser.c,plugin.c,string.c,token.c,variable.c ldflags=-ldl install=$(LIBDIR) diff --git a/src/string.c b/src/string.c index b68f041..4c34820 100644 --- a/src/string.c +++ b/src/string.c @@ -1,5 +1,5 @@ /* $Id$ */ -/* Copyright (c) 2010 Pierre Pronchery */ +/* Copyright (c) 2011 Pierre Pronchery */ /* This file is part of DeforaOS System libSystem */ /* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -249,3 +249,38 @@ ssize_t string_index(String const * string, String const * key) return -1; return i; } + + +/* string_replace */ +int string_replace(String ** string, String const * what, String const * by) +{ + String * ret = NULL; + String const * p; + size_t len = string_length(what); + ssize_t index; + String * q; + + for(p = *string; (index = string_index(p, what)) >= 0; p += index + len) + { + if((q = string_new_length(p, index)) == NULL + || string_append(&ret, q) != 0 + || string_append(&ret, by) != 0) + { + string_delete(q); + string_delete(ret); + return -1; + } + string_delete(q); + } + if(ret != NULL) + { + if(string_append(&ret, p) != 0) + { + string_delete(ret); + return -1; + } + string_delete(*string); + *string = ret; + } + return 0; +}