2 * Sherlock Library -- Configuration Parsing Helpers
4 * (c) 2006 Martin Mares <mj@ucw.cz>
5 * (c) 2006 Robert Spalek <robert@ucw.cz>
7 * This software may be freely distributed and used according to the terms
8 * of the GNU Lesser General Public License.
11 #include "sherlock/sherlock.h"
12 #include "sherlock/object.h"
13 #include "ucw/chartype.h"
14 #include "ucw/fastbuf.h"
15 #include "ucw/ff-unicode.h"
16 #include "ucw/unicode.h"
17 #include "sherlock/conf.h"
19 /*** Attribute names ***/
22 attr_sub_parser(byte *c, uns *ptr)
26 else if (c[0] == '(' && c[1] && c[1] != ')' && c[2] == ')' && !c[3])
27 *ptr = OBJ_ATTR_SON + c[1];
29 return "Invalid attribute name";
34 attr_parser(byte *c, uns *ptr)
37 if (err = attr_sub_parser(c, ptr))
39 if (*ptr >= OBJ_ATTR_SON)
40 return "Names of sub-objects are not allowed here";
45 attr_sub_dumper(struct fastbuf *b, uns *ptr)
48 bprintf(b, "<none> ");
49 else if (*ptr < OBJ_ATTR_SON)
50 bprintf(b, "%c ", *ptr);
52 bprintf(b, "(%c) ", *ptr - OBJ_ATTR_SON);
55 struct cf_user_type cf_type_attr = {
58 .parser = (cf_parser1 *) attr_parser,
59 .dumper = (cf_dumper1 *) attr_sub_dumper
62 struct cf_user_type cf_type_attr_sub = {
65 .parser = (cf_parser1 *) attr_sub_parser,
66 .dumper = (cf_dumper1 *) attr_sub_dumper
69 /*** Unicode characters ***/
72 uni_parser(byte *c, u16 *up)
75 byte *cc = (byte*)utf8_get(c, &u);
76 if (*cc || u == UNI_REPLACEMENT)
78 for (uns i=0; i<4; i++)
82 u = (u << 4) | Cxvalue(c[i]);
91 unichar_parser(byte *c, uns *up)
94 if (uni_parser(c, &u))
95 return "Expecting one UTF-8 character or its code";
101 unichar_dumper(struct fastbuf *b, uns *up)
107 struct cf_user_type cf_type_unichar = {
110 .parser = (cf_parser1 *) unichar_parser,
111 .dumper = (cf_dumper1 *) unichar_dumper
114 /*** Unicode ranges ***/
117 unirange_parser(byte *s, struct unirange *ur)
120 if ((c = strchr(s, '-')) && c > s)
123 if (uni_parser(s, &ur->min) || uni_parser(c, &ur->max))
128 if (uni_parser(s, &ur->min))
132 if (ur->min > ur->max)
133 return "Invalid code range (min>max)";
137 return "Incorrect syntax of a code range";
141 unirange_dumper(struct fastbuf *b, struct unirange *ur)
143 bprintf(b, (ur->min == ur->max ? "%04x " : "%04x-%04x "), ur->min, ur->max);
146 struct cf_user_type cf_type_unirange = {
147 .size = sizeof(struct unirange),
149 .parser = (cf_parser1 *) unirange_parser,
150 .dumper = (cf_dumper1 *) unirange_dumper
153 /*** Unsigned integer ranges ***/
156 unsrange_parser(byte *s, struct unsrange *r)
159 if ((c = strchr(s, '-')) && c > s)
163 return "Incorrect syntax of an unsigned range";
164 if ((msg = cf_parse_int(s, &r->min)) || (msg = cf_parse_int(c, &r->max)))
169 if (msg = cf_parse_int(s, &r->min))
174 return "Invalid unsigned range (min>max)";
179 unsrange_dumper(struct fastbuf *b, struct unsrange *r)
181 bprintf(b, (r->min == r->max ? "%u " : "%u-%u "), r->min, r->max);
184 struct cf_user_type cf_type_unsrange = {
185 .size = sizeof(struct unsrange),
186 .name = "gerr_range",
187 .parser = (cf_parser1 *) unsrange_parser,
188 .dumper = (cf_dumper1 *) unsrange_dumper
191 /* Configuration sections for (word|meta|string)-types */
194 parse_u8(byte *s, uns *w)
197 byte *msg = cf_parse_int(s, (int *)w);
201 return "Weights are limited to 0..255";
206 dump_u8(struct fastbuf *fb, uns *ptr)
208 bprintf(fb, "%d ", *ptr);
211 static struct cf_user_type weight_type = {
214 .parser = (cf_parser1*) parse_u8,
215 .dumper = (cf_dumper1*) dump_u8
219 cf_generate_word_type_config(struct cf_section *sec, byte **names, uns multiple, uns just_u8)
222 while (names[number])
224 struct cf_item *items = sec->cfg = xmalloc((number + 1) * sizeof(struct cf_item));
225 for (uns i = 0; i < number; i++) {
227 items[i] = (struct cf_item) CF_USER_ARY(names[i], ((uns*) NULL) + i*multiple, &weight_type, multiple);
229 items[i] = (struct cf_item) CF_UNS_ARY(names[i], ((uns*) NULL) + i*multiple, multiple);
231 items[number] = (struct cf_item) CF_END;