Tue, 23 Aug 2016 17:31:15 +0200
cleans up includes
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2016 Mike Becker. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
30 #include "ccodegen.h"
32 const char* ckeywords[] = {
33 "auto", "break", "case", "char", "const", "continue", "default", "do",
34 "double", "else", "enum", "extern", "float", "for", "goto", "if", "int",
35 "long", "register", "return", "short", "signed", "sizeof", "static",
36 "struct", "switch", "typedef", "union", "unsigned", "void", "volatile",
37 "while", NULL
38 };
40 void c_highlighter(char *src, UcxBuffer *dest, int *multiline_comment) {
41 /* TODO: try to replace these buffers */
42 char wordbuf[WORDBUF_SIZE];
43 sstr_t word;
44 word.ptr = wordbuf; word.length = 0;
46 char includefilebuf[512];
47 sstr_t includefile;
48 includefile.ptr = includefilebuf;
49 includefile.length = 0;
51 size_t sp = (size_t)-1;
52 int isstring = 0, iscomment = 0, isinclude = 0, parseinclude = 0;
53 char quote = '\0';
54 int isescaping = 0;
56 /* continue a multi line comment highlighting */
57 if (*multiline_comment) {
58 iscomment = 1;
59 ucx_buffer_puts(dest, "<span class=\"c2html-comment\">");
60 }
62 char c;
63 do {
64 c = src[++sp];
65 if (!c) break;
67 /* comments */
68 if (!isstring && c == '/') {
69 if (*multiline_comment && sp > 0 && src[sp-1] == '*') {
70 iscomment = 0;
71 *multiline_comment = 0;
72 ucx_buffer_puts(dest, "/</span>");
73 continue;
74 } else if (!iscomment && (src[sp+1] == '/' || src[sp+1] == '*')) {
75 iscomment = 1;
76 *multiline_comment = (src[sp+1] == '*');
77 ucx_buffer_puts(dest, "<span class=\"c2html-comment\">");
78 }
79 }
81 if (iscomment) {
82 if (c == '\n') {
83 ucx_buffer_puts(dest, "</span>\n");
84 } else {
85 put_htmlescaped(dest, c);
86 }
87 } else if (isinclude) {
88 if (c == '<') {
89 ucx_buffer_puts(dest,
90 "<span class=\"c2html-stdinclude\"><");
91 } else if (c == '\"') {
92 if (parseinclude) {
93 ucx_bprintf(dest, "\">%.*s\"</a>",
94 includefile.length, includefile.ptr);
95 parseinclude = 0;
96 } else {
97 ucx_buffer_puts(dest,
98 "<a class=\"c2html-userinclude\" href=\"");
99 includefile.length = 0;
100 includefile.ptr[includefile.length++] = '\"';
101 parseinclude = 1;
102 }
103 } else if (c == '>') {
104 ucx_buffer_puts(dest, "></span>");
105 } else {
106 if (parseinclude) {
107 includefile.ptr[includefile.length++] = c;
108 }
109 put_htmlescaped(dest, c);
110 }
111 } else {
112 /* strings */
113 if (!isescaping && (c == '\'' || c == '\"')) {
114 if (isstring) {
115 put_htmlescaped(dest, c);
116 if (c == quote) {
117 isstring = 0;
118 ucx_buffer_puts(dest, "</span>");
119 } else {
120 put_htmlescaped(dest, c);
121 }
122 } else {
123 isstring = 1;
124 quote = c;
125 ucx_buffer_puts(dest, "<span class=\"c2html-string\">");
126 put_htmlescaped(dest, c);
127 }
128 } else {
129 if (isstring) {
130 put_htmlescaped(dest, c);
131 } else if (!check_alnumex(c)) {
132 if (word.length > 0 && word.length < WORDBUF_SIZE) {
133 int closespan = 1;
134 sstr_t typesuffix = ST("_t");
135 if (check_keyword(word, ckeywords)) {
136 ucx_buffer_puts(dest,
137 "<span class=\"c2html-keyword\">");
138 } else if (sstrsuffix(word, typesuffix)) {
139 ucx_buffer_puts(dest,
140 "<span class=\"c2html-type\">");
141 } else if (word.ptr[0] == '#') {
142 isinclude = !sstrcmp(word, S("#include"));
143 ucx_buffer_puts(dest,
144 "<span class=\"c2html-directive\">");
145 } else if (check_capsonly(word)) {
146 ucx_buffer_puts(dest,
147 "<span class=\"c2html-macroconst\">");
148 } else {
149 closespan = 0;
150 }
151 put_htmlescapedstr(dest, word);
152 if (closespan) {
153 ucx_buffer_puts(dest, "</span>");
154 }
155 }
156 word.length = 0;
157 put_htmlescaped(dest, c);
158 } else {
159 /* read word */
160 if (word.length < WORDBUF_SIZE) {
161 word.ptr[word.length++] = c;
162 } else if (word.length == WORDBUF_SIZE) {
163 /* TODO: this will be removed */
164 ucx_buffer_puts(dest,
165 "!!! WARNING - WORD TOO LONG TO PARSE !!!");
166 word.length = 0;
167 } else {
168 put_htmlescaped(dest, c);
169 }
170 }
171 }
173 isescaping = !isescaping & (c == '\\');
174 }
175 } while (c != '\n');
176 }