X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Flib%2Flistparser.hc;h=4c5769af611b6c67853ec79b03fb71db6ac97910;hb=96448e268dbe81573fd4afc6fccbdd63f0bc6580;hp=2895be5e58ef5cfedfa1c930a8f536a069d94929;hpb=4df0e41e254d190fdbc8290ee38bfd31bd4342e8;p=util-vserver.git diff --git a/util-vserver/lib/listparser.hc b/util-vserver/lib/listparser.hc index 2895be5..4c5769a 100644 --- a/util-vserver/lib/listparser.hc +++ b/util-vserver/lib/listparser.hc @@ -22,8 +22,23 @@ #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,TYPE *res, char end_chr) \ + { \ + char *err_ptr; \ + *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 +49,32 @@ { \ if (len==0) len = strlen(str); \ for (;len>0;) { \ - char const *ptr = strchr(str, ','); \ - size_t cnt = ptr ? (size_t)(ptr-str) : len; \ + char const *ptr = strchr(str, ','); \ + size_t cnt; \ TYPE tmp; \ bool is_neg; \ \ - is_neg = len>1 && (*str=='!' || *str=='~'); \ + is_neg = *str=='!' || *str=='~'; \ if (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) \ + tmp = 0; \ + else if (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); \ \ if (tmp!=0) { \ - if (!is_neg) *flag |= tmp; \ + if (!is_neg) *flag |= tmp; \ + else *flag &= ~tmp; \ *mask |= tmp; \ } \ else { \