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