1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1998-2018 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@zend.com> |
16 | Zeev Suraski <zeev@zend.com> |
17 +----------------------------------------------------------------------+
18 */
19
20 /* $Id$ */
21
22 #include "zend.h"
23 #include <zend_language_parser.h>
24 #include "zend_compile.h"
25 #include "zend_highlight.h"
26 #include "zend_ptr_stack.h"
27 #include "zend_globals.h"
28 #include "zend_exceptions.h"
29
zend_html_putc(char c)30 ZEND_API void zend_html_putc(char c)
31 {
32 switch (c) {
33 case '\n':
34 ZEND_PUTS("<br />");
35 break;
36 case '<':
37 ZEND_PUTS("<");
38 break;
39 case '>':
40 ZEND_PUTS(">");
41 break;
42 case '&':
43 ZEND_PUTS("&");
44 break;
45 case ' ':
46 ZEND_PUTS(" ");
47 break;
48 case '\t':
49 ZEND_PUTS(" ");
50 break;
51 default:
52 ZEND_PUTC(c);
53 break;
54 }
55 }
56
57
zend_html_puts(const char * s,size_t len)58 ZEND_API void zend_html_puts(const char *s, size_t len)
59 {
60 const unsigned char *ptr = (const unsigned char*)s, *end = ptr + len;
61 unsigned char *filtered = NULL;
62 size_t filtered_len;
63
64 if (LANG_SCNG(output_filter)) {
65 LANG_SCNG(output_filter)(&filtered, &filtered_len, ptr, len);
66 ptr = filtered;
67 end = filtered + filtered_len;
68 }
69
70 while (ptr<end) {
71 if (*ptr==' ') {
72 do {
73 zend_html_putc(*ptr);
74 } while ((++ptr < end) && (*ptr==' '));
75 } else {
76 zend_html_putc(*ptr++);
77 }
78 }
79
80 if (LANG_SCNG(output_filter)) {
81 efree(filtered);
82 }
83 }
84
85
zend_highlight(zend_syntax_highlighter_ini * syntax_highlighter_ini)86 ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini)
87 {
88 zval token;
89 int token_type;
90 char *last_color = syntax_highlighter_ini->highlight_html;
91 char *next_color;
92
93 zend_printf("<code>");
94 zend_printf("<span style=\"color: %s\">\n", last_color);
95 /* highlight stuff coming back from zendlex() */
96 ZVAL_UNDEF(&token);
97 while ((token_type=lex_scan(&token))) {
98 switch (token_type) {
99 case T_INLINE_HTML:
100 next_color = syntax_highlighter_ini->highlight_html;
101 break;
102 case T_COMMENT:
103 case T_DOC_COMMENT:
104 next_color = syntax_highlighter_ini->highlight_comment;
105 break;
106 case T_OPEN_TAG:
107 case T_OPEN_TAG_WITH_ECHO:
108 case T_CLOSE_TAG:
109 case T_LINE:
110 case T_FILE:
111 case T_DIR:
112 case T_TRAIT_C:
113 case T_METHOD_C:
114 case T_FUNC_C:
115 case T_NS_C:
116 case T_CLASS_C:
117 next_color = syntax_highlighter_ini->highlight_default;
118 break;
119 case '"':
120 case T_ENCAPSED_AND_WHITESPACE:
121 case T_CONSTANT_ENCAPSED_STRING:
122 next_color = syntax_highlighter_ini->highlight_string;
123 break;
124 case T_WHITESPACE:
125 zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); /* no color needed */
126 ZVAL_UNDEF(&token);
127 continue;
128 break;
129 default:
130 if (Z_TYPE(token) == IS_UNDEF) {
131 next_color = syntax_highlighter_ini->highlight_keyword;
132 } else {
133 next_color = syntax_highlighter_ini->highlight_default;
134 }
135 break;
136 }
137
138 if (last_color != next_color) {
139 if (last_color != syntax_highlighter_ini->highlight_html) {
140 zend_printf("</span>");
141 }
142 last_color = next_color;
143 if (last_color != syntax_highlighter_ini->highlight_html) {
144 zend_printf("<span style=\"color: %s\">", last_color);
145 }
146 }
147
148 zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
149
150 if (Z_TYPE(token) == IS_STRING) {
151 switch (token_type) {
152 case T_OPEN_TAG:
153 case T_OPEN_TAG_WITH_ECHO:
154 case T_CLOSE_TAG:
155 case T_WHITESPACE:
156 case T_COMMENT:
157 case T_DOC_COMMENT:
158 break;
159 default:
160 zend_string_release(Z_STR(token));
161 break;
162 }
163 }
164 ZVAL_UNDEF(&token);
165 }
166
167 if (last_color != syntax_highlighter_ini->highlight_html) {
168 zend_printf("</span>\n");
169 }
170 zend_printf("</span>\n");
171 zend_printf("</code>");
172
173 /* Discard parse errors thrown during tokenization */
174 zend_clear_exception();
175 }
176
zend_strip(void)177 ZEND_API void zend_strip(void)
178 {
179 zval token;
180 int token_type;
181 int prev_space = 0;
182
183 ZVAL_UNDEF(&token);
184 while ((token_type=lex_scan(&token))) {
185 switch (token_type) {
186 case T_WHITESPACE:
187 if (!prev_space) {
188 zend_write(" ", sizeof(" ") - 1);
189 prev_space = 1;
190 }
191 /* lack of break; is intentional */
192 case T_COMMENT:
193 case T_DOC_COMMENT:
194 ZVAL_UNDEF(&token);
195 continue;
196
197 case T_END_HEREDOC:
198 zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
199 /* read the following character, either newline or ; */
200 if (lex_scan(&token) != T_WHITESPACE) {
201 zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
202 }
203 zend_write("\n", sizeof("\n") - 1);
204 prev_space = 1;
205 ZVAL_UNDEF(&token);
206 continue;
207
208 default:
209 zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
210 break;
211 }
212
213 if (Z_TYPE(token) == IS_STRING) {
214 switch (token_type) {
215 case T_OPEN_TAG:
216 case T_OPEN_TAG_WITH_ECHO:
217 case T_CLOSE_TAG:
218 case T_WHITESPACE:
219 case T_COMMENT:
220 case T_DOC_COMMENT:
221 break;
222
223 default:
224 zend_string_release(Z_STR(token));
225 break;
226 }
227 }
228 prev_space = 0;
229 ZVAL_UNDEF(&token);
230 }
231
232 /* Discard parse errors thrown during tokenization */
233 zend_clear_exception();
234 }
235
236 /*
237 * Local variables:
238 * tab-width: 4
239 * c-basic-offset: 4
240 * indent-tabs-mode: t
241 * End:
242 * vim600: sw=4 ts=4 fdm=marker
243 * vim<600: sw=4 ts=4
244 */
245