diff options
Diffstat (limited to 'devtools/clean-c.c')
-rw-r--r-- | devtools/clean-c.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/devtools/clean-c.c b/devtools/clean-c.c new file mode 100644 index 0000000..2f56087 --- /dev/null +++ b/devtools/clean-c.c @@ -0,0 +1,92 @@ +/* See LICENSE file for copyright and license details. */ +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + + +static char quote = 0; +static char comment = 0; + +static size_t +clean(char *text, size_t len) +{ + char *w = text; + size_t off; + + for (off = 0; off < len; off++) { + if (comment == '/') { + if (text[off] == '\n') + comment = 0; + } else if (comment == '*') { + if (text[off] == '*' && off + 1 < len && text[off + 1] == '/') { + comment = 0; + off += 1; + } + } else { + *w++ = text[off]; + switch (text[off]) { + case '\"': + case '\'': + quote = quote == text[off] ? 0 : text[off]; + break; + + case '\\': + if (off + 1 < len) { + off++; + w -= !!quote; + *w++ = text[off] == '\n' ? ' ' : text[off]; + } + break; + + case '/': + if (off + 1 < len) { + if (text[off + 1] == '*' || text[off + 1] == '/') { + comment = text[off++ + 1]; + w[-1] = ' '; + } + } + break; + + default: + break; + } + } + } + + return (size_t)(w - text); +} + +int +main(int argc, char *argv[]) +{ + char buf[8 << 10]; + size_t size, off; + ssize_t r; + + (void) argc; + + for (;;) { + r = read(STDIN_FILENO, buf, sizeof(buf)); + if (r <= 0) { + if (!r) + break; + if (errno == EINTR) + continue; + perror(argv[0]); + return 1; + } + size = clean(buf, (size_t)r); + for (off = 0; off < size; off += (size_t)r) { + r = write(STDOUT_FILENO, &buf[off], size - off); + if (r <= 0) { + if (errno == EINTR) + continue; + perror(argv[0]); + return 1; + } + } + } + + return 0; +} |