summaryrefslogtreecommitdiff
path: root/ext/tokenizer/tokenizer.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/tokenizer/tokenizer.c')
-rw-r--r--ext/tokenizer/tokenizer.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/ext/tokenizer/tokenizer.c b/ext/tokenizer/tokenizer.c
index db57323223..901e609d2d 100644
--- a/ext/tokenizer/tokenizer.c
+++ b/ext/tokenizer/tokenizer.c
@@ -420,11 +420,33 @@ struct event_context {
zend_class_entry *token_class;
};
-void on_event(zend_php_scanner_event event, int token, int line, void *context)
+static zval *extract_token_id_to_replace(zval *token_zv, const char *text, size_t length) {
+ zval *id_zv, *text_zv;
+ ZEND_ASSERT(token_zv);
+ if (Z_TYPE_P(token_zv) == IS_ARRAY) {
+ id_zv = zend_hash_index_find(Z_ARRVAL_P(token_zv), 0);
+ text_zv = zend_hash_index_find(Z_ARRVAL_P(token_zv), 1);
+ } else if (Z_TYPE_P(token_zv) == IS_OBJECT) {
+ id_zv = OBJ_PROP_NUM(Z_OBJ_P(token_zv), 0);
+ text_zv = OBJ_PROP_NUM(Z_OBJ_P(token_zv), 1);
+ } else {
+ return NULL;
+ }
+
+ /* There are multiple candidate tokens to which this feedback may apply,
+ * check text to make sure this is the right one. */
+ ZEND_ASSERT(Z_TYPE_P(text_zv) == IS_STRING);
+ if (Z_STRLEN_P(text_zv) == length && !memcmp(Z_STRVAL_P(text_zv), text, length)) {
+ return id_zv;
+ }
+ return NULL;
+}
+
+void on_event(
+ zend_php_scanner_event event, int token, int line,
+ const char *text, size_t length, void *context)
{
struct event_context *ctx = context;
- HashTable *tokens_ht;
- zval *token_zv;
switch (event) {
case ON_TOKEN:
@@ -435,19 +457,22 @@ void on_event(zend_php_scanner_event event, int token, int line, void *context)
} else if (token == T_ECHO && LANG_SCNG(yy_leng) == sizeof("<?=") - 1) {
token = T_OPEN_TAG_WITH_ECHO;
}
- add_token(ctx->tokens, token,
- LANG_SCNG(yy_text), LANG_SCNG(yy_leng), line, ctx->token_class, NULL);
+ add_token(
+ ctx->tokens, token, (unsigned char *) text, length, line, ctx->token_class, NULL);
break;
- case ON_FEEDBACK:
- tokens_ht = Z_ARRVAL_P(ctx->tokens);
- token_zv = zend_hash_index_find(tokens_ht, zend_hash_num_elements(tokens_ht) - 1);
- ZEND_ASSERT(token_zv);
- if (Z_TYPE_P(token_zv) == IS_ARRAY) {
- ZVAL_LONG(zend_hash_index_find(Z_ARRVAL_P(token_zv), 0), token);
- } else {
- zend_update_property_long(php_token_ce, token_zv, "type", sizeof("type")-1, token);
- }
+ case ON_FEEDBACK: {
+ HashTable *tokens_ht = Z_ARRVAL_P(ctx->tokens);
+ zval *token_zv, *id_zv = NULL;
+ ZEND_HASH_REVERSE_FOREACH_VAL(tokens_ht, token_zv) {
+ id_zv = extract_token_id_to_replace(token_zv, text, length);
+ if (id_zv) {
+ break;
+ }
+ } ZEND_HASH_FOREACH_END();
+ ZEND_ASSERT(id_zv);
+ ZVAL_LONG(id_zv, token);
break;
+ }
case ON_STOP:
if (LANG_SCNG(yy_cursor) != LANG_SCNG(yy_limit)) {
add_token(ctx->tokens, T_INLINE_HTML, LANG_SCNG(yy_cursor),