From 20c3006564121b381317996702e215149cc27f42 Mon Sep 17 00:00:00 2001 From: obarun <eric@obarun.org> Date: Tue, 27 Aug 2019 13:19:29 +1100 Subject: [PATCH] use parser from oblibs --- src/include/66/parser.h | 87 +--- src/lib66/parser.c | 135 +----- src/lib66/parser_utils.c | 986 +++++++++++++++------------------------ 3 files changed, 396 insertions(+), 812 deletions(-) diff --git a/src/include/66/parser.h b/src/include/66/parser.h index 62f05c48..b7e266dc 100644 --- a/src/include/66/parser.h +++ b/src/include/66/parser.h @@ -12,8 +12,8 @@ * except according to the terms contained in the LICENSE file./ */ -#ifndef PARSER_H -#define PARSER_H +#ifndef SS_PARSER_H +#define SS_PARSER_H #include <66/enum.h> @@ -22,6 +22,8 @@ #include <oblibs/oblist.h> #include <oblibs/stralist.h> +#include <oblibs/mill.h> + #include <skalibs/stralloc.h> #include <skalibs/genalloc.h> @@ -244,90 +246,41 @@ struct section_s .idx = { 0 } , \ .file = 0 } - -typedef struct parse_mill_inner_s parse_mill_inner_t, *parse_mill_inner_t_ref ; -struct parse_mill_inner_s -{ - char curr ; - uint32_t nline ; - uint8_t nopen ; //number of open found - uint8_t nclose ; //number of close found - uint8_t jumped ;//jump was made or not 1->no,0->yes - uint8_t flushed ;//flush was made or not 1->no,0->yes - -} ; -#define PARSE_MILL_INNER_ZERO { .curr = 0, \ - .nline = 1, \ - .nopen = 0, \ - .nclose = 0, \ - .jumped = 0, \ - .flushed = 0 } - -typedef struct parse_mill_s parse_mill_t,*parse_mill_t_ref ; -struct parse_mill_s -{ - char const open ; - char const close ; - uint8_t force ; //1 -> only one open and close - char const *skip ; - size_t skiplen ; - char const *end ; - size_t endlen ; - char const *jump ;//skip the complete line - size_t jumplen ; - uint8_t check ;//check if nopen == openclose, 0 -> no,1->yes - uint8_t flush ;//set nopen,nclose,sa.len to 0 at every new line - uint8_t forceskip ;//force to skip even if nopen is positive - parse_mill_inner_t inner ; -} ; - -typedef enum parse_enum_e parse_enum_t,*parse_enum_t_ref ; -enum parse_enum_e -{ - IGN = 0 , - KEEP , - JUMP , - EXIT , - END -} ; - -/** Main */ -extern int parser(sv_alltype *service,stralloc *src,char const *file) ; -extern int parse_config(parse_mill_t *p,char const *file, stralloc *src, stralloc *kp,size_t *pos) ; -extern char next(stralloc *s,size_t *pos) ; -extern uint8_t cclass (parse_mill_t *p) ; /** freed */ extern void sv_alltype_free(sv_alltype *sv) ; extern void keynocheck_free(keynocheck *nocheck) ; extern void section_free(section_t *sec) ; extern void freed_parser(void) ; /** enable phase */ +extern int parser(sv_alltype *service,stralloc *src,char const *file) ; extern int parse_service_get_list(stralloc *result, stralloc *list) ; extern int parse_service_before(ssexec_t *info, stralloc *parsed_list, char const *sv,unsigned int *nbsv, stralloc *sasv,unsigned int force,unsigned int exist) ; extern int parse_service_deps(ssexec_t *info,stralloc *parsed_list, sv_alltype *sv_before, char const *sv,unsigned int *nbsv,stralloc *sasv,unsigned int force) ; extern int parse_add_service(stralloc *parsed_list,sv_alltype *sv_before,char const *service,unsigned int *nbsv,uid_t owner) ; -/** utilities */ +/** mill utilities +extern parse_mill_t MILL_FIRST_BRACKET ; +extern parse_mill_t MILL_GET_AROBASE_KEY ; +extern parse_mill_t MILL_GET_COMMENTED_KEY ; +extern parse_mill_t MILL_GET_SECTION_NAME ; */ +/** utilities extern int parse_line(stralloc *src,size_t *pos) ; -extern int parse_quote(stralloc *src,size_t *pos) ; -extern int parse_bracket(stralloc *src,size_t *pos) ; -extern int parse_env(stralloc *src,size_t *pos) ; +extern int parse_bracket(stralloc *src,size_t *pos) ; */ /** split */ -extern int get_section_range(section_t *sasection,stralloc *src) ; -extern int get_key_range(genalloc *ga, section_t *sasection,char const *file,int *svtype) ; +extern int section_get_range(section_t *sasection,stralloc *src) ; +extern int key_get_range(genalloc *ga, section_t *sasection,int *svtype) ; extern int get_mandatory(genalloc *nocheck,int idsec,int idkey) ; extern int nocheck_toservice(keynocheck *nocheck,int svtype, sv_alltype *service) ; /** store */ extern int keep_common(sv_alltype *service,keynocheck *nocheck,int svtype) ; extern int keep_runfinish(sv_exec *exec,keynocheck *nocheck) ; extern int keep_logger(sv_execlog *log,keynocheck *nocheck) ; -/** helper */ -extern int read_svfile(stralloc *sasv,char const *name,char const *src) ; -extern ssize_t get_sep_before (char const *line, char const sepstart, char const sepend) ; +/** helper extern void section_setsa(int id, stralloc_ref *p,section_t *sa) ; -extern int section_skip(char const *s,size_t pos,int nline) ; -extern int section_valid(int id, uint32_t nline, size_t pos,stralloc *src, char const *file) ; -extern int clean_value(stralloc *sa) ; -extern void parse_err(int ierr,int idsec,int idkey) ; +extern int section_get_skip(char const *s,size_t pos,int nline) ; +extern int section_get_id(stralloc *secname, char const *string,size_t *pos,int *id) ; +extern int key_get_next_id(stralloc *sa, char const *string,size_t *pos) ; +extern void parse_err(int ierr,int idsec,int idkey) ; */ +extern int read_svfile(stralloc *sasv,char const *name,char const *src) ; extern int add_pipe(sv_alltype *sv, stralloc *sa) ; /** write */ extern int write_services(ssexec_t *info,sv_alltype *sv, char const *workdir, unsigned int force,unsigned int conf) ; diff --git a/src/lib66/parser.c b/src/lib66/parser.c index 98c6d451..7e495a61 100644 --- a/src/lib66/parser.c +++ b/src/lib66/parser.c @@ -13,6 +13,7 @@ */ #include <string.h> +#include <stdint.h> //#include <stdio.h> #include <oblibs/error2.h> @@ -20,6 +21,7 @@ #include <oblibs/files.h> #include <oblibs/stralist.h> #include <oblibs/obgetopt.h> +#include <oblibs/mill.h> #include <skalibs/buffer.h> #include <skalibs/stralloc.h> @@ -31,135 +33,6 @@ #include <66/utils.h> #include <66/parser.h> -inline uint8_t cclass (parse_mill_t *p) -{ - size_t i = 0 ; - - if (!p->inner.curr) return 0 ; - else if (p->inner.curr == '\n') - { - if (p->flush) p->inner.flushed = 1 ; - p->inner.jumped = 0 ; - p->inner.nline++ ; - } - for (; i < p->jumplen ; i++) - { - if (p->inner.curr == p->jump[i]) - { - p->inner.jumped = 1 ; - return 2 ; - } - } - for (i = 0 ; i < p->endlen ; i++) - { - if (p->inner.curr == p->end[i]) - { - if (p->inner.curr == p->close) p->inner.nclose++ ; - return 3 ; - } - } - for (i = 0 ; i < p->skiplen ; i++) - { - if (p->inner.curr == p->skip[i]) - { - if (p->open && !p->forceskip) return 1 ; - return 0 ; - } - } - /* close and open can be the same, in this case - * we skip open if it already found */ - if (p->inner.curr == p->open && !p->inner.nopen) - { - p->inner.nopen++ ; - return 0 ; - } - - if (p->inner.curr == p->close) - { - p->inner.nclose++ ; - if (p->force) return 3 ; - return 0 ; - } - - return 1 ; -} - -inline char next(stralloc *s,size_t *pos) -{ - char c ; - if (*pos >= s->len) return -1 ; - c = s->s[*pos] ; - (*pos) += 1 ; - return c ; -} -/** @Return 1 on sucess - * @Return 0 on fail - * @Return 2 for end of file - * @Return -1 if close was not found */ -inline int parse_config(parse_mill_t *p,char const *file, stralloc *src, stralloc *kp,size_t *pos) -{ - uint8_t what = 0 ; - static uint8_t const table[5] = { IGN, KEEP, JUMP, EXIT, END } ; - uint8_t state = 1, end = 0 ; - char j = 0 ; - while (state) - { - p->inner.curr = next(src, pos) ; - what = table[cclass(p)] ; - // end of file - if (p->inner.curr == -1) what = END ; - if (p->inner.flushed) - { - kp->len = 0 ; - p->inner.nopen = 0 ; - p->inner.nclose = 0 ; - p->inner.flushed = 0 ; - what = SKIP ; - } - switch(what) - { - case KEEP: - if (p->inner.nopen && !p->inner.jumped) - if (!stralloc_catb(kp,&p->inner.curr,1)) return 0 ; - break ; - case JUMP: - if (!p->inner.nopen) - { - while (j != '\n') - { - j = next(src,pos) ; - if (j < 0) break ;//end of string - } - p->inner.jumped = 0 ; - p->inner.nline++ ; - } - break ; - case IGN: - break ; - case EXIT: - state = 0 ; - break ; - case END: - state = 0 ; - end = 1 ; - break ; - default: break ; - } - } - - if (p->check && p->inner.nopen != p->inner.nclose) - { - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, p->inner.nline-1)] = 0 ; - char sepopen[2] = { p->open,0 } ; - char sepclose[2] = { p->close,0 } ; - strerr_warnw6x("umatched ",(p->inner.nopen > p->inner.nclose) ? sepopen : sepclose," in: ",file," at line: ",fmt) ; - return 0 ; - } - if (!p->inner.nclose) return -1 ; - if (end) return 2 ; - return 1 ; -} int parser(sv_alltype *service,stralloc *src,char const *file) { @@ -169,7 +42,7 @@ int parser(sv_alltype *service,stralloc *src,char const *file) genalloc ganocheck = GENALLOC_ZERO ; sasection.file = file ; - r = get_section_range(&sasection,src) ; + r = section_get_range(&sasection,src) ; if (r <= 0){ strerr_warnwu2x("parse section of service file: ",file) ; goto err ; @@ -179,7 +52,7 @@ int parser(sv_alltype *service,stralloc *src,char const *file) VERBO1 strerr_warnw2x("missing section [main] in service file: ", file) ; goto err ; } - if (!get_key_range(&ganocheck,&sasection,file,&svtype)) goto err ; + if (!key_get_range(&ganocheck,&sasection,&svtype)) goto err ; if (svtype < 0) { VERBO1 strerr_warnw2x("invalid value for key: @type in service file: ",file) ; diff --git a/src/lib66/parser_utils.c b/src/lib66/parser_utils.c index a7fbd0cc..48f00c56 100644 --- a/src/lib66/parser_utils.c +++ b/src/lib66/parser_utils.c @@ -17,15 +17,18 @@ #include <string.h> #include <unistd.h>//getuid #include <stdlib.h> -//#include <stdio.h> +#include <stdint.h> +#include <sys/types.h> +#include <stdio.h> #include <oblibs/bytes.h> #include <oblibs/string.h> #include <oblibs/files.h> #include <oblibs/error2.h> #include <oblibs/types.h> -#include <oblibs/directory.h> -#include <oblibs/strakeyval.h> +#include <oblibs/mill.h> +#include <oblibs/environ.h> +#include <oblibs/sastr.h> #include <skalibs/sig.h> #include <skalibs/genalloc.h> @@ -38,16 +41,33 @@ #include <66/constants.h> #include <66/enum.h> #include <66/utils.h>//MYUID -#include <66/environ.h>//MYUID stralloc keep = STRALLOC_ZERO ;//sv_alltype data stralloc deps = STRALLOC_ZERO ;//sv_name depends genalloc gadeps = GENALLOC_ZERO ;//unsigned int, pos in deps genalloc gasv = GENALLOC_ZERO ;//sv_alltype general +/********************************** + * function helper declaration + * *******************************/ + +void section_setsa(int id, stralloc_ref *p,section_t *sa) ; +int section_get_skip(char const *s,size_t pos,int nline) ; +int section_get_id(stralloc *secname, char const *string,size_t *pos,int *id) ; +int key_get_next_id(stralloc *sa, char const *string,size_t *pos) ; +int get_clean_val(keynocheck *ch) ; +int get_clean_val(keynocheck *ch) ; +int get_enum(char const *string, keynocheck *ch) ; +int get_timeout(keynocheck *ch,uint32_t *ui) ; +int get_uint(keynocheck *ch,uint32_t *ui) ; +void parse_err(int ierr,keynocheck *check) ; +int parse_line(stralloc *sa, size_t *pos) ; +int parse_bracket(stralloc *sa,size_t *pos) ; + /********************************** * freed function * *******************************/ + void sv_alltype_free(sv_alltype *sv) { stralloc_free(&sv->saenv) ; @@ -78,227 +98,74 @@ void freed_parser(void) sv_alltype_free(&genalloc_s(sv_alltype,&gasv)[i]) ; } /********************************** - * parser utilities + * Mill utilities * *******************************/ -int parse_line(stralloc *src, size_t *pos) -{ - size_t newpos = 0 ; - stralloc kp = STRALLOC_ZERO ; - char const *file = "parse_line" ; - parse_mill_t line = { .open = '@', .close = '\n', \ - .skip = " \t\r", .skiplen = 3, \ - .end = "\n", .endlen = 1, \ - .jump = 0, .jumplen = 0,\ - .check = 0, .flush = 0, \ - .forceskip = 0, .force = 1, \ - .inner = PARSE_MILL_INNER_ZERO } ; - - stralloc_inserts(src,0,"@") ; - if (!parse_config(&line,file,src,&kp,&newpos)) goto err ; - if (!stralloc_0(&kp)) goto err ; - if (!clean_value(&kp)) goto err ; - if (!stralloc_copy(src,&kp)) goto err ; - *pos += newpos - 1 ; - stralloc_free(&kp) ; - return 1 ; - err: - stralloc_free(&kp) ; - return 0 ; -} + +parse_mill_t MILL_FIRST_BRACKET = \ +{ \ + .search = "(", .searchlen = 1, \ + .inner.debug = "first_bracket" } ; -int parse_quote(stralloc *src,size_t *pos) -{ - int r, err = 0 ; - size_t newpos = 0 ; - char const *file = "parse_quote" ; - stralloc kp = STRALLOC_ZERO ; - parse_mill_t quote = { .open = '"', .close = '"', \ - .skip = 0, .skiplen = 0, \ - .end = "\n", .endlen = 1, \ - .jump = 0, .jumplen = 0,\ - .check = 0, .flush = 0, \ - .forceskip = 0, .force = 0, \ - .inner = PARSE_MILL_INNER_ZERO } ; +parse_mill_t MILL_GET_AROBASE_KEY = \ +{ \ + .open = '@', .close = '=', .keepopen = 1, \ + .forceclose = 1, .skip = " \t\r", .skiplen = 3, \ + .forceskip = 1, .inner.debug = "get_arobase_key" } ; - r = parse_config("e,file,src,&kp,&newpos) ; - if (!r) goto err ; - else if (r == -1) { err = -1 ; goto err ; } - if (!stralloc_0(&kp)) goto err ; - if (!stralloc_copy(src,&kp)) goto err ; - *pos += newpos - 1 ; - stralloc_free(&kp) ; - return 1 ; - err: - stralloc_free(&kp) ; - return err ; -} - -int parse_bracket(stralloc *src,size_t *pos) -{ - int err = -1 ; - size_t newpos = 0 ; - ssize_t id = -1, start = -1, end = -1 ; - char const *file = "parse_bracket" ; - stralloc kp = STRALLOC_ZERO ; - stralloc tmp = STRALLOC_ZERO ; - - parse_mill_t key = { .open = '@', .close = '=', \ - .skip = " \n\t\r", .skiplen = 4, \ - .end = 0, .endlen = 0, \ - .jump = 0, .jumplen = 0,\ - .check = 0, .flush = 1, \ - .forceskip = 0, .force = 1, \ - .inner = PARSE_MILL_INNER_ZERO } ; - - - while (id < 0 && newpos < src->len) - { - kp.len = 0 ; - key.inner.nclose = 0 ; - key.inner.nopen = 0 ; - if (!parse_config(&key,file,src,&kp,&newpos)) goto err ; - if (!kp.len) break ;//end of string - if (!stralloc_0(&kp)) goto err ; - if (!clean_value(&kp)) goto err ; - if (!stralloc_inserts(&kp,0,"@")) goto err ; - id = get_enumbyid(kp.s,key_enum_el) ; - } - /** id is negative and we are at the end of string - * field can contain instance name with @ character - * in this case we keep the src as it */ - if (id < 0) - { - if (!stralloc_cats(&tmp,src->s)) goto err ; - }else if (!stralloc_catb(&tmp,src->s,(newpos - (kp.len+1)))) goto err ;//+1 remove the @ of the next key - if (!stralloc_0(&tmp)) goto err ; - kp.len = 0 ; - start = get_len_until(tmp.s,'(') ; - if (start < 0) { err = -1 ; goto err ; } - start++ ; - end = get_rlen_until(tmp.s,')',tmp.len) ; - if (end < 0) { err = -1 ; goto err ; } - if (!stralloc_catb(&kp,tmp.s+start,end-start)) goto err ; - if (!stralloc_0(&kp)) goto err ; - if (!stralloc_copy(src,&kp)) goto err ; - *pos += end + 1 ; //+1 to remove the last ')' - stralloc_free(&kp) ; - stralloc_free(&tmp) ; - return 1 ; - err: - stralloc_free(&kp) ; - stralloc_free(&tmp) ; - return err ; -} +parse_mill_t MILL_GET_COMMENTED_KEY = \ +{ \ + .search = "#", .searchlen = 1, \ + .end = "@", .endlen = 1, + .inner.debug = "get_commented_key" } ; -int parse_env(stralloc *src,size_t *pos) -{ - int r ; - size_t newpos = 0 ; - size_t base ; - stralloc kp = STRALLOC_ZERO ; - stralloc tmp = STRALLOC_ZERO ; - char const *file = "parse_env" ; - parse_mill_t line = { .open = '@', .close = '\n', \ - .skip = " \t\r", .skiplen = 3, \ - .end = "\n", .endlen = 1, \ - .jump = "#", .jumplen = 1,\ - .check = 0, .flush = 0, \ - .forceskip = 0, .force = 1, \ - .inner = PARSE_MILL_INNER_ZERO } ; +parse_mill_t MILL_GET_SECTION_NAME = \ +{ \ + .open = '[', .close = ']', \ + .forceclose = 1, .forceskip = 1, \ + .skip = " \t\r", .skiplen = 3, \ + .inner.debug = "get_section_name" } ; - size_t blen = src->len, n = 0 ; - if (!stralloc_inserts(src,0,"@")) goto err ; - while(newpos < (blen+n)) - { - base = kp.len ; - line.inner.nopen = line.inner.nclose = 0 ; - r = parse_config(&line,file,src,&kp,&newpos) ; - if (!r) goto err ; - else if (r < 0){ kp.len = base ; goto append ; } - if (!stralloc_cats(&kp,"\n")) goto err ; - append: - if (!stralloc_inserts(src,newpos,"@")) goto err ; - n++; - } - if (!stralloc_0(&kp)) goto err ; - if (!stralloc_copy(src,&kp)) goto err ; - *pos += newpos - 1 ; - stralloc_free(&kp) ; - stralloc_free(&tmp) ; - return 1 ; - err: - stralloc_free(&kp) ; - stralloc_free(&tmp) ; - return 0 ; -} - /********************************** * parser split function * *******************************/ -int get_section_range(section_t *sasection,stralloc *src) +int section_get_range(section_t *sasection,stralloc *src) { + if (!src->len) return 0 ; size_t pos = 0, start = 0 ; - int n = 0, id = -1, /*idc = 0,*/ skip = 0, err = 0 ; + int r, n = 0, id = -1, skip = 0 ; stralloc secname = STRALLOC_ZERO ; stralloc_ref psasection ; - parse_mill_t section = { .open = '[', .close = ']', \ - .skip = " \n\t\r", .skiplen = 4, \ - .end = 0, .endlen = 0, \ - .jump = 0, .jumplen = 0,\ - .check = 0, .flush = 1, \ - .forceskip = 0, .force = 1, \ - .inner = PARSE_MILL_INNER_ZERO } ; - - while (pos < src->len) + stralloc cp = STRALLOC_ZERO ; + /** be clean */ + wild_zero_all(&MILL_GET_LINE) ; + wild_zero_all(&MILL_GET_SECTION_NAME) ; + r = mill_string(&cp,src,&MILL_GET_LINE) ; + if (r == -1 || !r) goto err ; + if (!sastr_rebuild_in_nline(&cp)) goto err ; + while (pos < cp.len) { if(secname.len && n) { - skip = section_skip(src->s,pos,section.inner.nline) ; + skip = section_get_skip(cp.s,pos,MILL_GET_SECTION_NAME.inner.nline) ; id = get_enumbyid(secname.s,key_enum_section_el) ; section_setsa(id,&psasection,sasection) ; if (skip) sasection->idx[id] = 1 ; } - secname.len = section.inner.nclose = section.inner.nopen = 0 ; - id = -1 ; - while (id < 0 && pos < src->len) - { - secname.len = section.inner.nclose = section.inner.nopen = 0 ; - if(!parse_config(§ion,sasection->file,src,&secname,&pos)) goto err ; - if (!secname.len) break ; //end of string - if (!stralloc_0(&secname)) goto err ; - id = get_enumbyid(secname.s,key_enum_section_el) ; - /*if (id < 0) - { - idc = section_valid(id,section.inner.nline,pos,src,sasection->file) ; - if (!idc) goto err ; - else if (idc < 0) goto invalid ; - }*/ - } + if (!section_get_id(&secname,cp.s,&pos,&id)) goto err ; if (!n) { - skip = section_skip(src->s,pos,section.inner.nline) ; + skip = section_get_skip(cp.s,pos,MILL_GET_SECTION_NAME.inner.nline) ; section_setsa(id,&psasection,sasection) ; if (skip) sasection->idx[id] = 1 ; start = pos ; - id = -1 ; - while (id < 0 && pos < src->len) - { - section.inner.nclose = section.inner.nopen = secname.len = 0 ; - if (!parse_config(§ion,sasection->file,src,&secname,&pos)) goto err ; - if (!secname.len) break ; //end of string - if (!stralloc_0(&secname)) goto err ; - id = get_enumbyid(secname.s,key_enum_section_el) ; - /*if (id < 0) - { - idc = section_valid(id,section.inner.nline,pos,src,sasection->file) ; - if (!idc) goto err ; - else if (idc < 0) goto invalid ; - }*/ - } + + if (!section_get_id(&secname,cp.s,&pos,&id)) goto err ; if(skip) { - if (!stralloc_catb(psasection,src->s+start,(pos - start) - (secname.len + 2))) goto err ;//+2 to remove '[]'character + r = get_rlen_until(cp.s,'\n',pos-1) ;//-1 to retrieve the end of previous line + if (r == -1) goto err ; + if (!stralloc_catb(psasection,cp.s+start,(r-start))) goto err ; if (!stralloc_0(psasection)) goto err ; } n++ ; @@ -308,37 +175,36 @@ int get_section_range(section_t *sasection,stralloc *src) { if (skip) { - if (!stralloc_catb(psasection,src->s+start,(pos - start) - (secname.len + 1))) goto err ;//only -1 to remove '\n'character + /** end of file do not contain section, avoid to remove the len of it if in the case*/ + if (secname.len) + { + r = get_rlen_until(cp.s,'\n',pos-1) ;//-1 to retrieve the end of previous line + if (r == -1) goto err ; + if (!stralloc_catb(psasection,cp.s+start,(r - start))) goto err ; + } + else if (!stralloc_cats(psasection,cp.s+start)) goto err ; if (!stralloc_0(psasection)) goto err ; } start = pos ; } } stralloc_free(&secname) ; + stralloc_free(&cp) ; return 1 ; - /*invalid: - err = -1 ; - VERBO1 strerr_warnw2x("invalid section: ",secname.s) ; - */err: + err: stralloc_free(&secname) ; - return err ; + stralloc_free(&cp) ; + return 0 ; } -int get_key_range(genalloc *ga, section_t *sasection,char const *file,int *svtype) +int key_get_range(genalloc *ga, section_t *sasection,int *svtype) { int r ; - size_t pos = 0 ; + size_t pos = 0, fakepos = 0 ; uint8_t found = 0 ; stralloc sakey = STRALLOC_ZERO ; stralloc_ref psasection ; key_all_t const *list = total_list ; - parse_mill_t key = { .open = '@', .close = '=', \ - .skip = " \n\t\r", .skiplen = 4, \ - .end = 0, .endlen = 0, \ - .jump = "#", .jumplen = 1,\ - .check = 0, .flush = 1, \ - .forceskip = 1, .force = 1, \ - .inner = PARSE_MILL_INNER_ZERO } ; for (int i = 0 ; i < key_enum_section_el ; i++) { @@ -354,7 +220,10 @@ int get_key_range(genalloc *ga, section_t *sasection,char const *file,int *svtyp nocheck.mandatory = OPTS ; section_setsa(i,&psasection,sasection) ; if (!stralloc_cats(&nocheck.val,psasection->s+1)) goto err ; - if (!parse_env(&nocheck.val,&pos)) { strerr_warnwu2x("parse section: ",get_keybyid(i)) ; goto err ; } + if (!environ_get_clean_env(&nocheck.val)) { VERBO3 strerr_warnwu2x("parse section: ",get_keybyid(i)) ; goto err ; } + if (!stralloc_cats(&nocheck.val,"\n") || + !stralloc_0(&nocheck.val)) goto err ; + nocheck.val.len-- ; if (!genalloc_append(keynocheck,ga,&nocheck)) goto err ; } else @@ -365,14 +234,16 @@ int get_key_range(genalloc *ga, section_t *sasection,char const *file,int *svtyp while (pos < blen) { keynocheck nocheck = KEYNOCHECK_ZERO ; - key.inner.nopen = key.inner.nclose = sakey.len = 0 ; - r = parse_config(&key,file,psasection,&sakey,&pos) ; - if (!r) goto err ; + sakey.len = 0 ; + r = mill_element(&sakey,psasection->s,&MILL_GET_AROBASE_KEY,&pos) ; + if (r == -1) goto err ; + if (!r) break ; //end of string + fakepos = get_rlen_until(psasection->s,'\n',pos) ; + r = mill_element(&sakey,psasection->s,&MILL_GET_COMMENTED_KEY,&fakepos) ; + if (r == -1) goto err ; + if (r) continue ; if (!stralloc_cats(&nocheck.val,psasection->s+pos)) goto err ; if (!stralloc_0(&nocheck.val)) goto err ; - if (!sakey.len) break ;// end of string - stralloc_inserts(&sakey,0,"@") ; - stralloc_0(&sakey) ; for (int j = 0 ; j < total_list_el[i]; j++) { found = 0 ; @@ -386,27 +257,39 @@ int get_key_range(genalloc *ga, section_t *sasection,char const *file,int *svtyp switch(list[i].list[j].expected) { case QUOTE: - r = parse_quote(&nocheck.val,&pos) ; - if (r < 0) + if (!sastr_get_double_quote(&nocheck.val)) { - VERBO3 parse_err(6,nocheck.idsec,nocheck.idkey) ; + VERBO3 parse_err(6,&nocheck) ; goto err ; } - else if (!r) goto err ; + if (!stralloc_0(&nocheck.val)) goto err ; break ; case BRACKET: r = parse_bracket(&nocheck.val,&pos) ; if (r < 0) { - VERBO3 parse_err(6,nocheck.idsec,nocheck.idkey) ; + VERBO3 parse_err(6,&nocheck) ; + goto err ; + } + if (nocheck.val.len == 1) + { + VERBO3 parse_err(9,&nocheck) ; goto err ; } - else if (!r) goto err ; break ; case LINE: case UINT: case SLASH: - if (!parse_line(&nocheck.val,&pos)) goto err ; + if (!parse_line(&nocheck.val,&pos)) + { + VERBO3 parse_err(7,&nocheck) ; + goto err ; + } + if (nocheck.val.len == 1) + { + VERBO3 parse_err(9,&nocheck) ; + goto err ; + } if (!i && !j) (*svtype) = get_enumbyid(nocheck.val.s,key_enum_el) ; break ; default: @@ -645,47 +528,32 @@ int nocheck_toservice(keynocheck *nocheck,int svtype, sv_alltype *service) /********************************** * store * *******************************/ - int keep_common(sv_alltype *service,keynocheck *nocheck,int svtype) { - int r, nbline ; - unsigned int i ; - genalloc gatmp = GENALLOC_ZERO ; - stralloc satmp = STRALLOC_ZERO ; - r = i = 0 ; - + int r = 0 ; + size_t pos = 0, *chlen = &nocheck->val.len ; + char *chval = nocheck->val.s ; + switch(nocheck->idkey){ case TYPE: - r = get_enumbyid(nocheck->val.s,key_enum_el) ; - if (r < 0) - { - VERBO3 parse_err(0,nocheck->idsec,TYPE) ; - return 0 ; - } + r = get_enum(chval,nocheck) ; + if (!r) return 0 ; service->cname.itype = r ; break ; case NAME: service->cname.name = keep.len ; - if (!stralloc_catb(&keep,nocheck->val.s,nocheck->val.len + 1)) retstralloc(0,"parse_common") ; + if (!stralloc_catb(&keep,chval,*chlen + 1)) retstralloc(0,"parse_common") ; break ; case DESCRIPTION: service->cname.description = keep.len ; - if (!stralloc_catb(&keep,nocheck->val.s,nocheck->val.len + 1)) retstralloc(0,"parse_common") ; + if (!stralloc_catb(&keep,chval,*chlen + 1)) retstralloc(0,"parse_common") ; break ; case OPTIONS: - if (!clean_val(&gatmp,nocheck->val.s)) - { - VERBO3 strerr_warnwu2x("parse file ",nocheck->val.s) ; - return 0 ; - } - for (i = 0;i<genalloc_len(stralist,&gatmp);i++) + if (!get_clean_val(nocheck)) return 0 ; + for (;pos < *chlen; pos += strlen(chval + pos)+1) { - r = get_enumbyid(gaistr(&gatmp,i),key_enum_el) ; - if (r < 0) - { - VERBO3 parse_err(0,nocheck->idsec,OPTIONS) ; - return 0 ; - } + r = get_enum(chval + pos,nocheck) ; + if (!r) return 0 ; if (svtype == CLASSIC || svtype == LONGRUN) { if (r == LOGGER) @@ -696,22 +564,13 @@ int keep_common(sv_alltype *service,keynocheck *nocheck,int svtype) if (r == ENVIR) service->opts[2] = 1 ; } - break ; case FLAGS: - if (!clean_val(&gatmp,nocheck->val.s)) + if (!get_clean_val(nocheck)) return 0 ; + for (;pos < *chlen; pos += strlen(chval + pos)+1) { - VERBO3 strerr_warnwu2x("parse file ",nocheck->val.s) ; - return 0 ; - } - for (unsigned int i = 0;i<genalloc_len(stralist,&gatmp);i++) - { - r = get_enumbyid(gaistr(&gatmp,i),key_enum_el) ; - if (r < 0) - { - VERBO3 parse_err(0,nocheck->idsec,FLAGS) ; - return 0 ; - } + r = get_enum(chval + pos,nocheck) ; + if (!r) return 0 ; if (r == DOWN) service->flags[0] = 1 ;/**0 means not enabled*/ if (r == NOSETSID) @@ -719,230 +578,117 @@ int keep_common(sv_alltype *service,keynocheck *nocheck,int svtype) } break ; case USER: - if (!clean_val(&gatmp,nocheck->val.s)) + if (!get_clean_val(nocheck)) return 0 ; { - VERBO3 strerr_warnwu2x("parse file ",nocheck->val.s) ; - return 0 ; - } - /** special case, we don't know which user want to use - * the service, we need a general name to allow all user - * the term "user" is took here to allow the current user*/ - if (stra_cmp(&gatmp,"user")) - { - stra_remove(&gatmp,"user") ; - for (i=0;i<genalloc_len(stralist,&gatmp);i++) + uid_t owner = MYUID ; + if (!owner) { - r = scan_uidlist(gaistr(&gatmp,i),(uid_t *)service->user) ; - if (!r) + if (sastr_find(&nocheck->val,"root") == -1) { - VERBO3 parse_err(0,nocheck->idsec,USER) ; + VERBO3 strerr_warnwu3x("use service: ",keep.s+service->cname.name," -- permission denied") ; return 0 ; } } - uid_t nb = service->user[0] ; - nb++ ; - service->user[0] = nb ; - service->user[nb] = MYUID ; - //search for root permissions - int e = 1 ; - for (int i =1; i < nb; i++) - if (!service->user[i]) e = 0 ; - if ((!MYUID) && (e)) + /** special case, we don't know which user want to use + * the service, we need a general name to allow all user + * the term "user" is took here to allow the current user*/ + ssize_t p = sastr_cmp(&nocheck->val,"user") ; + for (;pos < *chlen; pos += strlen(chval + pos)+1) { - VERBO3 strerr_warnwu3x("use ",keep.s+service->cname.name," service: permission denied") ; - return 0 ; + if (pos == (size_t)p) continue ; + if (!scan_uidlist(chval + pos,(uid_t *)service->user)) + { + VERBO3 parse_err(0,nocheck) ; + return 0 ; + } } - break ; - } - else - if (MYUID > 0) - { - VERBO3 strerr_warnwu3x("use ",keep.s+service->cname.name," service: permission denied") ; - return 0 ; - } - else if (genalloc_len(stralist,&gatmp) > 1) - { - r = scan_uidlist(nocheck->val.s,(uid_t *)service->user) ; - if (!r) + uid_t nb = service->user[0] ; + if (p == -1 && owner) { - VERBO3 parse_err(0,nocheck->idsec,USER) ; - return 0 ; + int e = 0 ; + for (int i = 1; i < nb+1; i++) + if (service->user[i] == owner) e = 1 ; + + if (!e) + { + VERBO3 strerr_warnwu3x("use service: ",keep.s+service->cname.name," -- permission denied") ; + return 0 ; + } } - break ; - } - else - r = scan_uidlist("root",(uid_t *)service->user) ; - if (!r) - { - VERBO3 parse_err(0,nocheck->idsec,USER) ; - return 0 ; } break ; case HIERCOPY: - if (!clean_val(&gatmp,nocheck->val.s)) + if (!get_clean_val(nocheck)) return 0 ; { - VERBO3 strerr_warnwu2x("parse file ",nocheck->val.s) ; - return 0 ; - } - for (i = 0 ; i < genalloc_len(stralist,&gatmp) ; i++) - { - char *name = gaistr(&gatmp,i) ; - size_t namelen = gaistrlen(&gatmp,i) ; - service->hiercopy[i+1] = keep.len ; - if (!stralloc_catb(&keep,name,namelen + 1)) retstralloc(0,"parse_common:hiercopy") ; - service->hiercopy[0] = i+1 ; + unsigned int idx = 0 ; + for (;pos < *chlen; pos += strlen(chval + pos)+1) + { + char *name = chval + pos ; + size_t namelen = strlen(chval + pos) ; + service->hiercopy[idx+1] = keep.len ; + if (!stralloc_catb(&keep,name,namelen + 1)) retstralloc(0,"parse_common:hiercopy") ; + service->hiercopy[0] = ++idx ; + } } break ; case DEPENDS: - if (service->cname.itype == CLASSIC) - { - VERBO3 strerr_warnw3x("key : ",get_keybyid(nocheck->idkey)," : is not valid for type classic") ; - return 0 ; - } - else - if (service->cname.itype == BUNDLE) - { - VERBO3 strerr_warnw3x("key : ",get_keybyid(nocheck->idkey)," : is not valid for type bundle") ; - return 0 ; - } - if (!clean_val(&gatmp,nocheck->val.s)) + if ((service->cname.itype == CLASSIC) || (service->cname.itype == BUNDLE)) { - VERBO3 strerr_warnwu2x("parse file ",nocheck->val.s) ; + VERBO3 strerr_warnw4x("key: ",get_keybyid(nocheck->idkey),": is not valid for type ",get_keybyid(service->cname.itype)) ; return 0 ; } + if (!get_clean_val(nocheck)) return 0 ; service->cname.idga = genalloc_len(unsigned int,&gadeps) ; - for (i = 0;i<genalloc_len(stralist,&gatmp);i++) + for (;pos < *chlen; pos += strlen(chval + pos)+1) { if (!genalloc_append(unsigned int,&gadeps,&deps.len)) retstralloc(0,"parse_common") ; - if (!stralloc_catb(&deps,gaistr(&gatmp,i),gaistrlen(&gatmp,i) + 1)) retstralloc(0,"parse_common") ; + if (!stralloc_catb(&deps,chval + pos,strlen(chval + pos) + 1)) retstralloc(0,"parse_common") ; service->cname.nga++ ; } break ; case CONTENTS: if (service->cname.itype != BUNDLE) { - VERBO3 strerr_warnw4x("key : ",get_keybyid(nocheck->idkey)," : is not valid for type ",get_keybyid(service->cname.itype)) ; - return 0 ; - } - if (!clean_val(&gatmp,nocheck->val.s)) - { - VERBO3 strerr_warnwu2x("parse file ",nocheck->val.s) ; + VERBO3 strerr_warnw4x("key: ",get_keybyid(nocheck->idkey),": is not valid for type ",get_keybyid(service->cname.itype)) ; return 0 ; } + if (!get_clean_val(nocheck)) return 0 ; service->cname.idga = genalloc_len(unsigned int,&gadeps) ; - for (i = 0;i<genalloc_len(stralist,&gatmp);i++) + for (;pos < *chlen; pos += strlen(chval + pos) + 1) { if (!genalloc_append(unsigned int,&gadeps,&deps.len)) retstralloc(0,"parse_common") ; - if (!stralloc_catb(&deps,gaistr(&gatmp,i),gaistrlen(&gatmp,i) + 1)) retstralloc(0,"parse_common") ; + if (!stralloc_catb(&deps,chval + pos,strlen(chval + pos) + 1)) retstralloc(0,"parse_common") ; service->cname.nga++ ; } break ; - case NOTIFY: - if (!clean_val(&gatmp,nocheck->val.s)) - { - VERBO3 strerr_warnwu2x("parse file ",nocheck->val.s) ; - return 0 ; - } - if (!scan_uint32(gastr(&gatmp))) - { - VERBO3 parse_err(3,nocheck->idsec,NOTIFY) ; - return 0 ; - } - if (!uint32_scan(gastr(&gatmp),&service->notification)) - { - VERBO3 parse_err(3,nocheck->idsec,NOTIFY) ; - return 0 ; - } - break ; case T_KILL: - r = scan_timeout(nocheck->val.s,(uint32_t *)service->timeout,0) ; - if (r < 0) - { - VERBO3 parse_err(3,nocheck->idsec,T_KILL) ; - return 0 ; - } - break ; case T_FINISH: - r = scan_timeout(nocheck->val.s,(uint32_t *)service->timeout,1) ; - if (r < 0) - { - VERBO3 parse_err(3,nocheck->idsec,T_FINISH) ; - return 0 ; - } - break ; case T_UP: - r = scan_timeout(nocheck->val.s,(uint32_t *)service->timeout,2) ; - if (r < 0) - { - VERBO3 parse_err(3,nocheck->idsec,T_UP) ; - return 0 ; - } - break ; case T_DOWN: - r = scan_timeout(nocheck->val.s,(uint32_t *)service->timeout,3) ; - if (r < 0) - { - VERBO3 parse_err(3,nocheck->idsec,T_DOWN) ; - return 0 ; - } + if (!get_timeout(nocheck,(uint32_t *)service->timeout)) return 0 ; break ; case DEATH: - if (!clean_val(&gatmp,nocheck->val.s)) - { - VERBO3 strerr_warnwu2x("parse file ",nocheck->val.s) ; - return 0 ; - } - if (!scan_uint32(gastr(&gatmp))) + if (!get_uint(nocheck,&service->death)) return 0 ; + break ; + case NOTIFY: + if (!get_uint(nocheck,&service->notification)) return 0 ; + break ; + case ENVAL: + if (!environ_clean_nline(&nocheck->val)) { - VERBO3 parse_err(3,nocheck->idsec,DEATH) ; + VERBO3 strerr_warnwu2x("clean environment value: ",chval) ; return 0 ; } - if (!uint32_scan(gastr(&gatmp),&service->death)) + if (!stralloc_copy(&service->saenv,&nocheck->val)) { - VERBO3 parse_err(3,nocheck->idsec,DEATH) ; + VERBO3 strerr_warnwu2x("store environment value: ",chval) ; return 0 ; } break ; - case ENVAL: - nbline = get_nbline_ga(nocheck->val.s,nocheck->val.len,&gatmp) ; - for (i = 0;i < nbline;i++) - { - satmp.len = 0 ; - if (!stralloc_cats(&satmp,gaistr(&gatmp,i)) || - !stralloc_0(&satmp)) - { - VERBO3 strerr_warnwu2x("append environment value: ",gaistr(&gatmp,i)) ; - stralloc_free(&satmp) ; - return 0 ; - } - r = env_clean(&satmp) ; - if (r > 0) - { - if (!stralloc_cats(&service->saenv,satmp.s) || - !stralloc_cats(&service->saenv,"\n")) - { - VERBO3 strerr_warnwu2x("store environment value: ",gaistr(&gatmp,i)) ; - stralloc_free(&satmp) ; - return 0 ; - } - } - else if (!r) - { - VERBO3 strerr_warnwu2x("clean environment value: ",gaistr(&gatmp,i)) ; - stralloc_free(&satmp) ; - return 0 ; - } - } - break ; case SIGNAL: - if (!clean_val(&gatmp,nocheck->val.s)) - { - VERBO3 strerr_warnwu2x("parse file ",nocheck->val.s) ; - return 0 ; - } - if (!sig0_scan(gastr(&gatmp), &service->signal)) + if (!sig0_scan(chval,&service->signal)) { - VERBO3 parse_err(3,nocheck->idsec,SIGNAL) ; + VERBO3 parse_err(3,nocheck) ; return 0 ; } break ; @@ -951,65 +697,55 @@ int keep_common(sv_alltype *service,keynocheck *nocheck,int svtype) return 0 ; } - genalloc_deepfree(stralist,&gatmp,stra_free) ; - stralloc_free(&satmp) ; return 1 ; } int keep_runfinish(sv_exec *exec,keynocheck *nocheck) { - int r ; + int r = 0 ; + size_t *chlen = &nocheck->val.len ; + char *chval = nocheck->val.s ; - genalloc gatmp = GENALLOC_ZERO ; - - switch(nocheck->idkey){ + switch(nocheck->idkey) + { case BUILD: - r = get_enumbyid(nocheck->val.s,key_enum_el) ; - if (r < 0) - { - VERBO3 parse_err(0,nocheck->idsec,BUILD) ; - return 0 ; - } + r = get_enum(chval,nocheck) ; + if (!r) return 0 ; exec->build = r ; break ; case RUNAS: - r = scan_uid(nocheck->val.s,&exec->runas) ; + r = scan_uid(chval,&exec->runas) ; if (!r) { - VERBO3 parse_err(0,nocheck->idsec,RUNAS) ; + VERBO3 parse_err(0,nocheck) ; return 0 ; } break ; case SHEBANG: - r = dir_scan_absopath(nocheck->val.s) ; - if (r < 0) + if (chval[0] != '/') { - VERBO3 parse_err(4,nocheck->idsec,SHEBANG) ; + VERBO3 parse_err(4,nocheck) ; return 0 ; } exec->shebang = keep.len ; - if (!stralloc_catb(&keep,nocheck->val.s,nocheck->val.len + 1)) exitstralloc("parse_runfinish:stralloc:SHEBANG") ; + if (!stralloc_catb(&keep,chval,*chlen + 1)) exitstralloc("parse_runfinish:stralloc:SHEBANG") ; break ; case EXEC: exec->exec = keep.len ; - if (!stralloc_catb(&keep,nocheck->val.s,nocheck->val.len + 1)) exitstralloc("parse_runfinish:stralloc:EXEC") ; - + if (!stralloc_catb(&keep,chval,*chlen + 1)) exitstralloc("parse_runfinish:stralloc:EXEC") ; break ; default: VERBO3 strerr_warnw2x("unknown key: ",get_keybyid(nocheck->idkey)) ; return 0 ; - } - - genalloc_deepfree(stralist,&gatmp,stra_free) ; - + } return 1 ; } int keep_logger(sv_execlog *log,keynocheck *nocheck) { - int r, i ; - - genalloc gatmp = GENALLOC_ZERO ; + int r ; + size_t pos = 0, *chlen = &nocheck->val.len ; + char *chval = nocheck->val.s ; switch(nocheck->idkey){ case BUILD: @@ -1019,16 +755,12 @@ int keep_logger(sv_execlog *log,keynocheck *nocheck) if (!keep_runfinish(&log->run,nocheck)) return 0 ; break ; case DEPENDS: - if (!clean_val(&gatmp,nocheck->val.s)) - { - VERBO3 strerr_warnwu2x("parse file ",nocheck->val.s) ; - return 0 ; - } + if (!get_clean_val(nocheck)) return 0 ; log->idga = genalloc_len(unsigned int,&gadeps) ; - for (i = 0;i<genalloc_len(stralist,&gatmp);i++) + for (;pos < *chlen; pos += strlen(chval + pos) + 1) { if (!genalloc_append(unsigned int,&gadeps,&deps.len)) retstralloc(0,"parse_logger") ; - if (!stralloc_catb(&deps,gaistr(&gatmp,i),gaistrlen(&gatmp,i) + 1)) retstralloc(0,"parse_logger") ; + if (!stralloc_catb(&deps,chval + pos,strlen(chval + pos) + 1)) retstralloc(0,"parse_logger") ; log->nga++ ; } break ; @@ -1039,64 +771,33 @@ int keep_logger(sv_execlog *log,keynocheck *nocheck) if (!keep_runfinish(&log->run,nocheck)) return 0 ; break ; case T_KILL: - r = scan_timeout(nocheck->val.s,(uint32_t *)log->timeout,0) ; - if (r < 0) parse_err(3,nocheck->idsec,T_KILL) ; - break ; case T_FINISH: - r = scan_timeout(nocheck->val.s,(uint32_t *)log->timeout,1) ; - if (r < 0) - { - VERBO3 parse_err(3,nocheck->idsec,T_FINISH) ; - return 0 ; - } + if (!get_timeout(nocheck,(uint32_t *)log->timeout)) return 0 ; break ; case DESTINATION: - r = dir_scan_absopath(nocheck->val.s) ; - if (r < 0) + if (chval[0] != '/') { - VERBO3 parse_err(4,nocheck->idsec,DESTINATION) ; + VERBO3 parse_err(4,nocheck) ; return 0 ; } log->destination = keep.len ; - if (!stralloc_catb(&keep,nocheck->val.s,nocheck->val.len + 1)) retstralloc(0,"parse_logger") ; + if (!stralloc_catb(&keep,chval,*chlen + 1)) retstralloc(0,"parse_logger") ; break ; case BACKUP: - if (!clean_val(&gatmp,nocheck->val.s)) - { - VERBO3 strerr_warnwu2x("parse file ",nocheck->val.s) ; - return 0 ; - } - if (!scan_uint32(gastr(&gatmp))) - { - VERBO3 parse_err(3,nocheck->idsec,BACKUP) ; - return 0 ; - } - uint_scan(gastr(&gatmp),&log->backup) ; + if (!get_uint(nocheck,&log->backup)) return 0 ; break ; case MAXSIZE: - if (!scan_uint32(nocheck->val.s)) - { - VERBO3 parse_err(3,nocheck->idsec,MAXSIZE) ; - return 0 ; - } - uint_scan(nocheck->val.s,&log->maxsize) ; + if (!get_uint(nocheck,&log->maxsize)) return 0 ; break ; case TIMESTP: - r = get_enumbyid (nocheck->val.s,key_enum_el) ; - if (r < 0) - { - VERBO3 parse_err(0,nocheck->idsec,TIMESTP) ; - return 0 ; - } + r = get_enum(chval,nocheck) ; + if (!r) return 0 ; log->timestamp = r ; break ; default: VERBO3 strerr_warnw2x("unknown key: ",get_keybyid(nocheck->idkey)) ; return 0 ; } - - genalloc_deepfree (stralist,&gatmp,stra_free) ; - return 1 ; } @@ -1138,14 +839,57 @@ int read_svfile(stralloc *sasv,char const *name,char const *src) return 1 ; } -ssize_t get_sep_before (char const *line, char const sepstart, char const sepend) +int add_pipe(sv_alltype *sv, stralloc *sa) { - size_t linend, linesep ; - linesep=get_len_until(line,sepstart) ; - linend=get_len_until(line,sepend) ; - if (linesep > linend) return -1 ; - if (!linend) return 0 ; - return linesep ; + char *prodname = keep.s+sv->cname.name ; + + stralloc tmp = STRALLOC_ZERO ; + + sv->pipeline = sa->len ; + if (!stralloc_cats(&tmp,SS_PIPE_NAME)) retstralloc(0,"add_pipe") ; + if (!stralloc_cats(&tmp,prodname)) retstralloc(0,"add_pipe") ; + if (!stralloc_0(&tmp)) retstralloc(0,"add_pipe") ; + + if (!stralloc_catb(sa,tmp.s,tmp.len+1)) retstralloc(0,"add_pipe") ; + + stralloc_free(&tmp) ; + + return 1 ; +} + +int parse_line(stralloc *sa, size_t *pos) +{ + if (!sa->len) return 0 ; + int r = 0 ; + size_t newpos = 0 ; + stralloc kp = STRALLOC_ZERO ; + wild_zero_all(&MILL_CLEAN_LINE) ; + r = mill_element(&kp,sa->s,&MILL_CLEAN_LINE,&newpos) ; + if (r == -1 || !r) goto err ; + if (!stralloc_0(&kp)) goto err ; + if (!stralloc_copy(sa,&kp)) goto err ; + *pos += newpos - 1 ; + stralloc_free(&kp) ; + return 1 ; + err: + stralloc_free(&kp) ; + return 0 ; +} + +int parse_bracket(stralloc *sa,size_t *pos) +{ + if (!sa->len) return 0 ; + size_t newpos = 0 ; + stralloc kp = STRALLOC_ZERO ; + if (!key_get_next_id(&kp,sa->s,&newpos)) goto err ; + if (!stralloc_0(&kp)) goto err ; + if (!stralloc_copy(sa,&kp)) goto err ; + *pos += newpos ; + stralloc_free(&kp) ; + return 1 ; + err: + stralloc_free(&kp) ; + return 0 ; } void section_setsa(int id, stralloc_ref *p,section_t *sa) @@ -1161,147 +905,161 @@ void section_setsa(int id, stralloc_ref *p,section_t *sa) } } -int section_skip(char const *s,size_t pos,int nline) +int section_get_skip(char const *s,size_t pos,int nline) { ssize_t r = -1 ; if (nline == 1) { - r = get_sep_before(s,'#','\n') ; + r = get_sep_before(s,'#','[') ; if (r >= 0) return 0 ; } r = get_rlen_until(s,'\n',pos) ; if (r >= 0) { - r = get_sep_before(s+r+1,'#','\n') ; + r = get_sep_before(s+r+1,'#','[') ; if (r >= 0) return 0 ; } return 1 ; } -/*@Return 1 on success - * @Return 0 on fail - * @Return -1 on invalid section */ -int section_valid(int id, uint32_t nline, size_t pos,stralloc *src, char const *file) +int section_get_id(stralloc *secname, char const *string,size_t *pos,int *id) { - int r, rn, found = 0, err = 0 ; - size_t tpos = 0 ; - stralloc tmp = STRALLOC_ZERO ; - stralloc fake = STRALLOC_ZERO ; - key_all_t const *list = total_list ; - parse_mill_t key = { .open = '@', .close = '=', \ - .skip = " \n\t\r", .skiplen = 4, \ - .end = 0, .endlen = 0, \ - .jump = 0, .jumplen = 0,\ - .check = 0, .flush = 0, \ - .forceskip = 1, .force = 1, \ - .inner = PARSE_MILL_INNER_ZERO } ; - - - /* keys like execute can contain '[]' regex character, - * check it and ignore the regex if it's the case*/ - r = get_rlen_until(src->s,'\n',pos) ; - /*we are on first line?*/ - if (r < 0 && nline > 1) goto err ; - else if (nline == 1) goto freed ; - r++; - rn = get_sep_before(src->s+r,'@','\n') ; - if (rn < 0) goto invalid ; - if (!stralloc_cats(&tmp,src->s+r)) goto err ; - if (!stralloc_0(&tmp)) goto err ; - if (!parse_config(&key,file,&tmp,&fake,&tpos)) goto err ; - if (!fake.len) goto err ; - stralloc_inserts(&fake,0,"@") ; - stralloc_0(&fake) ; - for (int i = 0 ; i < key_enum_section_el; i++) + size_t len = strlen(string) ; + size_t newpos = 0 ; + (*id) = -1 ; + + while ((*id) < 0 && (*pos) < len) { - for (int j = 0 ; j < total_list_el[i]; j++) + secname->len = 0 ; + newpos = 0 ; + if (mill_element(secname,string+(*pos),&MILL_GET_SECTION_NAME,&newpos) == -1) return 0 ; + if (secname->len) { - if (list[i].list[j].name && obstr_equal(fake.s,list[i].list[j].name)) - { found = 1 ; break ; } + if (!stralloc_0(secname)) return 0 ; + (*id) = get_enumbyid(secname->s,key_enum_section_el) ; } + (*pos) += newpos ; } - if (!found) goto invalid ; - freed: - stralloc_free(&tmp) ; - stralloc_free(&fake) ; - return 1 ; - invalid: - err = -1 ; - err: - stralloc_free(&tmp) ; - stralloc_free(&fake) ; - return err ; + return 1 ; } -int clean_value(stralloc *sa) +int key_get_next_id(stralloc *sa, char const *string,size_t *pos) { - size_t pos = 0 ; - char const *file = "clean_value" ; - stralloc tmp = STRALLOC_ZERO ; - parse_mill_t empty = { .open = '@', .close = ' ', \ - .skip = " \n\t\r", .skiplen = 4, \ - .end = 0, .endlen = 0, \ - .jump = 0, .jumplen = 0,\ - .check = 0, .flush = 0, \ - .forceskip = 1, .force = 1, \ - .inner = PARSE_MILL_INNER_ZERO } ; - if (!stralloc_inserts(sa,0,"@")) goto err ; - if (!stralloc_cats(sa," ")) goto err ; - if (!parse_config(&empty,file,sa,&tmp,&pos)) goto err ; - if (!stralloc_0(&tmp)) goto err ; - if (!stralloc_copy(sa,&tmp)) goto err ; - stralloc_free(&tmp) ; + if (!string) return 0 ; + int r = 0 ; + size_t newpos = 0, len = strlen(string) ; + stralloc kp = STRALLOC_ZERO ; + wild_zero_all(&MILL_GET_AROBASE_KEY) ; + wild_zero_all(&MILL_FIRST_BRACKET) ; + int id = -1 ; + r = mill_element(&kp,string,&MILL_FIRST_BRACKET,&newpos) ; + if (r == -1 || !r) goto err ; + *pos = newpos ; + while (id == -1 && newpos < len) + { + kp.len = 0 ; + r = mill_element(&kp,string,&MILL_GET_AROBASE_KEY,&newpos) ; + if (r == -1) goto err ; + if (!stralloc_0(&kp)) goto err ; + id = get_enumbyid(kp.s,key_enum_el) ; + } + newpos = get_rlen_until(string,')',newpos) ; + if (newpos == -1) goto err ; + stralloc_catb(sa,string+*pos,newpos - *pos) ; + *pos = newpos + 1 ; //+1 remove the last ')' + stralloc_free(&kp) ; return 1 ; err: - stralloc_free(&tmp) ; + stralloc_free(&kp) ; return 0 ; } -void parse_err(int ierr,int idsec,int idkey) +int get_clean_val(keynocheck *ch) { + if (!sastr_clean_element(&ch->val) || + !stralloc_0(&ch->val) || + !sastr_split_element_in_nline(&ch->val)) + { + VERBO3 parse_err(8,ch) ; + return 0 ; + } + return 1 ; +} + +int get_enum(char const *string, keynocheck *ch) +{ + int r = get_enumbyid(string,key_enum_el) ; + if (r == -1) + { + VERBO3 parse_err(0,ch) ; + return 0 ; + } + return r ; +} + +int get_timeout(keynocheck *ch,uint32_t *ui) +{ + int time = 0 ; + if (ch->idkey == T_KILL) time = 0 ; + else if (ch->idkey == T_FINISH) time = 1 ; + else if (ch->idkey == T_UP) time = 2 ; + else if (ch->idkey == T_DOWN) time = 3 ; + if (scan_timeout(ch->val.s,ui,time) == -1) + { + VERBO3 parse_err(3,ch) ; + return 0 ; + } + return 1 ; +} + +int get_uint(keynocheck *ch,uint32_t *ui) +{ + if (!uint32_scan(ch->val.s,ui)) + { + VERBO3 parse_err(3,ch) ; + return 0 ; + } + return 1 ; +} + +void parse_err(int ierr,keynocheck *check) +{ + int idsec = check->idsec ; + int idkey = check->idkey ; switch(ierr) { case 0: - strerr_warnw4x("invalid value for key: ",get_keybyid(idkey)," in section: ",get_keybyid(idsec)) ; + strerr_warnw4x("invalid value for key: ",get_keybyid(idkey),": in section: ",get_keybyid(idsec)) ; break ; case 1: - strerr_warnw4x("multiple definition of key: ",get_keybyid(idkey)," in section: ",get_keybyid(idsec)) ; + strerr_warnw4x("multiple definition of key: ",get_keybyid(idkey),": in section: ",get_keybyid(idsec)) ; break ; case 2: - strerr_warnw4x("same value for key: ",get_keybyid(idkey)," in section: ",get_keybyid(idsec)) ; + strerr_warnw4x("same value for key: ",get_keybyid(idkey),": in section: ",get_keybyid(idsec)) ; break ; case 3: - strerr_warnw4x("key: ",get_keybyid(idkey)," must be an integrer value in section: ",get_keybyid(idsec)) ; + strerr_warnw4x("key: ",get_keybyid(idkey),": must be an integrer value in section: ",get_keybyid(idsec)) ; break ; case 4: - strerr_warnw4x("key: ",get_keybyid(idkey)," must be an absolute path in section: ",get_keybyid(idsec)) ; + strerr_warnw4x("key: ",get_keybyid(idkey),": must be an absolute path in section: ",get_keybyid(idsec)) ; break ; case 5: - strerr_warnw4x("key: ",get_keybyid(idkey)," must be set in section: ",get_keybyid(idsec)) ; + strerr_warnw4x("key: ",get_keybyid(idkey),": must be set in section: ",get_keybyid(idsec)) ; break ; case 6: - strerr_warnw4x("invalid format of key: ",get_keybyid(idkey)," in section: ",get_keybyid(idsec)) ; + strerr_warnw4x("invalid format of key: ",get_keybyid(idkey),": in section: ",get_keybyid(idsec)) ; + break ; + case 7: + strerr_warnwu4x("parse key: ",get_keybyid(idkey),": in section: ",get_keybyid(idsec)) ; + break ; + case 8: + strerr_warnwu4x("clean value of key: ",get_keybyid(idkey),": in section: ",get_keybyid(idsec)) ; + break ; + case 9: + strerr_warnw4x("empty value of key: ",get_keybyid(idkey),": in section: ",get_keybyid(idsec)) ; break ; default: strerr_warnw1x("unknown parse_err number") ; break ; } } - -int add_pipe(sv_alltype *sv, stralloc *sa) -{ - char *prodname = keep.s+sv->cname.name ; - - stralloc tmp = STRALLOC_ZERO ; - - sv->pipeline = sa->len ; - if (!stralloc_cats(&tmp,SS_PIPE_NAME)) retstralloc(0,"add_pipe") ; - if (!stralloc_cats(&tmp,prodname)) retstralloc(0,"add_pipe") ; - if (!stralloc_0(&tmp)) retstralloc(0,"add_pipe") ; - - if (!stralloc_catb(sa,tmp.s,tmp.len+1)) retstralloc(0,"add_pipe") ; - - stralloc_free(&tmp) ; - - return 1 ; -} -- GitLab