Annotation of embedaddon/lighttpd/src/configparser.c, revision 1.1.1.1
1.1 misho 1: /* Driver template for the LEMON parser generator.
2: ** The author disclaims copyright to this source code.
3: */
4: /* First off, code is include which follows the "include" declaration
5: ** in the input file. */
6: #include <stdio.h>
7: #line 5 "../../src/configparser.y"
8:
9: #include "configfile.h"
10: #include "buffer.h"
11: #include "array.h"
12:
13: #include <assert.h>
14: #include <stdio.h>
15: #include <string.h>
16:
17: static void configparser_push(config_t *ctx, data_config *dc, int isnew) {
18: if (isnew) {
19: dc->context_ndx = ctx->all_configs->used;
20: assert(dc->context_ndx > ctx->current->context_ndx);
21: array_insert_unique(ctx->all_configs, (data_unset *)dc);
22: dc->parent = ctx->current;
23: array_insert_unique(dc->parent->childs, (data_unset *)dc);
24: }
25: if (ctx->configs_stack->used > 0 && ctx->current->context_ndx == 0) {
26: fprintf(stderr, "Cannot use conditionals inside a global { ... } block\n");
27: exit(-1);
28: }
29: array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current);
30: ctx->current = dc;
31: }
32:
33: static data_config *configparser_pop(config_t *ctx) {
34: data_config *old = ctx->current;
35: ctx->current = (data_config *) array_pop(ctx->configs_stack);
36: return old;
37: }
38:
39: /* return a copied variable */
40: static data_unset *configparser_get_variable(config_t *ctx, const buffer *key) {
41: data_unset *du;
42: data_config *dc;
43:
44: #if 0
45: fprintf(stderr, "get var %s\n", key->ptr);
46: #endif
47: for (dc = ctx->current; dc; dc = dc->parent) {
48: #if 0
49: fprintf(stderr, "get var on block: %s\n", dc->key->ptr);
50: array_print(dc->value, 0);
51: #endif
52: if (NULL != (du = array_get_element(dc->value, key->ptr))) {
53: return du->copy(du);
54: }
55: }
56: return NULL;
57: }
58:
59: /* op1 is to be eat/return by this function if success, op1->key is not cared
60: op2 is left untouch, unreferenced
61: */
62: data_unset *configparser_merge_data(data_unset *op1, const data_unset *op2) {
63: /* type mismatch */
64: if (op1->type != op2->type) {
65: if (op1->type == TYPE_STRING && op2->type == TYPE_INTEGER) {
66: data_string *ds = (data_string *)op1;
67: buffer_append_long(ds->value, ((data_integer*)op2)->value);
68: return op1;
69: } else if (op1->type == TYPE_INTEGER && op2->type == TYPE_STRING) {
70: data_string *ds = data_string_init();
71: buffer_append_long(ds->value, ((data_integer*)op1)->value);
72: buffer_append_string_buffer(ds->value, ((data_string*)op2)->value);
73: op1->free(op1);
74: return (data_unset *)ds;
75: } else {
76: fprintf(stderr, "data type mismatch, cannot merge\n");
77: return NULL;
78: }
79: }
80:
81: switch (op1->type) {
82: case TYPE_STRING:
83: buffer_append_string_buffer(((data_string *)op1)->value, ((data_string *)op2)->value);
84: break;
85: case TYPE_INTEGER:
86: ((data_integer *)op1)->value += ((data_integer *)op2)->value;
87: break;
88: case TYPE_ARRAY: {
89: array *dst = ((data_array *)op1)->value;
90: array *src = ((data_array *)op2)->value;
91: data_unset *du;
92: size_t i;
93:
94: for (i = 0; i < src->used; i ++) {
95: du = (data_unset *)src->data[i];
96: if (du) {
97: array_insert_unique(dst, du->copy(du));
98: }
99: }
100: break;
101: default:
102: assert(0);
103: break;
104: }
105: }
106: return op1;
107: }
108:
109:
110: #line 111 "configparser.c"
111: /* Next is all token values, in a form suitable for use by makeheaders.
112: ** This section will be null unless lemon is run with the -m switch.
113: */
114: /*
115: ** These constants (all generated automatically by the parser generator)
116: ** specify the various kinds of tokens (terminals) that the parser
117: ** understands.
118: **
119: ** Each symbol here is a terminal symbol in the grammar.
120: */
121: /* Make sure the INTERFACE macro is defined.
122: */
123: #ifndef INTERFACE
124: # define INTERFACE 1
125: #endif
126: /* The next thing included is series of defines which control
127: ** various aspects of the generated parser.
128: ** YYCODETYPE is the data type used for storing terminal
129: ** and nonterminal numbers. "unsigned char" is
130: ** used if there are fewer than 250 terminals
131: ** and nonterminals. "int" is used otherwise.
132: ** YYNOCODE is a number of type YYCODETYPE which corresponds
133: ** to no legal terminal or nonterminal number. This
134: ** number is used to fill in empty slots of the hash
135: ** table.
136: ** YYFALLBACK If defined, this indicates that one or more tokens
137: ** have fall-back values which should be used if the
138: ** original value of the token will not parse.
139: ** YYACTIONTYPE is the data type used for storing terminal
140: ** and nonterminal numbers. "unsigned char" is
141: ** used if there are fewer than 250 rules and
142: ** states combined. "int" is used otherwise.
143: ** configparserTOKENTYPE is the data type used for minor tokens given
144: ** directly to the parser from the tokenizer.
145: ** YYMINORTYPE is the data type used for all minor tokens.
146: ** This is typically a union of many types, one of
147: ** which is configparserTOKENTYPE. The entry in the union
148: ** for base tokens is called "yy0".
149: ** YYSTACKDEPTH is the maximum depth of the parser's stack.
150: ** configparserARG_SDECL A static variable declaration for the %extra_argument
151: ** configparserARG_PDECL A parameter declaration for the %extra_argument
152: ** configparserARG_STORE Code to store %extra_argument into yypParser
153: ** configparserARG_FETCH Code to extract %extra_argument from yypParser
154: ** YYNSTATE the combined number of states.
155: ** YYNRULE the number of rules in the grammar
156: ** YYERRORSYMBOL is the code number of the error symbol. If not
157: ** defined, then do no error processing.
158: */
159: /* & */
160: #define YYCODETYPE unsigned char
161: #define YYNOCODE 48
162: #define YYACTIONTYPE unsigned char
163: #define configparserTOKENTYPE buffer *
164: typedef union {
165: configparserTOKENTYPE yy0;
166: config_cond_t yy27;
167: array * yy40;
168: data_unset * yy41;
169: buffer * yy43;
170: data_config * yy78;
171: int yy95;
172: } YYMINORTYPE;
173: #define YYSTACKDEPTH 100
174: #define configparserARG_SDECL config_t *ctx;
175: #define configparserARG_PDECL ,config_t *ctx
176: #define configparserARG_FETCH config_t *ctx = yypParser->ctx
177: #define configparserARG_STORE yypParser->ctx = ctx
178: #define YYNSTATE 63
179: #define YYNRULE 40
180: #define YYERRORSYMBOL 26
181: #define YYERRSYMDT yy95
182: #define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
183: #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
184: #define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
185:
186: /* Next are that tables used to determine what action to take based on the
187: ** current state and lookahead token. These tables are used to implement
188: ** functions that take a state number and lookahead value and return an
189: ** action integer.
190: **
191: ** Suppose the action integer is N. Then the action is determined as
192: ** follows
193: **
194: ** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
195: ** token onto the stack and goto state N.
196: **
197: ** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
198: **
199: ** N == YYNSTATE+YYNRULE A syntax error has occurred.
200: **
201: ** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
202: **
203: ** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
204: ** slots in the yy_action[] table.
205: **
206: ** The action table is constructed as a single large table named yy_action[].
207: ** Given state S and lookahead X, the action is computed as
208: **
209: ** yy_action[ yy_shift_ofst[S] + X ]
210: **
211: ** If the index value yy_shift_ofst[S]+X is out of range or if the value
212: ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
213: ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
214: ** and that yy_default[S] should be used instead.
215: **
216: ** The formula above is for computing the action when the lookahead is
217: ** a terminal symbol. If the lookahead is a non-terminal (as occurs after
218: ** a reduce action) then the yy_reduce_ofst[] array is used in place of
219: ** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
220: ** YY_SHIFT_USE_DFLT.
221: **
222: ** The following are the tables generated in this section:
223: **
224: ** yy_action[] A single table containing all actions.
225: ** yy_lookahead[] A table containing the lookahead for each entry in
226: ** yy_action. Used to detect hash collisions.
227: ** yy_shift_ofst[] For each state, the offset into yy_action for
228: ** shifting terminals.
229: ** yy_reduce_ofst[] For each state, the offset into yy_action for
230: ** shifting non-terminals after a reduce.
231: ** yy_default[] Default action for each state.
232: */
233: static YYACTIONTYPE yy_action[] = {
234: /* 0 */ 2, 3, 4, 5, 13, 14, 63, 15, 7, 45,
235: /* 10 */ 20, 88, 16, 46, 28, 49, 41, 10, 40, 25,
236: /* 20 */ 22, 50, 46, 8, 15, 104, 1, 20, 28, 18,
237: /* 30 */ 58, 60, 6, 25, 22, 40, 47, 62, 11, 46,
238: /* 40 */ 20, 9, 23, 24, 26, 29, 89, 58, 60, 10,
239: /* 50 */ 17, 38, 28, 27, 37, 19, 30, 25, 22, 34,
240: /* 60 */ 15, 100, 20, 20, 23, 24, 26, 12, 19, 31,
241: /* 70 */ 32, 40, 19, 44, 43, 46, 95, 35, 90, 89,
242: /* 80 */ 28, 49, 42, 58, 60, 25, 22, 59, 28, 27,
243: /* 90 */ 33, 48, 52, 25, 22, 34, 28, 49, 51, 28,
244: /* 100 */ 36, 25, 22, 61, 25, 22, 89, 28, 39, 89,
245: /* 110 */ 89, 89, 25, 22, 54, 55, 56, 57, 89, 28,
246: /* 120 */ 53, 21, 89, 89, 25, 22, 25, 22,
247: };
248: static YYCODETYPE yy_lookahead[] = {
249: /* 0 */ 29, 30, 31, 32, 33, 34, 0, 1, 44, 38,
250: /* 10 */ 4, 15, 41, 16, 35, 36, 45, 46, 12, 40,
251: /* 20 */ 41, 42, 16, 15, 1, 27, 28, 4, 35, 36,
252: /* 30 */ 24, 25, 1, 40, 41, 12, 17, 14, 13, 16,
253: /* 40 */ 4, 38, 6, 7, 8, 9, 15, 24, 25, 46,
254: /* 50 */ 2, 3, 35, 36, 37, 5, 39, 40, 41, 42,
255: /* 60 */ 1, 11, 4, 4, 6, 7, 8, 28, 5, 9,
256: /* 70 */ 10, 12, 5, 14, 28, 16, 13, 11, 13, 47,
257: /* 80 */ 35, 36, 13, 24, 25, 40, 41, 42, 35, 36,
258: /* 90 */ 37, 18, 43, 40, 41, 42, 35, 36, 19, 35,
259: /* 100 */ 36, 40, 41, 42, 40, 41, 47, 35, 36, 47,
260: /* 110 */ 47, 47, 40, 41, 20, 21, 22, 23, 47, 35,
261: /* 120 */ 36, 35, 47, 47, 40, 41, 40, 41,
262: };
263: #define YY_SHIFT_USE_DFLT (-5)
264: static signed char yy_shift_ofst[] = {
265: /* 0 */ -5, 6, -5, -5, -5, 31, -4, 8, -3, -5,
266: /* 10 */ 25, -5, 23, -5, -5, -5, 48, 58, 67, 58,
267: /* 20 */ -5, -5, -5, -5, -5, -5, 36, 50, -5, -5,
268: /* 30 */ 60, -5, 58, -5, 66, 58, 67, -5, 58, 67,
269: /* 40 */ 65, 69, -5, 59, -5, -5, 19, 73, 58, 67,
270: /* 50 */ 79, 94, 58, 63, -5, -5, -5, -5, 58, -5,
271: /* 60 */ 58, -5, -5,
272: };
273: #define YY_REDUCE_USE_DFLT (-37)
274: static signed char yy_reduce_ofst[] = {
275: /* 0 */ -2, -29, -37, -37, -37, -36, -37, -37, 3, -37,
276: /* 10 */ -37, 39, -29, -37, -37, -37, -37, -7, -37, 86,
277: /* 20 */ -37, -37, -37, -37, -37, -37, 17, -37, -37, -37,
278: /* 30 */ -37, -37, 53, -37, -37, 64, -37, -37, 72, -37,
279: /* 40 */ -37, -37, 46, -29, -37, -37, -37, -37, -21, -37,
280: /* 50 */ -37, 49, 84, -37, -37, -37, -37, -37, 45, -37,
281: /* 60 */ 61, -37, -37,
282: };
283: static YYACTIONTYPE yy_default[] = {
284: /* 0 */ 65, 103, 64, 66, 67, 103, 68, 103, 103, 92,
285: /* 10 */ 103, 65, 103, 69, 70, 71, 103, 103, 72, 103,
286: /* 20 */ 74, 75, 77, 78, 79, 80, 103, 86, 76, 81,
287: /* 30 */ 103, 82, 84, 83, 103, 103, 87, 85, 103, 73,
288: /* 40 */ 103, 103, 65, 103, 91, 93, 103, 103, 103, 100,
289: /* 50 */ 103, 103, 103, 103, 96, 97, 98, 99, 103, 101,
290: /* 60 */ 103, 102, 94,
291: };
292: #define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0]))
293:
294: /* The next table maps tokens into fallback tokens. If a construct
295: ** like the following:
296: **
297: ** %fallback ID X Y Z.
298: **
299: ** appears in the grammer, then ID becomes a fallback token for X, Y,
300: ** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
301: ** but it does not parse, the type of the token is changed to ID and
302: ** the parse is retried before an error is thrown.
303: */
304: #ifdef YYFALLBACK
305: static const YYCODETYPE yyFallback[] = {
306: };
307: #endif /* YYFALLBACK */
308:
309: /* The following structure represents a single element of the
310: ** parser's stack. Information stored includes:
311: **
312: ** + The state number for the parser at this level of the stack.
313: **
314: ** + The value of the token stored at this level of the stack.
315: ** (In other words, the "major" token.)
316: **
317: ** + The semantic value stored at this level of the stack. This is
318: ** the information used by the action routines in the grammar.
319: ** It is sometimes called the "minor" token.
320: */
321: struct yyStackEntry {
322: int stateno; /* The state-number */
323: int major; /* The major token value. This is the code
324: ** number for the token at this stack level */
325: YYMINORTYPE minor; /* The user-supplied minor token value. This
326: ** is the value of the token */
327: };
328: typedef struct yyStackEntry yyStackEntry;
329:
330: /* The state of the parser is completely contained in an instance of
331: ** the following structure */
332: struct yyParser {
333: int yyidx; /* Index of top element in stack */
334: int yyerrcnt; /* Shifts left before out of the error */
335: configparserARG_SDECL /* A place to hold %extra_argument */
336: yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
337: };
338: typedef struct yyParser yyParser;
339:
340: #ifndef NDEBUG
341: #include <stdio.h>
342: static FILE *yyTraceFILE = NULL;
343: static char *yyTracePrompt = NULL;
344: #endif /* NDEBUG */
345:
346: #ifndef NDEBUG
347: /*
348: ** Turn parser tracing on by giving a stream to which to write the trace
349: ** and a prompt to preface each trace message. Tracing is turned off
350: ** by making either argument NULL
351: **
352: ** Inputs:
353: ** <ul>
354: ** <li> A FILE* to which trace output should be written.
355: ** If NULL, then tracing is turned off.
356: ** <li> A prefix string written at the beginning of every
357: ** line of trace output. If NULL, then tracing is
358: ** turned off.
359: ** </ul>
360: **
361: ** Outputs:
362: ** None.
363: */
364: #if 0
365: void configparserTrace(FILE *TraceFILE, char *zTracePrompt){
366: yyTraceFILE = TraceFILE;
367: yyTracePrompt = zTracePrompt;
368: if( yyTraceFILE==0 ) yyTracePrompt = 0;
369: else if( yyTracePrompt==0 ) yyTraceFILE = 0;
370: }
371: #endif
372: #endif /* NDEBUG */
373:
374: #ifndef NDEBUG
375: /* For tracing shifts, the names of all terminals and nonterminals
376: ** are required. The following table supplies these names */
377: static const char *yyTokenName[] = {
378: "$", "EOL", "ASSIGN", "APPEND",
379: "LKEY", "PLUS", "STRING", "INTEGER",
380: "LPARAN", "RPARAN", "COMMA", "ARRAY_ASSIGN",
381: "GLOBAL", "LCURLY", "RCURLY", "ELSE",
382: "DOLLAR", "SRVVARNAME", "LBRACKET", "RBRACKET",
383: "EQ", "MATCH", "NE", "NOMATCH",
384: "INCLUDE", "INCLUDE_SHELL", "error", "input",
385: "metalines", "metaline", "varline", "global",
386: "condlines", "include", "include_shell", "value",
387: "expression", "aelement", "condline", "aelements",
388: "array", "key", "stringop", "cond",
389: "eols", "globalstart", "context",
390: };
391: #endif /* NDEBUG */
392:
393: #ifndef NDEBUG
394: /* For tracing reduce actions, the names of all rules are required.
395: */
396: static const char *yyRuleName[] = {
397: /* 0 */ "input ::= metalines",
398: /* 1 */ "metalines ::= metalines metaline",
399: /* 2 */ "metalines ::=",
400: /* 3 */ "metaline ::= varline",
401: /* 4 */ "metaline ::= global",
402: /* 5 */ "metaline ::= condlines EOL",
403: /* 6 */ "metaline ::= include",
404: /* 7 */ "metaline ::= include_shell",
405: /* 8 */ "metaline ::= EOL",
406: /* 9 */ "varline ::= key ASSIGN expression",
407: /* 10 */ "varline ::= key APPEND expression",
408: /* 11 */ "key ::= LKEY",
409: /* 12 */ "expression ::= expression PLUS value",
410: /* 13 */ "expression ::= value",
411: /* 14 */ "value ::= key",
412: /* 15 */ "value ::= STRING",
413: /* 16 */ "value ::= INTEGER",
414: /* 17 */ "value ::= array",
415: /* 18 */ "array ::= LPARAN RPARAN",
416: /* 19 */ "array ::= LPARAN aelements RPARAN",
417: /* 20 */ "aelements ::= aelements COMMA aelement",
418: /* 21 */ "aelements ::= aelements COMMA",
419: /* 22 */ "aelements ::= aelement",
420: /* 23 */ "aelement ::= expression",
421: /* 24 */ "aelement ::= stringop ARRAY_ASSIGN expression",
422: /* 25 */ "eols ::= EOL",
423: /* 26 */ "eols ::=",
424: /* 27 */ "globalstart ::= GLOBAL",
425: /* 28 */ "global ::= globalstart LCURLY metalines RCURLY",
426: /* 29 */ "condlines ::= condlines eols ELSE condline",
427: /* 30 */ "condlines ::= condline",
428: /* 31 */ "condline ::= context LCURLY metalines RCURLY",
429: /* 32 */ "context ::= DOLLAR SRVVARNAME LBRACKET stringop RBRACKET cond expression",
430: /* 33 */ "cond ::= EQ",
431: /* 34 */ "cond ::= MATCH",
432: /* 35 */ "cond ::= NE",
433: /* 36 */ "cond ::= NOMATCH",
434: /* 37 */ "stringop ::= expression",
435: /* 38 */ "include ::= INCLUDE stringop",
436: /* 39 */ "include_shell ::= INCLUDE_SHELL stringop",
437: };
438: #endif /* NDEBUG */
439:
440: /*
441: ** This function returns the symbolic name associated with a token
442: ** value.
443: */
444: #if 0
445: const char *configparserTokenName(int tokenType){
446: #ifndef NDEBUG
447: if( tokenType>0 && (size_t)tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){
448: return yyTokenName[tokenType];
449: }else{
450: return "Unknown";
451: }
452: #else
453: return "";
454: #endif
455: }
456: #endif
457:
458: /*
459: ** This function allocates a new parser.
460: ** The only argument is a pointer to a function which works like
461: ** malloc.
462: **
463: ** Inputs:
464: ** A pointer to the function used to allocate memory.
465: **
466: ** Outputs:
467: ** A pointer to a parser. This pointer is used in subsequent calls
468: ** to configparser and configparserFree.
469: */
470: void *configparserAlloc(void *(*mallocProc)(size_t)){
471: yyParser *pParser;
472: pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
473: if( pParser ){
474: pParser->yyidx = -1;
475: }
476: return pParser;
477: }
478:
479: /* The following function deletes the value associated with a
480: ** symbol. The symbol can be either a terminal or nonterminal.
481: ** "yymajor" is the symbol code, and "yypminor" is a pointer to
482: ** the value.
483: */
484: static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
485: switch( yymajor ){
486: /* Here is inserted the actions which take place when a
487: ** terminal or non-terminal is destroyed. This can happen
488: ** when the symbol is popped from the stack during a
489: ** reduce or during error processing or when a parser is
490: ** being destroyed before it is finished parsing.
491: **
492: ** Note: during a reduce, the only symbols destroyed are those
493: ** which appear on the RHS of the rule, but which are not used
494: ** inside the C code.
495: */
496: case 1:
497: case 2:
498: case 3:
499: case 4:
500: case 5:
501: case 6:
502: case 7:
503: case 8:
504: case 9:
505: case 10:
506: case 11:
507: case 12:
508: case 13:
509: case 14:
510: case 15:
511: case 16:
512: case 17:
513: case 18:
514: case 19:
515: case 20:
516: case 21:
517: case 22:
518: case 23:
519: case 24:
520: case 25:
521: #line 144 "../../src/configparser.y"
522: { buffer_free((yypminor->yy0)); }
523: #line 523 "configparser.c"
524: break;
525: case 35:
526: #line 135 "../../src/configparser.y"
527: { (yypminor->yy41)->free((yypminor->yy41)); }
528: #line 528 "configparser.c"
529: break;
530: case 36:
531: #line 136 "../../src/configparser.y"
532: { (yypminor->yy41)->free((yypminor->yy41)); }
533: #line 533 "configparser.c"
534: break;
535: case 37:
536: #line 137 "../../src/configparser.y"
537: { (yypminor->yy41)->free((yypminor->yy41)); }
538: #line 538 "configparser.c"
539: break;
540: case 39:
541: #line 138 "../../src/configparser.y"
542: { array_free((yypminor->yy40)); }
543: #line 543 "configparser.c"
544: break;
545: case 40:
546: #line 139 "../../src/configparser.y"
547: { array_free((yypminor->yy40)); }
548: #line 548 "configparser.c"
549: break;
550: case 41:
551: #line 140 "../../src/configparser.y"
552: { buffer_free((yypminor->yy43)); }
553: #line 553 "configparser.c"
554: break;
555: case 42:
556: #line 141 "../../src/configparser.y"
557: { buffer_free((yypminor->yy43)); }
558: #line 558 "configparser.c"
559: break;
560: default: break; /* If no destructor action specified: do nothing */
561: }
562: }
563:
564: /*
565: ** Pop the parser's stack once.
566: **
567: ** If there is a destructor routine associated with the token which
568: ** is popped from the stack, then call it.
569: **
570: ** Return the major token number for the symbol popped.
571: */
572: static int yy_pop_parser_stack(yyParser *pParser){
573: YYCODETYPE yymajor;
574: yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
575:
576: if( pParser->yyidx<0 ) return 0;
577: #ifndef NDEBUG
578: if( yyTraceFILE && pParser->yyidx>=0 ){
579: fprintf(yyTraceFILE,"%sPopping %s\n",
580: yyTracePrompt,
581: yyTokenName[yytos->major]);
582: }
583: #endif
584: yymajor = yytos->major;
585: yy_destructor( yymajor, &yytos->minor);
586: pParser->yyidx--;
587: return yymajor;
588: }
589:
590: /*
591: ** Deallocate and destroy a parser. Destructors are all called for
592: ** all stack elements before shutting the parser down.
593: **
594: ** Inputs:
595: ** <ul>
596: ** <li> A pointer to the parser. This should be a pointer
597: ** obtained from configparserAlloc.
598: ** <li> A pointer to a function used to reclaim memory obtained
599: ** from malloc.
600: ** </ul>
601: */
602: void configparserFree(
603: void *p, /* The parser to be deleted */
604: void (*freeProc)(void*) /* Function used to reclaim memory */
605: ){
606: yyParser *pParser = (yyParser*)p;
607: if( pParser==NULL ) return;
608: while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
609: (*freeProc)((void*)pParser);
610: }
611:
612: /*
613: ** Find the appropriate action for a parser given the terminal
614: ** look-ahead token iLookAhead.
615: **
616: ** If the look-ahead token is YYNOCODE, then check to see if the action is
617: ** independent of the look-ahead. If it is, return the action, otherwise
618: ** return YY_NO_ACTION.
619: */
620: static int yy_find_shift_action(
621: yyParser *pParser, /* The parser */
622: int iLookAhead /* The look-ahead token */
623: ){
624: int i;
625: int stateno = pParser->yystack[pParser->yyidx].stateno;
626:
627: /* if( pParser->yyidx<0 ) return YY_NO_ACTION; */
628: i = yy_shift_ofst[stateno];
629: if( i==YY_SHIFT_USE_DFLT ){
630: return yy_default[stateno];
631: }
632: if( iLookAhead==YYNOCODE ){
633: return YY_NO_ACTION;
634: }
635: i += iLookAhead;
636: if( i<0 || (size_t)i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
637: #ifdef YYFALLBACK
638: int iFallback; /* Fallback token */
639: if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
640: && (iFallback = yyFallback[iLookAhead])!=0 ){
641: #ifndef NDEBUG
642: if( yyTraceFILE ){
643: fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
644: yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
645: }
646: #endif
647: return yy_find_shift_action(pParser, iFallback);
648: }
649: #endif
650: return yy_default[stateno];
651: }else{
652: return yy_action[i];
653: }
654: }
655:
656: /*
657: ** Find the appropriate action for a parser given the non-terminal
658: ** look-ahead token iLookAhead.
659: **
660: ** If the look-ahead token is YYNOCODE, then check to see if the action is
661: ** independent of the look-ahead. If it is, return the action, otherwise
662: ** return YY_NO_ACTION.
663: */
664: static int yy_find_reduce_action(
665: yyParser *pParser, /* The parser */
666: int iLookAhead /* The look-ahead token */
667: ){
668: int i;
669: int stateno = pParser->yystack[pParser->yyidx].stateno;
670:
671: i = yy_reduce_ofst[stateno];
672: if( i==YY_REDUCE_USE_DFLT ){
673: return yy_default[stateno];
674: }
675: if( iLookAhead==YYNOCODE ){
676: return YY_NO_ACTION;
677: }
678: i += iLookAhead;
679: if( i<0 || (size_t)i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
680: return yy_default[stateno];
681: }else{
682: return yy_action[i];
683: }
684: }
685:
686: /*
687: ** Perform a shift action.
688: */
689: static void yy_shift(
690: yyParser *yypParser, /* The parser to be shifted */
691: int yyNewState, /* The new state to shift in */
692: int yyMajor, /* The major token to shift in */
693: YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */
694: ){
695: yyStackEntry *yytos;
696: yypParser->yyidx++;
697: if( yypParser->yyidx>=YYSTACKDEPTH ){
698: configparserARG_FETCH;
699: yypParser->yyidx--;
700: #ifndef NDEBUG
701: if( yyTraceFILE ){
702: fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
703: }
704: #endif
705: while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
706: /* Here code is inserted which will execute if the parser
707: ** stack every overflows */
708: configparserARG_STORE; /* Suppress warning about unused %extra_argument var */
709: return;
710: }
711: yytos = &yypParser->yystack[yypParser->yyidx];
712: yytos->stateno = yyNewState;
713: yytos->major = yyMajor;
714: yytos->minor = *yypMinor;
715: #ifndef NDEBUG
716: if( yyTraceFILE && yypParser->yyidx>0 ){
717: int i;
718: fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
719: fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
720: for(i=1; i<=yypParser->yyidx; i++)
721: fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
722: fprintf(yyTraceFILE,"\n");
723: }
724: #endif
725: }
726:
727: /* The following table contains information about every rule that
728: ** is used during the reduce.
729: */
730: static struct {
731: YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
732: unsigned char nrhs; /* Number of right-hand side symbols in the rule */
733: } yyRuleInfo[] = {
734: { 27, 1 },
735: { 28, 2 },
736: { 28, 0 },
737: { 29, 1 },
738: { 29, 1 },
739: { 29, 2 },
740: { 29, 1 },
741: { 29, 1 },
742: { 29, 1 },
743: { 30, 3 },
744: { 30, 3 },
745: { 41, 1 },
746: { 36, 3 },
747: { 36, 1 },
748: { 35, 1 },
749: { 35, 1 },
750: { 35, 1 },
751: { 35, 1 },
752: { 40, 2 },
753: { 40, 3 },
754: { 39, 3 },
755: { 39, 2 },
756: { 39, 1 },
757: { 37, 1 },
758: { 37, 3 },
759: { 44, 1 },
760: { 44, 0 },
761: { 45, 1 },
762: { 31, 4 },
763: { 32, 4 },
764: { 32, 1 },
765: { 38, 4 },
766: { 46, 7 },
767: { 43, 1 },
768: { 43, 1 },
769: { 43, 1 },
770: { 43, 1 },
771: { 42, 1 },
772: { 33, 2 },
773: { 34, 2 },
774: };
775:
776: static void yy_accept(yyParser*); /* Forward Declaration */
777:
778: /*
779: ** Perform a reduce action and the shift that must immediately
780: ** follow the reduce.
781: */
782: static void yy_reduce(
783: yyParser *yypParser, /* The parser */
784: int yyruleno /* Number of the rule by which to reduce */
785: ){
786: int yygoto; /* The next state */
787: int yyact; /* The next action */
788: YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
789: yyStackEntry *yymsp; /* The top of the parser's stack */
790: int yysize; /* Amount to pop the stack */
791: configparserARG_FETCH;
792: yymsp = &yypParser->yystack[yypParser->yyidx];
793: #ifndef NDEBUG
794: if( yyTraceFILE && yyruleno>=0
795: && (size_t)yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
796: fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
797: yyRuleName[yyruleno]);
798: }
799: #endif /* NDEBUG */
800:
801: switch( yyruleno ){
802: /* Beginning here are the reduction cases. A typical example
803: ** follows:
804: ** case 0:
805: ** #line <lineno> <grammarfile>
806: ** { ... } // User supplied code
807: ** #line <lineno> <thisfile>
808: ** break;
809: */
810: case 0:
811: /* No destructor defined for metalines */
812: break;
813: case 1:
814: /* No destructor defined for metalines */
815: /* No destructor defined for metaline */
816: break;
817: case 2:
818: break;
819: case 3:
820: /* No destructor defined for varline */
821: break;
822: case 4:
823: /* No destructor defined for global */
824: break;
825: case 5:
826: #line 117 "../../src/configparser.y"
827: { yymsp[-1].minor.yy78 = NULL; }
828: #line 828 "configparser.c"
829: yy_destructor(1,&yymsp[0].minor);
830: break;
831: case 6:
832: /* No destructor defined for include */
833: break;
834: case 7:
835: /* No destructor defined for include_shell */
836: break;
837: case 8:
838: yy_destructor(1,&yymsp[0].minor);
839: break;
840: case 9:
841: #line 146 "../../src/configparser.y"
842: {
843: if (ctx->ok) {
844: buffer_copy_string_buffer(yymsp[0].minor.yy41->key, yymsp[-2].minor.yy43);
845: if (strncmp(yymsp[-2].minor.yy43->ptr, "env.", sizeof("env.") - 1) == 0) {
846: fprintf(stderr, "Setting env variable is not supported in conditional %d %s: %s\n",
847: ctx->current->context_ndx,
848: ctx->current->key->ptr, yymsp[-2].minor.yy43->ptr);
849: ctx->ok = 0;
850: } else if (NULL == array_get_element(ctx->current->value, yymsp[0].minor.yy41->key->ptr)) {
851: array_insert_unique(ctx->current->value, yymsp[0].minor.yy41);
852: yymsp[0].minor.yy41 = NULL;
853: } else {
854: fprintf(stderr, "Duplicate config variable in conditional %d %s: %s\n",
855: ctx->current->context_ndx,
856: ctx->current->key->ptr, yymsp[0].minor.yy41->key->ptr);
857: ctx->ok = 0;
858: yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
859: yymsp[0].minor.yy41 = NULL;
860: }
861: }
862: buffer_free(yymsp[-2].minor.yy43);
863: yymsp[-2].minor.yy43 = NULL;
864: }
865: #line 865 "configparser.c"
866: yy_destructor(2,&yymsp[-1].minor);
867: break;
868: case 10:
869: #line 170 "../../src/configparser.y"
870: {
871: array *vars = ctx->current->value;
872: data_unset *du;
873:
874: if (strncmp(yymsp[-2].minor.yy43->ptr, "env.", sizeof("env.") - 1) == 0) {
875: fprintf(stderr, "Appending env variable is not supported in conditional %d %s: %s\n",
876: ctx->current->context_ndx,
877: ctx->current->key->ptr, yymsp[-2].minor.yy43->ptr);
878: ctx->ok = 0;
879: } else if (NULL != (du = array_get_element(vars, yymsp[-2].minor.yy43->ptr))) {
880: /* exists in current block */
881: du = configparser_merge_data(du, yymsp[0].minor.yy41);
882: if (NULL == du) {
883: ctx->ok = 0;
884: }
885: else {
886: buffer_copy_string_buffer(du->key, yymsp[-2].minor.yy43);
887: array_replace(vars, du);
888: }
889: yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
890: } else if (NULL != (du = configparser_get_variable(ctx, yymsp[-2].minor.yy43))) {
891: du = configparser_merge_data(du, yymsp[0].minor.yy41);
892: if (NULL == du) {
893: ctx->ok = 0;
894: }
895: else {
896: buffer_copy_string_buffer(du->key, yymsp[-2].minor.yy43);
897: array_insert_unique(ctx->current->value, du);
898: }
899: yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
900: } else {
901: buffer_copy_string_buffer(yymsp[0].minor.yy41->key, yymsp[-2].minor.yy43);
902: array_insert_unique(ctx->current->value, yymsp[0].minor.yy41);
903: }
904: buffer_free(yymsp[-2].minor.yy43);
905: yymsp[-2].minor.yy43 = NULL;
906: yymsp[0].minor.yy41 = NULL;
907: }
908: #line 908 "configparser.c"
909: yy_destructor(3,&yymsp[-1].minor);
910: break;
911: case 11:
912: #line 209 "../../src/configparser.y"
913: {
914: if (strchr(yymsp[0].minor.yy0->ptr, '.') == NULL) {
915: yygotominor.yy43 = buffer_init_string("var.");
916: buffer_append_string_buffer(yygotominor.yy43, yymsp[0].minor.yy0);
917: buffer_free(yymsp[0].minor.yy0);
918: yymsp[0].minor.yy0 = NULL;
919: } else {
920: yygotominor.yy43 = yymsp[0].minor.yy0;
921: yymsp[0].minor.yy0 = NULL;
922: }
923: }
924: #line 924 "configparser.c"
925: break;
926: case 12:
927: #line 221 "../../src/configparser.y"
928: {
929: yygotominor.yy41 = configparser_merge_data(yymsp[-2].minor.yy41, yymsp[0].minor.yy41);
930: if (NULL == yygotominor.yy41) {
931: ctx->ok = 0;
932: }
933: yymsp[-2].minor.yy41 = NULL;
934: yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
935: yymsp[0].minor.yy41 = NULL;
936: }
937: #line 937 "configparser.c"
938: yy_destructor(5,&yymsp[-1].minor);
939: break;
940: case 13:
941: #line 231 "../../src/configparser.y"
942: {
943: yygotominor.yy41 = yymsp[0].minor.yy41;
944: yymsp[0].minor.yy41 = NULL;
945: }
946: #line 946 "configparser.c"
947: break;
948: case 14:
949: #line 236 "../../src/configparser.y"
950: {
951: yygotominor.yy41 = NULL;
952: if (strncmp(yymsp[0].minor.yy43->ptr, "env.", sizeof("env.") - 1) == 0) {
953: char *env;
954:
955: if (NULL != (env = getenv(yymsp[0].minor.yy43->ptr + 4))) {
956: data_string *ds;
957: ds = data_string_init();
958: buffer_append_string(ds->value, env);
959: yygotominor.yy41 = (data_unset *)ds;
960: }
961: else {
962: fprintf(stderr, "Undefined env variable: %s\n", yymsp[0].minor.yy43->ptr + 4);
963: ctx->ok = 0;
964: }
965: } else if (NULL == (yygotominor.yy41 = configparser_get_variable(ctx, yymsp[0].minor.yy43))) {
966: fprintf(stderr, "Undefined config variable: %s\n", yymsp[0].minor.yy43->ptr);
967: ctx->ok = 0;
968: }
969: if (!yygotominor.yy41) {
970: /* make a dummy so it won't crash */
971: yygotominor.yy41 = (data_unset *)data_string_init();
972: }
973: buffer_free(yymsp[0].minor.yy43);
974: yymsp[0].minor.yy43 = NULL;
975: }
976: #line 976 "configparser.c"
977: break;
978: case 15:
979: #line 263 "../../src/configparser.y"
980: {
981: yygotominor.yy41 = (data_unset *)data_string_init();
982: buffer_copy_string_buffer(((data_string *)(yygotominor.yy41))->value, yymsp[0].minor.yy0);
983: buffer_free(yymsp[0].minor.yy0);
984: yymsp[0].minor.yy0 = NULL;
985: }
986: #line 986 "configparser.c"
987: break;
988: case 16:
989: #line 270 "../../src/configparser.y"
990: {
991: yygotominor.yy41 = (data_unset *)data_integer_init();
992: ((data_integer *)(yygotominor.yy41))->value = strtol(yymsp[0].minor.yy0->ptr, NULL, 10);
993: buffer_free(yymsp[0].minor.yy0);
994: yymsp[0].minor.yy0 = NULL;
995: }
996: #line 996 "configparser.c"
997: break;
998: case 17:
999: #line 276 "../../src/configparser.y"
1000: {
1001: yygotominor.yy41 = (data_unset *)data_array_init();
1002: array_free(((data_array *)(yygotominor.yy41))->value);
1003: ((data_array *)(yygotominor.yy41))->value = yymsp[0].minor.yy40;
1004: yymsp[0].minor.yy40 = NULL;
1005: }
1006: #line 1006 "configparser.c"
1007: break;
1008: case 18:
1009: #line 282 "../../src/configparser.y"
1010: {
1011: yygotominor.yy40 = array_init();
1012: }
1013: #line 1013 "configparser.c"
1014: yy_destructor(8,&yymsp[-1].minor);
1015: yy_destructor(9,&yymsp[0].minor);
1016: break;
1017: case 19:
1018: #line 285 "../../src/configparser.y"
1019: {
1020: yygotominor.yy40 = yymsp[-1].minor.yy40;
1021: yymsp[-1].minor.yy40 = NULL;
1022: }
1023: #line 1023 "configparser.c"
1024: yy_destructor(8,&yymsp[-2].minor);
1025: yy_destructor(9,&yymsp[0].minor);
1026: break;
1027: case 20:
1028: #line 290 "../../src/configparser.y"
1029: {
1030: if (buffer_is_empty(yymsp[0].minor.yy41->key) ||
1031: NULL == array_get_element(yymsp[-2].minor.yy40, yymsp[0].minor.yy41->key->ptr)) {
1032: array_insert_unique(yymsp[-2].minor.yy40, yymsp[0].minor.yy41);
1033: yymsp[0].minor.yy41 = NULL;
1034: } else {
1035: fprintf(stderr, "Duplicate array-key: %s\n",
1036: yymsp[0].minor.yy41->key->ptr);
1037: ctx->ok = 0;
1038: yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
1039: yymsp[0].minor.yy41 = NULL;
1040: }
1041:
1042: yygotominor.yy40 = yymsp[-2].minor.yy40;
1043: yymsp[-2].minor.yy40 = NULL;
1044: }
1045: #line 1045 "configparser.c"
1046: yy_destructor(10,&yymsp[-1].minor);
1047: break;
1048: case 21:
1049: #line 307 "../../src/configparser.y"
1050: {
1051: yygotominor.yy40 = yymsp[-1].minor.yy40;
1052: yymsp[-1].minor.yy40 = NULL;
1053: }
1054: #line 1054 "configparser.c"
1055: yy_destructor(10,&yymsp[0].minor);
1056: break;
1057: case 22:
1058: #line 312 "../../src/configparser.y"
1059: {
1060: yygotominor.yy40 = array_init();
1061: array_insert_unique(yygotominor.yy40, yymsp[0].minor.yy41);
1062: yymsp[0].minor.yy41 = NULL;
1063: }
1064: #line 1064 "configparser.c"
1065: break;
1066: case 23:
1067: #line 318 "../../src/configparser.y"
1068: {
1069: yygotominor.yy41 = yymsp[0].minor.yy41;
1070: yymsp[0].minor.yy41 = NULL;
1071: }
1072: #line 1072 "configparser.c"
1073: break;
1074: case 24:
1075: #line 322 "../../src/configparser.y"
1076: {
1077: buffer_copy_string_buffer(yymsp[0].minor.yy41->key, yymsp[-2].minor.yy43);
1078: buffer_free(yymsp[-2].minor.yy43);
1079: yymsp[-2].minor.yy43 = NULL;
1080:
1081: yygotominor.yy41 = yymsp[0].minor.yy41;
1082: yymsp[0].minor.yy41 = NULL;
1083: }
1084: #line 1084 "configparser.c"
1085: yy_destructor(11,&yymsp[-1].minor);
1086: break;
1087: case 25:
1088: yy_destructor(1,&yymsp[0].minor);
1089: break;
1090: case 26:
1091: break;
1092: case 27:
1093: #line 334 "../../src/configparser.y"
1094: {
1095: data_config *dc;
1096: dc = (data_config *)array_get_element(ctx->srv->config_context, "global");
1097: assert(dc);
1098: configparser_push(ctx, dc, 0);
1099: }
1100: #line 1100 "configparser.c"
1101: yy_destructor(12,&yymsp[0].minor);
1102: break;
1103: case 28:
1104: #line 341 "../../src/configparser.y"
1105: {
1106: data_config *cur;
1107:
1108: cur = ctx->current;
1109: configparser_pop(ctx);
1110:
1111: assert(cur && ctx->current);
1112:
1113: yygotominor.yy78 = cur;
1114: }
1115: #line 1115 "configparser.c"
1116: /* No destructor defined for globalstart */
1117: yy_destructor(13,&yymsp[-2].minor);
1118: /* No destructor defined for metalines */
1119: yy_destructor(14,&yymsp[0].minor);
1120: break;
1121: case 29:
1122: #line 352 "../../src/configparser.y"
1123: {
1124: if (yymsp[-3].minor.yy78->context_ndx >= yymsp[0].minor.yy78->context_ndx) {
1125: fprintf(stderr, "unreachable else condition\n");
1126: ctx->ok = 0;
1127: }
1128: yymsp[0].minor.yy78->prev = yymsp[-3].minor.yy78;
1129: yymsp[-3].minor.yy78->next = yymsp[0].minor.yy78;
1130: yygotominor.yy78 = yymsp[0].minor.yy78;
1131: yymsp[-3].minor.yy78 = NULL;
1132: yymsp[0].minor.yy78 = NULL;
1133: }
1134: #line 1134 "configparser.c"
1135: /* No destructor defined for eols */
1136: yy_destructor(15,&yymsp[-1].minor);
1137: break;
1138: case 30:
1139: #line 364 "../../src/configparser.y"
1140: {
1141: yygotominor.yy78 = yymsp[0].minor.yy78;
1142: yymsp[0].minor.yy78 = NULL;
1143: }
1144: #line 1144 "configparser.c"
1145: break;
1146: case 31:
1147: #line 369 "../../src/configparser.y"
1148: {
1149: data_config *cur;
1150:
1151: cur = ctx->current;
1152: configparser_pop(ctx);
1153:
1154: assert(cur && ctx->current);
1155:
1156: yygotominor.yy78 = cur;
1157: }
1158: #line 1158 "configparser.c"
1159: /* No destructor defined for context */
1160: yy_destructor(13,&yymsp[-2].minor);
1161: /* No destructor defined for metalines */
1162: yy_destructor(14,&yymsp[0].minor);
1163: break;
1164: case 32:
1165: #line 380 "../../src/configparser.y"
1166: {
1167: data_config *dc;
1168: buffer *b, *rvalue, *op;
1169:
1170: if (ctx->ok && yymsp[0].minor.yy41->type != TYPE_STRING) {
1171: fprintf(stderr, "rvalue must be string");
1172: ctx->ok = 0;
1173: }
1174:
1175: switch(yymsp[-1].minor.yy27) {
1176: case CONFIG_COND_NE:
1177: op = buffer_init_string("!=");
1178: break;
1179: case CONFIG_COND_EQ:
1180: op = buffer_init_string("==");
1181: break;
1182: case CONFIG_COND_NOMATCH:
1183: op = buffer_init_string("!~");
1184: break;
1185: case CONFIG_COND_MATCH:
1186: op = buffer_init_string("=~");
1187: break;
1188: default:
1189: assert(0);
1190: return;
1191: }
1192:
1193: b = buffer_init();
1194: buffer_copy_string_buffer(b, ctx->current->key);
1195: buffer_append_string(b, "/");
1196: buffer_append_string_buffer(b, yymsp[-5].minor.yy0);
1197: buffer_append_string_buffer(b, yymsp[-3].minor.yy43);
1198: buffer_append_string_buffer(b, op);
1199: rvalue = ((data_string*)yymsp[0].minor.yy41)->value;
1200: buffer_append_string_buffer(b, rvalue);
1201:
1202: if (NULL != (dc = (data_config *)array_get_element(ctx->all_configs, b->ptr))) {
1203: configparser_push(ctx, dc, 0);
1204: } else {
1205: struct {
1206: comp_key_t comp;
1207: char *comp_key;
1208: size_t len;
1209: } comps[] = {
1210: { COMP_SERVER_SOCKET, CONST_STR_LEN("SERVER[\"socket\"]" ) },
1211: { COMP_HTTP_URL, CONST_STR_LEN("HTTP[\"url\"]" ) },
1212: { COMP_HTTP_HOST, CONST_STR_LEN("HTTP[\"host\"]" ) },
1213: { COMP_HTTP_REFERER, CONST_STR_LEN("HTTP[\"referer\"]" ) },
1214: { COMP_HTTP_USER_AGENT, CONST_STR_LEN("HTTP[\"useragent\"]" ) },
1215: { COMP_HTTP_USER_AGENT, CONST_STR_LEN("HTTP[\"user-agent\"]" ) },
1216: { COMP_HTTP_LANGUAGE, CONST_STR_LEN("HTTP[\"language\"]" ) },
1217: { COMP_HTTP_COOKIE, CONST_STR_LEN("HTTP[\"cookie\"]" ) },
1218: { COMP_HTTP_REMOTE_IP, CONST_STR_LEN("HTTP[\"remoteip\"]" ) },
1219: { COMP_HTTP_REMOTE_IP, CONST_STR_LEN("HTTP[\"remote-ip\"]" ) },
1220: { COMP_HTTP_QUERY_STRING, CONST_STR_LEN("HTTP[\"querystring\"]") },
1221: { COMP_HTTP_QUERY_STRING, CONST_STR_LEN("HTTP[\"query-string\"]") },
1222: { COMP_HTTP_REQUEST_METHOD, CONST_STR_LEN("HTTP[\"request-method\"]") },
1223: { COMP_HTTP_SCHEME, CONST_STR_LEN("HTTP[\"scheme\"]" ) },
1224: { COMP_UNSET, NULL, 0 },
1225: };
1226: size_t i;
1227:
1228: dc = data_config_init();
1229:
1230: buffer_copy_string_buffer(dc->key, b);
1231: buffer_copy_string_buffer(dc->op, op);
1232: buffer_copy_string_buffer(dc->comp_key, yymsp[-5].minor.yy0);
1233: buffer_append_string_len(dc->comp_key, CONST_STR_LEN("[\""));
1234: buffer_append_string_buffer(dc->comp_key, yymsp[-3].minor.yy43);
1235: buffer_append_string_len(dc->comp_key, CONST_STR_LEN("\"]"));
1236: dc->cond = yymsp[-1].minor.yy27;
1237:
1238: for (i = 0; comps[i].comp_key; i ++) {
1239: if (buffer_is_equal_string(
1240: dc->comp_key, comps[i].comp_key, comps[i].len)) {
1241: dc->comp = comps[i].comp;
1242: break;
1243: }
1244: }
1245: if (COMP_UNSET == dc->comp) {
1246: fprintf(stderr, "error comp_key %s", dc->comp_key->ptr);
1247: ctx->ok = 0;
1248: }
1249:
1250: switch(yymsp[-1].minor.yy27) {
1251: case CONFIG_COND_NE:
1252: case CONFIG_COND_EQ:
1253: dc->string = buffer_init_buffer(rvalue);
1254: break;
1255: case CONFIG_COND_NOMATCH:
1256: case CONFIG_COND_MATCH: {
1257: #ifdef HAVE_PCRE_H
1258: const char *errptr;
1259: int erroff, captures;
1260:
1261: if (NULL == (dc->regex =
1262: pcre_compile(rvalue->ptr, 0, &errptr, &erroff, NULL))) {
1263: dc->string = buffer_init_string(errptr);
1264: dc->cond = CONFIG_COND_UNSET;
1265:
1266: fprintf(stderr, "parsing regex failed: %s -> %s at offset %d\n",
1267: rvalue->ptr, errptr, erroff);
1268:
1269: ctx->ok = 0;
1270: } else if (NULL == (dc->regex_study =
1271: pcre_study(dc->regex, 0, &errptr)) &&
1272: errptr != NULL) {
1273: fprintf(stderr, "studying regex failed: %s -> %s\n",
1274: rvalue->ptr, errptr);
1275: ctx->ok = 0;
1276: } else if (0 != (pcre_fullinfo(dc->regex, dc->regex_study, PCRE_INFO_CAPTURECOUNT, &captures))) {
1277: fprintf(stderr, "getting capture count for regex failed: %s\n",
1278: rvalue->ptr);
1279: ctx->ok = 0;
1280: } else if (captures > 9) {
1281: fprintf(stderr, "Too many captures in regex, use (?:...) instead of (...): %s\n",
1282: rvalue->ptr);
1283: ctx->ok = 0;
1284: } else {
1285: dc->string = buffer_init_buffer(rvalue);
1286: }
1287: #else
1288: fprintf(stderr, "can't handle '$%s[%s] =~ ...' as you compiled without pcre support. \n"
1289: "(perhaps just a missing pcre-devel package ?) \n",
1290: yymsp[-5].minor.yy0->ptr, yymsp[-3].minor.yy43->ptr);
1291: ctx->ok = 0;
1292: #endif
1293: break;
1294: }
1295:
1296: default:
1297: fprintf(stderr, "unknown condition for $%s[%s]\n",
1298: yymsp[-5].minor.yy0->ptr, yymsp[-3].minor.yy43->ptr);
1299: ctx->ok = 0;
1300: break;
1301: }
1302:
1303: configparser_push(ctx, dc, 1);
1304: }
1305:
1306: buffer_free(b);
1307: buffer_free(op);
1308: buffer_free(yymsp[-5].minor.yy0);
1309: yymsp[-5].minor.yy0 = NULL;
1310: buffer_free(yymsp[-3].minor.yy43);
1311: yymsp[-3].minor.yy43 = NULL;
1312: yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
1313: yymsp[0].minor.yy41 = NULL;
1314: }
1315: #line 1315 "configparser.c"
1316: yy_destructor(16,&yymsp[-6].minor);
1317: yy_destructor(18,&yymsp[-4].minor);
1318: yy_destructor(19,&yymsp[-2].minor);
1319: break;
1320: case 33:
1321: #line 529 "../../src/configparser.y"
1322: {
1323: yygotominor.yy27 = CONFIG_COND_EQ;
1324: }
1325: #line 1325 "configparser.c"
1326: yy_destructor(20,&yymsp[0].minor);
1327: break;
1328: case 34:
1329: #line 532 "../../src/configparser.y"
1330: {
1331: yygotominor.yy27 = CONFIG_COND_MATCH;
1332: }
1333: #line 1333 "configparser.c"
1334: yy_destructor(21,&yymsp[0].minor);
1335: break;
1336: case 35:
1337: #line 535 "../../src/configparser.y"
1338: {
1339: yygotominor.yy27 = CONFIG_COND_NE;
1340: }
1341: #line 1341 "configparser.c"
1342: yy_destructor(22,&yymsp[0].minor);
1343: break;
1344: case 36:
1345: #line 538 "../../src/configparser.y"
1346: {
1347: yygotominor.yy27 = CONFIG_COND_NOMATCH;
1348: }
1349: #line 1349 "configparser.c"
1350: yy_destructor(23,&yymsp[0].minor);
1351: break;
1352: case 37:
1353: #line 542 "../../src/configparser.y"
1354: {
1355: yygotominor.yy43 = NULL;
1356: if (ctx->ok) {
1357: if (yymsp[0].minor.yy41->type == TYPE_STRING) {
1358: yygotominor.yy43 = buffer_init_buffer(((data_string*)yymsp[0].minor.yy41)->value);
1359: } else if (yymsp[0].minor.yy41->type == TYPE_INTEGER) {
1360: yygotominor.yy43 = buffer_init();
1361: buffer_copy_long(yygotominor.yy43, ((data_integer *)yymsp[0].minor.yy41)->value);
1362: } else {
1363: fprintf(stderr, "operand must be string");
1364: ctx->ok = 0;
1365: }
1366: }
1367: yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
1368: yymsp[0].minor.yy41 = NULL;
1369: }
1370: #line 1370 "configparser.c"
1371: break;
1372: case 38:
1373: #line 559 "../../src/configparser.y"
1374: {
1375: if (ctx->ok) {
1376: if (0 != config_parse_file(ctx->srv, ctx, yymsp[0].minor.yy43->ptr)) {
1377: ctx->ok = 0;
1378: }
1379: buffer_free(yymsp[0].minor.yy43);
1380: yymsp[0].minor.yy43 = NULL;
1381: }
1382: }
1383: #line 1383 "configparser.c"
1384: yy_destructor(24,&yymsp[-1].minor);
1385: break;
1386: case 39:
1387: #line 569 "../../src/configparser.y"
1388: {
1389: if (ctx->ok) {
1390: if (0 != config_parse_cmd(ctx->srv, ctx, yymsp[0].minor.yy43->ptr)) {
1391: ctx->ok = 0;
1392: }
1393: buffer_free(yymsp[0].minor.yy43);
1394: yymsp[0].minor.yy43 = NULL;
1395: }
1396: }
1397: #line 1397 "configparser.c"
1398: yy_destructor(25,&yymsp[-1].minor);
1399: break;
1400: };
1401: yygoto = yyRuleInfo[yyruleno].lhs;
1402: yysize = yyRuleInfo[yyruleno].nrhs;
1403: yypParser->yyidx -= yysize;
1404: yyact = yy_find_reduce_action(yypParser,yygoto);
1405: if( yyact < YYNSTATE ){
1406: yy_shift(yypParser,yyact,yygoto,&yygotominor);
1407: }else if( yyact == YYNSTATE + YYNRULE + 1 ){
1408: yy_accept(yypParser);
1409: }
1410: }
1411:
1412: /*
1413: ** The following code executes when the parse fails
1414: */
1415: static void yy_parse_failed(
1416: yyParser *yypParser /* The parser */
1417: ){
1418: configparserARG_FETCH;
1419: #ifndef NDEBUG
1420: if( yyTraceFILE ){
1421: fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
1422: }
1423: #endif
1424: while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
1425: /* Here code is inserted which will be executed whenever the
1426: ** parser fails */
1427: #line 108 "../../src/configparser.y"
1428:
1429: ctx->ok = 0;
1430:
1431: #line 1431 "configparser.c"
1432: configparserARG_STORE; /* Suppress warning about unused %extra_argument variable */
1433: }
1434:
1435: /*
1436: ** The following code executes when a syntax error first occurs.
1437: */
1438: static void yy_syntax_error(
1439: yyParser *yypParser, /* The parser */
1440: int yymajor, /* The major type of the error token */
1441: YYMINORTYPE yyminor /* The minor type of the error token */
1442: ){
1443: configparserARG_FETCH;
1444: UNUSED(yymajor);
1445: UNUSED(yyminor);
1446: #define TOKEN (yyminor.yy0)
1447: configparserARG_STORE; /* Suppress warning about unused %extra_argument variable */
1448: }
1449:
1450: /*
1451: ** The following is executed when the parser accepts
1452: */
1453: static void yy_accept(
1454: yyParser *yypParser /* The parser */
1455: ){
1456: configparserARG_FETCH;
1457: #ifndef NDEBUG
1458: if( yyTraceFILE ){
1459: fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
1460: }
1461: #endif
1462: while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
1463: /* Here code is inserted which will be executed whenever the
1464: ** parser accepts */
1465: configparserARG_STORE; /* Suppress warning about unused %extra_argument variable */
1466: }
1467:
1468: /* The main parser program.
1469: ** The first argument is a pointer to a structure obtained from
1470: ** "configparserAlloc" which describes the current state of the parser.
1471: ** The second argument is the major token number. The third is
1472: ** the minor token. The fourth optional argument is whatever the
1473: ** user wants (and specified in the grammar) and is available for
1474: ** use by the action routines.
1475: **
1476: ** Inputs:
1477: ** <ul>
1478: ** <li> A pointer to the parser (an opaque structure.)
1479: ** <li> The major token number.
1480: ** <li> The minor token number.
1481: ** <li> An option argument of a grammar-specified type.
1482: ** </ul>
1483: **
1484: ** Outputs:
1485: ** None.
1486: */
1487: void configparser(
1488: void *yyp, /* The parser */
1489: int yymajor, /* The major token code number */
1490: configparserTOKENTYPE yyminor /* The value for the token */
1491: configparserARG_PDECL /* Optional %extra_argument parameter */
1492: ){
1493: YYMINORTYPE yyminorunion;
1494: int yyact; /* The parser action. */
1495: int yyendofinput; /* True if we are at the end of input */
1496: int yyerrorhit = 0; /* True if yymajor has invoked an error */
1497: yyParser *yypParser; /* The parser */
1498:
1499: /* (re)initialize the parser, if necessary */
1500: yypParser = (yyParser*)yyp;
1501: if( yypParser->yyidx<0 ){
1502: if( yymajor==0 ) return;
1503: yypParser->yyidx = 0;
1504: yypParser->yyerrcnt = -1;
1505: yypParser->yystack[0].stateno = 0;
1506: yypParser->yystack[0].major = 0;
1507: }
1508: yyminorunion.yy0 = yyminor;
1509: yyendofinput = (yymajor==0);
1510: configparserARG_STORE;
1511:
1512: #ifndef NDEBUG
1513: if( yyTraceFILE ){
1514: fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
1515: }
1516: #endif
1517:
1518: do{
1519: yyact = yy_find_shift_action(yypParser,yymajor);
1520: if( yyact<YYNSTATE ){
1521: yy_shift(yypParser,yyact,yymajor,&yyminorunion);
1522: yypParser->yyerrcnt--;
1523: if( yyendofinput && yypParser->yyidx>=0 ){
1524: yymajor = 0;
1525: }else{
1526: yymajor = YYNOCODE;
1527: }
1528: }else if( yyact < YYNSTATE + YYNRULE ){
1529: yy_reduce(yypParser,yyact-YYNSTATE);
1530: }else if( yyact == YY_ERROR_ACTION ){
1531: int yymx;
1532: #ifndef NDEBUG
1533: if( yyTraceFILE ){
1534: fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
1535: }
1536: #endif
1537: #ifdef YYERRORSYMBOL
1538: /* A syntax error has occurred.
1539: ** The response to an error depends upon whether or not the
1540: ** grammar defines an error token "ERROR".
1541: **
1542: ** This is what we do if the grammar does define ERROR:
1543: **
1544: ** * Call the %syntax_error function.
1545: **
1546: ** * Begin popping the stack until we enter a state where
1547: ** it is legal to shift the error symbol, then shift
1548: ** the error symbol.
1549: **
1550: ** * Set the error count to three.
1551: **
1552: ** * Begin accepting and shifting new tokens. No new error
1553: ** processing will occur until three tokens have been
1554: ** shifted successfully.
1555: **
1556: */
1557: if( yypParser->yyerrcnt<0 ){
1558: yy_syntax_error(yypParser,yymajor,yyminorunion);
1559: }
1560: yymx = yypParser->yystack[yypParser->yyidx].major;
1561: if( yymx==YYERRORSYMBOL || yyerrorhit ){
1562: #ifndef NDEBUG
1563: if( yyTraceFILE ){
1564: fprintf(yyTraceFILE,"%sDiscard input token %s\n",
1565: yyTracePrompt,yyTokenName[yymajor]);
1566: }
1567: #endif
1568: yy_destructor(yymajor,&yyminorunion);
1569: yymajor = YYNOCODE;
1570: }else{
1571: while(
1572: yypParser->yyidx >= 0 &&
1573: yymx != YYERRORSYMBOL &&
1574: (yyact = yy_find_shift_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE
1575: ){
1576: yy_pop_parser_stack(yypParser);
1577: }
1578: if( yypParser->yyidx < 0 || yymajor==0 ){
1579: yy_destructor(yymajor,&yyminorunion);
1580: yy_parse_failed(yypParser);
1581: yymajor = YYNOCODE;
1582: }else if( yymx!=YYERRORSYMBOL ){
1583: YYMINORTYPE u2;
1584: u2.YYERRSYMDT = 0;
1585: yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
1586: }
1587: }
1588: yypParser->yyerrcnt = 3;
1589: yyerrorhit = 1;
1590: #else /* YYERRORSYMBOL is not defined */
1591: /* This is what we do if the grammar does not define ERROR:
1592: **
1593: ** * Report an error message, and throw away the input token.
1594: **
1595: ** * If the input token is $, then fail the parse.
1596: **
1597: ** As before, subsequent error messages are suppressed until
1598: ** three input tokens have been successfully shifted.
1599: */
1600: if( yypParser->yyerrcnt<=0 ){
1601: yy_syntax_error(yypParser,yymajor,yyminorunion);
1602: }
1603: yypParser->yyerrcnt = 3;
1604: yy_destructor(yymajor,&yyminorunion);
1605: if( yyendofinput ){
1606: yy_parse_failed(yypParser);
1607: }
1608: yymajor = YYNOCODE;
1609: #endif
1610: }else{
1611: yy_accept(yypParser);
1612: yymajor = YYNOCODE;
1613: }
1614: }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
1615: return;
1616: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>