chiark / gitweb /
space.c, space.1: New `-l' option to handle trailing blank lines.
authorMark Wooding <mdw@distorted.org.uk>
Wed, 14 Nov 2012 00:56:24 +0000 (00:56 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Wed, 14 Nov 2012 00:56:24 +0000 (00:56 +0000)
space.1
space.c

diff --git a/space.1 b/space.1
index 7d6c2e2571d6a754563c6ff00e4624dc2876a6f7..d1dc55a8328ef6533c720eadfa7e32600dc2a466 100644 (file)
--- a/space.1
+++ b/space.1
@@ -10,7 +10,7 @@
 space \- check and fix whitespace in files
 .SH SYNOPSIS
 .B space
-.RB [ \-cmtuv ]
+.RB [ \-clmtuv ]
 .RB [ \-i \c
 .RI [ backup ]]
 .RI [ file ...]
@@ -31,6 +31,9 @@ files.  In particular, it will notice and (if you want) fix
 .BR diff (1)
 not least;
 .hP \*o
+.I trailing blank lines
+\(en which some editors, notably Emacs, introduce by default;
+.hP \*o
 .I groups of spaces which could be replaced by tabs
 \(en replacing them with the appropriate tab characters; or
 .hP \*o
@@ -54,6 +57,14 @@ option with this; without it,
 .B space
 is silent.
 .TP
+.B \-l
+Check the file for trailing blank lines, i.e., lines containing only
+horizontal whitespace.  With
+.BR \-v ,
+report if the file has trailing blank lines; without
+.BR \-c ,
+remove these trailing blank lines from the output.
+.TP
 .BR \-i [ \fIbackup ]
 Modify all the
 .IR file s
diff --git a/space.c b/space.c
index 73fb3a770b492c85c9a91d01661fc61e4404e548..e9fa0dfacb4707456cf901c40ff7366d4d88ae8d 100644 (file)
--- a/space.c
+++ b/space.c
@@ -29,9 +29,10 @@ static unsigned flags = 0;
 #define F_UNTABIFY 16u
 #define F_TABIFY 32u
 #define F_VERBOSE 64u
+#define F_TBLANK 128u
 
 static void usage(FILE *fp)
-  { fprintf(fp, "Usage: %s [-cmtuv] [-i[BKP]] [FILE...]\n\n", ego); }
+  { fprintf(fp, "Usage: %s [-clmtuv] [-i[BKP]] [FILE...]\n\n", ego); }
 
 static char *augment(const char *name, const char *suffix)
 {
@@ -135,7 +136,8 @@ static int space(const char *name)
   char *newname = 0, *oldname = 0;
   int rc = TROUBLE, status = OK;
   int last = '\n';
-  unsigned nsp = 0, nwsp = 0, hpos = 0, ohpos = 0, nhpos = 0, nl = 1;
+  unsigned nsp = 0, nwsp = 0, nnl = 0;
+  unsigned hpos = 0, ohpos = 0, nhpos = 0, nl = 1;
   unsigned i;
 #define f_newline 1u
 #define f_warnspacetab 2u
@@ -145,7 +147,8 @@ static int space(const char *name)
 #define f_tab 32u
 #define f_bad 64u
 #define f_forced 128u
-  unsigned f = f_newline | (flags & F_TABIFY ? f_tabify : 0);
+#define f_begin 256u
+  unsigned f = f_newline | f_begin | (flags & F_TABIFY ? f_tabify : 0);
   int ch;
 
   if (strcmp(name, "-") == 0) {
@@ -201,11 +204,23 @@ static int space(const char *name)
        if (put(&b, '\t')) goto done_2;
        break;
       case EOF:
-       if (nwsp || !(f & f_newline)) {
-         if (flags & F_VERBOSE)
-           fprintf(stderr, "%s:%u: file ends in mid-line\n", name, nl);
-         status = BADNESS;
-         if (fout) putc('\n', fout);
+       if (!(f & f_begin)) {
+         if (!(f & f_newline)) {
+           if (flags & F_VERBOSE)
+             fprintf(stderr, "%s:%u: file ends in mid-line\n", name, nl);
+           status = BADNESS;
+           nnl = 1;
+         } else if (nnl > 1) {
+           if (flags & F_TBLANK) {
+             if (flags & F_VERBOSE) {
+               fprintf(stderr, "%s:%u: file has trailing blank lines\n",
+                       name, nl - nnl + 1);
+             }
+             status = BADNESS;
+             nnl = 1;
+           }
+         }
+         if (fout) while (nnl--) putc('\n', fout);
        }
        goto end;
       case '\n':
@@ -215,9 +230,14 @@ static int space(const char *name)
            fprintf(stderr, "%s:%u: trailing whitespace\n", name, nl);
          status = BADNESS;
        }
-       if (fout) putc('\n', fout);
        reset(&b);
        nsp = nwsp = hpos = ohpos = 0; nl++;
+       if (ch == '\n')
+         nnl++;
+       else if (fout) {
+         while (nnl) { putc('\n', fout); nnl--; }
+         putc(ch, fout);
+       }
        f |= f_newline;
        f &= ~(f_tab | f_warnspacetab | f_warntabs | f_warnspaces);
        if (flags & F_TABIFY)
@@ -227,6 +247,7 @@ static int space(const char *name)
        last = '\n';
        break;
       default:
+       if (fout) while (nnl) { putc('\n', fout); nnl--; }
        if (nwsp) {
          if (flags & F_UNTABIFY) {
            if (fout) for (; ohpos < hpos; ohpos++) putc(' ', fout);
@@ -264,6 +285,7 @@ static int space(const char *name)
          last = ch;
        break;
     }
+    f &= ~f_begin;
   }
 end:;
 
@@ -330,7 +352,7 @@ int main(int argc, char *argv[])
     ego++;
 
   for (;;) {
-    if ((i = getopt(argc, argv, "h" "cmtuv" "i::")) < 0)
+    if ((i = getopt(argc, argv, "h" "clmtuv" "i::")) < 0)
       break;
     switch (i) {
       case 'h':
@@ -339,6 +361,7 @@ int main(int argc, char *argv[])
        fputs("Options:\n\
   -h           Print this help text\n\
   -c           Check files for badness, but don't produce other output\n\
+  -l           Check for, and/or remove, trailing blank lines\n\
   -m           Fix spaces followed by tabs in mid-line\n\
   -t           Tabify file completely\n\
   -u           Untabify file completely\n\
@@ -355,6 +378,9 @@ int main(int argc, char *argv[])
       case 'c':
        flags |= F_CHECK;
        break;
+      case 'l':
+       flags |= F_TBLANK;
+       break;
       case 't':
        flags |= F_TABIFY;
        break;