Annotation of embedaddon/php/Zend/zend_ini_parser.y, revision 1.1.1.4
1.1 misho 1: %{
2: /*
3: +----------------------------------------------------------------------+
4: | Zend Engine |
5: +----------------------------------------------------------------------+
1.1.1.4 ! misho 6: | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
1.1 misho 7: +----------------------------------------------------------------------+
8: | This source file is subject to version 2.00 of the Zend license, |
9: | that is bundled with this package in the file LICENSE, and is |
10: | available through the world-wide-web at the following url: |
11: | http://www.zend.com/license/2_00.txt. |
12: | If you did not receive a copy of the Zend license and are unable to |
13: | obtain it through the world-wide-web, please send a note to |
14: | license@zend.com so we can mail you a copy immediately. |
15: +----------------------------------------------------------------------+
16: | Authors: Zeev Suraski <zeev@zend.com> |
17: | Jani Taskinen <jani@php.net> |
18: +----------------------------------------------------------------------+
19: */
20:
1.1.1.2 misho 21: /* $Id$ */
1.1 misho 22:
23: #define DEBUG_CFG_PARSER 0
24:
25: #include "zend.h"
26: #include "zend_API.h"
27: #include "zend_ini.h"
28: #include "zend_constants.h"
29: #include "zend_ini_scanner.h"
30: #include "zend_extensions.h"
31:
32: #define YYERROR_VERBOSE
33: #define YYSTYPE zval
34:
35: #ifdef ZTS
36: #define YYPARSE_PARAM tsrm_ls
37: #define YYLEX_PARAM tsrm_ls
38: int ini_parse(void *arg);
39: #else
40: int ini_parse(void);
41: #endif
42:
43: #define ZEND_INI_PARSER_CB (CG(ini_parser_param))->ini_parser_cb
44: #define ZEND_INI_PARSER_ARG (CG(ini_parser_param))->arg
45:
46: /* {{{ zend_ini_do_op()
47: */
48: static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
49: {
50: int i_result;
51: int i_op1, i_op2;
52: char str_result[MAX_LENGTH_OF_LONG];
53:
54: i_op1 = atoi(Z_STRVAL_P(op1));
55: free(Z_STRVAL_P(op1));
56: if (op2) {
57: i_op2 = atoi(Z_STRVAL_P(op2));
58: free(Z_STRVAL_P(op2));
59: } else {
60: i_op2 = 0;
61: }
62:
63: switch (type) {
64: case '|':
65: i_result = i_op1 | i_op2;
66: break;
67: case '&':
68: i_result = i_op1 & i_op2;
69: break;
70: case '~':
71: i_result = ~i_op1;
72: break;
73: case '!':
74: i_result = !i_op1;
75: break;
76: default:
77: i_result = 0;
78: break;
79: }
80:
81: Z_STRLEN_P(result) = zend_sprintf(str_result, "%d", i_result);
82: Z_STRVAL_P(result) = (char *) malloc(Z_STRLEN_P(result)+1);
83: memcpy(Z_STRVAL_P(result), str_result, Z_STRLEN_P(result));
84: Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
85: Z_TYPE_P(result) = IS_STRING;
86: }
87: /* }}} */
88:
89: /* {{{ zend_ini_init_string()
90: */
91: static void zend_ini_init_string(zval *result)
92: {
93: Z_STRVAL_P(result) = malloc(1);
94: Z_STRVAL_P(result)[0] = 0;
95: Z_STRLEN_P(result) = 0;
96: Z_TYPE_P(result) = IS_STRING;
97: }
98: /* }}} */
99:
100: /* {{{ zend_ini_add_string()
101: */
102: static void zend_ini_add_string(zval *result, zval *op1, zval *op2)
103: {
104: int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
105:
106: Z_STRVAL_P(result) = (char *) realloc(Z_STRVAL_P(op1), length+1);
107: memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
108: Z_STRVAL_P(result)[length] = 0;
109: Z_STRLEN_P(result) = length;
110: Z_TYPE_P(result) = IS_STRING;
111: }
112: /* }}} */
113:
114: /* {{{ zend_ini_get_constant()
115: */
116: static void zend_ini_get_constant(zval *result, zval *name TSRMLS_DC)
117: {
118: zval z_constant;
119:
120: /* If name contains ':' it is not a constant. Bug #26893. */
121: if (!memchr(Z_STRVAL_P(name), ':', Z_STRLEN_P(name))
122: && zend_get_constant(Z_STRVAL_P(name), Z_STRLEN_P(name), &z_constant TSRMLS_CC)) {
123: /* z_constant is emalloc()'d */
124: convert_to_string(&z_constant);
125: Z_STRVAL_P(result) = zend_strndup(Z_STRVAL(z_constant), Z_STRLEN(z_constant));
126: Z_STRLEN_P(result) = Z_STRLEN(z_constant);
127: Z_TYPE_P(result) = Z_TYPE(z_constant);
128: zval_dtor(&z_constant);
129: free(Z_STRVAL_P(name));
130: } else {
131: *result = *name;
132: }
133: }
134: /* }}} */
135:
136: /* {{{ zend_ini_get_var()
137: */
138: static void zend_ini_get_var(zval *result, zval *name TSRMLS_DC)
139: {
140: zval curval;
141: char *envvar;
142:
143: /* Fetch configuration option value */
144: if (zend_get_configuration_directive(Z_STRVAL_P(name), Z_STRLEN_P(name)+1, &curval) == SUCCESS) {
145: Z_STRVAL_P(result) = zend_strndup(Z_STRVAL(curval), Z_STRLEN(curval));
146: Z_STRLEN_P(result) = Z_STRLEN(curval);
147: /* ..or if not found, try ENV */
148: } else if ((envvar = zend_getenv(Z_STRVAL_P(name), Z_STRLEN_P(name) TSRMLS_CC)) != NULL ||
149: (envvar = getenv(Z_STRVAL_P(name))) != NULL) {
150: Z_STRVAL_P(result) = strdup(envvar);
151: Z_STRLEN_P(result) = strlen(envvar);
152: } else {
153: zend_ini_init_string(result);
154: }
155: }
156: /* }}} */
157:
158: /* {{{ ini_error()
159: */
160: static void ini_error(char *msg)
161: {
162: char *error_buf;
163: int error_buf_len;
164: char *currently_parsed_filename;
165: TSRMLS_FETCH();
166:
167: currently_parsed_filename = zend_ini_scanner_get_filename(TSRMLS_C);
168: if (currently_parsed_filename) {
169: error_buf_len = 128 + strlen(msg) + strlen(currently_parsed_filename); /* should be more than enough */
170: error_buf = (char *) emalloc(error_buf_len);
171:
172: sprintf(error_buf, "%s in %s on line %d\n", msg, currently_parsed_filename, zend_ini_scanner_get_lineno(TSRMLS_C));
173: } else {
174: error_buf = estrdup("Invalid configuration directive\n");
175: }
176:
177: if (CG(ini_parser_unbuffered_errors)) {
178: #ifdef PHP_WIN32
179: MessageBox(NULL, error_buf, "PHP Error", MB_OK|MB_TOPMOST|0x00200000L);
180: #else
181: fprintf(stderr, "PHP: %s", error_buf);
182: #endif
183: } else {
184: zend_error(E_WARNING, "%s", error_buf);
185: }
186: efree(error_buf);
187: }
188: /* }}} */
189:
190: /* {{{ zend_parse_ini_file()
191: */
192: ZEND_API int zend_parse_ini_file(zend_file_handle *fh, zend_bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg TSRMLS_DC)
193: {
194: int retval;
195: zend_ini_parser_param ini_parser_param;
196:
197: ini_parser_param.ini_parser_cb = ini_parser_cb;
198: ini_parser_param.arg = arg;
199: CG(ini_parser_param) = &ini_parser_param;
200:
201: if (zend_ini_open_file_for_scanning(fh, scanner_mode TSRMLS_CC) == FAILURE) {
202: return FAILURE;
203: }
204:
205: CG(ini_parser_unbuffered_errors) = unbuffered_errors;
206: retval = ini_parse(TSRMLS_C);
207: zend_file_handle_dtor(fh TSRMLS_CC);
208:
209: shutdown_ini_scanner(TSRMLS_C);
210:
211: if (retval == 0) {
212: return SUCCESS;
213: } else {
214: return FAILURE;
215: }
216: }
217: /* }}} */
218:
219: /* {{{ zend_parse_ini_string()
220: */
221: ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg TSRMLS_DC)
222: {
223: int retval;
224: zend_ini_parser_param ini_parser_param;
225:
226: ini_parser_param.ini_parser_cb = ini_parser_cb;
227: ini_parser_param.arg = arg;
228: CG(ini_parser_param) = &ini_parser_param;
229:
230: if (zend_ini_prepare_string_for_scanning(str, scanner_mode TSRMLS_CC) == FAILURE) {
231: return FAILURE;
232: }
233:
234: CG(ini_parser_unbuffered_errors) = unbuffered_errors;
235: retval = ini_parse(TSRMLS_C);
236:
237: shutdown_ini_scanner(TSRMLS_C);
238:
239: if (retval == 0) {
240: return SUCCESS;
241: } else {
242: return FAILURE;
243: }
244: }
245: /* }}} */
246:
247: %}
248:
249: %expect 0
250: %pure_parser
251:
252: %token TC_SECTION
253: %token TC_RAW
254: %token TC_CONSTANT
255: %token TC_NUMBER
256: %token TC_STRING
257: %token TC_WHITESPACE
258: %token TC_LABEL
259: %token TC_OFFSET
260: %token TC_DOLLAR_CURLY
261: %token TC_VARNAME
262: %token TC_QUOTED_STRING
263: %token BOOL_TRUE
264: %token BOOL_FALSE
265: %token END_OF_LINE
266: %token '=' ':' ',' '.' '"' '\'' '^' '+' '-' '/' '*' '%' '$' '~' '<' '>' '?' '@' '{' '}'
267: %left '|' '&'
268: %right '~' '!'
269:
270: %%
271:
272: statement_list:
273: statement_list statement
274: | /* empty */
275: ;
276:
277: statement:
278: TC_SECTION section_string_or_value ']' {
279: #if DEBUG_CFG_PARSER
280: printf("SECTION: [%s]\n", Z_STRVAL($2));
281: #endif
282: ZEND_INI_PARSER_CB(&$2, NULL, NULL, ZEND_INI_PARSER_SECTION, ZEND_INI_PARSER_ARG TSRMLS_CC);
283: free(Z_STRVAL($2));
284: }
285: | TC_LABEL '=' string_or_value {
286: #if DEBUG_CFG_PARSER
287: printf("NORMAL: '%s' = '%s'\n", Z_STRVAL($1), Z_STRVAL($3));
288: #endif
289: ZEND_INI_PARSER_CB(&$1, &$3, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC);
290: free(Z_STRVAL($1));
291: free(Z_STRVAL($3));
292: }
293: | TC_OFFSET option_offset ']' '=' string_or_value {
294: #if DEBUG_CFG_PARSER
295: printf("OFFSET: '%s'[%s] = '%s'\n", Z_STRVAL($1), Z_STRVAL($2), Z_STRVAL($5));
296: #endif
297: ZEND_INI_PARSER_CB(&$1, &$5, &$2, ZEND_INI_PARSER_POP_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC);
298: free(Z_STRVAL($1));
299: free(Z_STRVAL($2));
300: free(Z_STRVAL($5));
301: }
302: | TC_LABEL { ZEND_INI_PARSER_CB(&$1, NULL, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC); free(Z_STRVAL($1)); }
303: | END_OF_LINE
304: ;
305:
306: section_string_or_value:
307: var_string_list_section { $$ = $1; }
308: | /* empty */ { zend_ini_init_string(&$$); }
309: ;
310:
311: string_or_value:
312: expr { $$ = $1; }
313: | BOOL_TRUE { $$ = $1; }
314: | BOOL_FALSE { $$ = $1; }
315: | END_OF_LINE { zend_ini_init_string(&$$); }
316: ;
317:
318: option_offset:
319: var_string_list { $$ = $1; }
320: | /* empty */ { zend_ini_init_string(&$$); }
321: ;
322:
323: encapsed_list:
324: encapsed_list cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
325: | encapsed_list TC_QUOTED_STRING { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
326: | /* empty */ { zend_ini_init_string(&$$); }
327: ;
328:
329: var_string_list_section:
330: cfg_var_ref { $$ = $1; }
331: | constant_literal { $$ = $1; }
332: | '"' encapsed_list '"' { $$ = $2; }
333: | var_string_list_section cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
334: | var_string_list_section constant_literal { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
335: | var_string_list_section '"' encapsed_list '"' { zend_ini_add_string(&$$, &$1, &$3); free(Z_STRVAL($3)); }
336: ;
337:
338: var_string_list:
339: cfg_var_ref { $$ = $1; }
340: | constant_string { $$ = $1; }
341: | '"' encapsed_list '"' { $$ = $2; }
342: | var_string_list cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
343: | var_string_list constant_string { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
344: | var_string_list '"' encapsed_list '"' { zend_ini_add_string(&$$, &$1, &$3); free(Z_STRVAL($3)); }
345: ;
346:
347: expr:
348: var_string_list { $$ = $1; }
349: | expr '|' expr { zend_ini_do_op('|', &$$, &$1, &$3); }
350: | expr '&' expr { zend_ini_do_op('&', &$$, &$1, &$3); }
351: | '~' expr { zend_ini_do_op('~', &$$, &$2, NULL); }
352: | '!' expr { zend_ini_do_op('!', &$$, &$2, NULL); }
353: | '(' expr ')' { $$ = $2; }
354: ;
355:
356: cfg_var_ref:
357: TC_DOLLAR_CURLY TC_VARNAME '}' { zend_ini_get_var(&$$, &$2 TSRMLS_CC); free(Z_STRVAL($2)); }
358: ;
359:
360: constant_literal:
361: TC_CONSTANT { $$ = $1; }
362: | TC_RAW { $$ = $1; /*printf("TC_RAW: '%s'\n", Z_STRVAL($1));*/ }
363: | TC_NUMBER { $$ = $1; /*printf("TC_NUMBER: '%s'\n", Z_STRVAL($1));*/ }
364: | TC_STRING { $$ = $1; /*printf("TC_STRING: '%s'\n", Z_STRVAL($1));*/ }
365: | TC_WHITESPACE { $$ = $1; /*printf("TC_WHITESPACE: '%s'\n", Z_STRVAL($1));*/ }
366: ;
367:
368: constant_string:
369: TC_CONSTANT { zend_ini_get_constant(&$$, &$1 TSRMLS_CC); }
370: | TC_RAW { $$ = $1; /*printf("TC_RAW: '%s'\n", Z_STRVAL($1));*/ }
371: | TC_NUMBER { $$ = $1; /*printf("TC_NUMBER: '%s'\n", Z_STRVAL($1));*/ }
372: | TC_STRING { $$ = $1; /*printf("TC_STRING: '%s'\n", Z_STRVAL($1));*/ }
373: | TC_WHITESPACE { $$ = $1; /*printf("TC_WHITESPACE: '%s'\n", Z_STRVAL($1));*/ }
374: ;
375:
376: /*
377: * Local variables:
378: * tab-width: 4
379: * c-basic-offset: 4
380: * indent-tabs-mode: t
381: * End:
382: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>