PageRenderTime 26ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/Zend/zend_ini_parser.y

http://php52-backports.googlecode.com/
Happy | 316 lines | 265 code | 51 blank | 0 comment | 0 complexity | cdda3245a11bd19edaf9d58ee69669b6 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause
  1. %{
  2. /*
  3. +----------------------------------------------------------------------+
  4. | Zend Engine |
  5. +----------------------------------------------------------------------+
  6. | Copyright (c) 1998-2010 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. | Author: Zeev Suraski <zeev@zend.com> |
  17. +----------------------------------------------------------------------+
  18. */
  19. /* $Id: zend_ini_parser.y 293154 2010-01-05 20:40:23Z sebastian $ */
  20. #define DEBUG_CFG_PARSER 0
  21. #include "zend.h"
  22. #include "zend_API.h"
  23. #include "zend_ini.h"
  24. #include "zend_constants.h"
  25. #include "zend_ini_scanner.h"
  26. #include "zend_extensions.h"
  27. #define YYSTYPE zval
  28. #ifdef ZTS
  29. #define YYPARSE_PARAM tsrm_ls
  30. #define YYLEX_PARAM tsrm_ls
  31. #endif
  32. #define ZEND_INI_PARSER_CB (CG(ini_parser_param))->ini_parser_cb
  33. #define ZEND_INI_PARSER_ARG (CG(ini_parser_param))->arg
  34. int ini_lex(zval *ini_lval TSRMLS_DC);
  35. #ifdef ZTS
  36. int ini_parse(void *arg);
  37. #else
  38. int ini_parse(void);
  39. #endif
  40. zval yylval;
  41. #ifndef ZTS
  42. extern int ini_lex(zval *ini_lval TSRMLS_DC);
  43. extern FILE *ini_in;
  44. extern void init_cfg_scanner(void);
  45. #endif
  46. void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
  47. {
  48. int i_result;
  49. int i_op1, i_op2;
  50. char str_result[MAX_LENGTH_OF_LONG];
  51. i_op1 = atoi(Z_STRVAL_P(op1));
  52. free(Z_STRVAL_P(op1));
  53. if (op2) {
  54. i_op2 = atoi(Z_STRVAL_P(op2));
  55. free(Z_STRVAL_P(op2));
  56. } else {
  57. i_op2 = 0;
  58. }
  59. switch (type) {
  60. case '|':
  61. i_result = i_op1 | i_op2;
  62. break;
  63. case '&':
  64. i_result = i_op1 & i_op2;
  65. break;
  66. case '~':
  67. i_result = ~i_op1;
  68. break;
  69. case '!':
  70. i_result = !i_op1;
  71. break;
  72. default:
  73. i_result = 0;
  74. break;
  75. }
  76. Z_STRLEN_P(result) = zend_sprintf(str_result, "%d", i_result);
  77. Z_STRVAL_P(result) = (char *) malloc(Z_STRLEN_P(result)+1);
  78. memcpy(Z_STRVAL_P(result), str_result, Z_STRLEN_P(result));
  79. Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
  80. Z_TYPE_P(result) = IS_STRING;
  81. }
  82. void zend_ini_init_string(zval *result)
  83. {
  84. Z_STRVAL_P(result) = malloc(1);
  85. Z_STRVAL_P(result)[0] = 0;
  86. Z_STRLEN_P(result) = 0;
  87. Z_TYPE_P(result) = IS_STRING;
  88. }
  89. void zend_ini_add_string(zval *result, zval *op1, zval *op2)
  90. {
  91. int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
  92. Z_STRVAL_P(result) = (char *) realloc(Z_STRVAL_P(op1), length+1);
  93. memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
  94. Z_STRVAL_P(result)[length] = 0;
  95. Z_STRLEN_P(result) = length;
  96. Z_TYPE_P(result) = IS_STRING;
  97. }
  98. void zend_ini_get_constant(zval *result, zval *name)
  99. {
  100. zval z_constant;
  101. TSRMLS_FETCH();
  102. if (!memchr(Z_STRVAL_P(name), ':', Z_STRLEN_P(name))
  103. && zend_get_constant(Z_STRVAL_P(name), Z_STRLEN_P(name), &z_constant TSRMLS_CC)) {
  104. /* z_constant is emalloc()'d */
  105. convert_to_string(&z_constant);
  106. Z_STRVAL_P(result) = zend_strndup(Z_STRVAL(z_constant), Z_STRLEN(z_constant));
  107. Z_STRLEN_P(result) = Z_STRLEN(z_constant);
  108. Z_TYPE_P(result) = Z_TYPE(z_constant);
  109. zval_dtor(&z_constant);
  110. free(Z_STRVAL_P(name));
  111. } else {
  112. *result = *name;
  113. }
  114. }
  115. void zend_ini_get_var(zval *result, zval *name)
  116. {
  117. zval curval;
  118. char *envvar;
  119. TSRMLS_FETCH();
  120. if (zend_get_configuration_directive(Z_STRVAL_P(name), Z_STRLEN_P(name)+1, &curval) == SUCCESS) {
  121. Z_STRVAL_P(result) = zend_strndup(Z_STRVAL(curval), Z_STRLEN(curval));
  122. Z_STRLEN_P(result) = Z_STRLEN(curval);
  123. } else if ((envvar = zend_getenv(Z_STRVAL_P(name), Z_STRLEN_P(name) TSRMLS_CC)) != NULL ||
  124. (envvar = getenv(Z_STRVAL_P(name))) != NULL) {
  125. Z_STRVAL_P(result) = strdup(envvar);
  126. Z_STRLEN_P(result) = strlen(envvar);
  127. } else {
  128. zend_ini_init_string(result);
  129. }
  130. }
  131. static void ini_error(char *str)
  132. {
  133. char *error_buf;
  134. int error_buf_len;
  135. char *currently_parsed_filename;
  136. TSRMLS_FETCH();
  137. currently_parsed_filename = zend_ini_scanner_get_filename(TSRMLS_C);
  138. if (currently_parsed_filename) {
  139. error_buf_len = 128+strlen(currently_parsed_filename); /* should be more than enough */
  140. error_buf = (char *) emalloc(error_buf_len);
  141. sprintf(error_buf, "Error parsing %s on line %d\n", currently_parsed_filename, zend_ini_scanner_get_lineno(TSRMLS_C));
  142. } else {
  143. error_buf = estrdup("Invalid configuration directive\n");
  144. }
  145. if (CG(ini_parser_unbuffered_errors)) {
  146. #ifdef PHP_WIN32
  147. MessageBox(NULL, error_buf, "PHP Error", MB_OK|MB_TOPMOST|0x00200000L);
  148. #else
  149. fprintf(stderr, "PHP: %s", error_buf);
  150. #endif
  151. } else {
  152. zend_error(E_WARNING, "%s", error_buf);
  153. }
  154. efree(error_buf);
  155. }
  156. ZEND_API int zend_parse_ini_file(zend_file_handle *fh, zend_bool unbuffered_errors, zend_ini_parser_cb_t ini_parser_cb, void *arg)
  157. {
  158. int retval;
  159. zend_ini_parser_param ini_parser_param;
  160. TSRMLS_FETCH();
  161. ini_parser_param.ini_parser_cb = ini_parser_cb;
  162. ini_parser_param.arg = arg;
  163. CG(ini_parser_param) = &ini_parser_param;
  164. if (zend_ini_open_file_for_scanning(fh TSRMLS_CC)==FAILURE) {
  165. return FAILURE;
  166. }
  167. CG(ini_parser_unbuffered_errors) = unbuffered_errors;
  168. retval = ini_parse(TSRMLS_C);
  169. zend_ini_close_file(fh TSRMLS_CC);
  170. if (retval==0) {
  171. return SUCCESS;
  172. } else {
  173. return FAILURE;
  174. }
  175. }
  176. ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, zend_ini_parser_cb_t ini_parser_cb, void *arg)
  177. {
  178. zend_ini_parser_param ini_parser_param;
  179. TSRMLS_FETCH();
  180. ini_parser_param.ini_parser_cb = ini_parser_cb;
  181. ini_parser_param.arg = arg;
  182. CG(ini_parser_param) = &ini_parser_param;
  183. if (zend_ini_prepare_string_for_scanning(str TSRMLS_CC)==FAILURE) {
  184. return FAILURE;
  185. }
  186. CG(ini_parser_unbuffered_errors) = unbuffered_errors;
  187. if (ini_parse(TSRMLS_C)) {
  188. return SUCCESS;
  189. } else {
  190. return FAILURE;
  191. }
  192. }
  193. %}
  194. %pure_parser
  195. %token TC_STRING
  196. %token TC_ENCAPSULATED_STRING
  197. %token BRACK
  198. %token SECTION
  199. %token CFG_TRUE
  200. %token CFG_FALSE
  201. %token TC_DOLLAR_CURLY
  202. %left '|' '&'
  203. %right '~' '!'
  204. %%
  205. statement_list:
  206. statement_list statement
  207. | /* empty */
  208. ;
  209. statement:
  210. TC_STRING '=' string_or_value {
  211. #if DEBUG_CFG_PARSER
  212. printf("'%s' = '%s'\n", Z_STRVAL($1), Z_STRVAL($3));
  213. #endif
  214. ZEND_INI_PARSER_CB(&$1, &$3, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG);
  215. free(Z_STRVAL($1));
  216. free(Z_STRVAL($3));
  217. }
  218. | TC_STRING BRACK '=' string_or_value {
  219. #if DEBUG_CFG_PARSER
  220. printf("'%s'[ ] = '%s'\n", Z_STRVAL($1), Z_STRVAL($4));
  221. #endif
  222. ZEND_INI_PARSER_CB(&$1, &$4, ZEND_INI_PARSER_POP_ENTRY, ZEND_INI_PARSER_ARG);
  223. free(Z_STRVAL($1));
  224. free(Z_STRVAL($4));
  225. }
  226. | TC_STRING { ZEND_INI_PARSER_CB(&$1, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG); free(Z_STRVAL($1)); }
  227. | SECTION { ZEND_INI_PARSER_CB(&$1, NULL, ZEND_INI_PARSER_SECTION, ZEND_INI_PARSER_ARG); free(Z_STRVAL($1)); }
  228. | '\n'
  229. ;
  230. string_or_value:
  231. expr { $$ = $1; }
  232. | CFG_TRUE { $$ = $1; }
  233. | CFG_FALSE { $$ = $1; }
  234. | '\n' { zend_ini_init_string(&$$); }
  235. | /* empty */ { zend_ini_init_string(&$$); }
  236. ;
  237. var_string_list:
  238. cfg_var_ref { $$ = $1; }
  239. | TC_ENCAPSULATED_STRING { $$ = $1; }
  240. | constant_string { $$ = $1; }
  241. | var_string_list cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); free($2.value.str.val); }
  242. | var_string_list TC_ENCAPSULATED_STRING { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
  243. | var_string_list constant_string { zend_ini_add_string(&$$, &$1, &$2); free($2.value.str.val); }
  244. ;
  245. cfg_var_ref:
  246. TC_DOLLAR_CURLY TC_STRING '}' { zend_ini_get_var(&$$, &$2); free($2.value.str.val); }
  247. ;
  248. expr:
  249. var_string_list { $$ = $1; }
  250. | expr '|' expr { zend_ini_do_op('|', &$$, &$1, &$3); }
  251. | expr '&' expr { zend_ini_do_op('&', &$$, &$1, &$3); }
  252. | '~' expr { zend_ini_do_op('~', &$$, &$2, NULL); }
  253. | '!' expr { zend_ini_do_op('!', &$$, &$2, NULL); }
  254. | '(' expr ')' { $$ = $2; }
  255. ;
  256. constant_string:
  257. TC_STRING { zend_ini_get_constant(&$$, &$1); }
  258. ;
  259. /*
  260. * Local variables:
  261. * tab-width: 4
  262. * c-basic-offset: 4
  263. * indent-tabs-mode: t
  264. * End:
  265. */