ZEND_API void zend_strip(void) { zval token; int token_type; int prev_space = 0; ZVAL_UNDEF(&token); while ((token_type=lex_scan(&token))) { switch (token_type) { case T_WHITESPACE: if (!prev_space) { zend_write(" ", sizeof(" ") - 1); prev_space = 1; } /* lack of break; is intentional */ case T_COMMENT: case T_DOC_COMMENT: ZVAL_UNDEF(&token); continue; case T_END_HEREDOC: zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); /* read the following character, either newline or ; */ if (lex_scan(&token) != T_WHITESPACE) { zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); } zend_write("\n", sizeof("\n") - 1); prev_space = 1; ZVAL_UNDEF(&token); continue; default: zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); break; } if (Z_TYPE(token) == IS_STRING) { switch (token_type) { case T_OPEN_TAG: case T_OPEN_TAG_WITH_ECHO: case T_CLOSE_TAG: case T_WHITESPACE: case T_COMMENT: case T_DOC_COMMENT: break; default: zend_string_release(Z_STR(token)); break; } } prev_space = 0; ZVAL_UNDEF(&token); } /* Discard parse errors thrown during tokenization */ zend_clear_exception(); }
static zend_bool tokenize_parse(zval *return_value, zend_string *source) { zval source_zval; zend_lex_state original_lex_state; zend_bool original_in_compilation; zend_bool success; ZVAL_STR_COPY(&source_zval, source); original_in_compilation = CG(in_compilation); CG(in_compilation) = 1; zend_save_lexical_state(&original_lex_state); if ((success = (zend_prepare_string_for_scanning(&source_zval, "") == SUCCESS))) { CG(ast) = NULL; CG(ast_arena) = zend_arena_create(1024 * 32); LANG_SCNG(yy_state) = yycINITIAL; LANG_SCNG(on_event) = on_event; array_init(&token_stream); if((success = (zendparse() == SUCCESS))) { ZVAL_COPY_VALUE(return_value, &token_stream); } else { zval_ptr_dtor(&token_stream); } zend_ast_destroy(CG(ast)); zend_arena_destroy(CG(ast_arena)); } /* restore compiler and scanner global states */ zend_restore_lexical_state(&original_lex_state); CG(in_compilation) = original_in_compilation; zval_dtor(&source_zval); return success; }
void on_event(zend_php_scanner_event event, int token, int line, void *context) { zval *token_stream = (zval *) context; zval keyword; HashTable *tokens_ht; zval *token_zv; switch (event) { case ON_TOKEN: if (token == END) break; if (token >= 256) { array_init(&keyword); add_next_index_long(&keyword, token); add_next_index_stringl(&keyword, (char *)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); add_next_index_long(&keyword, line); add_next_index_zval(token_stream, &keyword); } else { add_next_index_stringl(token_stream, (char *)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); } break; case ON_FEEDBACK: tokens_ht = Z_ARRVAL_P(token_stream); token_zv = zend_hash_index_find(tokens_ht, zend_hash_num_elements(tokens_ht) - 1); if (token_zv && Z_TYPE_P(token_zv) == IS_ARRAY) { ZVAL_LONG(zend_hash_index_find(Z_ARRVAL_P(token_zv), 0), token); } break; case ON_STOP: if (LANG_SCNG(yy_cursor) != LANG_SCNG(yy_limit)) { array_init(&keyword); add_next_index_long(&keyword, T_INLINE_HTML); add_next_index_stringl(&keyword, (char *)LANG_SCNG(yy_cursor), LANG_SCNG(yy_limit) - LANG_SCNG(yy_cursor)); add_next_index_long(&keyword, CG(zend_lineno)); add_next_index_zval(token_stream, &keyword); } break; } }
ZEND_API zend_ast *zend_ast_create_decl( zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment, zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3 ) { zend_ast_decl *ast; ast = zend_ast_alloc(sizeof(zend_ast_decl)); ast->kind = kind; ast->attr = 0; ast->start_lineno = start_lineno; ast->end_lineno = CG(zend_lineno); ast->flags = flags; ast->lex_pos = LANG_SCNG(yy_text); ast->doc_comment = doc_comment; ast->name = name; ast->child[0] = child0; ast->child[1] = child1; ast->child[2] = child2; ast->child[3] = child3; return (zend_ast *) ast; }
ZEND_API void zend_indent() { zval token; int token_type; int in_string=0; int nest_level=0; int emit_whitespace[256]; int i; TSRMLS_FETCH(); memset(emit_whitespace, 0, sizeof(int)*256); /* highlight stuff coming back from zendlex() */ token.type = 0; while ((token_type=lex_scan(&token TSRMLS_CC))) { switch (token_type) { case T_INLINE_HTML: zend_write(LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); break; case T_WHITESPACE: { token.type = 0; /* eat whitespace, emit newlines */ for (i=0; i<LANG_SCNG(yy_leng); i++) { emit_whitespace[(unsigned char) LANG_SCNG(yy_text)[i]]++; } continue; } break; case '"': in_string = !in_string; /* break missing intentionally */ default: if (token.type==0) { /* keyword */ switch (token_type) { case ',': ZEND_PUTS(", "); goto dflt_printout; break; case '{': nest_level++; if (emit_whitespace['\n']>0) { ZEND_PUTS(" {\n"); memset(emit_whitespace, 0, sizeof(int)*256); } else { ZEND_PUTS("{"); } break; case '}': nest_level--; if (emit_whitespace['\n']==0) { ZEND_PUTS("\n"); } for (i=0; i<nest_level; i++) { ZEND_PUTS(" "); } goto dflt_printout; break; dflt_printout: default: if (emit_whitespace['\n']>0) { for (i=0; i<emit_whitespace['\n']; i++) { ZEND_PUTS("\n"); } memset(emit_whitespace, 0, sizeof(int)*256); for (i=0; i<nest_level; i++) { ZEND_PUTS(" "); } } else { handle_whitespace(emit_whitespace); } zend_write(LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); break; } } else { handle_whitespace(emit_whitespace); if (in_string) { zend_write(LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); /* a part of a string */ } else { zend_write(LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); } } break; } if (token.type == IS_STRING) { switch (token_type) { case T_OPEN_TAG: case T_CLOSE_TAG: case T_WHITESPACE: break; default: efree(token.value.str.val); break; } } token.type = 0; } }
static zend_bool tokenize(zval *return_value, zend_string *source) { zval source_zval; zend_lex_state original_lex_state; zval token; zval keyword; int token_type; int token_line = 1; int need_tokens = -1; /* for __halt_compiler lexing. -1 = disabled */ ZVAL_STR_COPY(&source_zval, source); zend_save_lexical_state(&original_lex_state); if (zend_prepare_string_for_scanning(&source_zval, "") == FAILURE) { zend_restore_lexical_state(&original_lex_state); return 0; } LANG_SCNG(yy_state) = yycINITIAL; array_init(return_value); ZVAL_UNDEF(&token); while ((token_type = lex_scan(&token))) { if (token_type == T_CLOSE_TAG && zendtext[zendleng - 1] != '>') { CG(zend_lineno)++; } if (token_type >= 256) { array_init(&keyword); add_next_index_long(&keyword, token_type); if (token_type == T_END_HEREDOC) { if (CG(increment_lineno)) { token_line = ++CG(zend_lineno); CG(increment_lineno) = 0; } } add_next_index_stringl(&keyword, (char *)zendtext, zendleng); add_next_index_long(&keyword, token_line); add_next_index_zval(return_value, &keyword); } else { add_next_index_stringl(return_value, (char *)zendtext, zendleng); } if (Z_TYPE(token) != IS_UNDEF) { zval_dtor(&token); ZVAL_UNDEF(&token); } /* after T_HALT_COMPILER collect the next three non-dropped tokens */ if (need_tokens != -1) { if (token_type != T_WHITESPACE && token_type != T_OPEN_TAG && token_type != T_COMMENT && token_type != T_DOC_COMMENT && --need_tokens == 0 ) { /* fetch the rest into a T_INLINE_HTML */ if (zendcursor != zendlimit) { array_init(&keyword); add_next_index_long(&keyword, T_INLINE_HTML); add_next_index_stringl(&keyword, (char *)zendcursor, zendlimit - zendcursor); add_next_index_long(&keyword, token_line); add_next_index_zval(return_value, &keyword); } break; } } else if (token_type == T_HALT_COMPILER) { need_tokens = 3; } token_line = CG(zend_lineno); } zval_dtor(&source_zval); zend_restore_lexical_state(&original_lex_state); return 1; }
ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini) { zval token; int token_type; char *last_color = syntax_highlighter_ini->highlight_html; char *next_color; zend_printf("<code>"); zend_printf("<span style=\"color: %s\">\n", last_color); /* highlight stuff coming back from zendlex() */ ZVAL_UNDEF(&token); while ((token_type=lex_scan(&token))) { switch (token_type) { case T_INLINE_HTML: next_color = syntax_highlighter_ini->highlight_html; break; case T_COMMENT: case T_DOC_COMMENT: next_color = syntax_highlighter_ini->highlight_comment; break; case T_OPEN_TAG: case T_OPEN_TAG_WITH_ECHO: case T_CLOSE_TAG: case T_LINE: case T_FILE: case T_DIR: case T_TRAIT_C: case T_METHOD_C: case T_FUNC_C: case T_NS_C: case T_CLASS_C: next_color = syntax_highlighter_ini->highlight_default; break; case '"': case T_ENCAPSED_AND_WHITESPACE: case T_CONSTANT_ENCAPSED_STRING: next_color = syntax_highlighter_ini->highlight_string; break; case T_WHITESPACE: zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); /* no color needed */ ZVAL_UNDEF(&token); continue; break; default: if (Z_TYPE(token) == IS_UNDEF) { next_color = syntax_highlighter_ini->highlight_keyword; } else { next_color = syntax_highlighter_ini->highlight_default; } break; } if (last_color != next_color) { if (last_color != syntax_highlighter_ini->highlight_html) { zend_printf("</span>"); } last_color = next_color; if (last_color != syntax_highlighter_ini->highlight_html) { zend_printf("<span style=\"color: %s\">", last_color); } } zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); if (Z_TYPE(token) == IS_STRING) { switch (token_type) { case T_OPEN_TAG: case T_OPEN_TAG_WITH_ECHO: case T_CLOSE_TAG: case T_WHITESPACE: case T_COMMENT: case T_DOC_COMMENT: break; default: zend_string_release(Z_STR(token)); break; } } ZVAL_UNDEF(&token); } if (last_color != syntax_highlighter_ini->highlight_html) { zend_printf("</span>\n"); } zend_printf("</span>\n"); zend_printf("</code>"); /* Discard parse errors thrown during tokenization */ zend_clear_exception(); }
ZEND_API const zend_encoding *zend_multibyte_get_script_encoding(void) { return LANG_SCNG(script_encoding); }