Author: ed
Date: Mon Feb  6 10:23:11 2012
New Revision: 231071
URL: http://svn.freebsd.org/changeset/base/231071

Log:
  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.

Added:
  head/tools/tools/fixwhite/
  head/tools/tools/fixwhite/Makefile   (contents, props changed)
  head/tools/tools/fixwhite/fixwhite.1   (contents, props changed)
  head/tools/tools/fixwhite/fixwhite.c   (contents, props changed)

Added: head/tools/tools/fixwhite/Makefile
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tools/tools/fixwhite/Makefile  Mon Feb  6 10:23:11 2012        
(r231071)
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+PROG=  fixwhite
+BINDIR=        /usr/bin
+WARNS= 6
+
+.include <bsd.prog.mk>

Added: head/tools/tools/fixwhite/fixwhite.1
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tools/tools/fixwhite/fixwhite.1        Mon Feb  6 10:23:11 2012        
(r231071)
@@ -0,0 +1,46 @@
+.\" Copyright (c) 2012 Ed Schouten <e...@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 e...@freebsd.org

Added: head/tools/tools/fixwhite/fixwhite.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tools/tools/fixwhite/fixwhite.c        Mon Feb  6 10:23:11 2012        
(r231071)
@@ -0,0 +1,167 @@
+/*-
+ * Copyright (c) 2012 Ed Schouten <e...@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);
+}
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to