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