zend_highlight.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1998-2016 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. /* $Id$ */
  20. #include "zend.h"
  21. #include <zend_language_parser.h>
  22. #include "zend_compile.h"
  23. #include "zend_highlight.h"
  24. #include "zend_ptr_stack.h"
  25. #include "zend_globals.h"
  26. ZEND_API void zend_html_putc(char c)
  27. {
  28. switch (c) {
  29. case '\n':
  30. ZEND_PUTS("<br />");
  31. break;
  32. case '<':
  33. ZEND_PUTS("&lt;");
  34. break;
  35. case '>':
  36. ZEND_PUTS("&gt;");
  37. break;
  38. case '&':
  39. ZEND_PUTS("&amp;");
  40. break;
  41. case ' ':
  42. ZEND_PUTS("&nbsp;");
  43. break;
  44. case '\t':
  45. ZEND_PUTS("&nbsp;&nbsp;&nbsp;&nbsp;");
  46. break;
  47. default:
  48. ZEND_PUTC(c);
  49. break;
  50. }
  51. }
  52. ZEND_API void zend_html_puts(const char *s, uint len TSRMLS_DC)
  53. {
  54. const unsigned char *ptr = (const unsigned char*)s, *end = ptr + len;
  55. unsigned char *filtered = NULL;
  56. size_t filtered_len;
  57. if (LANG_SCNG(output_filter)) {
  58. LANG_SCNG(output_filter)(&filtered, &filtered_len, ptr, len TSRMLS_CC);
  59. ptr = filtered;
  60. end = filtered + filtered_len;
  61. }
  62. while (ptr<end) {
  63. if (*ptr==' ') {
  64. do {
  65. zend_html_putc(*ptr);
  66. } while ((++ptr < end) && (*ptr==' '));
  67. } else {
  68. zend_html_putc(*ptr++);
  69. }
  70. }
  71. if (LANG_SCNG(output_filter)) {
  72. efree(filtered);
  73. }
  74. }
  75. ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini TSRMLS_DC)
  76. {
  77. zval token;
  78. int token_type;
  79. char *last_color = syntax_highlighter_ini->highlight_html;
  80. char *next_color;
  81. zend_printf("<code>");
  82. zend_printf("<span style=\"color: %s\">\n", last_color);
  83. /* highlight stuff coming back from zendlex() */
  84. token.type = 0;
  85. while ((token_type=lex_scan(&token TSRMLS_CC))) {
  86. switch (token_type) {
  87. case T_INLINE_HTML:
  88. next_color = syntax_highlighter_ini->highlight_html;
  89. break;
  90. case T_COMMENT:
  91. case T_DOC_COMMENT:
  92. next_color = syntax_highlighter_ini->highlight_comment;
  93. break;
  94. case T_OPEN_TAG:
  95. case T_OPEN_TAG_WITH_ECHO:
  96. next_color = syntax_highlighter_ini->highlight_default;
  97. break;
  98. case T_CLOSE_TAG:
  99. next_color = syntax_highlighter_ini->highlight_default;
  100. break;
  101. case '"':
  102. case T_ENCAPSED_AND_WHITESPACE:
  103. case T_CONSTANT_ENCAPSED_STRING:
  104. next_color = syntax_highlighter_ini->highlight_string;
  105. break;
  106. case T_WHITESPACE:
  107. zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng) TSRMLS_CC); /* no color needed */
  108. token.type = 0;
  109. continue;
  110. break;
  111. default:
  112. if (token.type == 0) {
  113. next_color = syntax_highlighter_ini->highlight_keyword;
  114. } else {
  115. next_color = syntax_highlighter_ini->highlight_default;
  116. }
  117. break;
  118. }
  119. if (last_color != next_color) {
  120. if (last_color != syntax_highlighter_ini->highlight_html) {
  121. zend_printf("</span>");
  122. }
  123. last_color = next_color;
  124. if (last_color != syntax_highlighter_ini->highlight_html) {
  125. zend_printf("<span style=\"color: %s\">", last_color);
  126. }
  127. }
  128. zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng) TSRMLS_CC);
  129. if (token.type == IS_STRING) {
  130. switch (token_type) {
  131. case T_OPEN_TAG:
  132. case T_OPEN_TAG_WITH_ECHO:
  133. case T_CLOSE_TAG:
  134. case T_WHITESPACE:
  135. case T_COMMENT:
  136. case T_DOC_COMMENT:
  137. break;
  138. default:
  139. str_efree(token.value.str.val);
  140. break;
  141. }
  142. }
  143. token.type = 0;
  144. }
  145. if (last_color != syntax_highlighter_ini->highlight_html) {
  146. zend_printf("</span>\n");
  147. }
  148. zend_printf("</span>\n");
  149. zend_printf("</code>");
  150. }
  151. ZEND_API void zend_strip(TSRMLS_D)
  152. {
  153. zval token;
  154. int token_type;
  155. int prev_space = 0;
  156. token.type = 0;
  157. while ((token_type=lex_scan(&token TSRMLS_CC))) {
  158. switch (token_type) {
  159. case T_WHITESPACE:
  160. if (!prev_space) {
  161. zend_write(" ", sizeof(" ") - 1);
  162. prev_space = 1;
  163. }
  164. /* lack of break; is intentional */
  165. case T_COMMENT:
  166. case T_DOC_COMMENT:
  167. token.type = 0;
  168. continue;
  169. case T_END_HEREDOC:
  170. zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
  171. /* read the following character, either newline or ; */
  172. if (lex_scan(&token TSRMLS_CC) != T_WHITESPACE) {
  173. zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
  174. }
  175. zend_write("\n", sizeof("\n") - 1);
  176. prev_space = 1;
  177. token.type = 0;
  178. continue;
  179. default:
  180. zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
  181. break;
  182. }
  183. if (token.type == IS_STRING) {
  184. switch (token_type) {
  185. case T_OPEN_TAG:
  186. case T_OPEN_TAG_WITH_ECHO:
  187. case T_CLOSE_TAG:
  188. case T_WHITESPACE:
  189. case T_COMMENT:
  190. case T_DOC_COMMENT:
  191. break;
  192. default:
  193. STR_FREE(token.value.str.val);
  194. break;
  195. }
  196. }
  197. prev_space = token.type = 0;
  198. }
  199. }
  200. /*
  201. * Local variables:
  202. * tab-width: 4
  203. * c-basic-offset: 4
  204. * indent-tabs-mode: t
  205. * End:
  206. */