File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / Zend / zend_ini_parser.y
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:04:03 2014 UTC (10 years ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

    1: %{
    2: /*
    3:    +----------------------------------------------------------------------+
    4:    | Zend Engine                                                          |
    5:    +----------------------------------------------------------------------+
    6:    | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
    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: 
   21: /* $Id: zend_ini_parser.y,v 1.1.1.4 2014/06/15 20:04:03 misho Exp $ */
   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>