Mercurial > ~dholland > hg > tradcpp > index.cgi
annotate output.c @ 206:9aa91d3fe3a3 release-0.5.3
release 0.5.3
author | David A. Holland |
---|---|
date | Mon, 21 Jan 2019 21:21:46 -0500 |
parents | 16b4451e34b8 |
children |
rev | line source |
---|---|
30 | 1 /*- |
2 * Copyright (c) 2010 The NetBSD Foundation, Inc. | |
3 * All rights reserved. | |
4 * | |
5 * This code is derived from software contributed to The NetBSD Foundation | |
6 * by David A. Holland. | |
7 * | |
8 * Redistribution and use in source and binary forms, with or without | |
9 * modification, are permitted provided that the following conditions | |
10 * are met: | |
11 * 1. Redistributions of source code must retain the above copyright | |
12 * notice, this list of conditions and the following disclaimer. | |
13 * 2. Redistributions in binary form must reproduce the above copyright | |
14 * notice, this list of conditions and the following disclaimer in the | |
15 * documentation and/or other materials provided with the distribution. | |
16 * | |
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
27 * POSSIBILITY OF SUCH DAMAGE. | |
28 */ | |
29 | |
185
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
143
diff
changeset
|
30 #include <stdio.h> |
27 | 31 #include <string.h> |
20 | 32 #include <unistd.h> |
33 #include <fcntl.h> | |
143 | 34 #include <errno.h> |
20 | 35 |
36 #include "utils.h" | |
37 #include "mode.h" | |
21 | 38 #include "place.h" |
20 | 39 #include "output.h" |
40 | |
41 static int outputfd = -1; | |
21 | 42 static bool incomment = false; |
27 | 43 static char *linebuf; |
44 static size_t linebufpos, linebufmax; | |
45 static struct place linebufplace; | |
20 | 46 |
47 static | |
48 void | |
49 output_open(void) | |
50 { | |
24 | 51 if (mode.output_file == NULL) { |
52 outputfd = STDOUT_FILENO; | |
53 } else { | |
54 outputfd = open(mode.output_file, O_WRONLY|O_CREAT|O_TRUNC, | |
55 0664); | |
56 if (outputfd < 0) { | |
143 | 57 complain(NULL, "%s: %s", |
58 mode.output_file, strerror(errno)); | |
24 | 59 die(); |
60 } | |
20 | 61 } |
62 } | |
63 | |
21 | 64 static |
20 | 65 void |
21 | 66 dowrite(const char *buf, size_t len) |
20 | 67 { |
68 size_t done; | |
69 ssize_t result; | |
70 static unsigned write_errors = 0; | |
71 | |
22 | 72 if (!mode.do_output) { |
73 return; | |
74 } | |
75 | |
20 | 76 if (outputfd < 0) { |
77 output_open(); | |
78 } | |
79 | |
80 done = 0; | |
81 while (done < len) { | |
82 result = write(outputfd, buf+done, len-done); | |
83 if (result == -1) { | |
143 | 84 complain(NULL, "%s: write: %s", |
85 mode.output_file, strerror(errno)); | |
20 | 86 complain_failed(); |
87 write_errors++; | |
88 if (write_errors > 5) { | |
143 | 89 complain(NULL, "%s: giving up", |
90 mode.output_file); | |
20 | 91 die(); |
92 } | |
93 /* XXX is this really a good idea? */ | |
94 sleep(1); | |
95 } | |
96 done += (size_t)result; | |
97 } | |
98 } | |
99 | |
27 | 100 |
101 static | |
20 | 102 void |
103 | 103 filter_output(const char *buf, size_t len) |
21 | 104 { |
105 size_t pos, start; | |
81
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
106 bool inesc = false; |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
107 bool inquote = false; |
128
1cda505ddc78
Don't expand macros within character constants.
David A. Holland
parents:
103
diff
changeset
|
108 char quote = '\0'; |
21 | 109 |
110 start = 0; | |
111 for (pos = 0; pos < len - 1; pos++) { | |
81
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
112 if (!inquote && buf[pos] == '/' && buf[pos+1] == '*') { |
78
4cc1c575951f
No need to warn about nested comments twice.
David A. Holland
parents:
39
diff
changeset
|
113 if (!incomment) { |
21 | 114 if (pos > start) { |
115 dowrite(buf + start, pos - start); | |
116 } | |
117 start = pos; | |
118 pos += 2; | |
119 incomment = true; | |
120 /* cancel out the loop's pos++ */ | |
121 pos--; | |
122 continue; | |
123 } | |
124 } else if (buf[pos] == '*' && buf[pos+1] == '/') { | |
125 if (incomment) { | |
126 pos += 2; | |
127 if (mode.output_retain_comments) { | |
128 dowrite(buf + start, pos - start); | |
129 } | |
130 start = pos; | |
131 incomment = false; | |
132 /* cancel out the loop's pos++ */ | |
133 pos--; | |
134 continue; | |
135 } | |
136 } | |
81
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
137 |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
138 if (incomment) { |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
139 /* nothing */ |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
140 } else if (inesc) { |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
141 inesc = false; |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
142 } else if (buf[pos] == '\\') { |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
143 inesc = true; |
128
1cda505ddc78
Don't expand macros within character constants.
David A. Holland
parents:
103
diff
changeset
|
144 } else if (!inquote && (buf[pos] == '"' || buf[pos] == '\'')) { |
1cda505ddc78
Don't expand macros within character constants.
David A. Holland
parents:
103
diff
changeset
|
145 inquote = true; |
1cda505ddc78
Don't expand macros within character constants.
David A. Holland
parents:
103
diff
changeset
|
146 quote = buf[pos]; |
1cda505ddc78
Don't expand macros within character constants.
David A. Holland
parents:
103
diff
changeset
|
147 } else if (inquote && buf[pos] == quote) { |
1cda505ddc78
Don't expand macros within character constants.
David A. Holland
parents:
103
diff
changeset
|
148 inquote = false; |
81
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
149 } |
21 | 150 } |
24 | 151 pos++; |
152 | |
153 if (pos > start) { | |
154 if (!incomment || mode.output_retain_comments) { | |
155 dowrite(buf + start, pos - start); | |
156 } | |
157 } | |
21 | 158 } |
159 | |
160 void | |
27 | 161 output(const struct place *p, const char *buf, size_t len) |
162 { | |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
30
diff
changeset
|
163 size_t oldmax; |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
30
diff
changeset
|
164 |
27 | 165 if (linebufpos + len > linebufmax) { |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
30
diff
changeset
|
166 oldmax = linebufmax; |
27 | 167 if (linebufmax == 0) { |
168 linebufmax = 64; | |
169 } | |
170 while (linebufpos + len > linebufmax) { | |
171 linebufmax *= 2; | |
172 } | |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
30
diff
changeset
|
173 linebuf = dorealloc(linebuf, oldmax, linebufmax); |
27 | 174 } |
175 if (linebufpos == 0) { | |
185
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
143
diff
changeset
|
176 if (!place_samefile(&linebufplace, p)) { |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
143
diff
changeset
|
177 if (mode.output_cheaplinenumbers) { |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
143
diff
changeset
|
178 char str[256]; |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
143
diff
changeset
|
179 |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
143
diff
changeset
|
180 snprintf(str, sizeof(str), "# %u \"%s\"\n", |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
143
diff
changeset
|
181 p->line, place_getname(p)); |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
143
diff
changeset
|
182 dowrite(str, strlen(str)); |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
143
diff
changeset
|
183 } |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
143
diff
changeset
|
184 } |
27 | 185 linebufplace = *p; |
186 } | |
187 memcpy(linebuf + linebufpos, buf, len); | |
188 linebufpos += len; | |
189 | |
190 if (len == 1 && buf[0] == '\n') { | |
103 | 191 filter_output(linebuf, linebufpos); |
27 | 192 linebufpos = 0; |
193 } | |
194 } | |
195 | |
196 void | |
20 | 197 output_eof(void) |
198 { | |
24 | 199 if (mode.output_file != NULL && outputfd >= 0) { |
20 | 200 close(outputfd); |
201 } | |
202 outputfd = -1; | |
203 } |