2 * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the author nor the names of any co-contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 #define CS_WAITVALUE 3
46 #define CS_WAITDELIM 6
51 nstrdup(char *ptr, int len) {
52 char *res = tmalloc(len + 1),
55 memcpy(res, ptr, len);
71 parse_hmap(char *in, HMap ** m) {
76 int state = CS_WAITKEY;
85 *m = mptr = (HMap *) t0malloc(sizeof(HMap) * (num + 2));
88 if (state == CS_WAITKEY) {
89 if (isalpha((unsigned char) *ptr)) {
92 } else if (!isspace((unsigned char) *ptr))
93 tlog(TL_ALARM|TL_EXIT,"parse_hmap: Syntax error in position %d near \"%c\"\n", (int) (ptr - in), *ptr);
94 } else if (state == CS_INKEY) {
95 if (isspace((unsigned char) *ptr)) {
96 mptr->key = nstrdup(begin, ptr - begin);
98 } else if (*ptr == '=') {
99 mptr->key = nstrdup(begin, ptr - begin);
100 state = CS_WAITVALUE;
101 } else if (!isalpha((unsigned char) *ptr))
102 tlog(TL_ALARM|TL_EXIT,"parse_hmap: Syntax error in position %d near \"%c\"\n", (int) (ptr - in), *ptr);
103 } else if (state == CS_WAITEQ) {
105 state = CS_WAITVALUE;
106 else if (!isspace((unsigned char) *ptr))
107 tlog(TL_ALARM|TL_EXIT,"parse_hmap: Syntax error in position %d near \"%c\"\n", (int) (ptr - in), *ptr);
108 } else if (state == CS_WAITVALUE) {
112 } else if (!isspace((unsigned char) *ptr)) {
116 } else if (state == CS_INVALUE) {
118 mptr->value = nstrdup(begin, ptr - begin);
120 state = CS_WAITDELIM;
121 } else if (*ptr == '\\')
123 } else if (state == CS_IN2VALUE) {
124 if (isspace((unsigned char) *ptr) || *ptr == ',') {
125 mptr->value = nstrdup(begin, ptr - begin);
127 state = (*ptr == ',') ? CS_WAITKEY : CS_WAITDELIM;
128 } else if (*ptr == '\\')
130 } else if (state == CS_WAITDELIM) {
133 else if (!isspace((unsigned char) *ptr))
134 tlog(TL_ALARM|TL_EXIT,"parse_hmap: Syntax error in position %d near \"%c\"\n", (int) (ptr - in), *ptr);
135 } else if (state == CS_INESC)
137 else if (state == CS_IN2ESC)
140 tlog(TL_CRIT|TL_EXIT,"parse_hmap: Bad parser state %d at position %d near \"%c\"\n", state, (int) (ptr - in), *ptr);
144 if (state == CS_IN2VALUE) {
145 mptr->value = nstrdup(begin, ptr - begin);
148 else if (!(state == CS_WAITDELIM || state == CS_WAITKEY))
149 tlog(TL_ALARM|TL_EXIT,"parse_hmap: unexpected end of line\n");