Remove generated file, add source instead
Showing
2 changed files
with
1035 additions
and
2563 deletions
mailbox/cfg_parser.c
deleted
100644 → 0
1 | /* A Bison parser, made by GNU Bison 2.3. */ | ||
2 | |||
3 | /* Skeleton implementation for Bison's Yacc-like parsers in C | ||
4 | |||
5 | Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 | ||
6 | Free Software Foundation, Inc. | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2, or (at your option) | ||
11 | any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
21 | Boston, MA 02110-1301, USA. */ | ||
22 | |||
23 | /* As a special exception, you may create a larger work that contains | ||
24 | part or all of the Bison parser skeleton and distribute that work | ||
25 | under terms of your choice, so long as that work isn't itself a | ||
26 | parser generator using the skeleton or a modified version thereof | ||
27 | as a parser skeleton. Alternatively, if you modify or redistribute | ||
28 | the parser skeleton itself, you may (at your option) remove this | ||
29 | special exception, which will cause the skeleton and the resulting | ||
30 | Bison output files to be licensed under the GNU General Public | ||
31 | License without this special exception. | ||
32 | |||
33 | This special exception was added by the Free Software Foundation in | ||
34 | version 2.2 of Bison. */ | ||
35 | |||
36 | /* C LALR(1) parser skeleton written by Richard Stallman, by | ||
37 | simplifying the original so-called "semantic" parser. */ | ||
38 | |||
39 | /* All symbols defined below should begin with mu_cfg_yy or YY, to avoid | ||
40 | infringing on user name space. This should be done even for local | ||
41 | variables, as they might otherwise be expanded by user macros. | ||
42 | There are some unavoidable exceptions within include files to | ||
43 | define necessary library symbols; they are noted "INFRINGES ON | ||
44 | USER NAME SPACE" below. */ | ||
45 | |||
46 | /* Identify Bison output. */ | ||
47 | #define YYBISON 1 | ||
48 | |||
49 | /* Bison version. */ | ||
50 | #define YYBISON_VERSION "2.3" | ||
51 | |||
52 | /* Skeleton name. */ | ||
53 | #define YYSKELETON_NAME "yacc.c" | ||
54 | |||
55 | /* Pure parsers. */ | ||
56 | #define YYPURE 0 | ||
57 | |||
58 | /* Using locations. */ | ||
59 | #define YYLSP_NEEDED 0 | ||
60 | |||
61 | |||
62 | |||
63 | /* Tokens. */ | ||
64 | #ifndef YYTOKENTYPE | ||
65 | # define YYTOKENTYPE | ||
66 | /* Put the tokens into the symbol table, so that GDB and other debuggers | ||
67 | know about them. */ | ||
68 | enum mu_cfg_yytokentype { | ||
69 | MU_CFG_EOL_TOKEN = 258, | ||
70 | MU_CFG_START_TOKEN = 259, | ||
71 | MU_CFG_END_TOKEN = 260, | ||
72 | MU_CFG_STRING_TOKEN = 261 | ||
73 | }; | ||
74 | #endif | ||
75 | /* Tokens. */ | ||
76 | #define MU_CFG_EOL_TOKEN 258 | ||
77 | #define MU_CFG_START_TOKEN 259 | ||
78 | #define MU_CFG_END_TOKEN 260 | ||
79 | #define MU_CFG_STRING_TOKEN 261 | ||
80 | |||
81 | |||
82 | |||
83 | |||
84 | /* Copy the first part of user declarations. */ | ||
85 | #line 1 "cfg_parser.y" | ||
86 | |||
87 | /* cfg_parser.y -- general-purpose configuration file parser | ||
88 | Copyright (C) 2007 Free Software Foundation, Inc. | ||
89 | |||
90 | GNU Mailutils is free software; you can redistribute it and/or | ||
91 | modify it under the terms of the GNU General Public License as | ||
92 | published by the Free Software Foundation; either version 3, or (at | ||
93 | your option) any later version. | ||
94 | |||
95 | This program is distributed in the hope that it will be useful, but | ||
96 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
97 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
98 | General Public License for more details. | ||
99 | |||
100 | You should have received a copy of the GNU General Public License | ||
101 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
102 | */ | ||
103 | |||
104 | #include <stdio.h> | ||
105 | #include <stdlib.h> | ||
106 | #include <stdarg.h> | ||
107 | #include <string.h> | ||
108 | #include <netdb.h> | ||
109 | #include "intprops.h" | ||
110 | #include <mailutils/nls.h> | ||
111 | #include <mailutils/cfg.h> | ||
112 | #include <mailutils/errno.h> | ||
113 | #include <mailutils/error.h> | ||
114 | |||
115 | static mu_cfg_node_t *parse_tree; | ||
116 | mu_cfg_locus_t mu_cfg_locus; | ||
117 | int mu_cfg_tie_in; | ||
118 | |||
119 | static int _mu_cfg_errcnt; | ||
120 | static mu_cfg_lexer_t _mu_cfg_lexer; | ||
121 | mu_cfg_perror_t mu_cfg_perror; | ||
122 | static void *_mu_cfg_lexer_data; | ||
123 | mu_cfg_alloc_t _mu_cfg_alloc; | ||
124 | mu_cfg_free_t _mu_cfg_free; | ||
125 | |||
126 | static int | ||
127 | mu_cfg_yyerror (char *s) | ||
128 | { | ||
129 | mu_cfg_perror (_mu_cfg_lexer_data, &mu_cfg_locus, "%s", s); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static int | ||
134 | mu_cfg_yylex () | ||
135 | { | ||
136 | return _mu_cfg_lexer (_mu_cfg_lexer_data); | ||
137 | } | ||
138 | |||
139 | static mu_cfg_node_t * | ||
140 | mu_cfg_alloc_node (enum mu_cfg_node_type type, mu_cfg_locus_t *loc, | ||
141 | char *tag, char *label, mu_cfg_node_t *node) | ||
142 | { | ||
143 | char *p; | ||
144 | mu_cfg_node_t *np; | ||
145 | size_t size = sizeof *np + strlen (tag) + 1 | ||
146 | + (label ? (strlen (label) + 1) : 0); | ||
147 | np = _mu_cfg_alloc (size); | ||
148 | if (!np) | ||
149 | { | ||
150 | mu_cfg_perror (_mu_cfg_lexer_data, &mu_cfg_locus, | ||
151 | _("Not enough memory")); | ||
152 | abort(); | ||
153 | } | ||
154 | np->type = type; | ||
155 | np->locus = *loc; | ||
156 | p = (char*) (np + 1); | ||
157 | np->tag_name = p; | ||
158 | strcpy (p, tag); | ||
159 | p += strlen (p) + 1; | ||
160 | if (label) | ||
161 | { | ||
162 | np->tag_label = p; | ||
163 | strcpy (p, label); | ||
164 | } | ||
165 | else | ||
166 | np->tag_label = label; | ||
167 | np->node = node; | ||
168 | np->next = NULL; | ||
169 | return np; | ||
170 | } | ||
171 | |||
172 | static void | ||
173 | _mu_cfg_default_perror (void *ptr, const mu_cfg_locus_t *loc, | ||
174 | const char *fmt, ...) | ||
175 | { | ||
176 | va_list ap; | ||
177 | |||
178 | fprintf (stderr, "%s:", loc->file ? loc->file : _("unknown file")); | ||
179 | if (loc->line > 0) | ||
180 | fprintf (stderr, "%lu", (unsigned long) loc->line); | ||
181 | else | ||
182 | fprintf (stderr, "%s", _("unknown line")); | ||
183 | fprintf (stderr, ": "); | ||
184 | va_start (ap, fmt); | ||
185 | vfprintf (stderr, fmt, ap); | ||
186 | va_end (ap); | ||
187 | fprintf (stderr, "\n"); | ||
188 | } | ||
189 | |||
190 | |||
191 | |||
192 | /* Enabling traces. */ | ||
193 | #ifndef YYDEBUG | ||
194 | # define YYDEBUG 1 | ||
195 | #endif | ||
196 | |||
197 | /* Enabling verbose error messages. */ | ||
198 | #ifdef YYERROR_VERBOSE | ||
199 | # undef YYERROR_VERBOSE | ||
200 | # define YYERROR_VERBOSE 1 | ||
201 | #else | ||
202 | # define YYERROR_VERBOSE 0 | ||
203 | #endif | ||
204 | |||
205 | /* Enabling the token table. */ | ||
206 | #ifndef YYTOKEN_TABLE | ||
207 | # define YYTOKEN_TABLE 0 | ||
208 | #endif | ||
209 | |||
210 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED | ||
211 | typedef union YYSTYPE | ||
212 | #line 115 "cfg_parser.y" | ||
213 | { | ||
214 | mu_cfg_node_t node; | ||
215 | mu_cfg_node_t *pnode; | ||
216 | struct | ||
217 | { | ||
218 | mu_cfg_node_t *head, *tail; | ||
219 | } nodelist; | ||
220 | char *string; | ||
221 | } | ||
222 | /* Line 187 of yacc.c. */ | ||
223 | #line 224 "cfg_parser.c" | ||
224 | YYSTYPE; | ||
225 | # define mu_cfg_yystype YYSTYPE /* obsolescent; will be withdrawn */ | ||
226 | # define YYSTYPE_IS_DECLARED 1 | ||
227 | # define YYSTYPE_IS_TRIVIAL 1 | ||
228 | #endif | ||
229 | |||
230 | |||
231 | |||
232 | /* Copy the second part of user declarations. */ | ||
233 | |||
234 | |||
235 | /* Line 216 of yacc.c. */ | ||
236 | #line 237 "cfg_parser.c" | ||
237 | |||
238 | #ifdef short | ||
239 | # undef short | ||
240 | #endif | ||
241 | |||
242 | #ifdef YYTYPE_UINT8 | ||
243 | typedef YYTYPE_UINT8 mu_cfg_yytype_uint8; | ||
244 | #else | ||
245 | typedef unsigned char mu_cfg_yytype_uint8; | ||
246 | #endif | ||
247 | |||
248 | #ifdef YYTYPE_INT8 | ||
249 | typedef YYTYPE_INT8 mu_cfg_yytype_int8; | ||
250 | #elif (defined __STDC__ || defined __C99__FUNC__ \ | ||
251 | || defined __cplusplus || defined _MSC_VER) | ||
252 | typedef signed char mu_cfg_yytype_int8; | ||
253 | #else | ||
254 | typedef short int mu_cfg_yytype_int8; | ||
255 | #endif | ||
256 | |||
257 | #ifdef YYTYPE_UINT16 | ||
258 | typedef YYTYPE_UINT16 mu_cfg_yytype_uint16; | ||
259 | #else | ||
260 | typedef unsigned short int mu_cfg_yytype_uint16; | ||
261 | #endif | ||
262 | |||
263 | #ifdef YYTYPE_INT16 | ||
264 | typedef YYTYPE_INT16 mu_cfg_yytype_int16; | ||
265 | #else | ||
266 | typedef short int mu_cfg_yytype_int16; | ||
267 | #endif | ||
268 | |||
269 | #ifndef YYSIZE_T | ||
270 | # ifdef __SIZE_TYPE__ | ||
271 | # define YYSIZE_T __SIZE_TYPE__ | ||
272 | # elif defined size_t | ||
273 | # define YYSIZE_T size_t | ||
274 | # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ | ||
275 | || defined __cplusplus || defined _MSC_VER) | ||
276 | # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ | ||
277 | # define YYSIZE_T size_t | ||
278 | # else | ||
279 | # define YYSIZE_T unsigned int | ||
280 | # endif | ||
281 | #endif | ||
282 | |||
283 | #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) | ||
284 | |||
285 | #ifndef YY_ | ||
286 | # if YYENABLE_NLS | ||
287 | # if ENABLE_NLS | ||
288 | # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ | ||
289 | # define YY_(msgid) dgettext ("bison-runtime", msgid) | ||
290 | # endif | ||
291 | # endif | ||
292 | # ifndef YY_ | ||
293 | # define YY_(msgid) msgid | ||
294 | # endif | ||
295 | #endif | ||
296 | |||
297 | /* Suppress unused-variable warnings by "using" E. */ | ||
298 | #if ! defined lint || defined __GNUC__ | ||
299 | # define YYUSE(e) ((void) (e)) | ||
300 | #else | ||
301 | # define YYUSE(e) /* empty */ | ||
302 | #endif | ||
303 | |||
304 | /* Identity function, used to suppress warnings about constant conditions. */ | ||
305 | #ifndef lint | ||
306 | # define YYID(n) (n) | ||
307 | #else | ||
308 | #if (defined __STDC__ || defined __C99__FUNC__ \ | ||
309 | || defined __cplusplus || defined _MSC_VER) | ||
310 | static int | ||
311 | YYID (int i) | ||
312 | #else | ||
313 | static int | ||
314 | YYID (i) | ||
315 | int i; | ||
316 | #endif | ||
317 | { | ||
318 | return i; | ||
319 | } | ||
320 | #endif | ||
321 | |||
322 | #if ! defined mu_cfg_yyoverflow || YYERROR_VERBOSE | ||
323 | |||
324 | /* The parser invokes alloca or malloc; define the necessary symbols. */ | ||
325 | |||
326 | # ifdef YYSTACK_USE_ALLOCA | ||
327 | # if YYSTACK_USE_ALLOCA | ||
328 | # ifdef __GNUC__ | ||
329 | # define YYSTACK_ALLOC __builtin_alloca | ||
330 | # elif defined __BUILTIN_VA_ARG_INCR | ||
331 | # include <alloca.h> /* INFRINGES ON USER NAME SPACE */ | ||
332 | # elif defined _AIX | ||
333 | # define YYSTACK_ALLOC __alloca | ||
334 | # elif defined _MSC_VER | ||
335 | # include <malloc.h> /* INFRINGES ON USER NAME SPACE */ | ||
336 | # define alloca _alloca | ||
337 | # else | ||
338 | # define YYSTACK_ALLOC alloca | ||
339 | # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ | ||
340 | || defined __cplusplus || defined _MSC_VER) | ||
341 | # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ | ||
342 | # ifndef _STDLIB_H | ||
343 | # define _STDLIB_H 1 | ||
344 | # endif | ||
345 | # endif | ||
346 | # endif | ||
347 | # endif | ||
348 | # endif | ||
349 | |||
350 | # ifdef YYSTACK_ALLOC | ||
351 | /* Pacify GCC's `empty if-body' warning. */ | ||
352 | # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) | ||
353 | # ifndef YYSTACK_ALLOC_MAXIMUM | ||
354 | /* The OS might guarantee only one guard page at the bottom of the stack, | ||
355 | and a page size can be as small as 4096 bytes. So we cannot safely | ||
356 | invoke alloca (N) if N exceeds 4096. Use a slightly smaller number | ||
357 | to allow for a few compiler-allocated temporary stack slots. */ | ||
358 | # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ | ||
359 | # endif | ||
360 | # else | ||
361 | # define YYSTACK_ALLOC YYMALLOC | ||
362 | # define YYSTACK_FREE YYFREE | ||
363 | # ifndef YYSTACK_ALLOC_MAXIMUM | ||
364 | # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM | ||
365 | # endif | ||
366 | # if (defined __cplusplus && ! defined _STDLIB_H \ | ||
367 | && ! ((defined YYMALLOC || defined malloc) \ | ||
368 | && (defined YYFREE || defined free))) | ||
369 | # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ | ||
370 | # ifndef _STDLIB_H | ||
371 | # define _STDLIB_H 1 | ||
372 | # endif | ||
373 | # endif | ||
374 | # ifndef YYMALLOC | ||
375 | # define YYMALLOC malloc | ||
376 | # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ | ||
377 | || defined __cplusplus || defined _MSC_VER) | ||
378 | void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ | ||
379 | # endif | ||
380 | # endif | ||
381 | # ifndef YYFREE | ||
382 | # define YYFREE free | ||
383 | # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ | ||
384 | || defined __cplusplus || defined _MSC_VER) | ||
385 | void free (void *); /* INFRINGES ON USER NAME SPACE */ | ||
386 | # endif | ||
387 | # endif | ||
388 | # endif | ||
389 | #endif /* ! defined mu_cfg_yyoverflow || YYERROR_VERBOSE */ | ||
390 | |||
391 | |||
392 | #if (! defined mu_cfg_yyoverflow \ | ||
393 | && (! defined __cplusplus \ | ||
394 | || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) | ||
395 | |||
396 | /* A type that is properly aligned for any stack member. */ | ||
397 | union mu_cfg_yyalloc | ||
398 | { | ||
399 | mu_cfg_yytype_int16 mu_cfg_yyss; | ||
400 | YYSTYPE mu_cfg_yyvs; | ||
401 | }; | ||
402 | |||
403 | /* The size of the maximum gap between one aligned stack and the next. */ | ||
404 | # define YYSTACK_GAP_MAXIMUM (sizeof (union mu_cfg_yyalloc) - 1) | ||
405 | |||
406 | /* The size of an array large to enough to hold all stacks, each with | ||
407 | N elements. */ | ||
408 | # define YYSTACK_BYTES(N) \ | ||
409 | ((N) * (sizeof (mu_cfg_yytype_int16) + sizeof (YYSTYPE)) \ | ||
410 | + YYSTACK_GAP_MAXIMUM) | ||
411 | |||
412 | /* Copy COUNT objects from FROM to TO. The source and destination do | ||
413 | not overlap. */ | ||
414 | # ifndef YYCOPY | ||
415 | # if defined __GNUC__ && 1 < __GNUC__ | ||
416 | # define YYCOPY(To, From, Count) \ | ||
417 | __builtin_memcpy (To, From, (Count) * sizeof (*(From))) | ||
418 | # else | ||
419 | # define YYCOPY(To, From, Count) \ | ||
420 | do \ | ||
421 | { \ | ||
422 | YYSIZE_T mu_cfg_yyi; \ | ||
423 | for (mu_cfg_yyi = 0; mu_cfg_yyi < (Count); mu_cfg_yyi++) \ | ||
424 | (To)[mu_cfg_yyi] = (From)[mu_cfg_yyi]; \ | ||
425 | } \ | ||
426 | while (YYID (0)) | ||
427 | # endif | ||
428 | # endif | ||
429 | |||
430 | /* Relocate STACK from its old location to the new one. The | ||
431 | local variables YYSIZE and YYSTACKSIZE give the old and new number of | ||
432 | elements in the stack, and YYPTR gives the new location of the | ||
433 | stack. Advance YYPTR to a properly aligned location for the next | ||
434 | stack. */ | ||
435 | # define YYSTACK_RELOCATE(Stack) \ | ||
436 | do \ | ||
437 | { \ | ||
438 | YYSIZE_T mu_cfg_yynewbytes; \ | ||
439 | YYCOPY (&mu_cfg_yyptr->Stack, Stack, mu_cfg_yysize); \ | ||
440 | Stack = &mu_cfg_yyptr->Stack; \ | ||
441 | mu_cfg_yynewbytes = mu_cfg_yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ | ||
442 | mu_cfg_yyptr += mu_cfg_yynewbytes / sizeof (*mu_cfg_yyptr); \ | ||
443 | } \ | ||
444 | while (YYID (0)) | ||
445 | |||
446 | #endif | ||
447 | |||
448 | /* YYFINAL -- State number of the termination state. */ | ||
449 | #define YYFINAL 10 | ||
450 | /* YYLAST -- Last index in YYTABLE. */ | ||
451 | #define YYLAST 17 | ||
452 | |||
453 | /* YYNTOKENS -- Number of terminals. */ | ||
454 | #define YYNTOKENS 7 | ||
455 | /* YYNNTS -- Number of nonterminals. */ | ||
456 | #define YYNNTS 8 | ||
457 | /* YYNRULES -- Number of rules. */ | ||
458 | #define YYNRULES 12 | ||
459 | /* YYNRULES -- Number of states. */ | ||
460 | #define YYNSTATES 19 | ||
461 | |||
462 | /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ | ||
463 | #define YYUNDEFTOK 2 | ||
464 | #define YYMAXUTOK 261 | ||
465 | |||
466 | #define YYTRANSLATE(YYX) \ | ||
467 | ((unsigned int) (YYX) <= YYMAXUTOK ? mu_cfg_yytranslate[YYX] : YYUNDEFTOK) | ||
468 | |||
469 | /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ | ||
470 | static const mu_cfg_yytype_uint8 mu_cfg_yytranslate[] = | ||
471 | { | ||
472 | 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
473 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
474 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
475 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
476 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
477 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
478 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
479 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
480 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
481 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
482 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
483 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
484 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
485 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
486 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
487 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
488 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
489 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
490 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
491 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
492 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
493 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
494 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
495 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
496 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
497 | 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, | ||
498 | 5, 6 | ||
499 | }; | ||
500 | |||
501 | #if YYDEBUG | ||
502 | /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in | ||
503 | YYRHS. */ | ||
504 | static const mu_cfg_yytype_uint8 mu_cfg_yyprhs[] = | ||
505 | { | ||
506 | 0, 0, 3, 5, 7, 10, 11, 13, 15, 18, | ||
507 | 24, 25, 26 | ||
508 | }; | ||
509 | |||
510 | /* YYRHS -- A `-1'-separated list of the rules' RHS. */ | ||
511 | static const mu_cfg_yytype_int8 mu_cfg_yyrhs[] = | ||
512 | { | ||
513 | 8, 0, -1, 9, -1, 12, -1, 9, 12, -1, | ||
514 | -1, 11, -1, 3, -1, 11, 3, -1, 4, 10, | ||
515 | 9, 5, 3, -1, -1, -1, 6, 13, 6, 14, | ||
516 | 3, -1 | ||
517 | }; | ||
518 | |||
519 | /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ | ||
520 | static const mu_cfg_yytype_uint8 mu_cfg_yyrline[] = | ||
521 | { | ||
522 | 0, 127, 127, 133, 137, 145, 146, 149, 150, 153, | ||
523 | 170, 171, 170 | ||
524 | }; | ||
525 | #endif | ||
526 | |||
527 | #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE | ||
528 | /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. | ||
529 | First, the terminals, then, starting at YYNTOKENS, nonterminals. */ | ||
530 | static const char *const mu_cfg_yytname[] = | ||
531 | { | ||
532 | "$end", "error", "$undefined", "MU_CFG_EOL_TOKEN", "MU_CFG_START_TOKEN", | ||
533 | "MU_CFG_END_TOKEN", "MU_CFG_STRING_TOKEN", "$accept", "input", "taglist", | ||
534 | "opt_eol", "eol", "tag", "@1", "@2", 0 | ||
535 | }; | ||
536 | #endif | ||
537 | |||
538 | # ifdef YYPRINT | ||
539 | /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to | ||
540 | token YYLEX-NUM. */ | ||
541 | static const mu_cfg_yytype_uint16 mu_cfg_yytoknum[] = | ||
542 | { | ||
543 | 0, 256, 257, 258, 259, 260, 261 | ||
544 | }; | ||
545 | # endif | ||
546 | |||
547 | /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ | ||
548 | static const mu_cfg_yytype_uint8 mu_cfg_yyr1[] = | ||
549 | { | ||
550 | 0, 7, 8, 9, 9, 10, 10, 11, 11, 12, | ||
551 | 13, 14, 12 | ||
552 | }; | ||
553 | |||
554 | /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ | ||
555 | static const mu_cfg_yytype_uint8 mu_cfg_yyr2[] = | ||
556 | { | ||
557 | 0, 2, 1, 1, 2, 0, 1, 1, 2, 5, | ||
558 | 0, 0, 5 | ||
559 | }; | ||
560 | |||
561 | /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state | ||
562 | STATE-NUM when YYTABLE doesn't specify something else to do. Zero | ||
563 | means the default is an error. */ | ||
564 | static const mu_cfg_yytype_uint8 mu_cfg_yydefact[] = | ||
565 | { | ||
566 | 0, 5, 10, 0, 2, 3, 7, 0, 6, 0, | ||
567 | 1, 4, 0, 8, 11, 0, 0, 9, 12 | ||
568 | }; | ||
569 | |||
570 | /* YYDEFGOTO[NTERM-NUM]. */ | ||
571 | static const mu_cfg_yytype_int8 mu_cfg_yydefgoto[] = | ||
572 | { | ||
573 | -1, 3, 4, 7, 8, 5, 9, 16 | ||
574 | }; | ||
575 | |||
576 | /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing | ||
577 | STATE-NUM. */ | ||
578 | #define YYPACT_NINF -5 | ||
579 | static const mu_cfg_yytype_int8 mu_cfg_yypact[] = | ||
580 | { | ||
581 | 0, 2, -5, 7, 0, -5, -5, 0, 6, 4, | ||
582 | -5, -5, -3, -5, -5, 8, 9, -5, -5 | ||
583 | }; | ||
584 | |||
585 | /* YYPGOTO[NTERM-NUM]. */ | ||
586 | static const mu_cfg_yytype_int8 mu_cfg_yypgoto[] = | ||
587 | { | ||
588 | -5, -5, 10, -5, -5, -4, -5, -5 | ||
589 | }; | ||
590 | |||
591 | /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If | ||
592 | positive, shift that token. If negative, reduce the rule which | ||
593 | number is the opposite. If zero, do what YYDEFACT says. | ||
594 | If YYTABLE_NINF, syntax error. */ | ||
595 | #define YYTABLE_NINF -1 | ||
596 | static const mu_cfg_yytype_uint8 mu_cfg_yytable[] = | ||
597 | { | ||
598 | 11, 1, 15, 2, 1, 6, 2, 10, 11, 13, | ||
599 | 14, 17, 18, 0, 0, 0, 0, 12 | ||
600 | }; | ||
601 | |||
602 | static const mu_cfg_yytype_int8 mu_cfg_yycheck[] = | ||
603 | { | ||
604 | 4, 4, 5, 6, 4, 3, 6, 0, 12, 3, | ||
605 | 6, 3, 3, -1, -1, -1, -1, 7 | ||
606 | }; | ||
607 | |||
608 | /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing | ||
609 | symbol of state STATE-NUM. */ | ||
610 | static const mu_cfg_yytype_uint8 mu_cfg_yystos[] = | ||
611 | { | ||
612 | 0, 4, 6, 8, 9, 12, 3, 10, 11, 13, | ||
613 | 0, 12, 9, 3, 6, 5, 14, 3, 3 | ||
614 | }; | ||
615 | |||
616 | #define mu_cfg_yyerrok (mu_cfg_yyerrstatus = 0) | ||
617 | #define mu_cfg_yyclearin (mu_cfg_yychar = YYEMPTY) | ||
618 | #define YYEMPTY (-2) | ||
619 | #define YYEOF 0 | ||
620 | |||
621 | #define YYACCEPT goto mu_cfg_yyacceptlab | ||
622 | #define YYABORT goto mu_cfg_yyabortlab | ||
623 | #define YYERROR goto mu_cfg_yyerrorlab | ||
624 | |||
625 | |||
626 | /* Like YYERROR except do call mu_cfg_yyerror. This remains here temporarily | ||
627 | to ease the transition to the new meaning of YYERROR, for GCC. | ||
628 | Once GCC version 2 has supplanted version 1, this can go. */ | ||
629 | |||
630 | #define YYFAIL goto mu_cfg_yyerrlab | ||
631 | |||
632 | #define YYRECOVERING() (!!mu_cfg_yyerrstatus) | ||
633 | |||
634 | #define YYBACKUP(Token, Value) \ | ||
635 | do \ | ||
636 | if (mu_cfg_yychar == YYEMPTY && mu_cfg_yylen == 1) \ | ||
637 | { \ | ||
638 | mu_cfg_yychar = (Token); \ | ||
639 | mu_cfg_yylval = (Value); \ | ||
640 | mu_cfg_yytoken = YYTRANSLATE (mu_cfg_yychar); \ | ||
641 | YYPOPSTACK (1); \ | ||
642 | goto mu_cfg_yybackup; \ | ||
643 | } \ | ||
644 | else \ | ||
645 | { \ | ||
646 | mu_cfg_yyerror (YY_("syntax error: cannot back up")); \ | ||
647 | YYERROR; \ | ||
648 | } \ | ||
649 | while (YYID (0)) | ||
650 | |||
651 | |||
652 | #define YYTERROR 1 | ||
653 | #define YYERRCODE 256 | ||
654 | |||
655 | |||
656 | /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. | ||
657 | If N is 0, then set CURRENT to the empty location which ends | ||
658 | the previous symbol: RHS[0] (always defined). */ | ||
659 | |||
660 | #define YYRHSLOC(Rhs, K) ((Rhs)[K]) | ||
661 | #ifndef YYLLOC_DEFAULT | ||
662 | # define YYLLOC_DEFAULT(Current, Rhs, N) \ | ||
663 | do \ | ||
664 | if (YYID (N)) \ | ||
665 | { \ | ||
666 | (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ | ||
667 | (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ | ||
668 | (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ | ||
669 | (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ | ||
670 | } \ | ||
671 | else \ | ||
672 | { \ | ||
673 | (Current).first_line = (Current).last_line = \ | ||
674 | YYRHSLOC (Rhs, 0).last_line; \ | ||
675 | (Current).first_column = (Current).last_column = \ | ||
676 | YYRHSLOC (Rhs, 0).last_column; \ | ||
677 | } \ | ||
678 | while (YYID (0)) | ||
679 | #endif | ||
680 | |||
681 | |||
682 | /* YY_LOCATION_PRINT -- Print the location on the stream. | ||
683 | This macro was not mandated originally: define only if we know | ||
684 | we won't break user code: when these are the locations we know. */ | ||
685 | |||
686 | #ifndef YY_LOCATION_PRINT | ||
687 | # if YYLTYPE_IS_TRIVIAL | ||
688 | # define YY_LOCATION_PRINT(File, Loc) \ | ||
689 | fprintf (File, "%d.%d-%d.%d", \ | ||
690 | (Loc).first_line, (Loc).first_column, \ | ||
691 | (Loc).last_line, (Loc).last_column) | ||
692 | # else | ||
693 | # define YY_LOCATION_PRINT(File, Loc) ((void) 0) | ||
694 | # endif | ||
695 | #endif | ||
696 | |||
697 | |||
698 | /* YYLEX -- calling `mu_cfg_yylex' with the right arguments. */ | ||
699 | |||
700 | #ifdef YYLEX_PARAM | ||
701 | # define YYLEX mu_cfg_yylex (YYLEX_PARAM) | ||
702 | #else | ||
703 | # define YYLEX mu_cfg_yylex () | ||
704 | #endif | ||
705 | |||
706 | /* Enable debugging if requested. */ | ||
707 | #if YYDEBUG | ||
708 | |||
709 | # ifndef YYFPRINTF | ||
710 | # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ | ||
711 | # define YYFPRINTF fprintf | ||
712 | # endif | ||
713 | |||
714 | # define YYDPRINTF(Args) \ | ||
715 | do { \ | ||
716 | if (mu_cfg_yydebug) \ | ||
717 | YYFPRINTF Args; \ | ||
718 | } while (YYID (0)) | ||
719 | |||
720 | # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ | ||
721 | do { \ | ||
722 | if (mu_cfg_yydebug) \ | ||
723 | { \ | ||
724 | YYFPRINTF (stderr, "%s ", Title); \ | ||
725 | mu_cfg_yy_symbol_print (stderr, \ | ||
726 | Type, Value); \ | ||
727 | YYFPRINTF (stderr, "\n"); \ | ||
728 | } \ | ||
729 | } while (YYID (0)) | ||
730 | |||
731 | |||
732 | /*--------------------------------. | ||
733 | | Print this symbol on YYOUTPUT. | | ||
734 | `--------------------------------*/ | ||
735 | |||
736 | /*ARGSUSED*/ | ||
737 | #if (defined __STDC__ || defined __C99__FUNC__ \ | ||
738 | || defined __cplusplus || defined _MSC_VER) | ||
739 | static void | ||
740 | mu_cfg_yy_symbol_value_print (FILE *mu_cfg_yyoutput, int mu_cfg_yytype, YYSTYPE const * const mu_cfg_yyvaluep) | ||
741 | #else | ||
742 | static void | ||
743 | mu_cfg_yy_symbol_value_print (mu_cfg_yyoutput, mu_cfg_yytype, mu_cfg_yyvaluep) | ||
744 | FILE *mu_cfg_yyoutput; | ||
745 | int mu_cfg_yytype; | ||
746 | YYSTYPE const * const mu_cfg_yyvaluep; | ||
747 | #endif | ||
748 | { | ||
749 | if (!mu_cfg_yyvaluep) | ||
750 | return; | ||
751 | # ifdef YYPRINT | ||
752 | if (mu_cfg_yytype < YYNTOKENS) | ||
753 | YYPRINT (mu_cfg_yyoutput, mu_cfg_yytoknum[mu_cfg_yytype], *mu_cfg_yyvaluep); | ||
754 | # else | ||
755 | YYUSE (mu_cfg_yyoutput); | ||
756 | # endif | ||
757 | switch (mu_cfg_yytype) | ||
758 | { | ||
759 | default: | ||
760 | break; | ||
761 | } | ||
762 | } | ||
763 | |||
764 | |||
765 | /*--------------------------------. | ||
766 | | Print this symbol on YYOUTPUT. | | ||
767 | `--------------------------------*/ | ||
768 | |||
769 | #if (defined __STDC__ || defined __C99__FUNC__ \ | ||
770 | || defined __cplusplus || defined _MSC_VER) | ||
771 | static void | ||
772 | mu_cfg_yy_symbol_print (FILE *mu_cfg_yyoutput, int mu_cfg_yytype, YYSTYPE const * const mu_cfg_yyvaluep) | ||
773 | #else | ||
774 | static void | ||
775 | mu_cfg_yy_symbol_print (mu_cfg_yyoutput, mu_cfg_yytype, mu_cfg_yyvaluep) | ||
776 | FILE *mu_cfg_yyoutput; | ||
777 | int mu_cfg_yytype; | ||
778 | YYSTYPE const * const mu_cfg_yyvaluep; | ||
779 | #endif | ||
780 | { | ||
781 | if (mu_cfg_yytype < YYNTOKENS) | ||
782 | YYFPRINTF (mu_cfg_yyoutput, "token %s (", mu_cfg_yytname[mu_cfg_yytype]); | ||
783 | else | ||
784 | YYFPRINTF (mu_cfg_yyoutput, "nterm %s (", mu_cfg_yytname[mu_cfg_yytype]); | ||
785 | |||
786 | mu_cfg_yy_symbol_value_print (mu_cfg_yyoutput, mu_cfg_yytype, mu_cfg_yyvaluep); | ||
787 | YYFPRINTF (mu_cfg_yyoutput, ")"); | ||
788 | } | ||
789 | |||
790 | /*------------------------------------------------------------------. | ||
791 | | mu_cfg_yy_stack_print -- Print the state stack from its BOTTOM up to its | | ||
792 | | TOP (included). | | ||
793 | `------------------------------------------------------------------*/ | ||
794 | |||
795 | #if (defined __STDC__ || defined __C99__FUNC__ \ | ||
796 | || defined __cplusplus || defined _MSC_VER) | ||
797 | static void | ||
798 | mu_cfg_yy_stack_print (mu_cfg_yytype_int16 *bottom, mu_cfg_yytype_int16 *top) | ||
799 | #else | ||
800 | static void | ||
801 | mu_cfg_yy_stack_print (bottom, top) | ||
802 | mu_cfg_yytype_int16 *bottom; | ||
803 | mu_cfg_yytype_int16 *top; | ||
804 | #endif | ||
805 | { | ||
806 | YYFPRINTF (stderr, "Stack now"); | ||
807 | for (; bottom <= top; ++bottom) | ||
808 | YYFPRINTF (stderr, " %d", *bottom); | ||
809 | YYFPRINTF (stderr, "\n"); | ||
810 | } | ||
811 | |||
812 | # define YY_STACK_PRINT(Bottom, Top) \ | ||
813 | do { \ | ||
814 | if (mu_cfg_yydebug) \ | ||
815 | mu_cfg_yy_stack_print ((Bottom), (Top)); \ | ||
816 | } while (YYID (0)) | ||
817 | |||
818 | |||
819 | /*------------------------------------------------. | ||
820 | | Report that the YYRULE is going to be reduced. | | ||
821 | `------------------------------------------------*/ | ||
822 | |||
823 | #if (defined __STDC__ || defined __C99__FUNC__ \ | ||
824 | || defined __cplusplus || defined _MSC_VER) | ||
825 | static void | ||
826 | mu_cfg_yy_reduce_print (YYSTYPE *mu_cfg_yyvsp, int mu_cfg_yyrule) | ||
827 | #else | ||
828 | static void | ||
829 | mu_cfg_yy_reduce_print (mu_cfg_yyvsp, mu_cfg_yyrule) | ||
830 | YYSTYPE *mu_cfg_yyvsp; | ||
831 | int mu_cfg_yyrule; | ||
832 | #endif | ||
833 | { | ||
834 | int mu_cfg_yynrhs = mu_cfg_yyr2[mu_cfg_yyrule]; | ||
835 | int mu_cfg_yyi; | ||
836 | unsigned long int mu_cfg_yylno = mu_cfg_yyrline[mu_cfg_yyrule]; | ||
837 | YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", | ||
838 | mu_cfg_yyrule - 1, mu_cfg_yylno); | ||
839 | /* The symbols being reduced. */ | ||
840 | for (mu_cfg_yyi = 0; mu_cfg_yyi < mu_cfg_yynrhs; mu_cfg_yyi++) | ||
841 | { | ||
842 | fprintf (stderr, " $%d = ", mu_cfg_yyi + 1); | ||
843 | mu_cfg_yy_symbol_print (stderr, mu_cfg_yyrhs[mu_cfg_yyprhs[mu_cfg_yyrule] + mu_cfg_yyi], | ||
844 | &(mu_cfg_yyvsp[(mu_cfg_yyi + 1) - (mu_cfg_yynrhs)]) | ||
845 | ); | ||
846 | fprintf (stderr, "\n"); | ||
847 | } | ||
848 | } | ||
849 | |||
850 | # define YY_REDUCE_PRINT(Rule) \ | ||
851 | do { \ | ||
852 | if (mu_cfg_yydebug) \ | ||
853 | mu_cfg_yy_reduce_print (mu_cfg_yyvsp, Rule); \ | ||
854 | } while (YYID (0)) | ||
855 | |||
856 | /* Nonzero means print parse trace. It is left uninitialized so that | ||
857 | multiple parsers can coexist. */ | ||
858 | int mu_cfg_yydebug; | ||
859 | #else /* !YYDEBUG */ | ||
860 | # define YYDPRINTF(Args) | ||
861 | # define YY_SYMBOL_PRINT(Title, Type, Value, Location) | ||
862 | # define YY_STACK_PRINT(Bottom, Top) | ||
863 | # define YY_REDUCE_PRINT(Rule) | ||
864 | #endif /* !YYDEBUG */ | ||
865 | |||
866 | |||
867 | /* YYINITDEPTH -- initial size of the parser's stacks. */ | ||
868 | #ifndef YYINITDEPTH | ||
869 | # define YYINITDEPTH 200 | ||
870 | #endif | ||
871 | |||
872 | /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only | ||
873 | if the built-in stack extension method is used). | ||
874 | |||
875 | Do not make this value too large; the results are undefined if | ||
876 | YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) | ||
877 | evaluated with infinite-precision integer arithmetic. */ | ||
878 | |||
879 | #ifndef YYMAXDEPTH | ||
880 | # define YYMAXDEPTH 10000 | ||
881 | #endif | ||
882 | |||
883 | |||
884 | |||
885 | #if YYERROR_VERBOSE | ||
886 | |||
887 | # ifndef mu_cfg_yystrlen | ||
888 | # if defined __GLIBC__ && defined _STRING_H | ||
889 | # define mu_cfg_yystrlen strlen | ||
890 | # else | ||
891 | /* Return the length of YYSTR. */ | ||
892 | #if (defined __STDC__ || defined __C99__FUNC__ \ | ||
893 | || defined __cplusplus || defined _MSC_VER) | ||
894 | static YYSIZE_T | ||
895 | mu_cfg_yystrlen (const char *mu_cfg_yystr) | ||
896 | #else | ||
897 | static YYSIZE_T | ||
898 | mu_cfg_yystrlen (mu_cfg_yystr) | ||
899 | const char *mu_cfg_yystr; | ||
900 | #endif | ||
901 | { | ||
902 | YYSIZE_T mu_cfg_yylen; | ||
903 | for (mu_cfg_yylen = 0; mu_cfg_yystr[mu_cfg_yylen]; mu_cfg_yylen++) | ||
904 | continue; | ||
905 | return mu_cfg_yylen; | ||
906 | } | ||
907 | # endif | ||
908 | # endif | ||
909 | |||
910 | # ifndef mu_cfg_yystpcpy | ||
911 | # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE | ||
912 | # define mu_cfg_yystpcpy stpcpy | ||
913 | # else | ||
914 | /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in | ||
915 | YYDEST. */ | ||
916 | #if (defined __STDC__ || defined __C99__FUNC__ \ | ||
917 | || defined __cplusplus || defined _MSC_VER) | ||
918 | static char * | ||
919 | mu_cfg_yystpcpy (char *mu_cfg_yydest, const char *mu_cfg_yysrc) | ||
920 | #else | ||
921 | static char * | ||
922 | mu_cfg_yystpcpy (mu_cfg_yydest, mu_cfg_yysrc) | ||
923 | char *mu_cfg_yydest; | ||
924 | const char *mu_cfg_yysrc; | ||
925 | #endif | ||
926 | { | ||
927 | char *mu_cfg_yyd = mu_cfg_yydest; | ||
928 | const char *mu_cfg_yys = mu_cfg_yysrc; | ||
929 | |||
930 | while ((*mu_cfg_yyd++ = *mu_cfg_yys++) != '\0') | ||
931 | continue; | ||
932 | |||
933 | return mu_cfg_yyd - 1; | ||
934 | } | ||
935 | # endif | ||
936 | # endif | ||
937 | |||
938 | # ifndef mu_cfg_yytnamerr | ||
939 | /* Copy to YYRES the contents of YYSTR after stripping away unnecessary | ||
940 | quotes and backslashes, so that it's suitable for mu_cfg_yyerror. The | ||
941 | heuristic is that double-quoting is unnecessary unless the string | ||
942 | contains an apostrophe, a comma, or backslash (other than | ||
943 | backslash-backslash). YYSTR is taken from mu_cfg_yytname. If YYRES is | ||
944 | null, do not copy; instead, return the length of what the result | ||
945 | would have been. */ | ||
946 | static YYSIZE_T | ||
947 | mu_cfg_yytnamerr (char *mu_cfg_yyres, const char *mu_cfg_yystr) | ||
948 | { | ||
949 | if (*mu_cfg_yystr == '"') | ||
950 | { | ||
951 | YYSIZE_T mu_cfg_yyn = 0; | ||
952 | char const *mu_cfg_yyp = mu_cfg_yystr; | ||
953 | |||
954 | for (;;) | ||
955 | switch (*++mu_cfg_yyp) | ||
956 | { | ||
957 | case '\'': | ||
958 | case ',': | ||
959 | goto do_not_strip_quotes; | ||
960 | |||
961 | case '\\': | ||
962 | if (*++mu_cfg_yyp != '\\') | ||
963 | goto do_not_strip_quotes; | ||
964 | /* Fall through. */ | ||
965 | default: | ||
966 | if (mu_cfg_yyres) | ||
967 | mu_cfg_yyres[mu_cfg_yyn] = *mu_cfg_yyp; | ||
968 | mu_cfg_yyn++; | ||
969 | break; | ||
970 | |||
971 | case '"': | ||
972 | if (mu_cfg_yyres) | ||
973 | mu_cfg_yyres[mu_cfg_yyn] = '\0'; | ||
974 | return mu_cfg_yyn; | ||
975 | } | ||
976 | do_not_strip_quotes: ; | ||
977 | } | ||
978 | |||
979 | if (! mu_cfg_yyres) | ||
980 | return mu_cfg_yystrlen (mu_cfg_yystr); | ||
981 | |||
982 | return mu_cfg_yystpcpy (mu_cfg_yyres, mu_cfg_yystr) - mu_cfg_yyres; | ||
983 | } | ||
984 | # endif | ||
985 | |||
986 | /* Copy into YYRESULT an error message about the unexpected token | ||
987 | YYCHAR while in state YYSTATE. Return the number of bytes copied, | ||
988 | including the terminating null byte. If YYRESULT is null, do not | ||
989 | copy anything; just return the number of bytes that would be | ||
990 | copied. As a special case, return 0 if an ordinary "syntax error" | ||
991 | message will do. Return YYSIZE_MAXIMUM if overflow occurs during | ||
992 | size calculation. */ | ||
993 | static YYSIZE_T | ||
994 | mu_cfg_yysyntax_error (char *mu_cfg_yyresult, int mu_cfg_yystate, int mu_cfg_yychar) | ||
995 | { | ||
996 | int mu_cfg_yyn = mu_cfg_yypact[mu_cfg_yystate]; | ||
997 | |||
998 | if (! (YYPACT_NINF < mu_cfg_yyn && mu_cfg_yyn <= YYLAST)) | ||
999 | return 0; | ||
1000 | else | ||
1001 | { | ||
1002 | int mu_cfg_yytype = YYTRANSLATE (mu_cfg_yychar); | ||
1003 | YYSIZE_T mu_cfg_yysize0 = mu_cfg_yytnamerr (0, mu_cfg_yytname[mu_cfg_yytype]); | ||
1004 | YYSIZE_T mu_cfg_yysize = mu_cfg_yysize0; | ||
1005 | YYSIZE_T mu_cfg_yysize1; | ||
1006 | int mu_cfg_yysize_overflow = 0; | ||
1007 | enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; | ||
1008 | char const *mu_cfg_yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; | ||
1009 | int mu_cfg_yyx; | ||
1010 | |||
1011 | # if 0 | ||
1012 | /* This is so xgettext sees the translatable formats that are | ||
1013 | constructed on the fly. */ | ||
1014 | YY_("syntax error, unexpected %s"); | ||
1015 | YY_("syntax error, unexpected %s, expecting %s"); | ||
1016 | YY_("syntax error, unexpected %s, expecting %s or %s"); | ||
1017 | YY_("syntax error, unexpected %s, expecting %s or %s or %s"); | ||
1018 | YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); | ||
1019 | # endif | ||
1020 | char *mu_cfg_yyfmt; | ||
1021 | char const *mu_cfg_yyf; | ||
1022 | static char const mu_cfg_yyunexpected[] = "syntax error, unexpected %s"; | ||
1023 | static char const mu_cfg_yyexpecting[] = ", expecting %s"; | ||
1024 | static char const mu_cfg_yyor[] = " or %s"; | ||
1025 | char mu_cfg_yyformat[sizeof mu_cfg_yyunexpected | ||
1026 | + sizeof mu_cfg_yyexpecting - 1 | ||
1027 | + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) | ||
1028 | * (sizeof mu_cfg_yyor - 1))]; | ||
1029 | char const *mu_cfg_yyprefix = mu_cfg_yyexpecting; | ||
1030 | |||
1031 | /* Start YYX at -YYN if negative to avoid negative indexes in | ||
1032 | YYCHECK. */ | ||
1033 | int mu_cfg_yyxbegin = mu_cfg_yyn < 0 ? -mu_cfg_yyn : 0; | ||
1034 | |||
1035 | /* Stay within bounds of both mu_cfg_yycheck and mu_cfg_yytname. */ | ||
1036 | int mu_cfg_yychecklim = YYLAST - mu_cfg_yyn + 1; | ||
1037 | int mu_cfg_yyxend = mu_cfg_yychecklim < YYNTOKENS ? mu_cfg_yychecklim : YYNTOKENS; | ||
1038 | int mu_cfg_yycount = 1; | ||
1039 | |||
1040 | mu_cfg_yyarg[0] = mu_cfg_yytname[mu_cfg_yytype]; | ||
1041 | mu_cfg_yyfmt = mu_cfg_yystpcpy (mu_cfg_yyformat, mu_cfg_yyunexpected); | ||
1042 | |||
1043 | for (mu_cfg_yyx = mu_cfg_yyxbegin; mu_cfg_yyx < mu_cfg_yyxend; ++mu_cfg_yyx) | ||
1044 | if (mu_cfg_yycheck[mu_cfg_yyx + mu_cfg_yyn] == mu_cfg_yyx && mu_cfg_yyx != YYTERROR) | ||
1045 | { | ||
1046 | if (mu_cfg_yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) | ||
1047 | { | ||
1048 | mu_cfg_yycount = 1; | ||
1049 | mu_cfg_yysize = mu_cfg_yysize0; | ||
1050 | mu_cfg_yyformat[sizeof mu_cfg_yyunexpected - 1] = '\0'; | ||
1051 | break; | ||
1052 | } | ||
1053 | mu_cfg_yyarg[mu_cfg_yycount++] = mu_cfg_yytname[mu_cfg_yyx]; | ||
1054 | mu_cfg_yysize1 = mu_cfg_yysize + mu_cfg_yytnamerr (0, mu_cfg_yytname[mu_cfg_yyx]); | ||
1055 | mu_cfg_yysize_overflow |= (mu_cfg_yysize1 < mu_cfg_yysize); | ||
1056 | mu_cfg_yysize = mu_cfg_yysize1; | ||
1057 | mu_cfg_yyfmt = mu_cfg_yystpcpy (mu_cfg_yyfmt, mu_cfg_yyprefix); | ||
1058 | mu_cfg_yyprefix = mu_cfg_yyor; | ||
1059 | } | ||
1060 | |||
1061 | mu_cfg_yyf = YY_(mu_cfg_yyformat); | ||
1062 | mu_cfg_yysize1 = mu_cfg_yysize + mu_cfg_yystrlen (mu_cfg_yyf); | ||
1063 | mu_cfg_yysize_overflow |= (mu_cfg_yysize1 < mu_cfg_yysize); | ||
1064 | mu_cfg_yysize = mu_cfg_yysize1; | ||
1065 | |||
1066 | if (mu_cfg_yysize_overflow) | ||
1067 | return YYSIZE_MAXIMUM; | ||
1068 | |||
1069 | if (mu_cfg_yyresult) | ||
1070 | { | ||
1071 | /* Avoid sprintf, as that infringes on the user's name space. | ||
1072 | Don't have undefined behavior even if the translation | ||
1073 | produced a string with the wrong number of "%s"s. */ | ||
1074 | char *mu_cfg_yyp = mu_cfg_yyresult; | ||
1075 | int mu_cfg_yyi = 0; | ||
1076 | while ((*mu_cfg_yyp = *mu_cfg_yyf) != '\0') | ||
1077 | { | ||
1078 | if (*mu_cfg_yyp == '%' && mu_cfg_yyf[1] == 's' && mu_cfg_yyi < mu_cfg_yycount) | ||
1079 | { | ||
1080 | mu_cfg_yyp += mu_cfg_yytnamerr (mu_cfg_yyp, mu_cfg_yyarg[mu_cfg_yyi++]); | ||
1081 | mu_cfg_yyf += 2; | ||
1082 | } | ||
1083 | else | ||
1084 | { | ||
1085 | mu_cfg_yyp++; | ||
1086 | mu_cfg_yyf++; | ||
1087 | } | ||
1088 | } | ||
1089 | } | ||
1090 | return mu_cfg_yysize; | ||
1091 | } | ||
1092 | } | ||
1093 | #endif /* YYERROR_VERBOSE */ | ||
1094 | |||
1095 | |||
1096 | /*-----------------------------------------------. | ||
1097 | | Release the memory associated to this symbol. | | ||
1098 | `-----------------------------------------------*/ | ||
1099 | |||
1100 | /*ARGSUSED*/ | ||
1101 | #if (defined __STDC__ || defined __C99__FUNC__ \ | ||
1102 | || defined __cplusplus || defined _MSC_VER) | ||
1103 | static void | ||
1104 | mu_cfg_yydestruct (const char *mu_cfg_yymsg, int mu_cfg_yytype, YYSTYPE *mu_cfg_yyvaluep) | ||
1105 | #else | ||
1106 | static void | ||
1107 | mu_cfg_yydestruct (mu_cfg_yymsg, mu_cfg_yytype, mu_cfg_yyvaluep) | ||
1108 | const char *mu_cfg_yymsg; | ||
1109 | int mu_cfg_yytype; | ||
1110 | YYSTYPE *mu_cfg_yyvaluep; | ||
1111 | #endif | ||
1112 | { | ||
1113 | YYUSE (mu_cfg_yyvaluep); | ||
1114 | |||
1115 | if (!mu_cfg_yymsg) | ||
1116 | mu_cfg_yymsg = "Deleting"; | ||
1117 | YY_SYMBOL_PRINT (mu_cfg_yymsg, mu_cfg_yytype, mu_cfg_yyvaluep, mu_cfg_yylocationp); | ||
1118 | |||
1119 | switch (mu_cfg_yytype) | ||
1120 | { | ||
1121 | |||
1122 | default: | ||
1123 | break; | ||
1124 | } | ||
1125 | } | ||
1126 | |||
1127 | |||
1128 | /* Prevent warnings from -Wmissing-prototypes. */ | ||
1129 | |||
1130 | #ifdef YYPARSE_PARAM | ||
1131 | #if defined __STDC__ || defined __cplusplus | ||
1132 | int mu_cfg_yyparse (void *YYPARSE_PARAM); | ||
1133 | #else | ||
1134 | int mu_cfg_yyparse (); | ||
1135 | #endif | ||
1136 | #else /* ! YYPARSE_PARAM */ | ||
1137 | #if defined __STDC__ || defined __cplusplus | ||
1138 | int mu_cfg_yyparse (void); | ||
1139 | #else | ||
1140 | int mu_cfg_yyparse (); | ||
1141 | #endif | ||
1142 | #endif /* ! YYPARSE_PARAM */ | ||
1143 | |||
1144 | |||
1145 | |||
1146 | /* The look-ahead symbol. */ | ||
1147 | int mu_cfg_yychar; | ||
1148 | |||
1149 | /* The semantic value of the look-ahead symbol. */ | ||
1150 | YYSTYPE mu_cfg_yylval; | ||
1151 | |||
1152 | /* Number of syntax errors so far. */ | ||
1153 | int mu_cfg_yynerrs; | ||
1154 | |||
1155 | |||
1156 | |||
1157 | /*----------. | ||
1158 | | mu_cfg_yyparse. | | ||
1159 | `----------*/ | ||
1160 | |||
1161 | #ifdef YYPARSE_PARAM | ||
1162 | #if (defined __STDC__ || defined __C99__FUNC__ \ | ||
1163 | || defined __cplusplus || defined _MSC_VER) | ||
1164 | int | ||
1165 | mu_cfg_yyparse (void *YYPARSE_PARAM) | ||
1166 | #else | ||
1167 | int | ||
1168 | mu_cfg_yyparse (YYPARSE_PARAM) | ||
1169 | void *YYPARSE_PARAM; | ||
1170 | #endif | ||
1171 | #else /* ! YYPARSE_PARAM */ | ||
1172 | #if (defined __STDC__ || defined __C99__FUNC__ \ | ||
1173 | || defined __cplusplus || defined _MSC_VER) | ||
1174 | int | ||
1175 | mu_cfg_yyparse (void) | ||
1176 | #else | ||
1177 | int | ||
1178 | mu_cfg_yyparse () | ||
1179 | |||
1180 | #endif | ||
1181 | #endif | ||
1182 | { | ||
1183 | |||
1184 | int mu_cfg_yystate; | ||
1185 | int mu_cfg_yyn; | ||
1186 | int mu_cfg_yyresult; | ||
1187 | /* Number of tokens to shift before error messages enabled. */ | ||
1188 | int mu_cfg_yyerrstatus; | ||
1189 | /* Look-ahead token as an internal (translated) token number. */ | ||
1190 | int mu_cfg_yytoken = 0; | ||
1191 | #if YYERROR_VERBOSE | ||
1192 | /* Buffer for error messages, and its allocated size. */ | ||
1193 | char mu_cfg_yymsgbuf[128]; | ||
1194 | char *mu_cfg_yymsg = mu_cfg_yymsgbuf; | ||
1195 | YYSIZE_T mu_cfg_yymsg_alloc = sizeof mu_cfg_yymsgbuf; | ||
1196 | #endif | ||
1197 | |||
1198 | /* Three stacks and their tools: | ||
1199 | `mu_cfg_yyss': related to states, | ||
1200 | `mu_cfg_yyvs': related to semantic values, | ||
1201 | `mu_cfg_yyls': related to locations. | ||
1202 | |||
1203 | Refer to the stacks thru separate pointers, to allow mu_cfg_yyoverflow | ||
1204 | to reallocate them elsewhere. */ | ||
1205 | |||
1206 | /* The state stack. */ | ||
1207 | mu_cfg_yytype_int16 mu_cfg_yyssa[YYINITDEPTH]; | ||
1208 | mu_cfg_yytype_int16 *mu_cfg_yyss = mu_cfg_yyssa; | ||
1209 | mu_cfg_yytype_int16 *mu_cfg_yyssp; | ||
1210 | |||
1211 | /* The semantic value stack. */ | ||
1212 | YYSTYPE mu_cfg_yyvsa[YYINITDEPTH]; | ||
1213 | YYSTYPE *mu_cfg_yyvs = mu_cfg_yyvsa; | ||
1214 | YYSTYPE *mu_cfg_yyvsp; | ||
1215 | |||
1216 | |||
1217 | |||
1218 | #define YYPOPSTACK(N) (mu_cfg_yyvsp -= (N), mu_cfg_yyssp -= (N)) | ||
1219 | |||
1220 | YYSIZE_T mu_cfg_yystacksize = YYINITDEPTH; | ||
1221 | |||
1222 | /* The variables used to return semantic value and location from the | ||
1223 | action routines. */ | ||
1224 | YYSTYPE mu_cfg_yyval; | ||
1225 | |||
1226 | |||
1227 | /* The number of symbols on the RHS of the reduced rule. | ||
1228 | Keep to zero when no symbol should be popped. */ | ||
1229 | int mu_cfg_yylen = 0; | ||
1230 | |||
1231 | YYDPRINTF ((stderr, "Starting parse\n")); | ||
1232 | |||
1233 | mu_cfg_yystate = 0; | ||
1234 | mu_cfg_yyerrstatus = 0; | ||
1235 | mu_cfg_yynerrs = 0; | ||
1236 | mu_cfg_yychar = YYEMPTY; /* Cause a token to be read. */ | ||
1237 | |||
1238 | /* Initialize stack pointers. | ||
1239 | Waste one element of value and location stack | ||
1240 | so that they stay on the same level as the state stack. | ||
1241 | The wasted elements are never initialized. */ | ||
1242 | |||
1243 | mu_cfg_yyssp = mu_cfg_yyss; | ||
1244 | mu_cfg_yyvsp = mu_cfg_yyvs; | ||
1245 | |||
1246 | goto mu_cfg_yysetstate; | ||
1247 | |||
1248 | /*------------------------------------------------------------. | ||
1249 | | mu_cfg_yynewstate -- Push a new state, which is found in mu_cfg_yystate. | | ||
1250 | `------------------------------------------------------------*/ | ||
1251 | mu_cfg_yynewstate: | ||
1252 | /* In all cases, when you get here, the value and location stacks | ||
1253 | have just been pushed. So pushing a state here evens the stacks. */ | ||
1254 | mu_cfg_yyssp++; | ||
1255 | |||
1256 | mu_cfg_yysetstate: | ||
1257 | *mu_cfg_yyssp = mu_cfg_yystate; | ||
1258 | |||
1259 | if (mu_cfg_yyss + mu_cfg_yystacksize - 1 <= mu_cfg_yyssp) | ||
1260 | { | ||
1261 | /* Get the current used size of the three stacks, in elements. */ | ||
1262 | YYSIZE_T mu_cfg_yysize = mu_cfg_yyssp - mu_cfg_yyss + 1; | ||
1263 | |||
1264 | #ifdef mu_cfg_yyoverflow | ||
1265 | { | ||
1266 | /* Give user a chance to reallocate the stack. Use copies of | ||
1267 | these so that the &'s don't force the real ones into | ||
1268 | memory. */ | ||
1269 | YYSTYPE *mu_cfg_yyvs1 = mu_cfg_yyvs; | ||
1270 | mu_cfg_yytype_int16 *mu_cfg_yyss1 = mu_cfg_yyss; | ||
1271 | |||
1272 | |||
1273 | /* Each stack pointer address is followed by the size of the | ||
1274 | data in use in that stack, in bytes. This used to be a | ||
1275 | conditional around just the two extra args, but that might | ||
1276 | be undefined if mu_cfg_yyoverflow is a macro. */ | ||
1277 | mu_cfg_yyoverflow (YY_("memory exhausted"), | ||
1278 | &mu_cfg_yyss1, mu_cfg_yysize * sizeof (*mu_cfg_yyssp), | ||
1279 | &mu_cfg_yyvs1, mu_cfg_yysize * sizeof (*mu_cfg_yyvsp), | ||
1280 | |||
1281 | &mu_cfg_yystacksize); | ||
1282 | |||
1283 | mu_cfg_yyss = mu_cfg_yyss1; | ||
1284 | mu_cfg_yyvs = mu_cfg_yyvs1; | ||
1285 | } | ||
1286 | #else /* no mu_cfg_yyoverflow */ | ||
1287 | # ifndef YYSTACK_RELOCATE | ||
1288 | goto mu_cfg_yyexhaustedlab; | ||
1289 | # else | ||
1290 | /* Extend the stack our own way. */ | ||
1291 | if (YYMAXDEPTH <= mu_cfg_yystacksize) | ||
1292 | goto mu_cfg_yyexhaustedlab; | ||
1293 | mu_cfg_yystacksize *= 2; | ||
1294 | if (YYMAXDEPTH < mu_cfg_yystacksize) | ||
1295 | mu_cfg_yystacksize = YYMAXDEPTH; | ||
1296 | |||
1297 | { | ||
1298 | mu_cfg_yytype_int16 *mu_cfg_yyss1 = mu_cfg_yyss; | ||
1299 | union mu_cfg_yyalloc *mu_cfg_yyptr = | ||
1300 | (union mu_cfg_yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (mu_cfg_yystacksize)); | ||
1301 | if (! mu_cfg_yyptr) | ||
1302 | goto mu_cfg_yyexhaustedlab; | ||
1303 | YYSTACK_RELOCATE (mu_cfg_yyss); | ||
1304 | YYSTACK_RELOCATE (mu_cfg_yyvs); | ||
1305 | |||
1306 | # undef YYSTACK_RELOCATE | ||
1307 | if (mu_cfg_yyss1 != mu_cfg_yyssa) | ||
1308 | YYSTACK_FREE (mu_cfg_yyss1); | ||
1309 | } | ||
1310 | # endif | ||
1311 | #endif /* no mu_cfg_yyoverflow */ | ||
1312 | |||
1313 | mu_cfg_yyssp = mu_cfg_yyss + mu_cfg_yysize - 1; | ||
1314 | mu_cfg_yyvsp = mu_cfg_yyvs + mu_cfg_yysize - 1; | ||
1315 | |||
1316 | |||
1317 | YYDPRINTF ((stderr, "Stack size increased to %lu\n", | ||
1318 | (unsigned long int) mu_cfg_yystacksize)); | ||
1319 | |||
1320 | if (mu_cfg_yyss + mu_cfg_yystacksize - 1 <= mu_cfg_yyssp) | ||
1321 | YYABORT; | ||
1322 | } | ||
1323 | |||
1324 | YYDPRINTF ((stderr, "Entering state %d\n", mu_cfg_yystate)); | ||
1325 | |||
1326 | goto mu_cfg_yybackup; | ||
1327 | |||
1328 | /*-----------. | ||
1329 | | mu_cfg_yybackup. | | ||
1330 | `-----------*/ | ||
1331 | mu_cfg_yybackup: | ||
1332 | |||
1333 | /* Do appropriate processing given the current state. Read a | ||
1334 | look-ahead token if we need one and don't already have one. */ | ||
1335 | |||
1336 | /* First try to decide what to do without reference to look-ahead token. */ | ||
1337 | mu_cfg_yyn = mu_cfg_yypact[mu_cfg_yystate]; | ||
1338 | if (mu_cfg_yyn == YYPACT_NINF) | ||
1339 | goto mu_cfg_yydefault; | ||
1340 | |||
1341 | /* Not known => get a look-ahead token if don't already have one. */ | ||
1342 | |||
1343 | /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ | ||
1344 | if (mu_cfg_yychar == YYEMPTY) | ||
1345 | { | ||
1346 | YYDPRINTF ((stderr, "Reading a token: ")); | ||
1347 | mu_cfg_yychar = YYLEX; | ||
1348 | } | ||
1349 | |||
1350 | if (mu_cfg_yychar <= YYEOF) | ||
1351 | { | ||
1352 | mu_cfg_yychar = mu_cfg_yytoken = YYEOF; | ||
1353 | YYDPRINTF ((stderr, "Now at end of input.\n")); | ||
1354 | } | ||
1355 | else | ||
1356 | { | ||
1357 | mu_cfg_yytoken = YYTRANSLATE (mu_cfg_yychar); | ||
1358 | YY_SYMBOL_PRINT ("Next token is", mu_cfg_yytoken, &mu_cfg_yylval, &mu_cfg_yylloc); | ||
1359 | } | ||
1360 | |||
1361 | /* If the proper action on seeing token YYTOKEN is to reduce or to | ||
1362 | detect an error, take that action. */ | ||
1363 | mu_cfg_yyn += mu_cfg_yytoken; | ||
1364 | if (mu_cfg_yyn < 0 || YYLAST < mu_cfg_yyn || mu_cfg_yycheck[mu_cfg_yyn] != mu_cfg_yytoken) | ||
1365 | goto mu_cfg_yydefault; | ||
1366 | mu_cfg_yyn = mu_cfg_yytable[mu_cfg_yyn]; | ||
1367 | if (mu_cfg_yyn <= 0) | ||
1368 | { | ||
1369 | if (mu_cfg_yyn == 0 || mu_cfg_yyn == YYTABLE_NINF) | ||
1370 | goto mu_cfg_yyerrlab; | ||
1371 | mu_cfg_yyn = -mu_cfg_yyn; | ||
1372 | goto mu_cfg_yyreduce; | ||
1373 | } | ||
1374 | |||
1375 | if (mu_cfg_yyn == YYFINAL) | ||
1376 | YYACCEPT; | ||
1377 | |||
1378 | /* Count tokens shifted since error; after three, turn off error | ||
1379 | status. */ | ||
1380 | if (mu_cfg_yyerrstatus) | ||
1381 | mu_cfg_yyerrstatus--; | ||
1382 | |||
1383 | /* Shift the look-ahead token. */ | ||
1384 | YY_SYMBOL_PRINT ("Shifting", mu_cfg_yytoken, &mu_cfg_yylval, &mu_cfg_yylloc); | ||
1385 | |||
1386 | /* Discard the shifted token unless it is eof. */ | ||
1387 | if (mu_cfg_yychar != YYEOF) | ||
1388 | mu_cfg_yychar = YYEMPTY; | ||
1389 | |||
1390 | mu_cfg_yystate = mu_cfg_yyn; | ||
1391 | *++mu_cfg_yyvsp = mu_cfg_yylval; | ||
1392 | |||
1393 | goto mu_cfg_yynewstate; | ||
1394 | |||
1395 | |||
1396 | /*-----------------------------------------------------------. | ||
1397 | | mu_cfg_yydefault -- do the default action for the current state. | | ||
1398 | `-----------------------------------------------------------*/ | ||
1399 | mu_cfg_yydefault: | ||
1400 | mu_cfg_yyn = mu_cfg_yydefact[mu_cfg_yystate]; | ||
1401 | if (mu_cfg_yyn == 0) | ||
1402 | goto mu_cfg_yyerrlab; | ||
1403 | goto mu_cfg_yyreduce; | ||
1404 | |||
1405 | |||
1406 | /*-----------------------------. | ||
1407 | | mu_cfg_yyreduce -- Do a reduction. | | ||
1408 | `-----------------------------*/ | ||
1409 | mu_cfg_yyreduce: | ||
1410 | /* mu_cfg_yyn is the number of a rule to reduce with. */ | ||
1411 | mu_cfg_yylen = mu_cfg_yyr2[mu_cfg_yyn]; | ||
1412 | |||
1413 | /* If YYLEN is nonzero, implement the default value of the action: | ||
1414 | `$$ = $1'. | ||
1415 | |||
1416 | Otherwise, the following line sets YYVAL to garbage. | ||
1417 | This behavior is undocumented and Bison | ||
1418 | users should not rely upon it. Assigning to YYVAL | ||
1419 | unconditionally makes the parser a bit smaller, and it avoids a | ||
1420 | GCC warning that YYVAL may be used uninitialized. */ | ||
1421 | mu_cfg_yyval = mu_cfg_yyvsp[1-mu_cfg_yylen]; | ||
1422 | |||
1423 | |||
1424 | YY_REDUCE_PRINT (mu_cfg_yyn); | ||
1425 | switch (mu_cfg_yyn) | ||
1426 | { | ||
1427 | case 2: | ||
1428 | #line 128 "cfg_parser.y" | ||
1429 | { | ||
1430 | parse_tree = (mu_cfg_yyvsp[(1) - (1)].nodelist).head; | ||
1431 | } | ||
1432 | break; | ||
1433 | |||
1434 | case 3: | ||
1435 | #line 134 "cfg_parser.y" | ||
1436 | { | ||
1437 | (mu_cfg_yyval.nodelist).head = (mu_cfg_yyval.nodelist).tail = (mu_cfg_yyvsp[(1) - (1)].pnode); | ||
1438 | } | ||
1439 | break; | ||
1440 | |||
1441 | case 4: | ||
1442 | #line 138 "cfg_parser.y" | ||
1443 | { | ||
1444 | (mu_cfg_yyval.nodelist) = (mu_cfg_yyvsp[(1) - (2)].nodelist); | ||
1445 | (mu_cfg_yyval.nodelist).tail->next = (mu_cfg_yyvsp[(2) - (2)].pnode); | ||
1446 | (mu_cfg_yyval.nodelist).tail = (mu_cfg_yyvsp[(2) - (2)].pnode); | ||
1447 | } | ||
1448 | break; | ||
1449 | |||
1450 | case 9: | ||
1451 | #line 154 "cfg_parser.y" | ||
1452 | { | ||
1453 | if ((mu_cfg_yyvsp[(4) - (5)].node).tag_name && strcmp ((mu_cfg_yyvsp[(4) - (5)].node).tag_name, (mu_cfg_yyvsp[(1) - (5)].node).tag_name)) | ||
1454 | { | ||
1455 | mu_cfg_perror (_mu_cfg_lexer_data, | ||
1456 | &(mu_cfg_yyvsp[(1) - (5)].node).locus, | ||
1457 | _("Tag %s not closed"), | ||
1458 | (mu_cfg_yyvsp[(1) - (5)].node).tag_name); | ||
1459 | mu_cfg_perror (_mu_cfg_lexer_data, | ||
1460 | &(mu_cfg_yyvsp[(4) - (5)].node).locus, | ||
1461 | _("Found closing %s tag instead"), | ||
1462 | (mu_cfg_yyvsp[(4) - (5)].node).tag_name); | ||
1463 | _mu_cfg_errcnt++; | ||
1464 | } | ||
1465 | (mu_cfg_yyval.pnode) = mu_cfg_alloc_node (mu_cfg_node_tag, &(mu_cfg_yyvsp[(1) - (5)].node).locus, | ||
1466 | (mu_cfg_yyvsp[(1) - (5)].node).tag_name, (mu_cfg_yyvsp[(1) - (5)].node).tag_label, (mu_cfg_yyvsp[(3) - (5)].nodelist).head); | ||
1467 | } | ||
1468 | break; | ||
1469 | |||
1470 | case 10: | ||
1471 | #line 170 "cfg_parser.y" | ||
1472 | { mu_cfg_tie_in++; } | ||
1473 | break; | ||
1474 | |||
1475 | case 11: | ||
1476 | #line 171 "cfg_parser.y" | ||
1477 | { mu_cfg_tie_in = 0; } | ||
1478 | break; | ||
1479 | |||
1480 | case 12: | ||
1481 | #line 172 "cfg_parser.y" | ||
1482 | { | ||
1483 | (mu_cfg_yyval.pnode) = mu_cfg_alloc_node (mu_cfg_node_param, &mu_cfg_locus, (mu_cfg_yyvsp[(1) - (5)].string), (mu_cfg_yyvsp[(3) - (5)].string), | ||
1484 | NULL); | ||
1485 | } | ||
1486 | break; | ||
1487 | |||
1488 | |||
1489 | /* Line 1267 of yacc.c. */ | ||
1490 | #line 1491 "cfg_parser.c" | ||
1491 | default: break; | ||
1492 | } | ||
1493 | YY_SYMBOL_PRINT ("-> $$ =", mu_cfg_yyr1[mu_cfg_yyn], &mu_cfg_yyval, &mu_cfg_yyloc); | ||
1494 | |||
1495 | YYPOPSTACK (mu_cfg_yylen); | ||
1496 | mu_cfg_yylen = 0; | ||
1497 | YY_STACK_PRINT (mu_cfg_yyss, mu_cfg_yyssp); | ||
1498 | |||
1499 | *++mu_cfg_yyvsp = mu_cfg_yyval; | ||
1500 | |||
1501 | |||
1502 | /* Now `shift' the result of the reduction. Determine what state | ||
1503 | that goes to, based on the state we popped back to and the rule | ||
1504 | number reduced by. */ | ||
1505 | |||
1506 | mu_cfg_yyn = mu_cfg_yyr1[mu_cfg_yyn]; | ||
1507 | |||
1508 | mu_cfg_yystate = mu_cfg_yypgoto[mu_cfg_yyn - YYNTOKENS] + *mu_cfg_yyssp; | ||
1509 | if (0 <= mu_cfg_yystate && mu_cfg_yystate <= YYLAST && mu_cfg_yycheck[mu_cfg_yystate] == *mu_cfg_yyssp) | ||
1510 | mu_cfg_yystate = mu_cfg_yytable[mu_cfg_yystate]; | ||
1511 | else | ||
1512 | mu_cfg_yystate = mu_cfg_yydefgoto[mu_cfg_yyn - YYNTOKENS]; | ||
1513 | |||
1514 | goto mu_cfg_yynewstate; | ||
1515 | |||
1516 | |||
1517 | /*------------------------------------. | ||
1518 | | mu_cfg_yyerrlab -- here on detecting error | | ||
1519 | `------------------------------------*/ | ||
1520 | mu_cfg_yyerrlab: | ||
1521 | /* If not already recovering from an error, report this error. */ | ||
1522 | if (!mu_cfg_yyerrstatus) | ||
1523 | { | ||
1524 | ++mu_cfg_yynerrs; | ||
1525 | #if ! YYERROR_VERBOSE | ||
1526 | mu_cfg_yyerror (YY_("syntax error")); | ||
1527 | #else | ||
1528 | { | ||
1529 | YYSIZE_T mu_cfg_yysize = mu_cfg_yysyntax_error (0, mu_cfg_yystate, mu_cfg_yychar); | ||
1530 | if (mu_cfg_yymsg_alloc < mu_cfg_yysize && mu_cfg_yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) | ||
1531 | { | ||
1532 | YYSIZE_T mu_cfg_yyalloc = 2 * mu_cfg_yysize; | ||
1533 | if (! (mu_cfg_yysize <= mu_cfg_yyalloc && mu_cfg_yyalloc <= YYSTACK_ALLOC_MAXIMUM)) | ||
1534 | mu_cfg_yyalloc = YYSTACK_ALLOC_MAXIMUM; | ||
1535 | if (mu_cfg_yymsg != mu_cfg_yymsgbuf) | ||
1536 | YYSTACK_FREE (mu_cfg_yymsg); | ||
1537 | mu_cfg_yymsg = (char *) YYSTACK_ALLOC (mu_cfg_yyalloc); | ||
1538 | if (mu_cfg_yymsg) | ||
1539 | mu_cfg_yymsg_alloc = mu_cfg_yyalloc; | ||
1540 | else | ||
1541 | { | ||
1542 | mu_cfg_yymsg = mu_cfg_yymsgbuf; | ||
1543 | mu_cfg_yymsg_alloc = sizeof mu_cfg_yymsgbuf; | ||
1544 | } | ||
1545 | } | ||
1546 | |||
1547 | if (0 < mu_cfg_yysize && mu_cfg_yysize <= mu_cfg_yymsg_alloc) | ||
1548 | { | ||
1549 | (void) mu_cfg_yysyntax_error (mu_cfg_yymsg, mu_cfg_yystate, mu_cfg_yychar); | ||
1550 | mu_cfg_yyerror (mu_cfg_yymsg); | ||
1551 | } | ||
1552 | else | ||
1553 | { | ||
1554 | mu_cfg_yyerror (YY_("syntax error")); | ||
1555 | if (mu_cfg_yysize != 0) | ||
1556 | goto mu_cfg_yyexhaustedlab; | ||
1557 | } | ||
1558 | } | ||
1559 | #endif | ||
1560 | } | ||
1561 | |||
1562 | |||
1563 | |||
1564 | if (mu_cfg_yyerrstatus == 3) | ||
1565 | { | ||
1566 | /* If just tried and failed to reuse look-ahead token after an | ||
1567 | error, discard it. */ | ||
1568 | |||
1569 | if (mu_cfg_yychar <= YYEOF) | ||
1570 | { | ||
1571 | /* Return failure if at end of input. */ | ||
1572 | if (mu_cfg_yychar == YYEOF) | ||
1573 | YYABORT; | ||
1574 | } | ||
1575 | else | ||
1576 | { | ||
1577 | mu_cfg_yydestruct ("Error: discarding", | ||
1578 | mu_cfg_yytoken, &mu_cfg_yylval); | ||
1579 | mu_cfg_yychar = YYEMPTY; | ||
1580 | } | ||
1581 | } | ||
1582 | |||
1583 | /* Else will try to reuse look-ahead token after shifting the error | ||
1584 | token. */ | ||
1585 | goto mu_cfg_yyerrlab1; | ||
1586 | |||
1587 | |||
1588 | /*---------------------------------------------------. | ||
1589 | | mu_cfg_yyerrorlab -- error raised explicitly by YYERROR. | | ||
1590 | `---------------------------------------------------*/ | ||
1591 | mu_cfg_yyerrorlab: | ||
1592 | |||
1593 | /* Pacify compilers like GCC when the user code never invokes | ||
1594 | YYERROR and the label mu_cfg_yyerrorlab therefore never appears in user | ||
1595 | code. */ | ||
1596 | if (/*CONSTCOND*/ 0) | ||
1597 | goto mu_cfg_yyerrorlab; | ||
1598 | |||
1599 | /* Do not reclaim the symbols of the rule which action triggered | ||
1600 | this YYERROR. */ | ||
1601 | YYPOPSTACK (mu_cfg_yylen); | ||
1602 | mu_cfg_yylen = 0; | ||
1603 | YY_STACK_PRINT (mu_cfg_yyss, mu_cfg_yyssp); | ||
1604 | mu_cfg_yystate = *mu_cfg_yyssp; | ||
1605 | goto mu_cfg_yyerrlab1; | ||
1606 | |||
1607 | |||
1608 | /*-------------------------------------------------------------. | ||
1609 | | mu_cfg_yyerrlab1 -- common code for both syntax error and YYERROR. | | ||
1610 | `-------------------------------------------------------------*/ | ||
1611 | mu_cfg_yyerrlab1: | ||
1612 | mu_cfg_yyerrstatus = 3; /* Each real token shifted decrements this. */ | ||
1613 | |||
1614 | for (;;) | ||
1615 | { | ||
1616 | mu_cfg_yyn = mu_cfg_yypact[mu_cfg_yystate]; | ||
1617 | if (mu_cfg_yyn != YYPACT_NINF) | ||
1618 | { | ||
1619 | mu_cfg_yyn += YYTERROR; | ||
1620 | if (0 <= mu_cfg_yyn && mu_cfg_yyn <= YYLAST && mu_cfg_yycheck[mu_cfg_yyn] == YYTERROR) | ||
1621 | { | ||
1622 | mu_cfg_yyn = mu_cfg_yytable[mu_cfg_yyn]; | ||
1623 | if (0 < mu_cfg_yyn) | ||
1624 | break; | ||
1625 | } | ||
1626 | } | ||
1627 | |||
1628 | /* Pop the current state because it cannot handle the error token. */ | ||
1629 | if (mu_cfg_yyssp == mu_cfg_yyss) | ||
1630 | YYABORT; | ||
1631 | |||
1632 | |||
1633 | mu_cfg_yydestruct ("Error: popping", | ||
1634 | mu_cfg_yystos[mu_cfg_yystate], mu_cfg_yyvsp); | ||
1635 | YYPOPSTACK (1); | ||
1636 | mu_cfg_yystate = *mu_cfg_yyssp; | ||
1637 | YY_STACK_PRINT (mu_cfg_yyss, mu_cfg_yyssp); | ||
1638 | } | ||
1639 | |||
1640 | if (mu_cfg_yyn == YYFINAL) | ||
1641 | YYACCEPT; | ||
1642 | |||
1643 | *++mu_cfg_yyvsp = mu_cfg_yylval; | ||
1644 | |||
1645 | |||
1646 | /* Shift the error token. */ | ||
1647 | YY_SYMBOL_PRINT ("Shifting", mu_cfg_yystos[mu_cfg_yyn], mu_cfg_yyvsp, mu_cfg_yylsp); | ||
1648 | |||
1649 | mu_cfg_yystate = mu_cfg_yyn; | ||
1650 | goto mu_cfg_yynewstate; | ||
1651 | |||
1652 | |||
1653 | /*-------------------------------------. | ||
1654 | | mu_cfg_yyacceptlab -- YYACCEPT comes here. | | ||
1655 | `-------------------------------------*/ | ||
1656 | mu_cfg_yyacceptlab: | ||
1657 | mu_cfg_yyresult = 0; | ||
1658 | goto mu_cfg_yyreturn; | ||
1659 | |||
1660 | /*-----------------------------------. | ||
1661 | | mu_cfg_yyabortlab -- YYABORT comes here. | | ||
1662 | `-----------------------------------*/ | ||
1663 | mu_cfg_yyabortlab: | ||
1664 | mu_cfg_yyresult = 1; | ||
1665 | goto mu_cfg_yyreturn; | ||
1666 | |||
1667 | #ifndef mu_cfg_yyoverflow | ||
1668 | /*-------------------------------------------------. | ||
1669 | | mu_cfg_yyexhaustedlab -- memory exhaustion comes here. | | ||
1670 | `-------------------------------------------------*/ | ||
1671 | mu_cfg_yyexhaustedlab: | ||
1672 | mu_cfg_yyerror (YY_("memory exhausted")); | ||
1673 | mu_cfg_yyresult = 2; | ||
1674 | /* Fall through. */ | ||
1675 | #endif | ||
1676 | |||
1677 | mu_cfg_yyreturn: | ||
1678 | if (mu_cfg_yychar != YYEOF && mu_cfg_yychar != YYEMPTY) | ||
1679 | mu_cfg_yydestruct ("Cleanup: discarding lookahead", | ||
1680 | mu_cfg_yytoken, &mu_cfg_yylval); | ||
1681 | /* Do not reclaim the symbols of the rule which action triggered | ||
1682 | this YYABORT or YYACCEPT. */ | ||
1683 | YYPOPSTACK (mu_cfg_yylen); | ||
1684 | YY_STACK_PRINT (mu_cfg_yyss, mu_cfg_yyssp); | ||
1685 | while (mu_cfg_yyssp != mu_cfg_yyss) | ||
1686 | { | ||
1687 | mu_cfg_yydestruct ("Cleanup: popping", | ||
1688 | mu_cfg_yystos[*mu_cfg_yyssp], mu_cfg_yyvsp); | ||
1689 | YYPOPSTACK (1); | ||
1690 | } | ||
1691 | #ifndef mu_cfg_yyoverflow | ||
1692 | if (mu_cfg_yyss != mu_cfg_yyssa) | ||
1693 | YYSTACK_FREE (mu_cfg_yyss); | ||
1694 | #endif | ||
1695 | #if YYERROR_VERBOSE | ||
1696 | if (mu_cfg_yymsg != mu_cfg_yymsgbuf) | ||
1697 | YYSTACK_FREE (mu_cfg_yymsg); | ||
1698 | #endif | ||
1699 | /* Make sure YYID is used. */ | ||
1700 | return YYID (mu_cfg_yyresult); | ||
1701 | } | ||
1702 | |||
1703 | |||
1704 | #line 178 "cfg_parser.y" | ||
1705 | |||
1706 | |||
1707 | int | ||
1708 | mu_cfg_parse (mu_cfg_node_t **ptree, | ||
1709 | void *data, mu_cfg_lexer_t lexer, | ||
1710 | mu_cfg_perror_t perror, | ||
1711 | mu_cfg_alloc_t palloc, mu_cfg_free_t pfree) | ||
1712 | { | ||
1713 | int rc; | ||
1714 | |||
1715 | _mu_cfg_lexer = lexer; | ||
1716 | _mu_cfg_lexer_data = data; | ||
1717 | mu_cfg_perror = perror ? perror : _mu_cfg_default_perror; | ||
1718 | _mu_cfg_alloc = palloc ? palloc : malloc; | ||
1719 | _mu_cfg_free = pfree ? pfree : free; | ||
1720 | _mu_cfg_errcnt = 0; | ||
1721 | mu_cfg_tie_in = 0; | ||
1722 | rc = mu_cfg_yyparse (); | ||
1723 | if (rc == 0 && _mu_cfg_errcnt) | ||
1724 | rc = 1; | ||
1725 | /* FIXME if (rc) free_memory; else */ | ||
1726 | *ptree = parse_tree; | ||
1727 | return rc; | ||
1728 | } | ||
1729 | |||
1730 | |||
1731 | |||
1732 | static void | ||
1733 | print_level (FILE *fp, int level) | ||
1734 | { | ||
1735 | while (level--) | ||
1736 | { | ||
1737 | fputc (' ', fp); | ||
1738 | fputc (' ', fp); | ||
1739 | } | ||
1740 | } | ||
1741 | |||
1742 | struct tree_print | ||
1743 | { | ||
1744 | unsigned level; | ||
1745 | FILE *fp; | ||
1746 | }; | ||
1747 | |||
1748 | int | ||
1749 | print_node (const mu_cfg_node_t *node, void *data) | ||
1750 | { | ||
1751 | struct tree_print *tp = data; | ||
1752 | |||
1753 | print_level (tp->fp, tp->level); | ||
1754 | switch (node->type) | ||
1755 | { | ||
1756 | case mu_cfg_node_undefined: | ||
1757 | fprintf (tp->fp, _("<UNDEFINED>")); | ||
1758 | break; | ||
1759 | |||
1760 | case mu_cfg_node_tag: | ||
1761 | fprintf (tp->fp, "<%s", node->tag_name); | ||
1762 | if (node->tag_label) | ||
1763 | fprintf (tp->fp, " %s", node->tag_label); | ||
1764 | fprintf (tp->fp, ">"); | ||
1765 | tp->level++; | ||
1766 | break; | ||
1767 | |||
1768 | case mu_cfg_node_param: | ||
1769 | fprintf (tp->fp, "%s", node->tag_name); | ||
1770 | if (node->tag_label) | ||
1771 | fprintf (tp->fp, " %s", node->tag_label); | ||
1772 | break; | ||
1773 | } | ||
1774 | fprintf (tp->fp, "\n"); | ||
1775 | return MU_CFG_ITER_OK; | ||
1776 | } | ||
1777 | |||
1778 | int | ||
1779 | print_node_end (const mu_cfg_node_t *node, void *data) | ||
1780 | { | ||
1781 | struct tree_print *tp = data; | ||
1782 | tp->level--; | ||
1783 | print_level (tp->fp, tp->level); | ||
1784 | fprintf (tp->fp, "</%s>\n", node->tag_name); | ||
1785 | return MU_CFG_ITER_OK; | ||
1786 | } | ||
1787 | |||
1788 | void | ||
1789 | mu_cfg_print_tree (FILE *fp, mu_cfg_node_t *node) | ||
1790 | { | ||
1791 | struct tree_print t; | ||
1792 | t.level = 0; | ||
1793 | t.fp = fp; | ||
1794 | mu_cfg_preorder (node, print_node, print_node_end, &t); | ||
1795 | } | ||
1796 | |||
1797 | |||
1798 | |||
1799 | static int | ||
1800 | _mu_cfg_preorder_recursive (mu_cfg_node_t *node, | ||
1801 | mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end, | ||
1802 | void *data) | ||
1803 | { | ||
1804 | switch (node->type) | ||
1805 | { | ||
1806 | case mu_cfg_node_undefined: | ||
1807 | abort (); | ||
1808 | |||
1809 | case mu_cfg_node_tag: | ||
1810 | switch (beg (node, data)) | ||
1811 | { | ||
1812 | case MU_CFG_ITER_OK: | ||
1813 | if (mu_cfg_preorder (node->node, beg, end, data)) | ||
1814 | return MU_CFG_ITER_STOP; | ||
1815 | if (end && end (node, data) == MU_CFG_ITER_STOP) | ||
1816 | return MU_CFG_ITER_STOP; | ||
1817 | break; | ||
1818 | |||
1819 | case MU_CFG_ITER_SKIP: | ||
1820 | break; | ||
1821 | |||
1822 | case MU_CFG_ITER_STOP: | ||
1823 | return MU_CFG_ITER_STOP; | ||
1824 | } | ||
1825 | break; | ||
1826 | |||
1827 | case mu_cfg_node_param: | ||
1828 | return beg (node, data); | ||
1829 | } | ||
1830 | return MU_CFG_ITER_OK; | ||
1831 | } | ||
1832 | |||
1833 | int | ||
1834 | mu_cfg_preorder(mu_cfg_node_t *node, | ||
1835 | mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end, void *data) | ||
1836 | { | ||
1837 | for (; node; node = node->next) | ||
1838 | if (_mu_cfg_preorder_recursive(node, beg, end, data) == MU_CFG_ITER_STOP) | ||
1839 | return 1; | ||
1840 | return 0; | ||
1841 | } | ||
1842 | |||
1843 | static int | ||
1844 | _mu_cfg_postorder_recursive(mu_cfg_node_t *node, | ||
1845 | mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end, | ||
1846 | void *data) | ||
1847 | { | ||
1848 | switch (node->type) | ||
1849 | { | ||
1850 | case mu_cfg_node_undefined: | ||
1851 | abort (); | ||
1852 | |||
1853 | case mu_cfg_node_tag: | ||
1854 | switch (beg (node, data)) | ||
1855 | { | ||
1856 | case MU_CFG_ITER_OK: | ||
1857 | if (mu_cfg_postorder (node->node, beg, end, data)) | ||
1858 | return MU_CFG_ITER_STOP; | ||
1859 | if (end && end (node, data) == MU_CFG_ITER_STOP) | ||
1860 | return MU_CFG_ITER_STOP; | ||
1861 | break; | ||
1862 | |||
1863 | case MU_CFG_ITER_SKIP: | ||
1864 | break; | ||
1865 | |||
1866 | case MU_CFG_ITER_STOP: | ||
1867 | return MU_CFG_ITER_STOP; | ||
1868 | } | ||
1869 | break; | ||
1870 | |||
1871 | case mu_cfg_node_param: | ||
1872 | return beg (node, data); | ||
1873 | } | ||
1874 | return 0; | ||
1875 | } | ||
1876 | |||
1877 | int | ||
1878 | mu_cfg_postorder (mu_cfg_node_t *node, | ||
1879 | mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end, void *data) | ||
1880 | { | ||
1881 | if (node->next | ||
1882 | && mu_cfg_postorder (node->next, beg, end, data) == MU_CFG_ITER_STOP) | ||
1883 | return 1; | ||
1884 | return _mu_cfg_postorder_recursive (node, beg, end, data) | ||
1885 | == MU_CFG_ITER_STOP; | ||
1886 | } | ||
1887 | |||
1888 | |||
1889 | static int | ||
1890 | free_section (const mu_cfg_node_t *node, void *data) | ||
1891 | { | ||
1892 | mu_cfg_free_t free_fn = data; | ||
1893 | if (node->type == mu_cfg_node_tag) | ||
1894 | free_fn ((void *) node); | ||
1895 | return MU_CFG_ITER_OK; | ||
1896 | } | ||
1897 | |||
1898 | static int | ||
1899 | free_param (const mu_cfg_node_t *node, void *data) | ||
1900 | { | ||
1901 | mu_cfg_free_t free_fn = data; | ||
1902 | if (node->type == mu_cfg_node_param) | ||
1903 | free_fn ((void*) node); | ||
1904 | return MU_CFG_ITER_OK; | ||
1905 | } | ||
1906 | |||
1907 | void | ||
1908 | mu_cfg_destroy_tree (mu_cfg_node_t **tree) | ||
1909 | { | ||
1910 | if (tree && *tree) | ||
1911 | { | ||
1912 | mu_cfg_postorder (*tree, free_param, free_section, _mu_cfg_free); | ||
1913 | *tree = NULL; | ||
1914 | } | ||
1915 | } | ||
1916 | |||
1917 | |||
1918 | |||
1919 | struct find_data | ||
1920 | { | ||
1921 | char *tag; | ||
1922 | char *label; | ||
1923 | char *next; | ||
1924 | const mu_cfg_node_t *node; | ||
1925 | }; | ||
1926 | |||
1927 | static void | ||
1928 | parse_tag (struct find_data *fptr) | ||
1929 | { | ||
1930 | char *p = strchr (fptr->tag, '='); | ||
1931 | if (p) | ||
1932 | { | ||
1933 | *p++ = 0; | ||
1934 | fptr->label = p; | ||
1935 | fptr->next = p + strlen (p) + 1; | ||
1936 | } | ||
1937 | else | ||
1938 | { | ||
1939 | fptr->label = NULL; | ||
1940 | fptr->next = fptr->tag + strlen (fptr->tag) + 1; | ||
1941 | } | ||
1942 | } | ||
1943 | |||
1944 | static int | ||
1945 | node_finder (const mu_cfg_node_t *node, void *data) | ||
1946 | { | ||
1947 | struct find_data *fdptr = data; | ||
1948 | if (strcmp (fdptr->tag, node->tag_name) == 0 | ||
1949 | && (!fdptr->label || strcmp (fdptr->label, node->tag_label) == 0)) | ||
1950 | { | ||
1951 | fdptr->tag = fdptr->next; | ||
1952 | parse_tag (fdptr); | ||
1953 | if (fdptr->tag[0] == 0) | ||
1954 | { | ||
1955 | fdptr->node = node; | ||
1956 | return MU_CFG_ITER_STOP; | ||
1957 | } | ||
1958 | } | ||
1959 | return MU_CFG_ITER_OK; | ||
1960 | } | ||
1961 | |||
1962 | int | ||
1963 | mu_cfg_find_node (mu_cfg_node_t *tree, const char *path, mu_cfg_node_t **pval) | ||
1964 | { | ||
1965 | int rc; | ||
1966 | char *p; | ||
1967 | char *xpath; | ||
1968 | size_t len; | ||
1969 | struct find_data data; | ||
1970 | |||
1971 | len = strlen (path) + 1; | ||
1972 | xpath = calloc (1, len + 1); | ||
1973 | if (!xpath) | ||
1974 | return 1; | ||
1975 | strcpy (xpath, path); | ||
1976 | xpath[len-1] = '/'; | ||
1977 | data.tag = xpath; | ||
1978 | for (p = data.tag; *p; p++) | ||
1979 | if (*p == '/') | ||
1980 | *p = 0; | ||
1981 | parse_tag (&data); | ||
1982 | rc = mu_cfg_preorder (tree, node_finder, NULL, &data); | ||
1983 | free (xpath); | ||
1984 | if (rc) | ||
1985 | { | ||
1986 | *pval = (mu_cfg_node_t *) data.node; | ||
1987 | return 0; | ||
1988 | } | ||
1989 | return MU_ERR_NOENT; | ||
1990 | } | ||
1991 | |||
1992 | int | ||
1993 | mu_cfg_find_node_label (mu_cfg_node_t *tree, const char *path, | ||
1994 | const char **pval) | ||
1995 | { | ||
1996 | mu_cfg_node_t *node; | ||
1997 | int rc = mu_cfg_find_node (tree, path, &node); | ||
1998 | if (rc) | ||
1999 | *pval = node->tag_label; | ||
2000 | return rc; | ||
2001 | } | ||
2002 | |||
2003 | |||
2004 | struct mu_cfg_section_list | ||
2005 | { | ||
2006 | struct mu_cfg_section_list *next; | ||
2007 | struct mu_cfg_section *sec; | ||
2008 | }; | ||
2009 | |||
2010 | struct scan_tree_data | ||
2011 | { | ||
2012 | struct mu_cfg_section_list *list; | ||
2013 | void *call_data; | ||
2014 | int error; | ||
2015 | }; | ||
2016 | |||
2017 | static struct mu_cfg_section * | ||
2018 | find_subsection (struct mu_cfg_section *sec, const char *ident, size_t len) | ||
2019 | { | ||
2020 | if (sec) | ||
2021 | { | ||
2022 | sec = sec->subsec; | ||
2023 | if (sec) | ||
2024 | { | ||
2025 | if (len == 0) | ||
2026 | len = strlen (ident); | ||
2027 | |||
2028 | for (; sec->ident; sec++) | ||
2029 | if (strlen (sec->ident) == len | ||
2030 | && memcmp (sec->ident, ident, len) == 0) | ||
2031 | return sec; | ||
2032 | } | ||
2033 | } | ||
2034 | return NULL; | ||
2035 | } | ||
2036 | |||
2037 | static struct mu_cfg_param * | ||
2038 | find_param (struct mu_cfg_section *sec, const char *ident, size_t len) | ||
2039 | { | ||
2040 | if (sec) | ||
2041 | { | ||
2042 | struct mu_cfg_param *p = sec->param; | ||
2043 | if (p) | ||
2044 | { | ||
2045 | if (len == 0) | ||
2046 | len = strlen (ident); | ||
2047 | for (; p->ident; p++) | ||
2048 | if (strlen (p->ident) == len && memcmp (p->ident, ident, len) == 0) | ||
2049 | return p; | ||
2050 | } | ||
2051 | } | ||
2052 | return NULL; | ||
2053 | } | ||
2054 | |||
2055 | static int | ||
2056 | push_section (struct scan_tree_data *dat, struct mu_cfg_section *sec) | ||
2057 | { | ||
2058 | struct mu_cfg_section_list *p = _mu_cfg_alloc (sizeof *p); | ||
2059 | if (!p) | ||
2060 | { | ||
2061 | mu_cfg_perror (dat->call_data, NULL, _("not enough memory")); | ||
2062 | return 1; | ||
2063 | } | ||
2064 | p->sec = sec; | ||
2065 | p->next = dat->list; | ||
2066 | dat->list = p; | ||
2067 | return 0; | ||
2068 | } | ||
2069 | |||
2070 | static struct mu_cfg_section * | ||
2071 | pop_section (struct scan_tree_data *dat) | ||
2072 | { | ||
2073 | struct mu_cfg_section_list *p = dat->list; | ||
2074 | struct mu_cfg_section *sec = p->sec; | ||
2075 | dat->list = p->next; | ||
2076 | _mu_cfg_free (p); | ||
2077 | return sec; | ||
2078 | } | ||
2079 | |||
2080 | #define STRTONUM(s, type, base, res, limit) \ | ||
2081 | { \ | ||
2082 | type sum = 0; \ | ||
2083 | \ | ||
2084 | while (*s) \ | ||
2085 | { \ | ||
2086 | type x; \ | ||
2087 | \ | ||
2088 | if ('0' <= *s && *s <= '9') \ | ||
2089 | x = sum * base + *s - '0'; \ | ||
2090 | else if (base == 16 && 'a' <= *s && *s <= 'f') \ | ||
2091 | x = sum * base + *s - 'a'; \ | ||
2092 | else if (base == 16 && 'A' <= *s && *s <= 'F') \ | ||
2093 | x = sum * base + *s - 'A'; \ | ||
2094 | else \ | ||
2095 | break; \ | ||
2096 | if (x <= sum) \ | ||
2097 | { \ | ||
2098 | mu_cfg_perror (sdata->call_data, \ | ||
2099 | &node->locus, \ | ||
2100 | _("numeric overflow")); \ | ||
2101 | return 1; \ | ||
2102 | } \ | ||
2103 | else if (limit && x > limit) \ | ||
2104 | { \ | ||
2105 | mu_cfg_perror (sdata->call_data, \ | ||
2106 | &node->locus, \ | ||
2107 | _("value out of allowed range")); \ | ||
2108 | return 1; \ | ||
2109 | } \ | ||
2110 | sum = x; \ | ||
2111 | *s++; \ | ||
2112 | } \ | ||
2113 | res = sum; \ | ||
2114 | } | ||
2115 | |||
2116 | #define STRxTONUM(s, type, res, limit) \ | ||
2117 | { \ | ||
2118 | int base; \ | ||
2119 | if (*s == '0') \ | ||
2120 | { \ | ||
2121 | s++; \ | ||
2122 | if (*s == 0) \ | ||
2123 | base = 10; \ | ||
2124 | else if (*s == 'x' || *s == 'X') \ | ||
2125 | { \ | ||
2126 | s++; \ | ||
2127 | base = 16; \ | ||
2128 | } \ | ||
2129 | else \ | ||
2130 | base = 8; \ | ||
2131 | } else \ | ||
2132 | base = 10; \ | ||
2133 | STRTONUM (s, type, base, res, limit); \ | ||
2134 | } | ||
2135 | |||
2136 | #define GETUNUM(str, type, res) \ | ||
2137 | { \ | ||
2138 | type tmpres; \ | ||
2139 | const char *s = str; \ | ||
2140 | STRxTONUM (s, type, tmpres, 0); \ | ||
2141 | if (*s) \ | ||
2142 | { \ | ||
2143 | mu_cfg_perror (sdata->call_data, \ | ||
2144 | &node->locus, \ | ||
2145 | _("not a number (stopped near `%s')"), \ | ||
2146 | s); \ | ||
2147 | return 1; \ | ||
2148 | } \ | ||
2149 | res = tmpres; \ | ||
2150 | } | ||
2151 | |||
2152 | #define GETSNUM(str, type, res) \ | ||
2153 | { \ | ||
2154 | unsigned type tmpres; \ | ||
2155 | const char *s = str; \ | ||
2156 | int sign; \ | ||
2157 | unsigned type limit; \ | ||
2158 | \ | ||
2159 | if (*s == '-') \ | ||
2160 | { \ | ||
2161 | sign++; \ | ||
2162 | s++; \ | ||
2163 | limit = TYPE_MINIMUM (type); \ | ||
2164 | limit = - limit; \ | ||
2165 | } \ | ||
2166 | else \ | ||
2167 | { \ | ||
2168 | sign = 0; \ | ||
2169 | limit = TYPE_MAXIMUM (type); \ | ||
2170 | } \ | ||
2171 | \ | ||
2172 | STRxTONUM (s, unsigned type, tmpres, limit); \ | ||
2173 | if (*s) \ | ||
2174 | { \ | ||
2175 | mu_cfg_perror (sdata->call_data, \ | ||
2176 | &node->locus, \ | ||
2177 | _("not a number (stopped near `%s')"), \ | ||
2178 | s); \ | ||
2179 | return 1; \ | ||
2180 | } \ | ||
2181 | res = sign ? - tmpres : tmpres; \ | ||
2182 | } | ||
2183 | |||
2184 | static int | ||
2185 | parse_ipv4 (struct scan_tree_data *sdata, const mu_cfg_node_t *node, | ||
2186 | struct in_addr *res) | ||
2187 | { | ||
2188 | struct in_addr addr; | ||
2189 | if (inet_aton (node->tag_label, &addr) == 0) | ||
2190 | { | ||
2191 | mu_cfg_perror (sdata->call_data, | ||
2192 | &node->locus, | ||
2193 | _("not an IPv4")); | ||
2194 | return 1; | ||
2195 | } | ||
2196 | addr.s_addr = ntohl (addr.s_addr); | ||
2197 | *res = addr; | ||
2198 | return 0; | ||
2199 | } | ||
2200 | |||
2201 | static int | ||
2202 | parse_host (struct scan_tree_data *sdata, const mu_cfg_node_t *node, | ||
2203 | struct in_addr *res) | ||
2204 | { | ||
2205 | struct in_addr addr; | ||
2206 | struct hostent *hp = gethostbyname (node->tag_label); | ||
2207 | if (hp) | ||
2208 | { | ||
2209 | addr.s_addr = *(unsigned long *)hp->h_addr; | ||
2210 | } | ||
2211 | else if (inet_aton(node->tag_label, &addr) == 0) | ||
2212 | { | ||
2213 | mu_cfg_perror (sdata->call_data, | ||
2214 | &node->locus, | ||
2215 | _("cannot resolve hostname `%s'"), | ||
2216 | node->tag_label); | ||
2217 | return 1; | ||
2218 | } | ||
2219 | addr.s_addr = ntohl (addr.s_addr); | ||
2220 | *res = addr; | ||
2221 | return 0; | ||
2222 | } | ||
2223 | |||
2224 | static int | ||
2225 | parse_cidr (struct scan_tree_data *sdata, const mu_cfg_node_t *node, | ||
2226 | mu_cfg_cidr_t *res) | ||
2227 | { | ||
2228 | struct in_addr addr; | ||
2229 | unsigned long mask; | ||
2230 | char astr[16], *p, *s; | ||
2231 | |||
2232 | p = strchr (node->tag_label, '/'); | ||
2233 | if (*p) | ||
2234 | { | ||
2235 | int len = p - node->tag_label; | ||
2236 | if (len > sizeof astr - 1) { | ||
2237 | mu_cfg_perror (sdata->call_data, | ||
2238 | &node->locus, | ||
2239 | _("not a valid IPv4 address in CIDR")); | ||
2240 | return 1; | ||
2241 | } | ||
2242 | memcpy (astr, node->tag_label, len); | ||
2243 | astr[len] = 0; | ||
2244 | if (inet_aton (astr, &addr) == 0) | ||
2245 | { | ||
2246 | mu_cfg_perror (sdata->call_data, | ||
2247 | &node->locus, | ||
2248 | _("not a valid IPv4 address in CIDR")); | ||
2249 | return 1; | ||
2250 | } | ||
2251 | addr.s_addr = ntohl (addr.s_addr); | ||
2252 | |||
2253 | p++; | ||
2254 | s = p; | ||
2255 | STRxTONUM (s, unsigned long, mask, 0); | ||
2256 | if (*s == '.') | ||
2257 | { | ||
2258 | struct in_addr a; | ||
2259 | if (inet_aton (p, &a) == 0) | ||
2260 | { | ||
2261 | mu_cfg_perror (sdata->call_data, | ||
2262 | &node->locus, | ||
2263 | _("not a valid network in CIDR")); | ||
2264 | return 1; | ||
2265 | } | ||
2266 | a.s_addr = ntohl (a.s_addr); | ||
2267 | for (mask = 0; (a.s_addr & 1) == 0 && mask < 32; ) | ||
2268 | { | ||
2269 | mask++; | ||
2270 | a.s_addr >>= 1; | ||
2271 | } | ||
2272 | mask = 32 - mask; | ||
2273 | } | ||
2274 | else if (mask > 32) | ||
2275 | { | ||
2276 | mu_cfg_perror (sdata->call_data, | ||
2277 | &node->locus, | ||
2278 | _("not a valid network mask in CIDR")); | ||
2279 | return 1; | ||
2280 | } | ||
2281 | } | ||
2282 | else | ||
2283 | { | ||
2284 | int i; | ||
2285 | unsigned short x; | ||
2286 | addr.s_addr = 0; | ||
2287 | |||
2288 | for (i = 0; i < 3; i++) | ||
2289 | { | ||
2290 | STRxTONUM(p, unsigned short, x, 255); | ||
2291 | if (*p != '.') | ||
2292 | break; | ||
2293 | addr.s_addr = (addr.s_addr << 8) + x; | ||
2294 | } | ||
2295 | |||
2296 | if (*p) | ||
2297 | { | ||
2298 | mu_cfg_perror (sdata->call_data, | ||
2299 | &node->locus, | ||
2300 | _("not a CIDR (stopped near `%s')"), | ||
2301 | p); | ||
2302 | return 1; | ||
2303 | } | ||
2304 | |||
2305 | mask = i * 8; | ||
2306 | |||
2307 | addr.s_addr <<= (4 - i) * 8; | ||
2308 | } | ||
2309 | |||
2310 | res->addr = addr; | ||
2311 | res->mask = mask; | ||
2312 | return 0; | ||
2313 | } | ||
2314 | |||
2315 | static int | ||
2316 | parse_bool (struct scan_tree_data *sdata, const mu_cfg_node_t *node, int *res) | ||
2317 | { | ||
2318 | if (strcmp (node->tag_label, "yes") == 0 | ||
2319 | || strcmp (node->tag_label, "on") == 0 | ||
2320 | || strcmp (node->tag_label, "t") == 0 | ||
2321 | || strcmp (node->tag_label, "true") == 0 | ||
2322 | || strcmp (node->tag_label, "1") == 0) | ||
2323 | *res = 1; | ||
2324 | else if (strcmp (node->tag_label, "no") == 0 | ||
2325 | || strcmp (node->tag_label, "off") == 0 | ||
2326 | || strcmp (node->tag_label, "nil") == 0 | ||
2327 | || strcmp (node->tag_label, "false") == 0 | ||
2328 | || strcmp (node->tag_label, "0") == 0) | ||
2329 | *res = 0; | ||
2330 | else | ||
2331 | { | ||
2332 | mu_cfg_perror (sdata->call_data, &node->locus, _("not a boolean")); | ||
2333 | return 1; | ||
2334 | } | ||
2335 | return 0; | ||
2336 | } | ||
2337 | |||
2338 | static int | ||
2339 | parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) | ||
2340 | { | ||
2341 | struct mu_cfg_param *param = find_param (sdata->list->sec, node->tag_name, | ||
2342 | 0); | ||
2343 | if (!param) | ||
2344 | { | ||
2345 | mu_cfg_perror (sdata->call_data, | ||
2346 | &node->locus, | ||
2347 | _("unknown keyword `%s'"), | ||
2348 | node->tag_name); | ||
2349 | return 1; | ||
2350 | } | ||
2351 | |||
2352 | switch (param->type) | ||
2353 | { | ||
2354 | case mu_cfg_string: | ||
2355 | { | ||
2356 | size_t len = strlen (node->tag_label); | ||
2357 | char *s = _mu_cfg_alloc (len + 1); | ||
2358 | if (!s) | ||
2359 | { | ||
2360 | mu_cfg_perror (sdata->call_data, | ||
2361 | &node->locus, | ||
2362 | _("not enough memory")); | ||
2363 | return 1; | ||
2364 | } | ||
2365 | strcpy (s, node->tag_label); | ||
2366 | /* FIXME: free param->data? */ | ||
2367 | *(char**)param->data = s; | ||
2368 | break; | ||
2369 | } | ||
2370 | |||
2371 | case mu_cfg_short: | ||
2372 | GETSNUM (node->tag_label, short, *(short*)param->data); | ||
2373 | break; | ||
2374 | |||
2375 | case mu_cfg_ushort: | ||
2376 | GETUNUM (node->tag_label, unsigned short, *(unsigned short*)param->data); | ||
2377 | break; | ||
2378 | |||
2379 | case mu_cfg_int: | ||
2380 | GETSNUM (node->tag_label, int, *(int*)param->data); | ||
2381 | break; | ||
2382 | |||
2383 | case mu_cfg_uint: | ||
2384 | GETUNUM (node->tag_label, unsigned int, *(unsigned int*)param->data); | ||
2385 | break; | ||
2386 | |||
2387 | case mu_cfg_long: | ||
2388 | GETSNUM (node->tag_label, long, *(long*)param->data); | ||
2389 | break; | ||
2390 | |||
2391 | case mu_cfg_ulong: | ||
2392 | GETUNUM (node->tag_label, unsigned long, *(unsigned long*)param->data); | ||
2393 | break; | ||
2394 | |||
2395 | case mu_cfg_size: | ||
2396 | GETUNUM (node->tag_label, size_t, *(size_t*)param->data); | ||
2397 | break; | ||
2398 | |||
2399 | case mu_cfg_off: | ||
2400 | mu_cfg_perror (sdata->call_data, &node->locus, _("not implemented yet")); | ||
2401 | /* GETSNUM(node->tag_label, off_t, *(off_t*)param->data); */ | ||
2402 | return 1; | ||
2403 | |||
2404 | case mu_cfg_bool: | ||
2405 | if (parse_bool (sdata, node, (int*) param->data)) | ||
2406 | return 1; | ||
2407 | break; | ||
2408 | |||
2409 | case mu_cfg_ipv4: | ||
2410 | if (parse_ipv4 (sdata, node, (struct in_addr *)param->data)) | ||
2411 | return 1; | ||
2412 | break; | ||
2413 | |||
2414 | case mu_cfg_cidr: | ||
2415 | if (parse_cidr (sdata, node, (mu_cfg_cidr_t *)param->data)) | ||
2416 | return 1; | ||
2417 | break; | ||
2418 | |||
2419 | case mu_cfg_host: | ||
2420 | if (parse_host (sdata, node, (struct in_addr *)param->data)) | ||
2421 | return 1; | ||
2422 | break; | ||
2423 | |||
2424 | case mu_cfg_callback: | ||
2425 | if (param->callback (&node->locus, param->data, node->tag_label)) | ||
2426 | return 1; | ||
2427 | break; | ||
2428 | |||
2429 | default: | ||
2430 | abort (); | ||
2431 | } | ||
2432 | return 0; | ||
2433 | } | ||
2434 | |||
2435 | |||
2436 | static int | ||
2437 | _scan_tree_helper (const mu_cfg_node_t *node, void *data) | ||
2438 | { | ||
2439 | struct scan_tree_data *sdata = data; | ||
2440 | struct mu_cfg_section *sec; | ||
2441 | |||
2442 | switch (node->type) | ||
2443 | { | ||
2444 | case mu_cfg_node_undefined: | ||
2445 | abort (); | ||
2446 | |||
2447 | case mu_cfg_node_tag: | ||
2448 | sec = find_subsection (sdata->list->sec, node->tag_name, 0); | ||
2449 | if (!sec) | ||
2450 | { | ||
2451 | mu_cfg_perror (sdata->call_data, | ||
2452 | &node->locus, | ||
2453 | _("unknown section `%s'"), | ||
2454 | node->tag_name); | ||
2455 | sdata->error++; | ||
2456 | return MU_CFG_ITER_SKIP; | ||
2457 | } | ||
2458 | if (!sec->subsec && !sec->param) | ||
2459 | return MU_CFG_ITER_SKIP; | ||
2460 | if (sec->parser && | ||
2461 | sec->parser (mu_cfg_section_start, node, | ||
2462 | sec->data, sdata->call_data)) | ||
2463 | { | ||
2464 | sdata->error++; | ||
2465 | return MU_CFG_ITER_SKIP; | ||
2466 | } | ||
2467 | push_section(sdata, sec); | ||
2468 | break; | ||
2469 | |||
2470 | case mu_cfg_node_param: | ||
2471 | if (parse_param (sdata, node)) | ||
2472 | { | ||
2473 | sdata->error++; | ||
2474 | return MU_CFG_ITER_SKIP; | ||
2475 | } | ||
2476 | break; | ||
2477 | } | ||
2478 | return MU_CFG_ITER_OK; | ||
2479 | } | ||
2480 | |||
2481 | static int | ||
2482 | _scan_tree_end_helper (const mu_cfg_node_t *node, void *data) | ||
2483 | { | ||
2484 | struct scan_tree_data *sdata = data; | ||
2485 | struct mu_cfg_section *sec; | ||
2486 | |||
2487 | switch (node->type) | ||
2488 | { | ||
2489 | default: | ||
2490 | abort (); | ||
2491 | |||
2492 | case mu_cfg_node_tag: | ||
2493 | sec = pop_section (sdata); | ||
2494 | if (sec && sec->parser) | ||
2495 | { | ||
2496 | if (sec->parser (mu_cfg_section_end, node, sec->data, | ||
2497 | sdata->call_data)) | ||
2498 | { | ||
2499 | sdata->error++; | ||
2500 | return MU_CFG_ITER_SKIP; | ||
2501 | } | ||
2502 | } | ||
2503 | } | ||
2504 | return MU_CFG_ITER_OK; | ||
2505 | } | ||
2506 | |||
2507 | int | ||
2508 | mu_cfg_scan_tree (mu_cfg_node_t *node, | ||
2509 | struct mu_cfg_section *sections, | ||
2510 | void *data, mu_cfg_perror_t perror, | ||
2511 | mu_cfg_alloc_t palloc, mu_cfg_free_t pfree) | ||
2512 | { | ||
2513 | struct scan_tree_data dat; | ||
2514 | dat.list = NULL; | ||
2515 | mu_cfg_perror = perror ? perror : _mu_cfg_default_perror; | ||
2516 | _mu_cfg_alloc = palloc ? palloc : malloc; | ||
2517 | _mu_cfg_free = pfree ? pfree : free; | ||
2518 | dat.call_data = data; | ||
2519 | dat.error = 0; | ||
2520 | if (push_section (&dat, sections)) | ||
2521 | return 1; | ||
2522 | mu_cfg_preorder (node, _scan_tree_helper, _scan_tree_end_helper, &dat); | ||
2523 | pop_section (&dat); | ||
2524 | return dat.error; | ||
2525 | } | ||
2526 | |||
2527 | int | ||
2528 | mu_cfg_find_section (struct mu_cfg_section *root_sec, | ||
2529 | const char *path, struct mu_cfg_section **retval) | ||
2530 | { | ||
2531 | while (path[0]) | ||
2532 | { | ||
2533 | struct mu_cfg_section *sec; | ||
2534 | size_t len; | ||
2535 | const char *p; | ||
2536 | |||
2537 | while (*path == '/') | ||
2538 | path++; | ||
2539 | |||
2540 | if (*path == 0) | ||
2541 | return MU_ERR_NOENT; | ||
2542 | |||
2543 | p = strchr (path, '/'); | ||
2544 | if (p) | ||
2545 | len = p - path; | ||
2546 | else | ||
2547 | len = strlen (path); | ||
2548 | |||
2549 | sec = find_subsection (root_sec, path, len); | ||
2550 | if (!sec) | ||
2551 | return MU_ERR_NOENT; | ||
2552 | root_sec = sec; | ||
2553 | path += len; | ||
2554 | } | ||
2555 | if (retval) | ||
2556 | *retval = root_sec; | ||
2557 | return 0; | ||
2558 | } | ||
2559 | |||
2560 | |||
2561 | |||
2562 | |||
2563 |
mailbox/cfg_parser.y
0 → 100644
1 | %{ | ||
2 | /* cfg_parser.y -- general-purpose configuration file parser | ||
3 | Copyright (C) 2007 Free Software Foundation, Inc. | ||
4 | |||
5 | GNU Mailutils is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU General Public License as | ||
7 | published by the Free Software Foundation; either version 3, or (at | ||
8 | your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <stdio.h> | ||
20 | #include <stdlib.h> | ||
21 | #include <stdarg.h> | ||
22 | #include <string.h> | ||
23 | #include <netdb.h> | ||
24 | #include "intprops.h" | ||
25 | #include <mailutils/nls.h> | ||
26 | #include <mailutils/cfg.h> | ||
27 | #include <mailutils/errno.h> | ||
28 | #include <mailutils/error.h> | ||
29 | |||
30 | static mu_cfg_node_t *parse_tree; | ||
31 | mu_cfg_locus_t mu_cfg_locus; | ||
32 | int mu_cfg_tie_in; | ||
33 | |||
34 | static int _mu_cfg_errcnt; | ||
35 | static mu_cfg_lexer_t _mu_cfg_lexer; | ||
36 | mu_cfg_perror_t mu_cfg_perror; | ||
37 | static void *_mu_cfg_lexer_data; | ||
38 | mu_cfg_alloc_t _mu_cfg_alloc; | ||
39 | mu_cfg_free_t _mu_cfg_free; | ||
40 | |||
41 | static int | ||
42 | yyerror (char *s) | ||
43 | { | ||
44 | mu_cfg_perror (_mu_cfg_lexer_data, &mu_cfg_locus, "%s", s); | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static int | ||
49 | yylex () | ||
50 | { | ||
51 | return _mu_cfg_lexer (_mu_cfg_lexer_data); | ||
52 | } | ||
53 | |||
54 | static mu_cfg_node_t * | ||
55 | mu_cfg_alloc_node (enum mu_cfg_node_type type, mu_cfg_locus_t *loc, | ||
56 | char *tag, char *label, mu_cfg_node_t *node) | ||
57 | { | ||
58 | char *p; | ||
59 | mu_cfg_node_t *np; | ||
60 | size_t size = sizeof *np + strlen (tag) + 1 | ||
61 | + (label ? (strlen (label) + 1) : 0); | ||
62 | np = _mu_cfg_alloc (size); | ||
63 | if (!np) | ||
64 | { | ||
65 | mu_cfg_perror (_mu_cfg_lexer_data, &mu_cfg_locus, | ||
66 | _("Not enough memory")); | ||
67 | abort(); | ||
68 | } | ||
69 | np->type = type; | ||
70 | np->locus = *loc; | ||
71 | p = (char*) (np + 1); | ||
72 | np->tag_name = p; | ||
73 | strcpy (p, tag); | ||
74 | p += strlen (p) + 1; | ||
75 | if (label) | ||
76 | { | ||
77 | np->tag_label = p; | ||
78 | strcpy (p, label); | ||
79 | } | ||
80 | else | ||
81 | np->tag_label = label; | ||
82 | np->node = node; | ||
83 | np->next = NULL; | ||
84 | return np; | ||
85 | } | ||
86 | |||
87 | static void | ||
88 | _mu_cfg_default_perror (void *ptr, const mu_cfg_locus_t *loc, | ||
89 | const char *fmt, ...) | ||
90 | { | ||
91 | va_list ap; | ||
92 | |||
93 | fprintf (stderr, "%s:", loc->file ? loc->file : _("unknown file")); | ||
94 | if (loc->line > 0) | ||
95 | fprintf (stderr, "%lu", (unsigned long) loc->line); | ||
96 | else | ||
97 | fprintf (stderr, "%s", _("unknown line")); | ||
98 | fprintf (stderr, ": "); | ||
99 | va_start (ap, fmt); | ||
100 | vfprintf (stderr, fmt, ap); | ||
101 | va_end (ap); | ||
102 | fprintf (stderr, "\n"); | ||
103 | } | ||
104 | |||
105 | %} | ||
106 | |||
107 | %token MU_CFG_EOL_TOKEN | ||
108 | %token <node> MU_CFG_START_TOKEN MU_CFG_END_TOKEN | ||
109 | %token <string> MU_CFG_STRING_TOKEN | ||
110 | |||
111 | %type <pnode> tag | ||
112 | %type <nodelist> taglist | ||
113 | |||
114 | %union | ||
115 | { | ||
116 | mu_cfg_node_t node; | ||
117 | mu_cfg_node_t *pnode; | ||
118 | struct | ||
119 | { | ||
120 | mu_cfg_node_t *head, *tail; | ||
121 | } nodelist; | ||
122 | char *string; | ||
123 | }; | ||
124 | |||
125 | %% | ||
126 | |||
127 | input : taglist | ||
128 | { | ||
129 | parse_tree = $1.head; | ||
130 | } | ||
131 | ; | ||
132 | |||
133 | taglist : tag | ||
134 | { | ||
135 | $$.head = $$.tail = $1; | ||
136 | } | ||
137 | | taglist tag | ||
138 | { | ||
139 | $$ = $1; | ||
140 | $$.tail->next = $2; | ||
141 | $$.tail = $2; | ||
142 | } | ||
143 | ; | ||
144 | |||
145 | opt_eol : /* empty */ | ||
146 | | eol | ||
147 | ; | ||
148 | |||
149 | eol : MU_CFG_EOL_TOKEN | ||
150 | | eol MU_CFG_EOL_TOKEN | ||
151 | ; | ||
152 | |||
153 | tag : MU_CFG_START_TOKEN opt_eol taglist MU_CFG_END_TOKEN MU_CFG_EOL_TOKEN | ||
154 | { | ||
155 | if ($4.tag_name && strcmp ($4.tag_name, $1.tag_name)) | ||
156 | { | ||
157 | mu_cfg_perror (_mu_cfg_lexer_data, | ||
158 | &$1.locus, | ||
159 | _("Tag %s not closed"), | ||
160 | $1.tag_name); | ||
161 | mu_cfg_perror (_mu_cfg_lexer_data, | ||
162 | &$4.locus, | ||
163 | _("Found closing %s tag instead"), | ||
164 | $4.tag_name); | ||
165 | _mu_cfg_errcnt++; | ||
166 | } | ||
167 | $$ = mu_cfg_alloc_node (mu_cfg_node_tag, &$1.locus, | ||
168 | $1.tag_name, $1.tag_label, $3.head); | ||
169 | } | ||
170 | | MU_CFG_STRING_TOKEN { mu_cfg_tie_in++; } | ||
171 | MU_CFG_STRING_TOKEN { mu_cfg_tie_in = 0; } MU_CFG_EOL_TOKEN | ||
172 | { | ||
173 | $$ = mu_cfg_alloc_node (mu_cfg_node_param, &mu_cfg_locus, $1, $3, | ||
174 | NULL); | ||
175 | } | ||
176 | ; | ||
177 | |||
178 | %% | ||
179 | |||
180 | int | ||
181 | mu_cfg_parse (mu_cfg_node_t **ptree, | ||
182 | void *data, mu_cfg_lexer_t lexer, | ||
183 | mu_cfg_perror_t perror, | ||
184 | mu_cfg_alloc_t palloc, mu_cfg_free_t pfree) | ||
185 | { | ||
186 | int rc; | ||
187 | |||
188 | _mu_cfg_lexer = lexer; | ||
189 | _mu_cfg_lexer_data = data; | ||
190 | mu_cfg_perror = perror ? perror : _mu_cfg_default_perror; | ||
191 | _mu_cfg_alloc = palloc ? palloc : malloc; | ||
192 | _mu_cfg_free = pfree ? pfree : free; | ||
193 | _mu_cfg_errcnt = 0; | ||
194 | mu_cfg_tie_in = 0; | ||
195 | rc = yyparse (); | ||
196 | if (rc == 0 && _mu_cfg_errcnt) | ||
197 | rc = 1; | ||
198 | /* FIXME if (rc) free_memory; else */ | ||
199 | *ptree = parse_tree; | ||
200 | return rc; | ||
201 | } | ||
202 | |||
203 | |||
204 | |||
205 | static void | ||
206 | print_level (FILE *fp, int level) | ||
207 | { | ||
208 | while (level--) | ||
209 | { | ||
210 | fputc (' ', fp); | ||
211 | fputc (' ', fp); | ||
212 | } | ||
213 | } | ||
214 | |||
215 | struct tree_print | ||
216 | { | ||
217 | unsigned level; | ||
218 | FILE *fp; | ||
219 | }; | ||
220 | |||
221 | int | ||
222 | print_node (const mu_cfg_node_t *node, void *data) | ||
223 | { | ||
224 | struct tree_print *tp = data; | ||
225 | |||
226 | print_level (tp->fp, tp->level); | ||
227 | switch (node->type) | ||
228 | { | ||
229 | case mu_cfg_node_undefined: | ||
230 | fprintf (tp->fp, _("<UNDEFINED>")); | ||
231 | break; | ||
232 | |||
233 | case mu_cfg_node_tag: | ||
234 | fprintf (tp->fp, "<%s", node->tag_name); | ||
235 | if (node->tag_label) | ||
236 | fprintf (tp->fp, " %s", node->tag_label); | ||
237 | fprintf (tp->fp, ">"); | ||
238 | tp->level++; | ||
239 | break; | ||
240 | |||
241 | case mu_cfg_node_param: | ||
242 | fprintf (tp->fp, "%s", node->tag_name); | ||
243 | if (node->tag_label) | ||
244 | fprintf (tp->fp, " %s", node->tag_label); | ||
245 | break; | ||
246 | } | ||
247 | fprintf (tp->fp, "\n"); | ||
248 | return MU_CFG_ITER_OK; | ||
249 | } | ||
250 | |||
251 | int | ||
252 | print_node_end (const mu_cfg_node_t *node, void *data) | ||
253 | { | ||
254 | struct tree_print *tp = data; | ||
255 | tp->level--; | ||
256 | print_level (tp->fp, tp->level); | ||
257 | fprintf (tp->fp, "</%s>\n", node->tag_name); | ||
258 | return MU_CFG_ITER_OK; | ||
259 | } | ||
260 | |||
261 | void | ||
262 | mu_cfg_print_tree (FILE *fp, mu_cfg_node_t *node) | ||
263 | { | ||
264 | struct tree_print t; | ||
265 | t.level = 0; | ||
266 | t.fp = fp; | ||
267 | mu_cfg_preorder (node, print_node, print_node_end, &t); | ||
268 | } | ||
269 | |||
270 | |||
271 | |||
272 | static int | ||
273 | _mu_cfg_preorder_recursive (mu_cfg_node_t *node, | ||
274 | mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end, | ||
275 | void *data) | ||
276 | { | ||
277 | switch (node->type) | ||
278 | { | ||
279 | case mu_cfg_node_undefined: | ||
280 | abort (); | ||
281 | |||
282 | case mu_cfg_node_tag: | ||
283 | switch (beg (node, data)) | ||
284 | { | ||
285 | case MU_CFG_ITER_OK: | ||
286 | if (mu_cfg_preorder (node->node, beg, end, data)) | ||
287 | return MU_CFG_ITER_STOP; | ||
288 | if (end && end (node, data) == MU_CFG_ITER_STOP) | ||
289 | return MU_CFG_ITER_STOP; | ||
290 | break; | ||
291 | |||
292 | case MU_CFG_ITER_SKIP: | ||
293 | break; | ||
294 | |||
295 | case MU_CFG_ITER_STOP: | ||
296 | return MU_CFG_ITER_STOP; | ||
297 | } | ||
298 | break; | ||
299 | |||
300 | case mu_cfg_node_param: | ||
301 | return beg (node, data); | ||
302 | } | ||
303 | return MU_CFG_ITER_OK; | ||
304 | } | ||
305 | |||
306 | int | ||
307 | mu_cfg_preorder(mu_cfg_node_t *node, | ||
308 | mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end, void *data) | ||
309 | { | ||
310 | for (; node; node = node->next) | ||
311 | if (_mu_cfg_preorder_recursive(node, beg, end, data) == MU_CFG_ITER_STOP) | ||
312 | return 1; | ||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int | ||
317 | _mu_cfg_postorder_recursive(mu_cfg_node_t *node, | ||
318 | mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end, | ||
319 | void *data) | ||
320 | { | ||
321 | switch (node->type) | ||
322 | { | ||
323 | case mu_cfg_node_undefined: | ||
324 | abort (); | ||
325 | |||
326 | case mu_cfg_node_tag: | ||
327 | switch (beg (node, data)) | ||
328 | { | ||
329 | case MU_CFG_ITER_OK: | ||
330 | if (mu_cfg_postorder (node->node, beg, end, data)) | ||
331 | return MU_CFG_ITER_STOP; | ||
332 | if (end && end (node, data) == MU_CFG_ITER_STOP) | ||
333 | return MU_CFG_ITER_STOP; | ||
334 | break; | ||
335 | |||
336 | case MU_CFG_ITER_SKIP: | ||
337 | break; | ||
338 | |||
339 | case MU_CFG_ITER_STOP: | ||
340 | return MU_CFG_ITER_STOP; | ||
341 | } | ||
342 | break; | ||
343 | |||
344 | case mu_cfg_node_param: | ||
345 | return beg (node, data); | ||
346 | } | ||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | int | ||
351 | mu_cfg_postorder (mu_cfg_node_t *node, | ||
352 | mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end, void *data) | ||
353 | { | ||
354 | if (node->next | ||
355 | && mu_cfg_postorder (node->next, beg, end, data) == MU_CFG_ITER_STOP) | ||
356 | return 1; | ||
357 | return _mu_cfg_postorder_recursive (node, beg, end, data) | ||
358 | == MU_CFG_ITER_STOP; | ||
359 | } | ||
360 | |||
361 | |||
362 | static int | ||
363 | free_section (const mu_cfg_node_t *node, void *data) | ||
364 | { | ||
365 | mu_cfg_free_t free_fn = data; | ||
366 | if (node->type == mu_cfg_node_tag) | ||
367 | free_fn ((void *) node); | ||
368 | return MU_CFG_ITER_OK; | ||
369 | } | ||
370 | |||
371 | static int | ||
372 | free_param (const mu_cfg_node_t *node, void *data) | ||
373 | { | ||
374 | mu_cfg_free_t free_fn = data; | ||
375 | if (node->type == mu_cfg_node_param) | ||
376 | free_fn ((void*) node); | ||
377 | return MU_CFG_ITER_OK; | ||
378 | } | ||
379 | |||
380 | void | ||
381 | mu_cfg_destroy_tree (mu_cfg_node_t **tree) | ||
382 | { | ||
383 | if (tree && *tree) | ||
384 | { | ||
385 | mu_cfg_postorder (*tree, free_param, free_section, _mu_cfg_free); | ||
386 | *tree = NULL; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | |||
391 | |||
392 | struct find_data | ||
393 | { | ||
394 | char *tag; | ||
395 | char *label; | ||
396 | char *next; | ||
397 | const mu_cfg_node_t *node; | ||
398 | }; | ||
399 | |||
400 | static void | ||
401 | parse_tag (struct find_data *fptr) | ||
402 | { | ||
403 | char *p = strchr (fptr->tag, '='); | ||
404 | if (p) | ||
405 | { | ||
406 | *p++ = 0; | ||
407 | fptr->label = p; | ||
408 | fptr->next = p + strlen (p) + 1; | ||
409 | } | ||
410 | else | ||
411 | { | ||
412 | fptr->label = NULL; | ||
413 | fptr->next = fptr->tag + strlen (fptr->tag) + 1; | ||
414 | } | ||
415 | } | ||
416 | |||
417 | static int | ||
418 | node_finder (const mu_cfg_node_t *node, void *data) | ||
419 | { | ||
420 | struct find_data *fdptr = data; | ||
421 | if (strcmp (fdptr->tag, node->tag_name) == 0 | ||
422 | && (!fdptr->label || strcmp (fdptr->label, node->tag_label) == 0)) | ||
423 | { | ||
424 | fdptr->tag = fdptr->next; | ||
425 | parse_tag (fdptr); | ||
426 | if (fdptr->tag[0] == 0) | ||
427 | { | ||
428 | fdptr->node = node; | ||
429 | return MU_CFG_ITER_STOP; | ||
430 | } | ||
431 | } | ||
432 | return MU_CFG_ITER_OK; | ||
433 | } | ||
434 | |||
435 | int | ||
436 | mu_cfg_find_node (mu_cfg_node_t *tree, const char *path, mu_cfg_node_t **pval) | ||
437 | { | ||
438 | int rc; | ||
439 | char *p; | ||
440 | char *xpath; | ||
441 | size_t len; | ||
442 | struct find_data data; | ||
443 | |||
444 | len = strlen (path) + 1; | ||
445 | xpath = calloc (1, len + 1); | ||
446 | if (!xpath) | ||
447 | return 1; | ||
448 | strcpy (xpath, path); | ||
449 | xpath[len-1] = '/'; | ||
450 | data.tag = xpath; | ||
451 | for (p = data.tag; *p; p++) | ||
452 | if (*p == '/') | ||
453 | *p = 0; | ||
454 | parse_tag (&data); | ||
455 | rc = mu_cfg_preorder (tree, node_finder, NULL, &data); | ||
456 | free (xpath); | ||
457 | if (rc) | ||
458 | { | ||
459 | *pval = (mu_cfg_node_t *) data.node; | ||
460 | return 0; | ||
461 | } | ||
462 | return MU_ERR_NOENT; | ||
463 | } | ||
464 | |||
465 | int | ||
466 | mu_cfg_find_node_label (mu_cfg_node_t *tree, const char *path, | ||
467 | const char **pval) | ||
468 | { | ||
469 | mu_cfg_node_t *node; | ||
470 | int rc = mu_cfg_find_node (tree, path, &node); | ||
471 | if (rc) | ||
472 | *pval = node->tag_label; | ||
473 | return rc; | ||
474 | } | ||
475 | |||
476 | |||
477 | struct mu_cfg_section_list | ||
478 | { | ||
479 | struct mu_cfg_section_list *next; | ||
480 | struct mu_cfg_section *sec; | ||
481 | }; | ||
482 | |||
483 | struct scan_tree_data | ||
484 | { | ||
485 | struct mu_cfg_section_list *list; | ||
486 | void *call_data; | ||
487 | int error; | ||
488 | }; | ||
489 | |||
490 | static struct mu_cfg_section * | ||
491 | find_subsection (struct mu_cfg_section *sec, const char *ident, size_t len) | ||
492 | { | ||
493 | if (sec) | ||
494 | { | ||
495 | sec = sec->subsec; | ||
496 | if (sec) | ||
497 | { | ||
498 | if (len == 0) | ||
499 | len = strlen (ident); | ||
500 | |||
501 | for (; sec->ident; sec++) | ||
502 | if (strlen (sec->ident) == len | ||
503 | && memcmp (sec->ident, ident, len) == 0) | ||
504 | return sec; | ||
505 | } | ||
506 | } | ||
507 | return NULL; | ||
508 | } | ||
509 | |||
510 | static struct mu_cfg_param * | ||
511 | find_param (struct mu_cfg_section *sec, const char *ident, size_t len) | ||
512 | { | ||
513 | if (sec) | ||
514 | { | ||
515 | struct mu_cfg_param *p = sec->param; | ||
516 | if (p) | ||
517 | { | ||
518 | if (len == 0) | ||
519 | len = strlen (ident); | ||
520 | for (; p->ident; p++) | ||
521 | if (strlen (p->ident) == len && memcmp (p->ident, ident, len) == 0) | ||
522 | return p; | ||
523 | } | ||
524 | } | ||
525 | return NULL; | ||
526 | } | ||
527 | |||
528 | static int | ||
529 | push_section (struct scan_tree_data *dat, struct mu_cfg_section *sec) | ||
530 | { | ||
531 | struct mu_cfg_section_list *p = _mu_cfg_alloc (sizeof *p); | ||
532 | if (!p) | ||
533 | { | ||
534 | mu_cfg_perror (dat->call_data, NULL, _("not enough memory")); | ||
535 | return 1; | ||
536 | } | ||
537 | p->sec = sec; | ||
538 | p->next = dat->list; | ||
539 | dat->list = p; | ||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | static struct mu_cfg_section * | ||
544 | pop_section (struct scan_tree_data *dat) | ||
545 | { | ||
546 | struct mu_cfg_section_list *p = dat->list; | ||
547 | struct mu_cfg_section *sec = p->sec; | ||
548 | dat->list = p->next; | ||
549 | _mu_cfg_free (p); | ||
550 | return sec; | ||
551 | } | ||
552 | |||
553 | #define STRTONUM(s, type, base, res, limit) \ | ||
554 | { \ | ||
555 | type sum = 0; \ | ||
556 | \ | ||
557 | while (*s) \ | ||
558 | { \ | ||
559 | type x; \ | ||
560 | \ | ||
561 | if ('0' <= *s && *s <= '9') \ | ||
562 | x = sum * base + *s - '0'; \ | ||
563 | else if (base == 16 && 'a' <= *s && *s <= 'f') \ | ||
564 | x = sum * base + *s - 'a'; \ | ||
565 | else if (base == 16 && 'A' <= *s && *s <= 'F') \ | ||
566 | x = sum * base + *s - 'A'; \ | ||
567 | else \ | ||
568 | break; \ | ||
569 | if (x <= sum) \ | ||
570 | { \ | ||
571 | mu_cfg_perror (sdata->call_data, \ | ||
572 | &node->locus, \ | ||
573 | _("numeric overflow")); \ | ||
574 | return 1; \ | ||
575 | } \ | ||
576 | else if (limit && x > limit) \ | ||
577 | { \ | ||
578 | mu_cfg_perror (sdata->call_data, \ | ||
579 | &node->locus, \ | ||
580 | _("value out of allowed range")); \ | ||
581 | return 1; \ | ||
582 | } \ | ||
583 | sum = x; \ | ||
584 | *s++; \ | ||
585 | } \ | ||
586 | res = sum; \ | ||
587 | } | ||
588 | |||
589 | #define STRxTONUM(s, type, res, limit) \ | ||
590 | { \ | ||
591 | int base; \ | ||
592 | if (*s == '0') \ | ||
593 | { \ | ||
594 | s++; \ | ||
595 | if (*s == 0) \ | ||
596 | base = 10; \ | ||
597 | else if (*s == 'x' || *s == 'X') \ | ||
598 | { \ | ||
599 | s++; \ | ||
600 | base = 16; \ | ||
601 | } \ | ||
602 | else \ | ||
603 | base = 8; \ | ||
604 | } else \ | ||
605 | base = 10; \ | ||
606 | STRTONUM (s, type, base, res, limit); \ | ||
607 | } | ||
608 | |||
609 | #define GETUNUM(str, type, res) \ | ||
610 | { \ | ||
611 | type tmpres; \ | ||
612 | const char *s = str; \ | ||
613 | STRxTONUM (s, type, tmpres, 0); \ | ||
614 | if (*s) \ | ||
615 | { \ | ||
616 | mu_cfg_perror (sdata->call_data, \ | ||
617 | &node->locus, \ | ||
618 | _("not a number (stopped near `%s')"), \ | ||
619 | s); \ | ||
620 | return 1; \ | ||
621 | } \ | ||
622 | res = tmpres; \ | ||
623 | } | ||
624 | |||
625 | #define GETSNUM(str, type, res) \ | ||
626 | { \ | ||
627 | unsigned type tmpres; \ | ||
628 | const char *s = str; \ | ||
629 | int sign; \ | ||
630 | unsigned type limit; \ | ||
631 | \ | ||
632 | if (*s == '-') \ | ||
633 | { \ | ||
634 | sign++; \ | ||
635 | s++; \ | ||
636 | limit = TYPE_MINIMUM (type); \ | ||
637 | limit = - limit; \ | ||
638 | } \ | ||
639 | else \ | ||
640 | { \ | ||
641 | sign = 0; \ | ||
642 | limit = TYPE_MAXIMUM (type); \ | ||
643 | } \ | ||
644 | \ | ||
645 | STRxTONUM (s, unsigned type, tmpres, limit); \ | ||
646 | if (*s) \ | ||
647 | { \ | ||
648 | mu_cfg_perror (sdata->call_data, \ | ||
649 | &node->locus, \ | ||
650 | _("not a number (stopped near `%s')"), \ | ||
651 | s); \ | ||
652 | return 1; \ | ||
653 | } \ | ||
654 | res = sign ? - tmpres : tmpres; \ | ||
655 | } | ||
656 | |||
657 | static int | ||
658 | parse_ipv4 (struct scan_tree_data *sdata, const mu_cfg_node_t *node, | ||
659 | struct in_addr *res) | ||
660 | { | ||
661 | struct in_addr addr; | ||
662 | if (inet_aton (node->tag_label, &addr) == 0) | ||
663 | { | ||
664 | mu_cfg_perror (sdata->call_data, | ||
665 | &node->locus, | ||
666 | _("not an IPv4")); | ||
667 | return 1; | ||
668 | } | ||
669 | addr.s_addr = ntohl (addr.s_addr); | ||
670 | *res = addr; | ||
671 | return 0; | ||
672 | } | ||
673 | |||
674 | static int | ||
675 | parse_host (struct scan_tree_data *sdata, const mu_cfg_node_t *node, | ||
676 | struct in_addr *res) | ||
677 | { | ||
678 | struct in_addr addr; | ||
679 | struct hostent *hp = gethostbyname (node->tag_label); | ||
680 | if (hp) | ||
681 | { | ||
682 | addr.s_addr = *(unsigned long *)hp->h_addr; | ||
683 | } | ||
684 | else if (inet_aton(node->tag_label, &addr) == 0) | ||
685 | { | ||
686 | mu_cfg_perror (sdata->call_data, | ||
687 | &node->locus, | ||
688 | _("cannot resolve hostname `%s'"), | ||
689 | node->tag_label); | ||
690 | return 1; | ||
691 | } | ||
692 | addr.s_addr = ntohl (addr.s_addr); | ||
693 | *res = addr; | ||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | static int | ||
698 | parse_cidr (struct scan_tree_data *sdata, const mu_cfg_node_t *node, | ||
699 | mu_cfg_cidr_t *res) | ||
700 | { | ||
701 | struct in_addr addr; | ||
702 | unsigned long mask; | ||
703 | char astr[16], *p, *s; | ||
704 | |||
705 | p = strchr (node->tag_label, '/'); | ||
706 | if (*p) | ||
707 | { | ||
708 | int len = p - node->tag_label; | ||
709 | if (len > sizeof astr - 1) { | ||
710 | mu_cfg_perror (sdata->call_data, | ||
711 | &node->locus, | ||
712 | _("not a valid IPv4 address in CIDR")); | ||
713 | return 1; | ||
714 | } | ||
715 | memcpy (astr, node->tag_label, len); | ||
716 | astr[len] = 0; | ||
717 | if (inet_aton (astr, &addr) == 0) | ||
718 | { | ||
719 | mu_cfg_perror (sdata->call_data, | ||
720 | &node->locus, | ||
721 | _("not a valid IPv4 address in CIDR")); | ||
722 | return 1; | ||
723 | } | ||
724 | addr.s_addr = ntohl (addr.s_addr); | ||
725 | |||
726 | p++; | ||
727 | s = p; | ||
728 | STRxTONUM (s, unsigned long, mask, 0); | ||
729 | if (*s == '.') | ||
730 | { | ||
731 | struct in_addr a; | ||
732 | if (inet_aton (p, &a) == 0) | ||
733 | { | ||
734 | mu_cfg_perror (sdata->call_data, | ||
735 | &node->locus, | ||
736 | _("not a valid network in CIDR")); | ||
737 | return 1; | ||
738 | } | ||
739 | a.s_addr = ntohl (a.s_addr); | ||
740 | for (mask = 0; (a.s_addr & 1) == 0 && mask < 32; ) | ||
741 | { | ||
742 | mask++; | ||
743 | a.s_addr >>= 1; | ||
744 | } | ||
745 | mask = 32 - mask; | ||
746 | } | ||
747 | else if (mask > 32) | ||
748 | { | ||
749 | mu_cfg_perror (sdata->call_data, | ||
750 | &node->locus, | ||
751 | _("not a valid network mask in CIDR")); | ||
752 | return 1; | ||
753 | } | ||
754 | } | ||
755 | else | ||
756 | { | ||
757 | int i; | ||
758 | unsigned short x; | ||
759 | addr.s_addr = 0; | ||
760 | |||
761 | for (i = 0; i < 3; i++) | ||
762 | { | ||
763 | STRxTONUM(p, unsigned short, x, 255); | ||
764 | if (*p != '.') | ||
765 | break; | ||
766 | addr.s_addr = (addr.s_addr << 8) + x; | ||
767 | } | ||
768 | |||
769 | if (*p) | ||
770 | { | ||
771 | mu_cfg_perror (sdata->call_data, | ||
772 | &node->locus, | ||
773 | _("not a CIDR (stopped near `%s')"), | ||
774 | p); | ||
775 | return 1; | ||
776 | } | ||
777 | |||
778 | mask = i * 8; | ||
779 | |||
780 | addr.s_addr <<= (4 - i) * 8; | ||
781 | } | ||
782 | |||
783 | res->addr = addr; | ||
784 | res->mask = mask; | ||
785 | return 0; | ||
786 | } | ||
787 | |||
788 | static int | ||
789 | parse_bool (struct scan_tree_data *sdata, const mu_cfg_node_t *node, int *res) | ||
790 | { | ||
791 | if (strcmp (node->tag_label, "yes") == 0 | ||
792 | || strcmp (node->tag_label, "on") == 0 | ||
793 | || strcmp (node->tag_label, "t") == 0 | ||
794 | || strcmp (node->tag_label, "true") == 0 | ||
795 | || strcmp (node->tag_label, "1") == 0) | ||
796 | *res = 1; | ||
797 | else if (strcmp (node->tag_label, "no") == 0 | ||
798 | || strcmp (node->tag_label, "off") == 0 | ||
799 | || strcmp (node->tag_label, "nil") == 0 | ||
800 | || strcmp (node->tag_label, "false") == 0 | ||
801 | || strcmp (node->tag_label, "0") == 0) | ||
802 | *res = 0; | ||
803 | else | ||
804 | { | ||
805 | mu_cfg_perror (sdata->call_data, &node->locus, _("not a boolean")); | ||
806 | return 1; | ||
807 | } | ||
808 | return 0; | ||
809 | } | ||
810 | |||
811 | static int | ||
812 | parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) | ||
813 | { | ||
814 | struct mu_cfg_param *param = find_param (sdata->list->sec, node->tag_name, | ||
815 | 0); | ||
816 | if (!param) | ||
817 | { | ||
818 | mu_cfg_perror (sdata->call_data, | ||
819 | &node->locus, | ||
820 | _("unknown keyword `%s'"), | ||
821 | node->tag_name); | ||
822 | return 1; | ||
823 | } | ||
824 | |||
825 | switch (param->type) | ||
826 | { | ||
827 | case mu_cfg_string: | ||
828 | { | ||
829 | size_t len = strlen (node->tag_label); | ||
830 | char *s = _mu_cfg_alloc (len + 1); | ||
831 | if (!s) | ||
832 | { | ||
833 | mu_cfg_perror (sdata->call_data, | ||
834 | &node->locus, | ||
835 | _("not enough memory")); | ||
836 | return 1; | ||
837 | } | ||
838 | strcpy (s, node->tag_label); | ||
839 | /* FIXME: free param->data? */ | ||
840 | *(char**)param->data = s; | ||
841 | break; | ||
842 | } | ||
843 | |||
844 | case mu_cfg_short: | ||
845 | GETSNUM (node->tag_label, short, *(short*)param->data); | ||
846 | break; | ||
847 | |||
848 | case mu_cfg_ushort: | ||
849 | GETUNUM (node->tag_label, unsigned short, *(unsigned short*)param->data); | ||
850 | break; | ||
851 | |||
852 | case mu_cfg_int: | ||
853 | GETSNUM (node->tag_label, int, *(int*)param->data); | ||
854 | break; | ||
855 | |||
856 | case mu_cfg_uint: | ||
857 | GETUNUM (node->tag_label, unsigned int, *(unsigned int*)param->data); | ||
858 | break; | ||
859 | |||
860 | case mu_cfg_long: | ||
861 | GETSNUM (node->tag_label, long, *(long*)param->data); | ||
862 | break; | ||
863 | |||
864 | case mu_cfg_ulong: | ||
865 | GETUNUM (node->tag_label, unsigned long, *(unsigned long*)param->data); | ||
866 | break; | ||
867 | |||
868 | case mu_cfg_size: | ||
869 | GETUNUM (node->tag_label, size_t, *(size_t*)param->data); | ||
870 | break; | ||
871 | |||
872 | case mu_cfg_off: | ||
873 | mu_cfg_perror (sdata->call_data, &node->locus, _("not implemented yet")); | ||
874 | /* GETSNUM(node->tag_label, off_t, *(off_t*)param->data); */ | ||
875 | return 1; | ||
876 | |||
877 | case mu_cfg_bool: | ||
878 | if (parse_bool (sdata, node, (int*) param->data)) | ||
879 | return 1; | ||
880 | break; | ||
881 | |||
882 | case mu_cfg_ipv4: | ||
883 | if (parse_ipv4 (sdata, node, (struct in_addr *)param->data)) | ||
884 | return 1; | ||
885 | break; | ||
886 | |||
887 | case mu_cfg_cidr: | ||
888 | if (parse_cidr (sdata, node, (mu_cfg_cidr_t *)param->data)) | ||
889 | return 1; | ||
890 | break; | ||
891 | |||
892 | case mu_cfg_host: | ||
893 | if (parse_host (sdata, node, (struct in_addr *)param->data)) | ||
894 | return 1; | ||
895 | break; | ||
896 | |||
897 | case mu_cfg_callback: | ||
898 | if (param->callback (&node->locus, param->data, node->tag_label)) | ||
899 | return 1; | ||
900 | break; | ||
901 | |||
902 | default: | ||
903 | abort (); | ||
904 | } | ||
905 | return 0; | ||
906 | } | ||
907 | |||
908 | |||
909 | static int | ||
910 | _scan_tree_helper (const mu_cfg_node_t *node, void *data) | ||
911 | { | ||
912 | struct scan_tree_data *sdata = data; | ||
913 | struct mu_cfg_section *sec; | ||
914 | |||
915 | switch (node->type) | ||
916 | { | ||
917 | case mu_cfg_node_undefined: | ||
918 | abort (); | ||
919 | |||
920 | case mu_cfg_node_tag: | ||
921 | sec = find_subsection (sdata->list->sec, node->tag_name, 0); | ||
922 | if (!sec) | ||
923 | { | ||
924 | mu_cfg_perror (sdata->call_data, | ||
925 | &node->locus, | ||
926 | _("unknown section `%s'"), | ||
927 | node->tag_name); | ||
928 | sdata->error++; | ||
929 | return MU_CFG_ITER_SKIP; | ||
930 | } | ||
931 | if (!sec->subsec && !sec->param) | ||
932 | return MU_CFG_ITER_SKIP; | ||
933 | if (sec->parser && | ||
934 | sec->parser (mu_cfg_section_start, node, | ||
935 | sec->data, sdata->call_data)) | ||
936 | { | ||
937 | sdata->error++; | ||
938 | return MU_CFG_ITER_SKIP; | ||
939 | } | ||
940 | push_section(sdata, sec); | ||
941 | break; | ||
942 | |||
943 | case mu_cfg_node_param: | ||
944 | if (parse_param (sdata, node)) | ||
945 | { | ||
946 | sdata->error++; | ||
947 | return MU_CFG_ITER_SKIP; | ||
948 | } | ||
949 | break; | ||
950 | } | ||
951 | return MU_CFG_ITER_OK; | ||
952 | } | ||
953 | |||
954 | static int | ||
955 | _scan_tree_end_helper (const mu_cfg_node_t *node, void *data) | ||
956 | { | ||
957 | struct scan_tree_data *sdata = data; | ||
958 | struct mu_cfg_section *sec; | ||
959 | |||
960 | switch (node->type) | ||
961 | { | ||
962 | default: | ||
963 | abort (); | ||
964 | |||
965 | case mu_cfg_node_tag: | ||
966 | sec = pop_section (sdata); | ||
967 | if (sec && sec->parser) | ||
968 | { | ||
969 | if (sec->parser (mu_cfg_section_end, node, sec->data, | ||
970 | sdata->call_data)) | ||
971 | { | ||
972 | sdata->error++; | ||
973 | return MU_CFG_ITER_SKIP; | ||
974 | } | ||
975 | } | ||
976 | } | ||
977 | return MU_CFG_ITER_OK; | ||
978 | } | ||
979 | |||
980 | int | ||
981 | mu_cfg_scan_tree (mu_cfg_node_t *node, | ||
982 | struct mu_cfg_section *sections, | ||
983 | void *data, mu_cfg_perror_t perror, | ||
984 | mu_cfg_alloc_t palloc, mu_cfg_free_t pfree) | ||
985 | { | ||
986 | struct scan_tree_data dat; | ||
987 | dat.list = NULL; | ||
988 | mu_cfg_perror = perror ? perror : _mu_cfg_default_perror; | ||
989 | _mu_cfg_alloc = palloc ? palloc : malloc; | ||
990 | _mu_cfg_free = pfree ? pfree : free; | ||
991 | dat.call_data = data; | ||
992 | dat.error = 0; | ||
993 | if (push_section (&dat, sections)) | ||
994 | return 1; | ||
995 | mu_cfg_preorder (node, _scan_tree_helper, _scan_tree_end_helper, &dat); | ||
996 | pop_section (&dat); | ||
997 | return dat.error; | ||
998 | } | ||
999 | |||
1000 | int | ||
1001 | mu_cfg_find_section (struct mu_cfg_section *root_sec, | ||
1002 | const char *path, struct mu_cfg_section **retval) | ||
1003 | { | ||
1004 | while (path[0]) | ||
1005 | { | ||
1006 | struct mu_cfg_section *sec; | ||
1007 | size_t len; | ||
1008 | const char *p; | ||
1009 | |||
1010 | while (*path == '/') | ||
1011 | path++; | ||
1012 | |||
1013 | if (*path == 0) | ||
1014 | return MU_ERR_NOENT; | ||
1015 | |||
1016 | p = strchr (path, '/'); | ||
1017 | if (p) | ||
1018 | len = p - path; | ||
1019 | else | ||
1020 | len = strlen (path); | ||
1021 | |||
1022 | sec = find_subsection (root_sec, path, len); | ||
1023 | if (!sec) | ||
1024 | return MU_ERR_NOENT; | ||
1025 | root_sec = sec; | ||
1026 | path += len; | ||
1027 | } | ||
1028 | if (retval) | ||
1029 | *retval = root_sec; | ||
1030 | return 0; | ||
1031 | } | ||
1032 | |||
1033 | |||
1034 | |||
1035 |
-
Please register or sign in to post a comment