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
|
22
|
32 if (!mode.do_output) {
|
|
33 return;
|
|
34 }
|
|
35
|
20
|
36 if (outputfd < 0) {
|
|
37 output_open();
|
|
38 }
|
|
39
|
|
40 /* XXX this will often come by ones and twos, should buffer */
|
|
41
|
|
42 done = 0;
|
|
43 while (done < len) {
|
|
44 result = write(outputfd, buf+done, len-done);
|
|
45 if (result == -1) {
|
|
46 warn("%s: write", mode.output_file);
|
|
47 complain_failed();
|
|
48 write_errors++;
|
|
49 if (write_errors > 5) {
|
|
50 warnx("%s: giving up", mode.output_file);
|
|
51 die();
|
|
52 }
|
|
53 /* XXX is this really a good idea? */
|
|
54 sleep(1);
|
|
55 }
|
|
56 done += (size_t)result;
|
|
57 }
|
|
58 }
|
|
59
|
|
60 void
|
21
|
61 output(const struct place *p, const char *buf, size_t len)
|
|
62 {
|
|
63 size_t pos, start;
|
|
64 struct place p2;
|
|
65
|
|
66 start = 0;
|
|
67 for (pos = 0; pos < len - 1; pos++) {
|
|
68 if (buf[pos] == '/' && buf[pos+1] == '*') {
|
|
69 if (incomment && warns.nestcomment) {
|
|
70 p2 = *p;
|
|
71 p2.column += pos;
|
|
72 complain(p, "Warning: %c%c within comment",
|
|
73 '/', '*');
|
|
74 if (mode.werror) {
|
|
75 complain_failed();
|
|
76 }
|
|
77 } else if (!incomment) {
|
|
78 if (pos > start) {
|
|
79 dowrite(buf + start, pos - start);
|
|
80 }
|
|
81 start = pos;
|
|
82 pos += 2;
|
|
83 incomment = true;
|
|
84 /* cancel out the loop's pos++ */
|
|
85 pos--;
|
|
86 continue;
|
|
87 }
|
|
88 } else if (buf[pos] == '*' && buf[pos+1] == '/') {
|
|
89 if (incomment) {
|
|
90 pos += 2;
|
|
91 if (mode.output_retain_comments) {
|
|
92 dowrite(buf + start, pos - start);
|
|
93 }
|
|
94 start = pos;
|
|
95 pos += 2;
|
|
96 incomment = false;
|
|
97 /* cancel out the loop's pos++ */
|
|
98 pos--;
|
|
99 continue;
|
|
100 }
|
|
101 }
|
|
102 }
|
|
103 }
|
|
104
|
|
105 void
|
20
|
106 output_eof(void)
|
|
107 {
|
|
108 if (outputfd >= 0) {
|
|
109 close(outputfd);
|
|
110 }
|
|
111 outputfd = -1;
|
|
112 }
|