root/Zend/zend_ini_parser.y

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. zend_ini_do_op
  2. zend_ini_init_string
  3. zend_ini_add_string
  4. zend_ini_get_constant
  5. zend_ini_get_var
  6. ini_error
  7. zend_parse_ini_file
  8. zend_parse_ini_string

   1 %{
   2 /*
   3    +----------------------------------------------------------------------+
   4    | Zend Engine                                                          |
   5    +----------------------------------------------------------------------+
   6    | Copyright (c) 1998-2016 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$ */
  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 #ifdef ZEND_WIN32
  33 #include "win32/syslog.h"
  34 #endif
  35 
  36 #define YYERROR_VERBOSE
  37 #define YYSTYPE zval
  38 
  39 int ini_parse(void);
  40 
  41 #define ZEND_INI_PARSER_CB      (CG(ini_parser_param))->ini_parser_cb
  42 #define ZEND_INI_PARSER_ARG     (CG(ini_parser_param))->arg
  43 
  44 #ifdef _MSC_VER
  45 #define YYMALLOC malloc
  46 #define YYFREE free
  47 #endif
  48 
  49 /* {{{ zend_ini_do_op()
  50 */
  51 static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
  52 {
  53         int i_result;
  54         int i_op1, i_op2;
  55         int str_len;
  56         char str_result[MAX_LENGTH_OF_LONG];
  57 
  58         i_op1 = atoi(Z_STRVAL_P(op1));
  59         zend_string_free(Z_STR_P(op1));
  60         if (op2) {
  61                 i_op2 = atoi(Z_STRVAL_P(op2));
  62                 zend_string_free(Z_STR_P(op2));
  63         } else {
  64                 i_op2 = 0;
  65         }
  66 
  67         switch (type) {
  68                 case '|':
  69                         i_result = i_op1 | i_op2;
  70                         break;
  71                 case '&':
  72                         i_result = i_op1 & i_op2;
  73                         break;
  74                 case '^':
  75                         i_result = i_op1 ^ i_op2;
  76                         break;
  77                 case '~':
  78                         i_result = ~i_op1;
  79                         break;
  80                 case '!':
  81                         i_result = !i_op1;
  82                         break;
  83                 default:
  84                         i_result = 0;
  85                         break;
  86         }
  87 
  88         str_len = zend_sprintf(str_result, "%d", i_result);
  89         ZVAL_PSTRINGL(result, str_result, str_len);
  90 }
  91 /* }}} */
  92 
  93 /* {{{ zend_ini_init_string()
  94 */
  95 static void zend_ini_init_string(zval *result)
  96 {
  97         ZVAL_EMPTY_PSTRING(result);
  98 }
  99 /* }}} */
 100 
 101 /* {{{ zend_ini_add_string()
 102 */
 103 static void zend_ini_add_string(zval *result, zval *op1, zval *op2)
 104 {
 105         int length, op1_len;
 106 
 107         if (Z_TYPE_P(op1) != IS_STRING) {
 108                 zend_string *str = zval_get_string(op1);
 109                 /* ZEND_ASSERT(!Z_REFCOUNTED_P(op1)); */
 110                 ZVAL_PSTRINGL(op1, ZSTR_VAL(str), ZSTR_LEN(str));
 111                 zend_string_release(str);
 112         }
 113         op1_len = (int)Z_STRLEN_P(op1);
 114         
 115         if (Z_TYPE_P(op2) != IS_STRING) {
 116                 convert_to_string(op2);
 117         }
 118         length = op1_len + (int)Z_STRLEN_P(op2);
 119 
 120         ZVAL_NEW_STR(result, zend_string_extend(Z_STR_P(op1), length, 1));
 121         memcpy(Z_STRVAL_P(result) + op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2) + 1);
 122 }
 123 /* }}} */
 124 
 125 /* {{{ zend_ini_get_constant()
 126 */
 127 static void zend_ini_get_constant(zval *result, zval *name)
 128 {
 129         zval *c, tmp;
 130 
 131         /* If name contains ':' it is not a constant. Bug #26893. */
 132         if (!memchr(Z_STRVAL_P(name), ':', Z_STRLEN_P(name))
 133                         && (c = zend_get_constant(Z_STR_P(name))) != 0) {
 134                 if (Z_TYPE_P(c) != IS_STRING) {
 135                         ZVAL_COPY_VALUE(&tmp, c);
 136                         if (Z_OPT_CONSTANT(tmp)) {
 137                                 zval_update_constant_ex(&tmp, 1, NULL);
 138                         }
 139                         zval_opt_copy_ctor(&tmp);
 140                         convert_to_string(&tmp);
 141                         c = &tmp;
 142                 }
 143                 ZVAL_PSTRINGL(result, Z_STRVAL_P(c), Z_STRLEN_P(c));
 144                 if (c == &tmp) {
 145                         zend_string_release(Z_STR(tmp));
 146                 }
 147                 zend_string_free(Z_STR_P(name));
 148         } else {
 149                 *result = *name;
 150         }
 151 }
 152 /* }}} */
 153 
 154 /* {{{ zend_ini_get_var()
 155 */
 156 static void zend_ini_get_var(zval *result, zval *name)
 157 {
 158         zval *curval;
 159         char *envvar;
 160 
 161         /* Fetch configuration option value */
 162         if ((curval = zend_get_configuration_directive(Z_STR_P(name))) != NULL) {
 163                 ZVAL_PSTRINGL(result, Z_STRVAL_P(curval), Z_STRLEN_P(curval));
 164         /* ..or if not found, try ENV */
 165         } else if ((envvar = zend_getenv(Z_STRVAL_P(name), Z_STRLEN_P(name))) != NULL ||
 166                            (envvar = getenv(Z_STRVAL_P(name))) != NULL) {
 167                 ZVAL_PSTRING(result, envvar);
 168         } else {
 169                 zend_ini_init_string(result);
 170         }
 171 }
 172 /* }}} */
 173 
 174 /* {{{ ini_error()
 175 */
 176 static ZEND_COLD void ini_error(const char *msg)
 177 {
 178         char *error_buf;
 179         int error_buf_len;
 180         char *currently_parsed_filename;
 181 
 182         currently_parsed_filename = zend_ini_scanner_get_filename();
 183         if (currently_parsed_filename) {
 184                 error_buf_len = 128 + (int)strlen(msg) + (int)strlen(currently_parsed_filename); /* should be more than enough */
 185                 error_buf = (char *) emalloc(error_buf_len);
 186 
 187                 sprintf(error_buf, "%s in %s on line %d\n", msg, currently_parsed_filename, zend_ini_scanner_get_lineno());
 188         } else {
 189                 error_buf = estrdup("Invalid configuration directive\n");
 190         }
 191 
 192         if (CG(ini_parser_unbuffered_errors)) {
 193 #ifdef ZEND_WIN32
 194                 syslog(LOG_ALERT, "PHP: %s (%s)", error_buf, GetCommandLine());
 195 #endif
 196                 fprintf(stderr, "PHP:  %s", error_buf);
 197         } else {
 198                 zend_error(E_WARNING, "%s", error_buf);
 199         }
 200         efree(error_buf);
 201 }
 202 /* }}} */
 203 
 204 /* {{{ zend_parse_ini_file()
 205 */
 206 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)
 207 {
 208         int retval;
 209         zend_ini_parser_param ini_parser_param;
 210 
 211         ini_parser_param.ini_parser_cb = ini_parser_cb;
 212         ini_parser_param.arg = arg;
 213         CG(ini_parser_param) = &ini_parser_param;
 214 
 215         if (zend_ini_open_file_for_scanning(fh, scanner_mode) == FAILURE) {
 216                 return FAILURE;
 217         }
 218 
 219         CG(ini_parser_unbuffered_errors) = unbuffered_errors;
 220         retval = ini_parse();
 221         zend_file_handle_dtor(fh);
 222 
 223         shutdown_ini_scanner();
 224 
 225         if (retval == 0) {
 226                 return SUCCESS;
 227         } else {
 228                 return FAILURE;
 229         }
 230 }
 231 /* }}} */
 232 
 233 /* {{{ zend_parse_ini_string()
 234 */
 235 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)
 236 {
 237         int retval;
 238         zend_ini_parser_param ini_parser_param;
 239 
 240         ini_parser_param.ini_parser_cb = ini_parser_cb;
 241         ini_parser_param.arg = arg;
 242         CG(ini_parser_param) = &ini_parser_param;
 243 
 244         if (zend_ini_prepare_string_for_scanning(str, scanner_mode) == FAILURE) {
 245                 return FAILURE;
 246         }
 247 
 248         CG(ini_parser_unbuffered_errors) = unbuffered_errors;
 249         retval = ini_parse();
 250 
 251         shutdown_ini_scanner();
 252 
 253         if (retval == 0) {
 254                 return SUCCESS;
 255         } else {
 256                 return FAILURE;
 257         }
 258 }
 259 /* }}} */
 260 
 261 %}
 262 
 263 %expect 0
 264 %pure_parser
 265 
 266 %token TC_SECTION
 267 %token TC_RAW
 268 %token TC_CONSTANT
 269 %token TC_NUMBER
 270 %token TC_STRING
 271 %token TC_WHITESPACE
 272 %token TC_LABEL
 273 %token TC_OFFSET
 274 %token TC_DOLLAR_CURLY
 275 %token TC_VARNAME
 276 %token TC_QUOTED_STRING
 277 %token BOOL_TRUE
 278 %token BOOL_FALSE
 279 %token NULL_NULL
 280 %token END_OF_LINE
 281 %token '=' ':' ',' '.' '"' '\'' '^' '+' '-' '/' '*' '%' '$' '~' '<' '>' '?' '@' '{' '}'
 282 %left '|' '&' '^'
 283 %right '~' '!'
 284 
 285 %%
 286 
 287 statement_list:
 288                 statement_list statement
 289         |       /* empty */
 290 ;
 291 
 292 statement:
 293                 TC_SECTION section_string_or_value ']' {
 294 #if DEBUG_CFG_PARSER
 295                         printf("SECTION: [%s]\n", Z_STRVAL($2));
 296 #endif
 297                         ZEND_INI_PARSER_CB(&$2, NULL, NULL, ZEND_INI_PARSER_SECTION, ZEND_INI_PARSER_ARG);
 298                         zend_string_release(Z_STR($2));
 299                 }
 300         |       TC_LABEL '=' string_or_value {
 301 #if DEBUG_CFG_PARSER
 302                         printf("NORMAL: '%s' = '%s'\n", Z_STRVAL($1), Z_STRVAL($3));
 303 #endif
 304                         ZEND_INI_PARSER_CB(&$1, &$3, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG);
 305                         zend_string_release(Z_STR($1));
 306                         zval_ptr_dtor(&$3);
 307                 }
 308         |       TC_OFFSET option_offset ']' '=' string_or_value {
 309 #if DEBUG_CFG_PARSER
 310                         printf("OFFSET: '%s'[%s] = '%s'\n", Z_STRVAL($1), Z_STRVAL($2), Z_STRVAL($5));
 311 #endif
 312                         ZEND_INI_PARSER_CB(&$1, &$5, &$2, ZEND_INI_PARSER_POP_ENTRY, ZEND_INI_PARSER_ARG);
 313                         zend_string_release(Z_STR($1));
 314                         if (Z_TYPE($2) == IS_STRING) {
 315                                 zend_string_release(Z_STR($2));
 316                         } else {
 317                                 zval_dtor(&$2);
 318                         }
 319                         zval_ptr_dtor(&$5);
 320                 }
 321         |       TC_LABEL        { ZEND_INI_PARSER_CB(&$1, NULL, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG); zend_string_release(Z_STR($1)); }
 322         |       END_OF_LINE
 323 ;
 324 
 325 section_string_or_value:
 326                 var_string_list_section                 { $$ = $1; }
 327         |       /* empty */                                             { zend_ini_init_string(&$$); }
 328 ;
 329 
 330 string_or_value:
 331                 expr                                                    { $$ = $1; }
 332         |       BOOL_TRUE                                               { $$ = $1; }
 333         |       BOOL_FALSE                                              { $$ = $1; }
 334         |       NULL_NULL                                               { $$ = $1; }
 335         |       END_OF_LINE                                             { zend_ini_init_string(&$$); }
 336 ;
 337 
 338 option_offset:
 339                 var_string_list                                 { $$ = $1; }
 340         |       /* empty */                                             { zend_ini_init_string(&$$); }
 341 ;
 342 
 343 encapsed_list:
 344                 encapsed_list cfg_var_ref               { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); }
 345         |       encapsed_list TC_QUOTED_STRING  { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); }
 346         |       /* empty */                                             { zend_ini_init_string(&$$); }
 347 ;
 348 
 349 var_string_list_section:
 350                 cfg_var_ref                                             { $$ = $1; }
 351         |       constant_literal                                { $$ = $1; }
 352         |       '"' encapsed_list '"'                   { $$ = $2; }
 353         |       var_string_list_section cfg_var_ref     { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); }
 354         |       var_string_list_section constant_literal        { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); }
 355         |       var_string_list_section '"' encapsed_list '"'  { zend_ini_add_string(&$$, &$1, &$3); zend_string_free(Z_STR($3)); }
 356 ;
 357 
 358 var_string_list:
 359                 cfg_var_ref                                             { $$ = $1; }
 360         |       constant_string                                 { $$ = $1; }
 361         |       '"' encapsed_list '"'                   { $$ = $2; }
 362         |       var_string_list cfg_var_ref     { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); }
 363         |       var_string_list constant_string { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); }
 364         |       var_string_list '"' encapsed_list '"'  { zend_ini_add_string(&$$, &$1, &$3); zend_string_free(Z_STR($3)); }
 365 ;
 366 
 367 expr:
 368                 var_string_list                                 { $$ = $1; }
 369         |       expr '|' expr                                   { zend_ini_do_op('|', &$$, &$1, &$3); }
 370         |       expr '&' expr                                   { zend_ini_do_op('&', &$$, &$1, &$3); }
 371         |       expr '^' expr                                   { zend_ini_do_op('^', &$$, &$1, &$3); }
 372         |       '~' expr                                                { zend_ini_do_op('~', &$$, &$2, NULL); }
 373         |       '!'     expr                                            { zend_ini_do_op('!', &$$, &$2, NULL); }
 374         |       '(' expr ')'                                    { $$ = $2; }
 375 ;
 376 
 377 cfg_var_ref:
 378                 TC_DOLLAR_CURLY TC_VARNAME '}'  { zend_ini_get_var(&$$, &$2); zend_string_free(Z_STR($2)); }
 379 ;
 380 
 381 constant_literal:
 382                 TC_CONSTANT                                             { $$ = $1; }
 383         |       TC_RAW                                                  { $$ = $1; /*printf("TC_RAW: '%s'\n", Z_STRVAL($1));*/ }
 384         |       TC_NUMBER                                               { $$ = $1; /*printf("TC_NUMBER: '%s'\n", Z_STRVAL($1));*/ }
 385         |       TC_STRING                                               { $$ = $1; /*printf("TC_STRING: '%s'\n", Z_STRVAL($1));*/ }
 386         |       TC_WHITESPACE                                   { $$ = $1; /*printf("TC_WHITESPACE: '%s'\n", Z_STRVAL($1));*/ }
 387 ;
 388 
 389 constant_string:
 390                 TC_CONSTANT                                             { zend_ini_get_constant(&$$, &$1); }
 391         |       TC_RAW                                                  { $$ = $1; /*printf("TC_RAW: '%s'\n", Z_STRVAL($1));*/ }
 392         |       TC_NUMBER                                               { $$ = $1; /*printf("TC_NUMBER: '%s'\n", Z_STRVAL($1));*/ }
 393         |       TC_STRING                                               { $$ = $1; /*printf("TC_STRING: '%s'\n", Z_STRVAL($1));*/ }
 394         |       TC_WHITESPACE                                   { $$ = $1; /*printf("TC_WHITESPACE: '%s'\n", Z_STRVAL($1));*/ }
 395 ;
 396 
 397 /*
 398  * Local variables:
 399  * tab-width: 4
 400  * c-basic-offset: 4
 401  * indent-tabs-mode: t
 402  * End:
 403  */

/* [<][>][^][v][top][bottom][index][help] */