/* Unqualified %code blocks. */
-int php_json_yylex(union YYSTYPE *value, php_json_parser *parser);
-void php_json_yyerror(php_json_parser *parser, char const *msg);
-void php_json_parser_object_init(php_json_parser *parser, zval *object);
-int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue);
-void php_json_parser_array_init(zval *object);
-void php_json_parser_array_append(zval *array, zval *zvalue);
+static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser);
+static void php_json_yyerror(php_json_parser *parser, char const *msg);
-#define PHP_JSON_DEPTH_DEC --parser->depth
-#define PHP_JSON_DEPTH_INC \
- if (parser->max_depth && parser->depth >= parser->max_depth) { \
- parser->scanner.errcode = PHP_JSON_ERROR_DEPTH; \
- YYERROR; \
- } \
- ++parser->depth
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
- 0, 92, 92, 98, 105, 105, 113, 114, 123, 126,
- 130, 136, 142, 149, 154, 161, 161, 169, 170, 179,
- 182, 186, 191, 196, 203, 204, 208, 209, 210, 211,
- 212, 213, 214, 215, 216, 217, 221
+ 0, 81, 81, 87, 94, 94, 104, 105, 114, 117,
+ 121, 127, 133, 140, 145, 152, 152, 162, 163, 172,
+ 175, 179, 184, 189, 196, 197, 201, 202, 203, 204,
+ 205, 206, 207, 208, 209, 210, 214
};
#endif
case 4:
- { PHP_JSON_DEPTH_INC; }
+ { if (FAILURE == parser->methods->object_start(parser)) YYERROR; }
break;
case 5:
{
- PHP_JSON_DEPTH_DEC;
(yyval.value) = (yyvsp[-1].value);
+ if (FAILURE == parser->methods->object_end(parser, &(yyval.value))) {
+ YYERROR;
+ }
}
break;
case 8:
{
- php_json_parser_object_init(parser, &(yyval.value));
+ parser->methods->object_create(parser, &(yyval.value));
}
break;
case 10:
{
- php_json_parser_object_init(parser, &(yyval.value));
- if (php_json_parser_object_update(parser, &(yyval.value), (yyvsp[0].pair).key, &(yyvsp[0].pair).val) == FAILURE)
+ parser->methods->object_create(parser, &(yyval.value));
+ if (parser->methods->object_update(parser, &(yyval.value), (yyvsp[0].pair).key, &(yyvsp[0].pair).val) == FAILURE)
YYERROR;
}
case 11:
{
- if (php_json_parser_object_update(parser, &(yyvsp[-2].value), (yyvsp[0].pair).key, &(yyvsp[0].pair).val) == FAILURE)
+ if (parser->methods->object_update(parser, &(yyvsp[-2].value), (yyvsp[0].pair).key, &(yyvsp[0].pair).val) == FAILURE)
YYERROR;
ZVAL_COPY_VALUE(&(yyval.value), &(yyvsp[-2].value));
}
case 15:
- { PHP_JSON_DEPTH_INC; }
+ { if (FAILURE == parser->methods->array_start(parser)) YYERROR; }
break;
case 16:
{
- PHP_JSON_DEPTH_DEC;
ZVAL_COPY_VALUE(&(yyval.value), &(yyvsp[-1].value));
+ if (FAILURE == parser->methods->array_end(parser, &(yyval.value))) {
+ YYERROR;
+ }
}
break;
case 19:
{
- php_json_parser_array_init(&(yyval.value));
+ parser->methods->array_create(parser, &(yyval.value));
}
break;
case 21:
{
- php_json_parser_array_init(&(yyval.value));
- php_json_parser_array_append(&(yyval.value), &(yyvsp[0].value));
+ parser->methods->array_create(parser, &(yyval.value));
+ parser->methods->array_append(parser, &(yyval.value), &(yyvsp[0].value));
}
break;
case 22:
{
- php_json_parser_array_append(&(yyvsp[-2].value), &(yyvsp[0].value));
+ parser->methods->array_append(parser, &(yyvsp[-2].value), &(yyvsp[0].value));
ZVAL_COPY_VALUE(&(yyval.value), &(yyvsp[-2].value));
}
/* Functions */
-void php_json_parser_init(php_json_parser *parser, zval *return_value, char *str, size_t str_len, int options, int max_depth)
+static int php_json_parser_array_create(php_json_parser *parser, zval *array)
{
- memset(parser, 0, sizeof(php_json_parser));
- php_json_scanner_init(&parser->scanner, str, str_len, options);
- parser->depth = 1;
- parser->max_depth = max_depth;
- parser->return_value = return_value;
+ return array_init(array);
}
-php_json_error_code php_json_parser_error_code(php_json_parser *parser)
+static int php_json_parser_array_append(php_json_parser *parser, zval *array, zval *zvalue)
{
- return parser->scanner.errcode;
+ zend_hash_next_index_insert(Z_ARRVAL_P(array), zvalue);
+ return SUCCESS;
}
-void php_json_parser_object_init(php_json_parser *parser, zval *object)
+static int php_json_parser_array_start(php_json_parser *parser)
+{
+ return parser->methods->depth_increase(parser);
+}
+
+static int php_json_parser_array_end(php_json_parser *parser, zval *object)
+{
+ return parser->methods->depth_decrease(parser);
+}
+
+static int php_json_parser_object_create(php_json_parser *parser, zval *object)
{
if (parser->scanner.options & PHP_JSON_OBJECT_AS_ARRAY) {
- array_init(object);
+ return array_init(object);
} else {
- object_init(object);
+ return object_init(object);
}
}
-int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue)
+static int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue)
{
/* if JSON_OBJECT_AS_ARRAY is set */
if (Z_TYPE_P(object) == IS_ARRAY) {
return SUCCESS;
}
-void php_json_parser_array_init(zval *array)
+static int php_json_parser_object_start(php_json_parser *parser)
{
- array_init(array);
+ return parser->methods->depth_increase(parser);
}
-void php_json_parser_array_append(zval *array, zval *zvalue)
+static int php_json_parser_object_end(php_json_parser *parser, zval *object)
{
- zend_hash_next_index_insert(Z_ARRVAL_P(array), zvalue);
+ return parser->methods->depth_decrease(parser);
}
-
-int php_json_yylex(union YYSTYPE *value, php_json_parser *parser)
+
+static int php_json_parser_depth_increase(php_json_parser *parser)
+{
+ if (parser->max_depth && parser->depth >= parser->max_depth) {
+ parser->scanner.errcode = PHP_JSON_ERROR_DEPTH;
+ return FAILURE;
+ }
+ ++parser->depth;
+ return SUCCESS;
+}
+
+static int php_json_parser_depth_decrease(php_json_parser *parser)
+{
+ --parser->depth;
+ return SUCCESS;
+}
+
+static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser)
{
int token = php_json_scan(&parser->scanner);
value->value = parser->scanner.value;
return token;
}
-void php_json_yyerror(php_json_parser *parser, char const *msg)
+static void php_json_yyerror(php_json_parser *parser, char const *msg)
{
if (!parser->scanner.errcode) {
parser->scanner.errcode = PHP_JSON_ERROR_SYNTAX;
}
}
+
+php_json_error_code php_json_parser_error_code(const php_json_parser *parser)
+{
+ return parser->scanner.errcode;
+}
+
+static const php_json_parser_methods default_parser_methods =
+{
+ php_json_parser_array_create,
+ php_json_parser_array_append,
+ php_json_parser_array_start,
+ php_json_parser_array_end,
+ php_json_parser_object_create,
+ php_json_parser_object_update,
+ php_json_parser_object_start,
+ php_json_parser_object_end,
+ php_json_parser_depth_increase,
+ php_json_parser_depth_decrease
+};
+
+void php_json_parser_init_ex(php_json_parser *parser,
+ zval *return_value,
+ char *str,
+ size_t str_len,
+ int options,
+ int max_depth,
+ const php_json_parser_methods *parser_methods)
+{
+ memset(parser, 0, sizeof(php_json_parser));
+ php_json_scanner_init(&parser->scanner, str, str_len, options);
+ parser->depth = 1;
+ parser->max_depth = max_depth;
+ parser->return_value = return_value;
+ parser->methods = parser_methods;
+}
+
+void php_json_parser_init(php_json_parser *parser,
+ zval *return_value,
+ char *str,
+ size_t str_len,
+ int options,
+ int max_depth)
+{
+ php_json_parser_init_ex(
+ parser,
+ return_value,
+ str,
+ str_len,
+ options,
+ max_depth,
+ &default_parser_methods);
+}
%destructor { zend_string_release($$.key); zval_dtor(&$$.val); } <pair>
%code {
-int php_json_yylex(union YYSTYPE *value, php_json_parser *parser);
-void php_json_yyerror(php_json_parser *parser, char const *msg);
-void php_json_parser_object_init(php_json_parser *parser, zval *object);
-int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue);
-void php_json_parser_array_init(zval *object);
-void php_json_parser_array_append(zval *array, zval *zvalue);
-
-#define PHP_JSON_DEPTH_DEC --parser->depth
-#define PHP_JSON_DEPTH_INC \
- if (parser->max_depth && parser->depth >= parser->max_depth) { \
- parser->scanner.errcode = PHP_JSON_ERROR_DEPTH; \
- YYERROR; \
- } \
- ++parser->depth
+static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser);
+static void php_json_yyerror(php_json_parser *parser, char const *msg);
+
}
%% /* Rules */
;
object:
- '{' { PHP_JSON_DEPTH_INC; } members object_end
+ '{' { if (FAILURE == parser->methods->object_start(parser)) YYERROR; } members object_end
{
- PHP_JSON_DEPTH_DEC;
$$ = $3;
+ if (FAILURE == parser->methods->object_end(parser, &$$)) {
+ YYERROR;
+ }
}
;
members:
/* empty */
{
- php_json_parser_object_init(parser, &$$);
+ parser->methods->object_create(parser, &$$);
}
| member
;
member:
pair
{
- php_json_parser_object_init(parser, &$$);
- if (php_json_parser_object_update(parser, &$$, $1.key, &$1.val) == FAILURE)
+ parser->methods->object_create(parser, &$$);
+ if (parser->methods->object_update(parser, &$$, $1.key, &$1.val) == FAILURE)
YYERROR;
}
| member ',' pair
{
- if (php_json_parser_object_update(parser, &$1, $3.key, &$3.val) == FAILURE)
+ if (parser->methods->object_update(parser, &$1, $3.key, &$3.val) == FAILURE)
YYERROR;
ZVAL_COPY_VALUE(&$$, &$1);
}
;
array:
- '[' { PHP_JSON_DEPTH_INC; } elements array_end
+ '[' { if (FAILURE == parser->methods->array_start(parser)) YYERROR; } elements array_end
{
- PHP_JSON_DEPTH_DEC;
ZVAL_COPY_VALUE(&$$, &$3);
+ if (FAILURE == parser->methods->array_end(parser, &$$)) {
+ YYERROR;
+ }
}
;
elements:
/* empty */
{
- php_json_parser_array_init(&$$);
+ parser->methods->array_create(parser, &$$);
}
| element
;
element:
value
{
- php_json_parser_array_init(&$$);
- php_json_parser_array_append(&$$, &$1);
+ parser->methods->array_create(parser, &$$);
+ parser->methods->array_append(parser, &$$, &$1);
}
| element ',' value
{
- php_json_parser_array_append(&$1, &$3);
+ parser->methods->array_append(parser, &$1, &$3);
ZVAL_COPY_VALUE(&$$, &$1);
}
| element errlex
%% /* Functions */
-void php_json_parser_init(php_json_parser *parser, zval *return_value, char *str, size_t str_len, int options, int max_depth)
+static int php_json_parser_array_create(php_json_parser *parser, zval *array)
{
- memset(parser, 0, sizeof(php_json_parser));
- php_json_scanner_init(&parser->scanner, str, str_len, options);
- parser->depth = 1;
- parser->max_depth = max_depth;
- parser->return_value = return_value;
+ return array_init(array);
}
-php_json_error_code php_json_parser_error_code(php_json_parser *parser)
+static int php_json_parser_array_append(php_json_parser *parser, zval *array, zval *zvalue)
{
- return parser->scanner.errcode;
+ zend_hash_next_index_insert(Z_ARRVAL_P(array), zvalue);
+ return SUCCESS;
}
-void php_json_parser_object_init(php_json_parser *parser, zval *object)
+static int php_json_parser_array_start(php_json_parser *parser)
+{
+ return parser->methods->depth_increase(parser);
+}
+
+static int php_json_parser_array_end(php_json_parser *parser, zval *object)
+{
+ return parser->methods->depth_decrease(parser);
+}
+
+static int php_json_parser_object_create(php_json_parser *parser, zval *object)
{
if (parser->scanner.options & PHP_JSON_OBJECT_AS_ARRAY) {
- array_init(object);
+ return array_init(object);
} else {
- object_init(object);
+ return object_init(object);
}
}
-int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue)
+static int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue)
{
/* if JSON_OBJECT_AS_ARRAY is set */
if (Z_TYPE_P(object) == IS_ARRAY) {
return SUCCESS;
}
-void php_json_parser_array_init(zval *array)
+static int php_json_parser_object_start(php_json_parser *parser)
{
- array_init(array);
+ return parser->methods->depth_increase(parser);
}
-void php_json_parser_array_append(zval *array, zval *zvalue)
+static int php_json_parser_object_end(php_json_parser *parser, zval *object)
{
- zend_hash_next_index_insert(Z_ARRVAL_P(array), zvalue);
+ return parser->methods->depth_decrease(parser);
}
-
-int php_json_yylex(union YYSTYPE *value, php_json_parser *parser)
+
+static int php_json_parser_depth_increase(php_json_parser *parser)
+{
+ if (parser->max_depth && parser->depth >= parser->max_depth) {
+ parser->scanner.errcode = PHP_JSON_ERROR_DEPTH;
+ return FAILURE;
+ }
+ ++parser->depth;
+ return SUCCESS;
+}
+
+static int php_json_parser_depth_decrease(php_json_parser *parser)
+{
+ --parser->depth;
+ return SUCCESS;
+}
+
+static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser)
{
int token = php_json_scan(&parser->scanner);
value->value = parser->scanner.value;
return token;
}
-void php_json_yyerror(php_json_parser *parser, char const *msg)
+static void php_json_yyerror(php_json_parser *parser, char const *msg)
{
if (!parser->scanner.errcode) {
parser->scanner.errcode = PHP_JSON_ERROR_SYNTAX;
}
}
+
+php_json_error_code php_json_parser_error_code(const php_json_parser *parser)
+{
+ return parser->scanner.errcode;
+}
+
+static const php_json_parser_methods default_parser_methods =
+{
+ php_json_parser_array_create,
+ php_json_parser_array_append,
+ php_json_parser_array_start,
+ php_json_parser_array_end,
+ php_json_parser_object_create,
+ php_json_parser_object_update,
+ php_json_parser_object_start,
+ php_json_parser_object_end,
+ php_json_parser_depth_increase,
+ php_json_parser_depth_decrease
+};
+
+void php_json_parser_init_ex(php_json_parser *parser,
+ zval *return_value,
+ char *str,
+ size_t str_len,
+ int options,
+ int max_depth,
+ const php_json_parser_methods *parser_methods)
+{
+ memset(parser, 0, sizeof(php_json_parser));
+ php_json_scanner_init(&parser->scanner, str, str_len, options);
+ parser->depth = 1;
+ parser->max_depth = max_depth;
+ parser->return_value = return_value;
+ parser->methods = parser_methods;
+}
+
+void php_json_parser_init(php_json_parser *parser,
+ zval *return_value,
+ char *str,
+ size_t str_len,
+ int options,
+ int max_depth)
+{
+ php_json_parser_init_ex(
+ parser,
+ return_value,
+ str,
+ str_len,
+ options,
+ max_depth,
+ &default_parser_methods);
+}
#include "php.h"
#include "php_json_scanner.h"
-typedef struct _php_json_parser {
+typedef struct _php_json_parser php_json_parser;
+
+typedef int (*php_json_parser_func_array_create_t)(
+ php_json_parser *parser, zval *array);
+typedef int (*php_json_parser_func_array_append_t)(
+ php_json_parser *parser, zval *array, zval *zvalue);
+typedef int (*php_json_parser_func_array_start_t)(
+ php_json_parser *parser);
+typedef int (*php_json_parser_func_array_end_t)(
+ php_json_parser *parser, zval *object);
+typedef int (*php_json_parser_func_object_create_t)(
+ php_json_parser *parser, zval *object);
+typedef int (*php_json_parser_func_object_update_t)(
+ php_json_parser *parser, zval *object, zend_string *key, zval *zvalue);
+typedef int (*php_json_parser_func_object_start_t)(
+ php_json_parser *parser);
+typedef int (*php_json_parser_func_object_end_t)(
+ php_json_parser *parser, zval *object);
+typedef int (*php_json_parser_func_depth_increase_t)(
+ php_json_parser *parser);
+typedef int (*php_json_parser_func_depth_decrease_t)(
+ php_json_parser *parser);
+
+typedef struct _php_json_parser_methods {
+ php_json_parser_func_array_create_t array_create;
+ php_json_parser_func_array_append_t array_append;
+ php_json_parser_func_array_start_t array_start;
+ php_json_parser_func_array_end_t array_end;
+ php_json_parser_func_object_create_t object_create;
+ php_json_parser_func_object_update_t object_update;
+ php_json_parser_func_object_start_t object_start;
+ php_json_parser_func_object_end_t object_end;
+ php_json_parser_func_depth_increase_t depth_increase;
+ php_json_parser_func_depth_decrease_t depth_decrease;
+} php_json_parser_methods;
+
+struct _php_json_parser {
php_json_scanner scanner;
zval *return_value;
- int depth;
+ unsigned int depth;
int max_depth;
-} php_json_parser;
+ const php_json_parser_methods *methods;
+};
+
+PHP_JSON_API void php_json_parser_init_ex(
+ php_json_parser *parser,
+ zval *return_value,
+ char *str,
+ size_t str_len,
+ int options,
+ int max_depth,
+ const php_json_parser_methods *methods);
-void php_json_parser_init(php_json_parser *parser, zval *return_value, char *str, size_t str_len, int options, int max_depth);
+PHP_JSON_API void php_json_parser_init(
+ php_json_parser *parser,
+ zval *return_value,
+ char *str,
+ size_t str_len,
+ int options,
+ int max_depth);
-php_json_error_code php_json_parser_error_code(php_json_parser *parser);
+PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser);
-int php_json_yyparse(php_json_parser *parser);
+PHP_JSON_API int php_json_yyparse(php_json_parser *parser);
#endif /* PHP_JSON_PARSER_H */