summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2012-02-06 10:23:11 +0000
committered <ed@FreeBSD.org>2012-02-06 10:23:11 +0000
commite6c6bd0894f3f6ef50583bcc692f09967d523649 (patch)
treed40be7b98bb23310a74364400a35fac1c468adf2 /tools
parent4c30dca03ce0adfe9afe16c9874c62ff034f244d (diff)
downloadFreeBSD-src-e6c6bd0894f3f6ef50583bcc692f09967d523649.zip
FreeBSD-src-e6c6bd0894f3f6ef50583bcc692f09967d523649.tar.gz
Add fixwhite(1).
This small utility can be used to `sanitize' the whitespace in source code. It does the following things: Global: - Remove empty lines at the beginning and the end of a file. - Merge successive empty lines into a single empty line. Per-line: - Remove trailing whitespace. - Merge spaces preceeding tabs into the tabs. It operated on stdin/stdout. This means that if you use vi(1), you can just run :%!fixwhite to reorganize the file.
Diffstat (limited to 'tools')
-rw-r--r--tools/tools/fixwhite/Makefile7
-rw-r--r--tools/tools/fixwhite/fixwhite.146
-rw-r--r--tools/tools/fixwhite/fixwhite.c167
3 files changed, 220 insertions, 0 deletions
diff --git a/tools/tools/fixwhite/Makefile b/tools/tools/fixwhite/Makefile
new file mode 100644
index 0000000..dbaabc2
--- /dev/null
+++ b/tools/tools/fixwhite/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+PROG= fixwhite
+BINDIR= /usr/bin
+WARNS= 6
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/fixwhite/fixwhite.1 b/tools/tools/fixwhite/fixwhite.1
new file mode 100644
index 0000000..852a390
--- /dev/null
+++ b/tools/tools/fixwhite/fixwhite.1
@@ -0,0 +1,46 @@
+.\" Copyright (c) 2012 Ed Schouten <ed@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 6, 2012
+.Dt FIXWHITE 1
+.Os
+.Sh NAME
+.Nm fixwhite
+.Nd remove unneeded whitespace from text files
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+The
+.Nm
+utility removes unneeded whitespace from text passed to standard input
+and prints the result to standard output.
+.Pp
+It removes leading and trailing empty lines from the input, as well as
+trailing whitespace characters from ever line of text.
+Multiple successive empty lines are merged together.
+Also, spaces preceeding tabs will be merged into the tab character.
+.Sh AUTHORS
+.An Ed Schouten Aq ed@FreeBSD.org
diff --git a/tools/tools/fixwhite/fixwhite.c b/tools/tools/fixwhite/fixwhite.c
new file mode 100644
index 0000000..276ae2e
--- /dev/null
+++ b/tools/tools/fixwhite/fixwhite.c
@@ -0,0 +1,167 @@
+/*-
+ * Copyright (c) 2012 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static char *queue = NULL;
+static size_t queuelen = 0, queuesize = 0;
+static off_t column = 0;
+
+static void
+savebyte(char c)
+{
+
+ if (queuelen >= queuesize) {
+ queuesize += 128;
+ queue = realloc(queue, queuesize);
+ if (queue == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+ }
+ queue[queuelen++] = c;
+
+ switch (c) {
+ case '\n':
+ column = 0;
+ break;
+ case ' ':
+ column++;
+ break;
+ case '\t':
+ column = (column / 8 + 1) * 8;
+ break;
+ }
+}
+
+static bool
+peekbyte(size_t back, char c)
+{
+
+ return (queuelen >= back && queue[queuelen - back] == c);
+}
+
+static void
+savewhite(char c, bool leading)
+{
+ off_t ncolumn;
+
+ switch (c) {
+ case '\n':
+ if (leading) {
+ /* Remove empty lines before input. */
+ queuelen = 0;
+ column = 0;
+ } else {
+ /* Remove trailing whitespace. */
+ while (peekbyte(1, ' ') || peekbyte(1, '\t'))
+ queuelen--;
+ /* Remove redundant empty lines. */
+ if (peekbyte(2, '\n') && peekbyte(1, '\n'))
+ return;
+ savebyte('\n');
+ }
+ break;
+ case ' ':
+ savebyte(' ');
+ break;
+ case '\t':
+ /* Convert preceeding spaces to tabs. */
+ ncolumn = (column / 8 + 1) * 8;
+ while (peekbyte(1, ' ')) {
+ queuelen--;
+ column--;
+ }
+ while (column < ncolumn)
+ savebyte('\t');
+ break;
+ }
+}
+
+static void
+printwhite(void)
+{
+
+ if (fwrite(queue, 1, queuelen, stdout) != queuelen) {
+ perror("write");
+ exit(1);
+ }
+ queuelen = 0;
+}
+
+static char
+readchar(void)
+{
+ int c;
+
+ c = getchar();
+ if (c == EOF && ferror(stdin)) {
+ perror("read");
+ exit(1);
+ }
+ return (c);
+}
+
+static void
+writechar(char c)
+{
+
+ if (putchar(c) == EOF) {
+ perror("write");
+ exit(1);
+ }
+ /* XXX: Multi-byte characters. */
+ column++;
+}
+
+int
+main(void)
+{
+ int c;
+ bool leading = true;
+
+ while ((c = readchar()) != EOF) {
+ if (isspace(c))
+ /* Save whitespace. */
+ savewhite(c, leading);
+ else {
+ /* Reprint whitespace and print regular character. */
+ printwhite();
+ writechar(c);
+ leading = false;
+ }
+ }
+ /* Terminate non-empty files with a newline. */
+ if (!leading)
+ writechar('\n');
+ return (0);
+}
OpenPOWER on IntegriCloud