Mercurial > ~dholland > hg > tradcpp > index.cgi
view output.c @ 27:01c3a2088ab4
fix some more bugs
author | David A. Holland |
---|---|
date | Mon, 20 Dec 2010 05:01:18 -0500 |
parents | daa801fe719e |
children | 76c114899f63 |
line wrap: on
line source
#include <string.h> #include <unistd.h> #include <fcntl.h> #include <err.h> #include "utils.h" #include "mode.h" #include "place.h" #include "output.h" static int outputfd = -1; static bool incomment = false; static char *linebuf; static size_t linebufpos, linebufmax; static struct place linebufplace; static void output_open(void) { if (mode.output_file == NULL) { outputfd = STDOUT_FILENO; } else { outputfd = open(mode.output_file, O_WRONLY|O_CREAT|O_TRUNC, 0664); if (outputfd < 0) { warn("%s", mode.output_file); die(); } } } static void dowrite(const char *buf, size_t len) { size_t done; ssize_t result; static unsigned write_errors = 0; if (!mode.do_output) { return; } if (outputfd < 0) { output_open(); } done = 0; while (done < len) { result = write(outputfd, buf+done, len-done); if (result == -1) { warn("%s: write", mode.output_file); complain_failed(); write_errors++; if (write_errors > 5) { warnx("%s: giving up", mode.output_file); die(); } /* XXX is this really a good idea? */ sleep(1); } done += (size_t)result; } } static void filter_output(const struct place *p, const char *buf, size_t len) { size_t pos, start; struct place p2; start = 0; for (pos = 0; pos < len - 1; pos++) { if (buf[pos] == '/' && buf[pos+1] == '*') { if (incomment && warns.nestcomment) { p2 = *p; p2.column += pos; complain(p, "Warning: %c%c within comment", '/', '*'); if (mode.werror) { complain_failed(); } } else if (!incomment) { if (pos > start) { dowrite(buf + start, pos - start); } start = pos; pos += 2; incomment = true; /* cancel out the loop's pos++ */ pos--; continue; } } else if (buf[pos] == '*' && buf[pos+1] == '/') { if (incomment) { pos += 2; if (mode.output_retain_comments) { dowrite(buf + start, pos - start); } start = pos; incomment = false; /* cancel out the loop's pos++ */ pos--; continue; } } } pos++; if (pos > start) { if (!incomment || mode.output_retain_comments) { dowrite(buf + start, pos - start); } } } void output(const struct place *p, const char *buf, size_t len) { if (linebufpos + len > linebufmax) { if (linebufmax == 0) { linebufmax = 64; } while (linebufpos + len > linebufmax) { linebufmax *= 2; } linebuf = dorealloc(linebuf, linebufmax); } if (linebufpos == 0) { linebufplace = *p; } memcpy(linebuf + linebufpos, buf, len); linebufpos += len; if (len == 1 && buf[0] == '\n') { filter_output(&linebufplace, linebuf, linebufpos); linebufpos = 0; } } void output_eof(void) { if (mode.output_file != NULL && outputfd >= 0) { close(outputfd); } outputfd = -1; }