1BSD/s6/fix.c
#
/*
* fix - fix up data
*
* Author: Kurt Shoens UCB July, 1977
*
* Fix reads the concatenation of the files presented to
* it and transcribes them to the standard output with unprintable
* characters removed. A report of the bad characters found is put
* on the diagnostic output stream if desired. The options of this
* program are as follows:
*
* fix [ -crnhfqblo ] file ...
* c carriage returns (015) are illegal
* r a report is put on diagnostic output
* n no output is put on standard output (report only)
* h erase processing is done on control-h's
* f form feeds (014) are illegal
* q given multiple files, this suppresses printing of file name
* on report lines
* l line numbers are printed on report lines.
* o bad characters are printed in octal instead of as ?'s
*
* The n, l, and o flags turn on the r flag.
*/
#define CLEAN 1
#define REPORT 2
#define CTLH 4
#define CRILL 8
#define FFILL 16
#define VERBOSE 32
#define BELLILL 64
#define LNO 128
#define OCTAL 256
char buf[512],wbuf[512],*nxtchar;
int wcount,avail,eof,errs,linenum;
int FLAGS;
extern int fout;
main(argc,argv)
char **argv;
{
register fd;
register char *cp;
FLAGS = CLEAN | VERBOSE;
if (*argv[1] == '-')
{
cp = *++argv;
++cp;
--argc;
while (*cp)
{
switch (*cp)
{
case 'c':
FLAGS =| CRILL;
break;
case 'r':
FLAGS =| REPORT;
break;
case 'n':
FLAGS =& ~CLEAN;
FLAGS =| REPORT;
break;
case 'h':
FLAGS =| CTLH;
break;
case 'f':
FLAGS =| FFILL;
break;
case 'q':
FLAGS =& ~VERBOSE;
break;
case 'b':
FLAGS =| BELLILL;
break;
case 'l':
FLAGS =| LNO | REPORT;
break;
case 'o':
FLAGS =| OCTAL|REPORT;
break;
default:
prs("Usage: fix [ -crnhfqblo ] [ file ... ]\n");
errs++;
exit(errs);
}
++cp;
}
}
if (errs) exit(errs);
if (argc == 1)
{
FLAGS =& ~VERBOSE;
linenum = 0;
eof = 0;
fix(0,"standard input");
flushout();
exit(errs);
}
if (argc == 2) FLAGS =& ~VERBOSE;
while (--argc)
{
fd = open(*++argv,0);
if (fd < 0)
{
perror(*argv);
errs++;
continue;
}
nxtchar = buf + 512;
eof = 0;
avail = 0;
linenum = 0;
fix(fd,*argv);
close(fd);
}
flushout();
}
fix(f,file)
char *file;
{
char line[512],*cp,ch;
int count;
while (!eof)
{
ch = bread(f);
count = 0;
cp = line;
while (ch != 012 && ch != 015 && !eof && count < 512)
{
*cp++ = ch;
count++;
ch = bread(f);
}
++linenum;
if (count >= 512)
{
prs("Line too long.\n");
while (ch != 012 && ch != 015 && !eof) ch = bread(f);
++errs;
}
*cp = 0;
if (FLAGS & REPORT) printbad(line,file);
if (FLAGS & CTLH) fixctlh(line);
if (FLAGS & CLEAN)
{
cp = line;
while (*cp) if (legalchar(*cp)) bwrite(*cp++);
else ++cp;
if (ch == 012) bwrite(012);
}
}
}
printbad(cp,file)
char *cp,*file;
{
char mine[512];
register char *cp2;
register bad,x;
cp2 = mine;
bad = 0;
while (*cp)
if (!legalchar(*cp))
{
if (FLAGS & OCTAL)
{
x = *cp;
*cp2++ = '\\';
*cp2++ = ((x & 0300) >> 6) | '0';
*cp2++ = ((x & 0070) >> 3) | '0';
*cp2++ = ((x & 0007) ) | '0';
}
else *cp2++ = '?';
++bad;
++cp;
} else *cp2++ = *cp++;
*cp2++ = 012;
if (bad)
{
if (FLAGS & VERBOSE)
{
prs(file);
if (FLAGS & LNO) prs("/");
else prs(":");
}
if (FLAGS & LNO)
{
prd(linenum);
prs(":");
}
write(2,mine,cp2-mine);
}
}
fixctlh(cp)
char *cp;
{
register char *np,*bp;
bp = np = cp;
while (*cp)
{
if (*cp == '\b')
{
++cp;
if (bp != np) --np;
}
else *np++ = *cp++;
}
*np = 0;
}
bread(f)
{
for (;;)
{
if (eof) return(-1);
if (!avail)
{
avail = read(f,buf,512);
nxtchar = buf;
}
if (!avail)
{
eof = 1;
return(-1);
}
--avail;
if (*nxtchar) return(*nxtchar++);
++nxtchar;
return(0177);
}
}
bwrite(ch)
{
wbuf[wcount++] = ch;
if (wcount >= 512)
{
wcount = 0;
if (write(1,wbuf,512) != 512)
{
prs("fatal write error.\n");
exit(1);
}
}
}
flushout()
{
if (write(1,wbuf,wcount) != wcount)
{
prs("fatal write error\n");
exit(1);
}
}
prs(str)
char *str;
{
register char *dart;
dart=str;
while (*dart) dart++;
write(2,str,dart-str);
}
legalchar(ch)
char ch;
{
if (FLAGS & FFILL && ch == 014) return(0);
if (FLAGS & CRILL && ch == 015) return(0);
if (FLAGS & BELLILL && ch == 007) return(0);
if (any(ch,"\t\014\015\007")) return(1);
if (ch < 040 || ch > 0176) return(0);
return(1);
}
any(c,cp)
char c,*cp;
{
while (*cp) if (c == *cp++) return(-1);
return(0);
}
prd(x)
{
char nbuf[10];
int i,j,negf;
if (!x)
{
prs("0");
return;
}
i=8;
nbuf[9] = 0;
if (x < 0)
{
negf = 1;
x = -x;
}
else negf = 0;
while (x)
{
j = x % 10;
nbuf[i--] = j + 060;
x =/ 10;
}
if (negf) prs("-");
prs(nbuf+ ++i);
}