X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Flib%2Flistparser.hc;h=3cf6cb9704a43be97df81fc22d988bdfe4ada1cf;hb=539a5f71aff885c7f54046ce8c13a56b15c01886;hp=4c5769af611b6c67853ec79b03fb71db6ac97910;hpb=9215c73e89c692ee2ce9abafe644d1a5b144e320;p=util-vserver.git diff --git a/util-vserver/lib/listparser.hc b/util-vserver/lib/listparser.hc index 4c5769a..3cf6cb9 100644 --- a/util-vserver/lib/listparser.hc +++ b/util-vserver/lib/listparser.hc @@ -27,13 +27,18 @@ #define TONUMBER_uint64(S,E,B) strtoll(S,E,B) #define TONUMBER_uint32(S,E,B) strtol (S,E,B) -#define ISNUMBER(TYPE,SHORT) \ - static inline ALWAYSINLINE bool \ - isNumber_##SHORT(char const *str,TYPE *res, char end_chr) \ - { \ - char *err_ptr; \ - *res = TONUMBER_##SHORT(str, &err_ptr, 0); \ - return err_ptr>str && *err_ptr==end_chr; \ +#define ISNUMBER(TYPE,SHORT) \ + static inline ALWAYSINLINE bool \ + isNumber_##SHORT(char const **str,size_t *len,TYPE *res,char end_chr) \ + { \ + char *err_ptr; \ + if (**str=='^') { \ + *res = ((TYPE)(1)) << TONUMBER_##SHORT(++*str, &err_ptr, 0); \ + if (len) --*len; \ + } \ + else \ + *res = TONUMBER_##SHORT(*str, &err_ptr, 0); \ + return err_ptr>*str && *err_ptr==end_chr; \ } @@ -43,19 +48,21 @@ utilvserver_listparser_ ## SHORT(char const *str, size_t len, \ char const **err_ptr, \ size_t *err_len, \ - TYPE *flag, \ - TYPE *mask, \ - TYPE (*func)(char const *, size_t)) \ + TYPE * const flag, \ + TYPE * const mask, \ + TYPE (*func)(char const *, \ + size_t, bool *)) \ { \ if (len==0) len = strlen(str); \ for (;len>0;) { \ char const *ptr = strchr(str, ','); \ size_t cnt; \ - TYPE tmp; \ - bool is_neg; \ - \ - is_neg = *str=='!' || *str=='~'; \ - if (is_neg) { \ + TYPE tmp = 0; \ + bool is_neg = false; \ + bool failed = false; \ + \ + while (mask!=0 && len>0 && (*str=='!' || *str=='~')) { \ + is_neg = !is_neg; \ ++str; \ --len; \ } \ @@ -64,18 +71,20 @@ if (cnt>=len) { cnt=len; len=0; } \ else len-=(cnt+1); \ \ - if (cnt==0) \ - tmp = 0; \ - else if (strncasecmp(str,"all",cnt)==0 || \ - strncasecmp(str,"any",cnt)==0) \ + if (cnt==0) \ + failed = true; \ + else if (mask!=0 && \ + (strncasecmp(str,"all",cnt)==0 || \ + strncasecmp(str,"any",cnt)==0)) \ tmp = ~(TYPE)(0); \ - else if (!isNumber_##SHORT(str, &tmp, str[cnt])) \ - tmp = (*func)(str,cnt); \ + else if (mask!=0 && strncasecmp(str,"none",cnt)==0) {} \ + else if (!isNumber_##SHORT(&str, &cnt, &tmp, str[cnt])) \ + tmp = (*func)(str,cnt, &failed); \ \ - if (tmp!=0) { \ + if (!failed) { \ if (!is_neg) *flag |= tmp; \ else *flag &= ~tmp; \ - *mask |= tmp; \ + if (mask!=0) *mask |= tmp; \ } \ else { \ if (err_ptr) *err_ptr = str; \