20
|
1 #include <unistd.h>
|
|
2 #include <fcntl.h>
|
|
3 #include <err.h>
|
|
4
|
|
5 #include "utils.h"
|
|
6 #include "mode.h"
|
21
|
7 #include "place.h"
|
20
|
8 #include "output.h"
|
|
9
|
|
10 static int outputfd = -1;
|
21
|
11 static bool incomment = false;
|
20
|
12
|
|
13 static
|
|
14 void
|
|
15 output_open(void)
|
|
16 {
|
|
17 outputfd = open(mode.output_file, O_WRONLY|O_CREAT|O_TRUNC, 0664);
|
|
18 if (outputfd < 0) {
|
|
19 warn("%s", mode.output_file);
|
|
20 die();
|
|
21 }
|
|
22 }
|
|
23
|
21
|
24 static
|
20
|
25 void
|
21
|
26 dowrite(const char *buf, size_t len)
|
20
|
27 {
|
|
28 size_t done;
|
|
29 ssize_t result;
|
|
30 static unsigned write_errors = 0;
|
|
31
|
|
32 if (outputfd < 0) {
|
|
33 output_open();
|
|
34 }
|
|
35
|
|
36 /* XXX this will often come by ones and twos, should buffer */
|
|
37
|
|
38 done = 0;
|
|
39 while (done < len) {
|
|
40 result = write(outputfd, buf+done, len-done);
|
|
41 if (result == -1) {
|
|
42 warn("%s: write", mode.output_file);
|
|
43 complain_failed();
|
|
44 write_errors++;
|
|
45 if (write_errors > 5) {
|
|
46 warnx("%s: giving up", mode.output_file);
|
|
47 die();
|
|
48 }
|
|
49 /* XXX is this really a good idea? */
|
|
50 sleep(1);
|
|
51 }
|
|
52 done += (size_t)result;
|
|
53 }
|
|
54 }
|
|
55
|
|
56 void
|
21
|
57 output(const struct place *p, const char *buf, size_t len)
|
|
58 {
|
|
59 size_t pos, start;
|
|
60 struct place p2;
|
|
61
|
|
62 start = 0;
|
|
63 for (pos = 0; pos < len - 1; pos++) {
|
|
64 if (buf[pos] == '/' && buf[pos+1] == '*') {
|
|
65 if (incomment && warns.nestcomment) {
|
|
66 p2 = *p;
|
|
67 p2.column += pos;
|
|
68 complain(p, "Warning: %c%c within comment",
|
|
69 '/', '*');
|
|
70 if (mode.werror) {
|
|
71 complain_failed();
|
|
72 }
|
|
73 } else if (!incomment) {
|
|
74 if (pos > start) {
|
|
75 dowrite(buf + start, pos - start);
|
|
76 }
|
|
77 start = pos;
|
|
78 pos += 2;
|
|
79 incomment = true;
|
|
80 /* cancel out the loop's pos++ */
|
|
81 pos--;
|
|
82 continue;
|
|
83 }
|
|
84 } else if (buf[pos] == '*' && buf[pos+1] == '/') {
|
|
85 if (incomment) {
|
|
86 pos += 2;
|
|
87 if (mode.output_retain_comments) {
|
|
88 dowrite(buf + start, pos - start);
|
|
89 }
|
|
90 start = pos;
|
|
91 pos += 2;
|
|
92 incomment = false;
|
|
93 /* cancel out the loop's pos++ */
|
|
94 pos--;
|
|
95 continue;
|
|
96 }
|
|
97 }
|
|
98 }
|
|
99 }
|
|
100
|
|
101 void
|
20
|
102 output_eof(void)
|
|
103 {
|
|
104 if (outputfd >= 0) {
|
|
105 close(outputfd);
|
|
106 }
|
|
107 outputfd = -1;
|
|
108 }
|