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