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