initial checkin
[util-vserver.git] / util-vserver / lib / listparser.hc
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
26 #define LISTPARSER(TYPE,SHORT)                                          \
27   int                                                                   \
28   utilvserver_listparser_ ## SHORT(char const *str, size_t len,         \
29                                    char const **err_ptr,                \
30                                    size_t *err_len,                     \
31                                    TYPE *flag,                          \
32                                    TYPE *mask,                          \
33                                    TYPE (*func)(char const *, size_t))  \
34   {                                                                     \
35     if (len==0) len = strlen(str);                                      \
36     for (;len>0;) {                                                     \
37       char const                *ptr = strchr(str, ',');                \
38       size_t            cnt  = ptr ? (size_t)(ptr-str) : len;           \
39       TYPE              tmp;                                            \
40       bool              is_neg;                                         \
41                                                                         \
42       is_neg = len>1 && (*str=='!' || *str=='~');                       \
43       if (is_neg) {                                                     \
44         ++str;                                                          \
45         --len;                                                          \
46       }                                                                 \
47                                                                         \
48       if (cnt>=len) { cnt=len; len=0; }                                 \
49       else len-=(cnt+1);                                                \
50                                                                         \
51       tmp = (*func)(str,cnt);                                           \
52                                                                         \
53       if (tmp!=0) {                                                     \
54         if (!is_neg) *flag |= tmp;                                      \
55         *mask |= tmp;                                                   \
56       }                                                                 \
57       else {                                                            \
58         if (err_ptr) *err_ptr = str;                                    \
59         if (err_len) *err_len = cnt;                                    \
60         return -1;                                                      \
61       }                                                                 \
62                                                                         \
63       if (ptr==0) break;                                                \
64       str = ptr+1;                                                      \
65     }                                                                   \
66                                                                         \
67     if (err_ptr) *err_ptr = 0;                                          \
68     if (err_len) *err_len = 0;                                          \
69     return 0;                                                           \
70   }