vshost-util-vserver

Build script and sources for util-vserver.
git clone https://ccx.te2000.cz/git/vshost-util-vserver
Log | Files | Refs

listparser.hc (3212B)


      1 // $Id$    --*- c -*--
      2 
      3 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
      4 //  
      5 // This program is free software; you can redistribute it and/or modify
      6 // it under the terms of the GNU General Public License as published by
      7 // the Free Software Foundation; version 2 of the License.
      8 //  
      9 // This program is distributed in the hope that it will be useful,
     10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 // GNU General Public License for more details.
     13 //  
     14 // You should have received a copy of the GNU General Public License
     15 // along with this program; if not, write to the Free Software
     16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     17 
     18 
     19 #ifdef HAVE_CONFIG_H
     20 #  include <config.h>
     21 #endif
     22 
     23 #include <stdlib.h>
     24 #include <string.h>
     25 #include <strings.h>
     26 
     27 #define TONUMBER_uint64(S,E,B)		strtoll(S,E,B)
     28 #define TONUMBER_uint32(S,E,B)		strtol (S,E,B)
     29 
     30 #define ISNUMBER(TYPE,SHORT)						\
     31   static inline ALWAYSINLINE bool					\
     32   isNumber_##SHORT(char const **str,size_t *len,TYPE *res,char end_chr) \
     33   {									\
     34     char	*err_ptr;						\
     35     if (**str=='^') {							\
     36       *res = ((TYPE)(1)) << TONUMBER_##SHORT(++*str, &err_ptr, 0);	\
     37       if (len) --*len;							\
     38     }									\
     39     else								\
     40       *res = TONUMBER_##SHORT(*str, &err_ptr, 0);			\
     41     return err_ptr>*str && *err_ptr==end_chr;				\
     42   }
     43 
     44 
     45 #define LISTPARSER(TYPE,SHORT)						\
     46   ISNUMBER(TYPE,SHORT)							\
     47   int									\
     48   utilvserver_listparser_ ## SHORT(char const *str, size_t len,		\
     49 				   char const **err_ptr,		\
     50 				   size_t *err_len,			\
     51 				   TYPE * const flag,			\
     52 				   TYPE * const mask,			\
     53 				   TYPE (*func)(char const *,		\
     54 						size_t, bool *))	\
     55   {									\
     56     if (len==0) len = strlen(str);					\
     57     for (;len>0;) {							\
     58       char const	*ptr = strchr(str, ',');			\
     59       size_t		cnt;						\
     60       TYPE		tmp = 0;					\
     61       bool		is_neg     = false;				\
     62       bool		failed     = false;				\
     63       									\
     64       while (mask!=0 && len>0 && (*str=='!' || *str=='~')) {		\
     65 	is_neg = !is_neg;						\
     66 	++str;								\
     67 	--len;								\
     68       }									\
     69       									\
     70       cnt = ptr ? (size_t)(ptr-str) : len;				\
     71       if (cnt>=len) { cnt=len; len=0; }					\
     72       else len-=(cnt+1);						\
     73 									\
     74       if (cnt==0) 							\
     75 	failed = true;							\
     76       else if (mask!=0 &&						\
     77 	       (strncasecmp(str,"all",cnt)==0 ||			\
     78 		strncasecmp(str,"any",cnt)==0))				\
     79 	tmp = ~(TYPE)(0);						\
     80       else if (mask!=0 && strncasecmp(str,"none",cnt)==0) {}		\
     81       else if (!isNumber_##SHORT(&str, &cnt, &tmp, str[cnt]))		\
     82 	tmp = (*func)(str,cnt, &failed);				\
     83 									\
     84       if (!failed) {							\
     85 	if (!is_neg) *flag |=  tmp;					\
     86 	else         *flag &= ~tmp;					\
     87 	if (mask!=0) *mask |=  tmp;					\
     88       }									\
     89       else {								\
     90 	if (err_ptr) *err_ptr = str;					\
     91 	if (err_len) *err_len = cnt;					\
     92 	return -1;							\
     93       }									\
     94 									\
     95       if (ptr==0) break;						\
     96       str = ptr+1;							\
     97     }									\
     98 									\
     99     if (err_ptr) *err_ptr = 0;						\
    100     if (err_len) *err_len = 0;						\
    101     return 0;								\
    102   }