summaryrefslogblamecommitdiffstats
path: root/devtools/clean-c.c
blob: 2f56087582ac3a1a0b7ad84634ac00eb69f435b1 (plain) (tree)



























































































                                                                                           
/* 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;
}