Mercurial > ~dholland > hg > tradcpp > index.cgi
view output.c @ 22:cef2dc916269
honor mode.do_output
author | David A. Holland |
---|---|
date | Mon, 20 Dec 2010 04:17:32 -0500 |
parents | e3fab8f1b52c |
children | daa801fe719e |
line wrap: on
line source
#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 void output_open(void) { 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(); } /* XXX this will often come by ones and twos, should buffer */ 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; } } void 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; pos += 2; incomment = false; /* cancel out the loop's pos++ */ pos--; continue; } } } } void output_eof(void) { if (outputfd >= 0) { close(outputfd); } outputfd = -1; }