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