2 * Copyright (c) 2010 The NetBSD Foundation, Inc.
5 * This code is derived from software contributed to The NetBSD Foundation
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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.
41 static int outputfd = -1;
42 static bool incomment = false;
44 static size_t linebufpos, linebufmax;
45 static struct place linebufplace;
51 if (mode.output_file == NULL) {
52 outputfd = STDOUT_FILENO;
54 outputfd = open(mode.output_file, O_WRONLY|O_CREAT|O_TRUNC,
57 complain(NULL, "%s: %s",
58 mode.output_file, strerror(errno));
66 dowrite(const char *buf, size_t len)
70 static unsigned write_errors = 0;
72 if (!mode.do_output) {
82 result = write(outputfd, buf+done, len-done);
84 complain(NULL, "%s: write: %s",
85 mode.output_file, strerror(errno));
88 if (write_errors > 5) {
89 complain(NULL, "%s: giving up",
93 /* XXX is this really a good idea? */
96 done += (size_t)result;
103 filter_output(const char *buf, size_t len)
107 bool inquote = false;
111 for (pos = 0; pos < len - 1; pos++) {
112 if (!inquote && buf[pos] == '/' && buf[pos+1] == '*') {
115 dowrite(buf + start, pos - start);
120 /* cancel out the loop's pos++ */
124 } else if (buf[pos] == '*' && buf[pos+1] == '/') {
127 if (mode.output_retain_comments) {
128 dowrite(buf + start, pos - start);
132 /* cancel out the loop's pos++ */
142 } else if (buf[pos] == '\\') {
144 } else if (!inquote && (buf[pos] == '"' || buf[pos] == '\'')) {
147 } else if (inquote && buf[pos] == quote) {
154 if (!incomment || mode.output_retain_comments) {
155 dowrite(buf + start, pos - start);
161 output(const struct place *p, const char *buf, size_t len)
165 if (linebufpos + len > linebufmax) {
167 if (linebufmax == 0) {
170 while (linebufpos + len > linebufmax) {
173 linebuf = dorealloc(linebuf, oldmax, linebufmax);
175 if (linebufpos == 0) {
176 if (!place_samefile(&linebufplace, p)) {
177 if (mode.output_cheaplinenumbers) {
180 snprintf(str, sizeof(str), "# %u \"%s\"\n",
181 p->line, place_getname(p));
182 dowrite(str, strlen(str));
187 memcpy(linebuf + linebufpos, buf, len);
190 if (len == 1 && buf[0] == '\n') {
191 filter_output(linebuf, linebufpos);
199 if (mode.output_file != NULL && outputfd >= 0) {