annotate output.c @ 203:3a25180d3a5c

Abort on line numbering or column numbering overflow. Line numbers are limited to values that fit in "unsigned int". Also reject input lines longer than 2^32-1 characters. It seems reasonable to presume that any input that violates these constraints is someone screwing around and not a serious attempt to compile or preprocess anything useful. Done in response to n2129, but without getting into any of the silliness found there.
author David A. Holland
date Tue, 01 Aug 2017 14:51:04 -0400
parents 16b4451e34b8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
30
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
1 /*-
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
2 * Copyright (c) 2010 The NetBSD Foundation, Inc.
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
3 * All rights reserved.
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
4 *
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
5 * This code is derived from software contributed to The NetBSD Foundation
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
6 * by David A. Holland.
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
7 *
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
8 * Redistribution and use in source and binary forms, with or without
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
9 * modification, are permitted provided that the following conditions
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
10 * are met:
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
11 * 1. Redistributions of source code must retain the above copyright
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
12 * notice, this list of conditions and the following disclaimer.
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
13 * 2. Redistributions in binary form must reproduce the above copyright
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
14 * notice, this list of conditions and the following disclaimer in the
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
15 * documentation and/or other materials provided with the distribution.
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
16 *
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
27 * POSSIBILITY OF SUCH DAMAGE.
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
28 */
76c114899f63 copyrights
David A. Holland
parents: 27
diff changeset
29
185
16b4451e34b8 Add the ability to output line numbers, sort of.
David A. Holland
parents: 143
diff changeset
30 #include <stdio.h>
27
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
31 #include <string.h>
20
40748b097655 add output.
David A. Holland
parents:
diff changeset
32 #include <unistd.h>
40748b097655 add output.
David A. Holland
parents:
diff changeset
33 #include <fcntl.h>
143
ed45f2d8d3bc Don't use the <err.h> functions.
David A. Holland
parents: 128
diff changeset
34 #include <errno.h>
20
40748b097655 add output.
David A. Holland
parents:
diff changeset
35
40748b097655 add output.
David A. Holland
parents:
diff changeset
36 #include "utils.h"
40748b097655 add output.
David A. Holland
parents:
diff changeset
37 #include "mode.h"
21
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
38 #include "place.h"
20
40748b097655 add output.
David A. Holland
parents:
diff changeset
39 #include "output.h"
40748b097655 add output.
David A. Holland
parents:
diff changeset
40
40748b097655 add output.
David A. Holland
parents:
diff changeset
41 static int outputfd = -1;
21
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
42 static bool incomment = false;
27
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
43 static char *linebuf;
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
44 static size_t linebufpos, linebufmax;
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
45 static struct place linebufplace;
20
40748b097655 add output.
David A. Holland
parents:
diff changeset
46
40748b097655 add output.
David A. Holland
parents:
diff changeset
47 static
40748b097655 add output.
David A. Holland
parents:
diff changeset
48 void
40748b097655 add output.
David A. Holland
parents:
diff changeset
49 output_open(void)
40748b097655 add output.
David A. Holland
parents:
diff changeset
50 {
24
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
51 if (mode.output_file == NULL) {
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
52 outputfd = STDOUT_FILENO;
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
53 } else {
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
54 outputfd = open(mode.output_file, O_WRONLY|O_CREAT|O_TRUNC,
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
55 0664);
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
56 if (outputfd < 0) {
143
ed45f2d8d3bc Don't use the <err.h> functions.
David A. Holland
parents: 128
diff changeset
57 complain(NULL, "%s: %s",
ed45f2d8d3bc Don't use the <err.h> functions.
David A. Holland
parents: 128
diff changeset
58 mode.output_file, strerror(errno));
24
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
59 die();
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
60 }
20
40748b097655 add output.
David A. Holland
parents:
diff changeset
61 }
40748b097655 add output.
David A. Holland
parents:
diff changeset
62 }
40748b097655 add output.
David A. Holland
parents:
diff changeset
63
21
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
64 static
20
40748b097655 add output.
David A. Holland
parents:
diff changeset
65 void
21
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
66 dowrite(const char *buf, size_t len)
20
40748b097655 add output.
David A. Holland
parents:
diff changeset
67 {
40748b097655 add output.
David A. Holland
parents:
diff changeset
68 size_t done;
40748b097655 add output.
David A. Holland
parents:
diff changeset
69 ssize_t result;
40748b097655 add output.
David A. Holland
parents:
diff changeset
70 static unsigned write_errors = 0;
40748b097655 add output.
David A. Holland
parents:
diff changeset
71
22
cef2dc916269 honor mode.do_output
David A. Holland
parents: 21
diff changeset
72 if (!mode.do_output) {
cef2dc916269 honor mode.do_output
David A. Holland
parents: 21
diff changeset
73 return;
cef2dc916269 honor mode.do_output
David A. Holland
parents: 21
diff changeset
74 }
cef2dc916269 honor mode.do_output
David A. Holland
parents: 21
diff changeset
75
20
40748b097655 add output.
David A. Holland
parents:
diff changeset
76 if (outputfd < 0) {
40748b097655 add output.
David A. Holland
parents:
diff changeset
77 output_open();
40748b097655 add output.
David A. Holland
parents:
diff changeset
78 }
40748b097655 add output.
David A. Holland
parents:
diff changeset
79
40748b097655 add output.
David A. Holland
parents:
diff changeset
80 done = 0;
40748b097655 add output.
David A. Holland
parents:
diff changeset
81 while (done < len) {
40748b097655 add output.
David A. Holland
parents:
diff changeset
82 result = write(outputfd, buf+done, len-done);
40748b097655 add output.
David A. Holland
parents:
diff changeset
83 if (result == -1) {
143
ed45f2d8d3bc Don't use the <err.h> functions.
David A. Holland
parents: 128
diff changeset
84 complain(NULL, "%s: write: %s",
ed45f2d8d3bc Don't use the <err.h> functions.
David A. Holland
parents: 128
diff changeset
85 mode.output_file, strerror(errno));
20
40748b097655 add output.
David A. Holland
parents:
diff changeset
86 complain_failed();
40748b097655 add output.
David A. Holland
parents:
diff changeset
87 write_errors++;
40748b097655 add output.
David A. Holland
parents:
diff changeset
88 if (write_errors > 5) {
143
ed45f2d8d3bc Don't use the <err.h> functions.
David A. Holland
parents: 128
diff changeset
89 complain(NULL, "%s: giving up",
ed45f2d8d3bc Don't use the <err.h> functions.
David A. Holland
parents: 128
diff changeset
90 mode.output_file);
20
40748b097655 add output.
David A. Holland
parents:
diff changeset
91 die();
40748b097655 add output.
David A. Holland
parents:
diff changeset
92 }
40748b097655 add output.
David A. Holland
parents:
diff changeset
93 /* XXX is this really a good idea? */
40748b097655 add output.
David A. Holland
parents:
diff changeset
94 sleep(1);
40748b097655 add output.
David A. Holland
parents:
diff changeset
95 }
40748b097655 add output.
David A. Holland
parents:
diff changeset
96 done += (size_t)result;
40748b097655 add output.
David A. Holland
parents:
diff changeset
97 }
40748b097655 add output.
David A. Holland
parents:
diff changeset
98 }
40748b097655 add output.
David A. Holland
parents:
diff changeset
99
27
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
100
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
101 static
20
40748b097655 add output.
David A. Holland
parents:
diff changeset
102 void
103
343af355df1b Pass -Wunused.
David A. Holland
parents: 81
diff changeset
103 filter_output(const char *buf, size_t len)
21
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
104 {
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
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
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
109
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
110 start = 0;
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
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
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
114 if (pos > start) {
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
115 dowrite(buf + start, pos - start);
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
116 }
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
117 start = pos;
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
118 pos += 2;
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
119 incomment = true;
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
120 /* cancel out the loop's pos++ */
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
121 pos--;
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
122 continue;
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
123 }
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
124 } else if (buf[pos] == '*' && buf[pos+1] == '/') {
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
125 if (incomment) {
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
126 pos += 2;
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
127 if (mode.output_retain_comments) {
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
128 dowrite(buf + start, pos - start);
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
129 }
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
130 start = pos;
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
131 incomment = false;
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
132 /* cancel out the loop's pos++ */
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
133 pos--;
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
134 continue;
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
135 }
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
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
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
150 }
24
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
151 pos++;
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
152
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
153 if (pos > start) {
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
154 if (!incomment || mode.output_retain_comments) {
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
155 dowrite(buf + start, pos - start);
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
156 }
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
157 }
21
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
158 }
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
159
e3fab8f1b52c strip comments.
David A. Holland
parents: 20
diff changeset
160 void
27
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
161 output(const struct place *p, const char *buf, size_t len)
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
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
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
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
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
167 if (linebufmax == 0) {
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
168 linebufmax = 64;
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
169 }
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
170 while (linebufpos + len > linebufmax) {
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
171 linebufmax *= 2;
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
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
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
174 }
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
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
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
185 linebufplace = *p;
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
186 }
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
187 memcpy(linebuf + linebufpos, buf, len);
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
188 linebufpos += len;
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
189
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
190 if (len == 1 && buf[0] == '\n') {
103
343af355df1b Pass -Wunused.
David A. Holland
parents: 81
diff changeset
191 filter_output(linebuf, linebufpos);
27
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
192 linebufpos = 0;
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
193 }
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
194 }
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
195
01c3a2088ab4 fix some more bugs
David A. Holland
parents: 24
diff changeset
196 void
20
40748b097655 add output.
David A. Holland
parents:
diff changeset
197 output_eof(void)
40748b097655 add output.
David A. Holland
parents:
diff changeset
198 {
24
daa801fe719e fix some bugs
David A. Holland
parents: 22
diff changeset
199 if (mode.output_file != NULL && outputfd >= 0) {
20
40748b097655 add output.
David A. Holland
parents:
diff changeset
200 close(outputfd);
40748b097655 add output.
David A. Holland
parents:
diff changeset
201 }
40748b097655 add output.
David A. Holland
parents:
diff changeset
202 outputfd = -1;
40748b097655 add output.
David A. Holland
parents:
diff changeset
203 }