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