Mercurial > ~dholland > hg > tradcpp > index.cgi
annotate output.c @ 108:0921c47b4f22
C99INLINE, not __c99inline
author | David A. Holland |
---|---|
date | Tue, 11 Jun 2013 12:17:27 -0400 |
parents | 343af355df1b |
children | 1cda505ddc78 |
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 | |
27 | 30 #include <string.h> |
20 | 31 #include <unistd.h> |
32 #include <fcntl.h> | |
33 #include <err.h> | |
34 | |
35 #include "utils.h" | |
36 #include "mode.h" | |
21 | 37 #include "place.h" |
20 | 38 #include "output.h" |
39 | |
40 static int outputfd = -1; | |
21 | 41 static bool incomment = false; |
27 | 42 static char *linebuf; |
43 static size_t linebufpos, linebufmax; | |
44 static struct place linebufplace; | |
20 | 45 |
46 static | |
47 void | |
48 output_open(void) | |
49 { | |
24 | 50 if (mode.output_file == NULL) { |
51 outputfd = STDOUT_FILENO; | |
52 } else { | |
53 outputfd = open(mode.output_file, O_WRONLY|O_CREAT|O_TRUNC, | |
54 0664); | |
55 if (outputfd < 0) { | |
56 warn("%s", mode.output_file); | |
57 die(); | |
58 } | |
20 | 59 } |
60 } | |
61 | |
21 | 62 static |
20 | 63 void |
21 | 64 dowrite(const char *buf, size_t len) |
20 | 65 { |
66 size_t done; | |
67 ssize_t result; | |
68 static unsigned write_errors = 0; | |
69 | |
22 | 70 if (!mode.do_output) { |
71 return; | |
72 } | |
73 | |
20 | 74 if (outputfd < 0) { |
75 output_open(); | |
76 } | |
77 | |
78 done = 0; | |
79 while (done < len) { | |
80 result = write(outputfd, buf+done, len-done); | |
81 if (result == -1) { | |
82 warn("%s: write", mode.output_file); | |
83 complain_failed(); | |
84 write_errors++; | |
85 if (write_errors > 5) { | |
86 warnx("%s: giving up", mode.output_file); | |
87 die(); | |
88 } | |
89 /* XXX is this really a good idea? */ | |
90 sleep(1); | |
91 } | |
92 done += (size_t)result; | |
93 } | |
94 } | |
95 | |
27 | 96 |
97 static | |
20 | 98 void |
103 | 99 filter_output(const char *buf, size_t len) |
21 | 100 { |
101 size_t pos, start; | |
81
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
102 bool inesc = false; |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
103 bool inquote = false; |
21 | 104 |
105 start = 0; | |
106 for (pos = 0; pos < len - 1; pos++) { | |
81
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
107 if (!inquote && buf[pos] == '/' && buf[pos+1] == '*') { |
78
4cc1c575951f
No need to warn about nested comments twice.
David A. Holland
parents:
39
diff
changeset
|
108 if (!incomment) { |
21 | 109 if (pos > start) { |
110 dowrite(buf + start, pos - start); | |
111 } | |
112 start = pos; | |
113 pos += 2; | |
114 incomment = true; | |
115 /* cancel out the loop's pos++ */ | |
116 pos--; | |
117 continue; | |
118 } | |
119 } else if (buf[pos] == '*' && buf[pos+1] == '/') { | |
120 if (incomment) { | |
121 pos += 2; | |
122 if (mode.output_retain_comments) { | |
123 dowrite(buf + start, pos - start); | |
124 } | |
125 start = pos; | |
126 incomment = false; | |
127 /* cancel out the loop's pos++ */ | |
128 pos--; | |
129 continue; | |
130 } | |
131 } | |
81
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
132 |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
133 if (incomment) { |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
134 /* nothing */ |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
135 } else if (inesc) { |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
136 inesc = false; |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
137 } else if (buf[pos] == '\\') { |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
138 inesc = true; |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
139 } else if (buf[pos] == '"') { |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
140 inquote = !inquote; |
27c9aafcaca1
Don't recognize comments within double-quote strings.
David A. Holland
parents:
78
diff
changeset
|
141 } |
21 | 142 } |
24 | 143 pos++; |
144 | |
145 if (pos > start) { | |
146 if (!incomment || mode.output_retain_comments) { | |
147 dowrite(buf + start, pos - start); | |
148 } | |
149 } | |
21 | 150 } |
151 | |
152 void | |
27 | 153 output(const struct place *p, const char *buf, size_t len) |
154 { | |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
30
diff
changeset
|
155 size_t oldmax; |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
30
diff
changeset
|
156 |
27 | 157 if (linebufpos + len > linebufmax) { |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
30
diff
changeset
|
158 oldmax = linebufmax; |
27 | 159 if (linebufmax == 0) { |
160 linebufmax = 64; | |
161 } | |
162 while (linebufpos + len > linebufmax) { | |
163 linebufmax *= 2; | |
164 } | |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
30
diff
changeset
|
165 linebuf = dorealloc(linebuf, oldmax, linebufmax); |
27 | 166 } |
167 if (linebufpos == 0) { | |
168 linebufplace = *p; | |
169 } | |
170 memcpy(linebuf + linebufpos, buf, len); | |
171 linebufpos += len; | |
172 | |
173 if (len == 1 && buf[0] == '\n') { | |
103 | 174 filter_output(linebuf, linebufpos); |
27 | 175 linebufpos = 0; |
176 } | |
177 } | |
178 | |
179 void | |
20 | 180 output_eof(void) |
181 { | |
24 | 182 if (mode.output_file != NULL && outputfd >= 0) { |
20 | 183 close(outputfd); |
184 } | |
185 outputfd = -1; | |
186 } |