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