X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Flib%2Flistparser.hc;h=bc35153122fa06c59f8604762d51f79d83caadf5;hb=3eb1b2279739d0f16391a3724a9897c686f030d3;hp=2895be5e58ef5cfedfa1c930a8f536a069d94929;hpb=4df0e41e254d190fdbc8290ee38bfd31bd4342e8;p=util-vserver.git diff --git a/util-vserver/lib/listparser.hc b/util-vserver/lib/listparser.hc index 2895be5..bc35153 100644 --- a/util-vserver/lib/listparser.hc +++ b/util-vserver/lib/listparser.hc @@ -22,8 +22,28 @@ #include #include +#include + +#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,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; \ + } + #define LISTPARSER(TYPE,SHORT) \ + ISNUMBER(TYPE,SHORT) \ int \ utilvserver_listparser_ ## SHORT(char const *str, size_t len, \ char const **err_ptr, \ @@ -34,24 +54,36 @@ { \ if (len==0) len = strlen(str); \ for (;len>0;) { \ - char const *ptr = strchr(str, ','); \ - size_t cnt = ptr ? (size_t)(ptr-str) : len; \ - TYPE tmp; \ - bool is_neg; \ - \ - is_neg = len>1 && (*str=='!' || *str=='~'); \ - if (is_neg) { \ + char const *ptr = strchr(str, ','); \ + size_t cnt; \ + TYPE tmp = 0; \ + bool is_neg = false; \ + bool allow_zero = true; \ + \ + while (len>0 && (*str=='!' || *str=='~')) { \ + is_neg = !is_neg; \ ++str; \ --len; \ } \ - \ + \ + cnt = ptr ? (size_t)(ptr-str) : len; \ if (cnt>=len) { cnt=len; len=0; } \ else len-=(cnt+1); \ \ - tmp = (*func)(str,cnt); \ + if (cnt==0) \ + allow_zero = false; \ + else if (strncasecmp(str,"all",cnt)==0 || \ + strncasecmp(str,"any",cnt)==0) \ + tmp = ~(TYPE)(0); \ + else if (strncasecmp(str,"none",cnt)==0) {} \ + else if (!isNumber_##SHORT(&str, &cnt, &tmp, str[cnt])) { \ + tmp = (*func)(str,cnt); \ + allow_zero = false; \ + } \ \ - if (tmp!=0) { \ - if (!is_neg) *flag |= tmp; \ + if (tmp!=0 || allow_zero) { \ + if (!is_neg) *flag |= tmp; \ + else *flag &= ~tmp; \ *mask |= tmp; \ } \ else { \