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: zend_highlight.c,v 1.1.1.4 2014/06/15 20:04:03 misho 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: {
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:
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:
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:
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:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>