[net.sources] couch - count characters

colonel@sunybcs.UUCP (Col. G. L. Sicherman) (10/20/86)

This is something like the "ctype" posted recently.  We've been using
it for a while now ...
-----
.\" @(#)couch.1	1.0  3/22/86
.ie n .ds Q ""
.el .ds Q ``
.ie n .ds U ""
.el .ds U ''
.TH COUCH 1 "11 June 1986" "" "Local UNIX Programmer's Manual"
.SH NAME
couch \- count characters
.SH SYNOPSIS
.B couch
[
.B \-bcdlpM
] file ...
.SH DESCRIPTION
.I Couch
counts the different characters in the
argument files or the standard input
and writes the totals to the standard output.
Each output line contains two fields:
a character and the number of times it appears.
Unprintable characters appear in \*Q^\fIx\fR\*U format;
blank is denoted by \*Q^\`\*U.
.PP
Various options select types of characters:
.B \-b
for blanks,
.B \-c
for control characters,
.B \-d 
for digits,
.B \-l
for letters, and
.B \-p
for punctuation.
The default is all characters; i.e.,
.B \-bcdlp .
The parity bit is normally ignored; to take it into account, specify
.B \-M .
.SH AUTHOR
Col. Sicherman
-----
/*
 *	couch - count characters.
 */

/*	couch [ -bcdlpM ] file ...		*/

#include <stdio.h>
#include <ctype.h>

int k[256];
int bflag, cflag, lflag, dflag, pflag, Mflag;
int bgo=1, cgo=1, lgo=1, dgo=1, pgo=1;
FILE *file;

main(argc,argv)
int argc;
char **argv;
{
	char c;
	int i, mask;
	char *unctrl();
	if (**++argv == '-') {
		while (*++*argv) switch (**argv) {
		case 'b':
			bflag++;
			break;
		case 'c':
			cflag++;
			break;
		case 'd':
			dflag++;
			break;
		case 'l':
			lflag++;
			break;
		case 'p':
			pflag++;
			break;
		case 'M':
			Mflag++;
			break;
		default:
			bomb();
		}
		argv++;
	}
	if (bflag||cflag||dflag||lflag||pflag) {
		bgo=bflag;
		cgo=cflag;
		dgo=dflag;
		lgo=lflag;
		pgo=pflag;
	}
	mask = Mflag? 0377: 0177;
	file=stdin;
	do {
		if (*argv) if (!(file=fopen(*argv++,"r"))) {
			fprintf(stderr,"couch: cannot read %s\n",*--argv);
			exit(1);
		}
		while (EOF!=(c=getc(file))) k[mask&c]++;
	} while (*argv);
	for (i=0; i<(Mflag? 256: 128); i++) {
		register j;
		j=0177&i;
		if (k[i]&&(bgo&&' '==j||cgo&&(j<040||j==0177)||dgo&&isdigit(j)||
			lgo&&isalpha(j)||pgo&&ispunct(j)))
		printf("%-4s %9d\n",unctrl(i),k[i]);
	}
}

char a[] = "M-^^";

char *unctrl(c)
int c;
{
	register char x;
	x = ~0200 & c;
	if (isprint(x) && ' '!=x) {
		a[2]=x;
		a[3]=0;
	}
	else {
		a[2]='^';
		a[3]=x^0100;
	}
	return c&0200? a: a+2;
}

bomb() {
	fprintf(stderr,"usage: couch [ -bcdlpM ] file ...\n");
	exit(1);
}
-- 
Col. G. L. Sicherman
UU: ...{rocksvax|decvax}!sunybcs!colonel
CS: colonel@buffalo-cs
BI: colonel@sunybcs, csdsiche@sunyabvc