3 * Teodor Sigaev <teodor@sigaev.ru>
17 #define CS_WAITVALUE 3
20 #define CS_WAITDELIM 6
25 nstrdup(char *ptr, int len)
27 char *res = palloc(len + 1),
30 memcpy(res, ptr, len);
47 parse_cfgdict(text *in, Map ** m)
50 char *ptr = VARDATA(in),
53 int state = CS_WAITKEY;
55 while (ptr - VARDATA(in) < VARSIZE(in) - VARHDRSZ)
62 *m = mptr = (Map *) palloc(sizeof(Map) * (num + 2));
63 memset(mptr, 0, sizeof(Map) * (num + 2));
65 while (ptr - VARDATA(in) < VARSIZE(in) - VARHDRSZ)
67 if (state == CS_WAITKEY)
69 if (isalpha((unsigned char) *ptr))
74 else if (!isspace((unsigned char) *ptr))
76 (errcode(ERRCODE_SYNTAX_ERROR),
77 errmsg("syntax error"),
78 errdetail("Syntax error in position %d near \"%c\"",
79 (int) (ptr - VARDATA(in)), *ptr)));
81 else if (state == CS_INKEY)
83 if (isspace((unsigned char) *ptr))
85 mptr->key = nstrdup(begin, ptr - begin);
90 mptr->key = nstrdup(begin, ptr - begin);
93 else if (!isalpha((unsigned char) *ptr))
95 (errcode(ERRCODE_SYNTAX_ERROR),
96 errmsg("syntax error"),
97 errdetail("Syntax error in position %d near \"%c\"",
98 (int) (ptr - VARDATA(in)), *ptr)));
100 else if (state == CS_WAITEQ)
103 state = CS_WAITVALUE;
104 else if (!isspace((unsigned char) *ptr))
106 (errcode(ERRCODE_SYNTAX_ERROR),
107 errmsg("syntax error"),
108 errdetail("Syntax error in position %d near \"%c\"",
109 (int) (ptr - VARDATA(in)), *ptr)));
111 else if (state == CS_WAITVALUE)
118 else if (!isspace((unsigned char) *ptr))
124 else if (state == CS_INVALUE)
128 mptr->value = nstrdup(begin, ptr - begin);
130 state = CS_WAITDELIM;
132 else if (*ptr == '\\')
135 else if (state == CS_IN2VALUE)
137 if (isspace((unsigned char) *ptr) || *ptr == ',')
139 mptr->value = nstrdup(begin, ptr - begin);
141 state = (*ptr == ',') ? CS_WAITKEY : CS_WAITDELIM;
143 else if (*ptr == '\\')
146 else if (state == CS_WAITDELIM)
150 else if (!isspace((unsigned char) *ptr))
152 (errcode(ERRCODE_SYNTAX_ERROR),
153 errmsg("syntax error"),
154 errdetail("Syntax error in position %d near \"%c\"",
155 (int) (ptr - VARDATA(in)), *ptr)));
157 else if (state == CS_INESC)
159 else if (state == CS_IN2ESC)
163 (errcode(ERRCODE_SYNTAX_ERROR),
164 errmsg("bad parser state"),
165 errdetail("%d at position %d near \"%c\"",
166 state, (int) (ptr - VARDATA(in)), *ptr)));
170 if (state == CS_IN2VALUE)
172 mptr->value = nstrdup(begin, ptr - begin);
175 else if (!(state == CS_WAITDELIM || state == CS_WAITKEY))
177 (errcode(ERRCODE_SYNTAX_ERROR),
178 errmsg("unexpected end of line")));