Skip to content

Commit 06dec89

Browse files
authored
Merge pull request #9 from sjinks/development
Make parser return errors on failure
2 parents df2fb8a + e71e46b commit 06dec89

File tree

4 files changed

+98
-63
lines changed

4 files changed

+98
-63
lines changed

install-development

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ if [ x"$CC" == x ]; then
5656
exit 1
5757
fi
5858

59-
export CFLAGS="-g3 -O0 -Wall -fvisibility=hidden -march=native"
59+
export CFLAGS="-g3 -O0 -Wall -Werror -fvisibility=hidden"
6060

6161
if [ x"$CC" == xclang ]; then
6262
export CFLAGS="${CFLAGS} -fcolor-diagnostics"

parser/base.c

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const xx_token_names xx_tokens[] =
2020
{ XX_T_INTEGER, "INTEGER" },
2121
{ XX_T_DOUBLE, "DOUBLE" },
2222
{ XX_T_STRING, "STRING" },
23-
{ XX_T_IDENTIFIER, "IDENTIFIER" },
23+
{ XX_T_IDENTIFIER, "IDENTIFIER" },
2424
{ XX_T_AT, "@" },
2525
{ XX_T_COMMA, "," },
2626
{ XX_T_ASSIGN, "=" },
@@ -72,7 +72,7 @@ static void xx_parse_with_token(void* xx_parser, int opcode, int parsercode, xx_
7272
/**
7373
* Parses a programm and returning an intermediate array representation
7474
*/
75-
void xx_parse_program(zval *return_value, char *program, size_t program_length, char *file_path, zval **error_msg) {
75+
void xx_parse_program(zval *return_value, char *program, size_t program_length, char *file_path, zval *error_msg) {
7676

7777
char *error;
7878
xx_scanner_state *state;
@@ -433,16 +433,15 @@ void xx_parse_program(zval *return_value, char *program, size_t program_length,
433433
case XX_T_TYPE_VAR:
434434
xx_(xx_parser, XX_TYPE_VAR, NULL, parser_status);
435435
break;
436-
case XX_T_TYPE_OBJECT:
437-
xx_(xx_parser, XX_TYPE_OBJECT, NULL, parser_status);
438-
break;
439-
case XX_T_TYPE_RESOURCE:
440-
xx_(xx_parser, XX_TYPE_RESOURCE, NULL, parser_status);
441-
break;
442-
case XX_T_TYPE_CALLABLE:
443-
xx_(xx_parser, XX_TYPE_CALLABLE, NULL, parser_status);
444-
break;
445-
436+
case XX_T_TYPE_OBJECT:
437+
xx_(xx_parser, XX_TYPE_OBJECT, NULL, parser_status);
438+
break;
439+
case XX_T_TYPE_RESOURCE:
440+
xx_(xx_parser, XX_TYPE_RESOURCE, NULL, parser_status);
441+
break;
442+
case XX_T_TYPE_CALLABLE:
443+
xx_(xx_parser, XX_TYPE_CALLABLE, NULL, parser_status);
444+
break;
446445
case XX_T_ADD:
447446
xx_(xx_parser, XX_ADD, NULL, parser_status);
448447
break;
@@ -521,12 +520,24 @@ void xx_parse_program(zval *return_value, char *program, size_t program_length,
521520

522521
default:
523522
parser_status->status = XX_PARSING_FAILED;
524-
if (!*error_msg) {
523+
if (error_msg && Z_TYPE_P(error_msg) != IS_ARRAY) {
525524
int length = (48 + strlen(file_path));
526525
error = emalloc(sizeof(char) * length);
527526
snprintf(error, length, "Scanner: unknown opcode %d on in %s line %d", token.opcode, file_path, state->active_line);
528-
//ZVAL_STRING(*error_msg, error, 1);
527+
528+
array_init(error_msg);
529+
#if PHP_VERSION_ID >= 70000
530+
add_assoc_string(error_msg, "type", "error");
531+
add_assoc_string(error_msg, "message", error);
532+
add_assoc_string(error_msg, "file", state->active_file);
529533
efree(error);
534+
#else
535+
add_assoc_string(error_msg, "type", "error", 1);
536+
add_assoc_string(error_msg, "message", error, 0);
537+
add_assoc_string(error_msg, "file", state->active_file, 1);
538+
#endif
539+
add_assoc_long(error_msg, "line", state->active_line);
540+
add_assoc_long(error_msg, "char", state->active_char);
530541
}
531542
break;
532543
}
@@ -543,20 +554,27 @@ void xx_parse_program(zval *return_value, char *program, size_t program_length,
543554
switch (scanner_status) {
544555
case XX_SCANNER_RETCODE_ERR:
545556
case XX_SCANNER_RETCODE_IMPOSSIBLE:
546-
{
557+
if (error_msg && Z_TYPE_P(error_msg) == IS_NULL) {
547558
error = emalloc(sizeof(char) * 1024);
548559
if (state->start) {
549560
snprintf(error, 1024, "Scanner error: %d %s", scanner_status, state->start);
550561
} else {
551562
snprintf(error, 1024, "Scanner error: %d", scanner_status);
552563
}
553-
#if PHP_VERSION_ID < 70000
554-
ALLOC_INIT_ZVAL(*error_msg);
555-
ZVAL_STRING(*error_msg, error, 1);
564+
565+
array_init(error_msg);
566+
#if PHP_VERSION_ID >= 70000
567+
add_assoc_string(error_msg, "type", "error");
568+
add_assoc_string(error_msg, "message", error);
569+
add_assoc_string(error_msg, "file", state->active_file);
570+
efree(error);
556571
#else
557-
ZVAL_STRING(*error_msg, error);
572+
add_assoc_string(error_msg, "type", "error", 1);
573+
add_assoc_string(error_msg, "message", error, 0);
574+
add_assoc_string(error_msg, "file", state->active_file, 1);
558575
#endif
559-
efree(error);
576+
add_assoc_long(error_msg, "line", state->active_line);
577+
add_assoc_long(error_msg, "char", state->active_char);
560578
status = FAILURE;
561579
}
562580
break;
@@ -570,18 +588,31 @@ void xx_parse_program(zval *return_value, char *program, size_t program_length,
570588

571589
if (parser_status->status != XX_PARSING_OK) {
572590
status = FAILURE;
573-
if (parser_status->syntax_error) {
574-
#if PHP_VERSION_ID < 70000
575-
if (!*error_msg) {
576-
ALLOC_INIT_ZVAL(*error_msg);
577-
ZVAL_STRING(*error_msg, parser_status->syntax_error, 1);
578-
}
591+
if (parser_status->syntax_error && error_msg && Z_TYPE_P(error_msg) != IS_ARRAY) {
592+
array_init(error_msg);
593+
#if PHP_VERSION_ID >= 70000
594+
add_assoc_string(error_msg, "type", "error");
595+
add_assoc_string(error_msg, "message", parser_status->syntax_error);
596+
add_assoc_string(error_msg, "file", state->active_file);
597+
efree(parser_status->syntax_error);
579598
#else
580-
if (Z_TYPE_P(*error_msg) == IS_UNDEF) {
581-
ZVAL_STRING(*error_msg, parser_status->syntax_error);
582-
}
599+
add_assoc_string(error_msg, "type", "error", 1);
600+
add_assoc_string(error_msg, "message", parser_status->syntax_error, 0);
601+
add_assoc_string(error_msg, "file", state->active_file, 1);
602+
#endif
603+
add_assoc_long(error_msg, "line", state->active_line);
604+
add_assoc_long(error_msg, "char", state->active_char);
605+
606+
parser_status->syntax_error = NULL;
607+
}
608+
else if (error_msg && Z_TYPE_P(error_msg) != IS_ARRAY) {
609+
#if PHP_VERSION_ID >= 70000
610+
assert(Z_TYPE(parser_status->ret) == IS_ARRAY);
611+
ZVAL_ZVAL(error_msg, &parser_status->ret, 1, 1);
612+
#else
613+
assert(Z_TYPE_P(parser_status->ret) == IS_ARRAY);
614+
ZVAL_ZVAL(error_msg, parser_status->ret, 1, 1);
583615
#endif
584-
efree(parser_status->syntax_error);
585616
}
586617
}
587618

php_zephir_parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ extern zend_module_entry zephir_parser_module_entry;
4242

4343
#define ZEPHIR_PARSER_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(zephir_parser, v)
4444

45-
#if defined(ZTS) && defined(COMPILE_DL_ZEPHIR_PARSER)
45+
#if defined(ZTS) && defined(COMPILE_DL_ZEPHIR_PARSER) && PHP_VERSION_ID >= 70000
4646
ZEND_TSRMLS_CACHE_EXTERN();
4747
#endif
4848

zephir_parser.c

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,45 +26,49 @@
2626
#include "ext/standard/info.h"
2727
#include "php_zephir_parser.h"
2828

29-
extern void *xx_parse_program(zval *return_value, char *program, size_t program_length, char *file_path, zval **error_msg);
29+
extern void *xx_parse_program(zval *return_value, char *program, size_t program_length, char *file_path, zval *error_msg);
3030

3131
/* {{{ proto array zephir_parse_file(string content, string filepath)
3232
Parses a file and returning an intermediate array representation */
33-
PHP_FUNCTION(zephir_parse_file)
33+
static PHP_FUNCTION(zephir_parse_file)
3434
{
3535
size_t filepath_len = 0;
3636
size_t content_len = 0;
3737
char *content = NULL;
3838
char *filepath = NULL;
3939
#if PHP_VERSION_ID >= 70000
40+
zval error_msg;
4041
zval ret;
41-
zval error, *error_ptr = &error;
42-
zval **error_msg = &error_ptr;
43-
ZVAL_UNDEF(error_ptr);
42+
zval *e = &error_msg;
43+
zval *r = &ret;
4444
#else
45-
zval *ret = NULL;
46-
zval **error_msg = NULL;
45+
zval *error_msg;
46+
zval *e;
47+
zval *ret;
48+
zval *r;
4749
#endif
4850

4951
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &content, &content_len, &filepath, &filepath_len) == FAILURE) {
5052
RETURN_FALSE;
5153
}
5254

53-
#if PHP_VERSION_ID >= 70000
54-
xx_parse_program(&ret, content, content_len, filepath, error_msg);
55-
#else
55+
#if PHP_VERSION_ID < 70000
5656
MAKE_STD_ZVAL(ret);
57-
xx_parse_program(ret, content, content_len, filepath, error_msg);
57+
MAKE_STD_ZVAL(error_msg);
58+
e = error_msg;
59+
r = ret;
5860
#endif
61+
ZVAL_NULL(e);
62+
xx_parse_program(r, content, content_len, filepath, e);
5963

60-
#if PHP_VERSION_ID >= 70000
61-
if (Z_TYPE_P(error_ptr) != IS_UNDEF) {
62-
RETURN_ZVAL(error_ptr, 1, 1);
64+
if (Z_TYPE_P(e) == IS_ARRAY) {
65+
zval_ptr_dtor(&ret);
66+
RETURN_ZVAL(e, 1, 0);
6367
}
64-
RETURN_ZVAL(&ret, 1, 1);
65-
#else
66-
RETVAL_ZVAL(ret, 1, 1);
67-
#endif
68+
69+
assert(Z_TYPE_P(r) == IS_ARRAY);
70+
zval_ptr_dtor(&error_msg);
71+
RETURN_ZVAL(r, 1, 1);
6872
}
6973
/* }}} */
7074

@@ -106,30 +110,30 @@ PHP_MINFO_FUNCTION(zephir_parser)
106110
* Every user visible function must have an entry in zephir_parser_functions[].
107111
*/
108112
static const zend_function_entry zephir_parser_functions[] = {
109-
PHP_FE(zephir_parse_file, NULL)
110-
PHP_FE_END
113+
PHP_FE(zephir_parse_file, NULL)
114+
PHP_FE_END
111115
};
112116
/* }}} */
113117

114118
/* {{{ zephir_parser_module_entry
115119
*/
116120
zend_module_entry zephir_parser_module_entry = {
117-
STANDARD_MODULE_HEADER,
118-
PHP_ZEPHIR_PARSER_NAME,
119-
zephir_parser_functions,
120-
PHP_MINIT(zephir_parser),
121-
PHP_MSHUTDOWN(zephir_parser),
122-
NULL, /* RINIT */
123-
NULL, /* RSHUTDOWN */
124-
PHP_MINFO(zephir_parser),
125-
PHP_ZEPHIR_PARSER_VERSION,
126-
STANDARD_MODULE_PROPERTIES
121+
STANDARD_MODULE_HEADER,
122+
PHP_ZEPHIR_PARSER_NAME,
123+
zephir_parser_functions,
124+
PHP_MINIT(zephir_parser),
125+
PHP_MSHUTDOWN(zephir_parser),
126+
NULL, /* RINIT */
127+
NULL, /* RSHUTDOWN */
128+
PHP_MINFO(zephir_parser),
129+
PHP_ZEPHIR_PARSER_VERSION,
130+
STANDARD_MODULE_PROPERTIES
127131
};
128132
/* }}} */
129133

130134
/* implement standard "stub" routine to introduce ourselves to Zend */
131135
#ifdef COMPILE_DL_ZEPHIR_PARSER
132-
#ifdef ZTS
136+
#if defined(ZTS) && PHP_VERSION_ID >= 70000
133137
ZEND_TSRMLS_CACHE_DEFINE();
134138
#endif
135139
ZEND_GET_MODULE(zephir_parser)

0 commit comments

Comments
 (0)