zend_highlight.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 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@php.net> |
  16. | Zeev Suraski <zeev@php.net> |
  17. +----------------------------------------------------------------------+
  18. */
  19. #include "zend.h"
  20. #include <zend_language_parser.h>
  21. #include "zend_compile.h"
  22. #include "zend_highlight.h"
  23. #include "zend_ptr_stack.h"
  24. #include "zend_globals.h"
  25. #include "zend_exceptions.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, size_t len)
  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);
  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)
  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. while ((token_type=lex_scan(&token, NULL))) {
  85. switch (token_type) {
  86. case T_INLINE_HTML:
  87. next_color = syntax_highlighter_ini->highlight_html;
  88. break;
  89. case T_COMMENT:
  90. case T_DOC_COMMENT:
  91. next_color = syntax_highlighter_ini->highlight_comment;
  92. break;
  93. case T_OPEN_TAG:
  94. case T_OPEN_TAG_WITH_ECHO:
  95. case T_CLOSE_TAG:
  96. case T_LINE:
  97. case T_FILE:
  98. case T_DIR:
  99. case T_TRAIT_C:
  100. case T_METHOD_C:
  101. case T_FUNC_C:
  102. case T_NS_C:
  103. case T_CLASS_C:
  104. next_color = syntax_highlighter_ini->highlight_default;
  105. break;
  106. case '"':
  107. case T_ENCAPSED_AND_WHITESPACE:
  108. case T_CONSTANT_ENCAPSED_STRING:
  109. next_color = syntax_highlighter_ini->highlight_string;
  110. break;
  111. case T_WHITESPACE:
  112. zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); /* no color needed */
  113. ZVAL_UNDEF(&token);
  114. continue;
  115. break;
  116. default:
  117. if (Z_TYPE(token) == IS_UNDEF) {
  118. next_color = syntax_highlighter_ini->highlight_keyword;
  119. } else {
  120. next_color = syntax_highlighter_ini->highlight_default;
  121. }
  122. break;
  123. }
  124. if (last_color != next_color) {
  125. if (last_color != syntax_highlighter_ini->highlight_html) {
  126. zend_printf("</span>");
  127. }
  128. last_color = next_color;
  129. if (last_color != syntax_highlighter_ini->highlight_html) {
  130. zend_printf("<span style=\"color: %s\">", last_color);
  131. }
  132. }
  133. zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
  134. if (Z_TYPE(token) == IS_STRING) {
  135. switch (token_type) {
  136. case T_OPEN_TAG:
  137. case T_OPEN_TAG_WITH_ECHO:
  138. case T_CLOSE_TAG:
  139. case T_WHITESPACE:
  140. case T_COMMENT:
  141. case T_DOC_COMMENT:
  142. break;
  143. default:
  144. zval_ptr_dtor_str(&token);
  145. break;
  146. }
  147. }
  148. ZVAL_UNDEF(&token);
  149. }
  150. if (last_color != syntax_highlighter_ini->highlight_html) {
  151. zend_printf("</span>\n");
  152. }
  153. zend_printf("</span>\n");
  154. zend_printf("</code>");
  155. /* Discard parse errors thrown during tokenization */
  156. zend_clear_exception();
  157. }
  158. ZEND_API void zend_strip(void)
  159. {
  160. zval token;
  161. int token_type;
  162. int prev_space = 0;
  163. while ((token_type=lex_scan(&token, NULL))) {
  164. switch (token_type) {
  165. case T_WHITESPACE:
  166. if (!prev_space) {
  167. zend_write(" ", sizeof(" ") - 1);
  168. prev_space = 1;
  169. }
  170. ZEND_FALLTHROUGH;
  171. case T_COMMENT:
  172. case T_DOC_COMMENT:
  173. ZVAL_UNDEF(&token);
  174. continue;
  175. case T_END_HEREDOC:
  176. zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
  177. /* read the following character, either newline or ; */
  178. if (lex_scan(&token, NULL) != T_WHITESPACE) {
  179. zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
  180. }
  181. zend_write("\n", sizeof("\n") - 1);
  182. prev_space = 1;
  183. ZVAL_UNDEF(&token);
  184. continue;
  185. default:
  186. zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
  187. break;
  188. }
  189. if (Z_TYPE(token) == IS_STRING) {
  190. switch (token_type) {
  191. case T_OPEN_TAG:
  192. case T_OPEN_TAG_WITH_ECHO:
  193. case T_CLOSE_TAG:
  194. case T_WHITESPACE:
  195. case T_COMMENT:
  196. case T_DOC_COMMENT:
  197. break;
  198. default:
  199. zval_ptr_dtor_str(&token);
  200. break;
  201. }
  202. }
  203. prev_space = 0;
  204. ZVAL_UNDEF(&token);
  205. }
  206. /* Discard parse errors thrown during tokenization */
  207. zend_clear_exception();
  208. }