/src/php-src/Zend/zend_highlight.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | +----------------------------------------------------------------------+ |
3 | | | Zend Engine | |
4 | | +----------------------------------------------------------------------+ |
5 | | | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | |
6 | | +----------------------------------------------------------------------+ |
7 | | | This source file is subject to version 2.00 of the Zend license, | |
8 | | | that is bundled with this package in the file LICENSE, and is | |
9 | | | available through the world-wide-web at the following url: | |
10 | | | http://www.zend.com/license/2_00.txt. | |
11 | | | If you did not receive a copy of the Zend license and are unable to | |
12 | | | obtain it through the world-wide-web, please send a note to | |
13 | | | license@zend.com so we can mail you a copy immediately. | |
14 | | +----------------------------------------------------------------------+ |
15 | | | Authors: Andi Gutmans <andi@php.net> | |
16 | | | Zeev Suraski <zeev@php.net> | |
17 | | +----------------------------------------------------------------------+ |
18 | | */ |
19 | | |
20 | | #include "zend.h" |
21 | | #include <zend_language_parser.h> |
22 | | #include "zend_compile.h" |
23 | | #include "zend_highlight.h" |
24 | | #include "zend_ptr_stack.h" |
25 | | #include "zend_globals.h" |
26 | | #include "zend_exceptions.h" |
27 | | |
28 | | ZEND_API void zend_html_putc(char c) |
29 | 44.1M | { |
30 | 44.1M | switch (c) { |
31 | 872k | case '<': |
32 | 872k | ZEND_PUTS("<"); |
33 | 872k | break; |
34 | 138k | case '>': |
35 | 138k | ZEND_PUTS(">"); |
36 | 138k | break; |
37 | 102k | case '&': |
38 | 102k | ZEND_PUTS("&"); |
39 | 102k | break; |
40 | 226k | case '\t': |
41 | 226k | ZEND_PUTS(" "); |
42 | 226k | break; |
43 | 42.7M | default: |
44 | 42.7M | ZEND_PUTC(c); |
45 | 42.7M | break; |
46 | 44.1M | } |
47 | 44.1M | } |
48 | | |
49 | | |
50 | | ZEND_API void zend_html_puts(const char *s, size_t len) |
51 | 8.68M | { |
52 | 8.68M | const unsigned char *ptr = (const unsigned char*)s, *end = ptr + len; |
53 | 8.68M | unsigned char *filtered = NULL; |
54 | 8.68M | size_t filtered_len; |
55 | | |
56 | 8.68M | if (LANG_SCNG(output_filter)) { |
57 | 0 | LANG_SCNG(output_filter)(&filtered, &filtered_len, ptr, len); |
58 | 0 | ptr = filtered; |
59 | 0 | end = filtered + filtered_len; |
60 | 0 | } |
61 | | |
62 | 51.5M | while (ptr<end) { |
63 | 42.8M | if (*ptr==' ') { |
64 | 3.38M | do { |
65 | 3.38M | zend_html_putc(*ptr); |
66 | 3.38M | } while ((++ptr < end) && (*ptr==' ')); |
67 | 40.7M | } else { |
68 | 40.7M | zend_html_putc(*ptr++); |
69 | 40.7M | } |
70 | 42.8M | } |
71 | | |
72 | 8.68M | if (LANG_SCNG(output_filter)) { |
73 | 0 | efree(filtered); |
74 | 0 | } |
75 | 8.68M | } |
76 | | |
77 | | |
78 | | ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini) |
79 | 23.9k | { |
80 | 23.9k | zval token; |
81 | 23.9k | int token_type; |
82 | 23.9k | char *last_color = syntax_highlighter_ini->highlight_html; |
83 | 23.9k | char *next_color; |
84 | | |
85 | 23.9k | zend_printf("<pre><code style=\"color: %s\">", last_color); |
86 | | /* highlight stuff coming back from zendlex() */ |
87 | 8.71M | while ((token_type=lex_scan(&token, NULL))) { |
88 | 8.68M | switch (token_type) { |
89 | 29.0k | case T_INLINE_HTML: |
90 | 29.0k | next_color = syntax_highlighter_ini->highlight_html; |
91 | 29.0k | break; |
92 | 100k | case T_COMMENT: |
93 | 102k | case T_DOC_COMMENT: |
94 | 102k | next_color = syntax_highlighter_ini->highlight_comment; |
95 | 102k | break; |
96 | 27.9k | case T_OPEN_TAG: |
97 | 28.4k | case T_OPEN_TAG_WITH_ECHO: |
98 | 36.2k | case T_CLOSE_TAG: |
99 | 36.7k | case T_LINE: |
100 | 36.8k | case T_FILE: |
101 | 37.2k | case T_DIR: |
102 | 37.7k | case T_TRAIT_C: |
103 | 38.9k | case T_METHOD_C: |
104 | 39.1k | case T_FUNC_C: |
105 | 39.2k | case T_PROPERTY_C: |
106 | 40.0k | case T_NS_C: |
107 | 40.4k | case T_CLASS_C: |
108 | 40.4k | next_color = syntax_highlighter_ini->highlight_default; |
109 | 40.4k | break; |
110 | 11.9k | case '"': |
111 | 62.3k | case T_ENCAPSED_AND_WHITESPACE: |
112 | 183k | case T_CONSTANT_ENCAPSED_STRING: |
113 | 183k | next_color = syntax_highlighter_ini->highlight_string; |
114 | 183k | break; |
115 | 1.25M | case T_WHITESPACE: |
116 | 1.25M | zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); /* no color needed */ |
117 | 1.25M | ZVAL_UNDEF(&token); |
118 | 1.25M | continue; |
119 | 0 | break; |
120 | 7.07M | default: |
121 | 7.07M | if (Z_TYPE(token) == IS_UNDEF) { |
122 | 5.44M | next_color = syntax_highlighter_ini->highlight_keyword; |
123 | 5.44M | } else { |
124 | 1.62M | next_color = syntax_highlighter_ini->highlight_default; |
125 | 1.62M | } |
126 | 7.07M | break; |
127 | 8.68M | } |
128 | | |
129 | 7.42M | if (last_color != next_color) { |
130 | 3.13M | if (last_color != syntax_highlighter_ini->highlight_html) { |
131 | 3.10M | zend_printf("</span>"); |
132 | 3.10M | } |
133 | 3.13M | last_color = next_color; |
134 | 3.13M | if (last_color != syntax_highlighter_ini->highlight_html) { |
135 | 3.12M | zend_printf("<span style=\"color: %s\">", last_color); |
136 | 3.12M | } |
137 | 3.13M | } |
138 | | |
139 | 7.42M | zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); |
140 | | |
141 | 7.42M | if (Z_TYPE(token) == IS_STRING) { |
142 | 1.55M | switch (token_type) { |
143 | 0 | case T_OPEN_TAG: |
144 | 0 | case T_OPEN_TAG_WITH_ECHO: |
145 | 0 | case T_CLOSE_TAG: |
146 | 0 | case T_WHITESPACE: |
147 | 0 | case T_COMMENT: |
148 | 0 | case T_DOC_COMMENT: |
149 | 0 | break; |
150 | 1.55M | default: |
151 | 1.55M | zval_ptr_dtor_str(&token); |
152 | 1.55M | break; |
153 | 1.55M | } |
154 | 1.55M | } |
155 | 7.42M | ZVAL_UNDEF(&token); |
156 | 7.42M | } |
157 | | |
158 | 23.9k | if (last_color != syntax_highlighter_ini->highlight_html) { |
159 | 20.5k | zend_printf("</span>"); |
160 | 20.5k | } |
161 | 23.9k | zend_printf("</code></pre>"); |
162 | | |
163 | | /* Discard parse errors thrown during tokenization */ |
164 | 23.9k | zend_clear_exception(); |
165 | 23.9k | } |
166 | | |
167 | | ZEND_API void zend_strip(void) |
168 | 0 | { |
169 | 0 | zval token; |
170 | 0 | int token_type; |
171 | 0 | int prev_space = 0; |
172 | |
|
173 | 0 | while ((token_type=lex_scan(&token, NULL))) { |
174 | 0 | switch (token_type) { |
175 | 0 | case T_WHITESPACE: |
176 | 0 | if (!prev_space) { |
177 | 0 | zend_write(" ", sizeof(" ") - 1); |
178 | 0 | prev_space = 1; |
179 | 0 | } |
180 | 0 | ZEND_FALLTHROUGH; |
181 | 0 | case T_COMMENT: |
182 | 0 | case T_DOC_COMMENT: |
183 | 0 | ZVAL_UNDEF(&token); |
184 | 0 | continue; |
185 | | |
186 | 0 | case T_END_HEREDOC: |
187 | 0 | zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); |
188 | | /* read the following character, either newline or ; */ |
189 | 0 | if (lex_scan(&token, NULL) != T_WHITESPACE) { |
190 | 0 | zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); |
191 | 0 | } |
192 | 0 | zend_write("\n", sizeof("\n") - 1); |
193 | 0 | prev_space = 1; |
194 | 0 | ZVAL_UNDEF(&token); |
195 | 0 | continue; |
196 | | |
197 | 0 | default: |
198 | 0 | zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); |
199 | 0 | break; |
200 | 0 | } |
201 | | |
202 | 0 | if (Z_TYPE(token) == IS_STRING) { |
203 | 0 | switch (token_type) { |
204 | 0 | case T_OPEN_TAG: |
205 | 0 | case T_OPEN_TAG_WITH_ECHO: |
206 | 0 | case T_CLOSE_TAG: |
207 | 0 | case T_WHITESPACE: |
208 | 0 | case T_COMMENT: |
209 | 0 | case T_DOC_COMMENT: |
210 | 0 | break; |
211 | | |
212 | 0 | default: |
213 | 0 | zval_ptr_dtor_str(&token); |
214 | 0 | break; |
215 | 0 | } |
216 | 0 | } |
217 | 0 | prev_space = 0; |
218 | 0 | ZVAL_UNDEF(&token); |
219 | 0 | } |
220 | | |
221 | | /* Discard parse errors thrown during tokenization */ |
222 | 0 | zend_clear_exception(); |
223 | 0 | } |