xref: /plan9-contrib/sys/src/cmd/freq.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
43e12c5d1SDavid du Colombier 
53e12c5d1SDavid du Colombier long	count[1<<16];
63e12c5d1SDavid du Colombier Biobuf	bout;
73e12c5d1SDavid du Colombier 
83e12c5d1SDavid du Colombier void	freq(int, char*);
93e12c5d1SDavid du Colombier long	flag;
103e12c5d1SDavid du Colombier enum
113e12c5d1SDavid du Colombier {
123e12c5d1SDavid du Colombier 	Fdec	= 1<<0,
133e12c5d1SDavid du Colombier 	Fhex	= 1<<1,
143e12c5d1SDavid du Colombier 	Foct	= 1<<2,
153e12c5d1SDavid du Colombier 	Fchar	= 1<<3,
163e12c5d1SDavid du Colombier 	Frune	= 1<<4,
173e12c5d1SDavid du Colombier };
183e12c5d1SDavid du Colombier 
193e12c5d1SDavid du Colombier void
203e12c5d1SDavid du Colombier main(int argc, char *argv[])
213e12c5d1SDavid du Colombier {
223e12c5d1SDavid du Colombier 	int f, i;
233e12c5d1SDavid du Colombier 
243e12c5d1SDavid du Colombier 	flag = 0;
253e12c5d1SDavid du Colombier 	Binit(&bout, 1, OWRITE);
263e12c5d1SDavid du Colombier 	ARGBEGIN{
273e12c5d1SDavid du Colombier 	default:
283e12c5d1SDavid du Colombier 		fprint(2, "freq: unknown option %c\n", ARGC());
293e12c5d1SDavid du Colombier 		exits("usage");
303e12c5d1SDavid du Colombier 	case 'd':
313e12c5d1SDavid du Colombier 		flag |= Fdec;
323e12c5d1SDavid du Colombier 		break;
333e12c5d1SDavid du Colombier 	case 'x':
343e12c5d1SDavid du Colombier 		flag |= Fhex;
353e12c5d1SDavid du Colombier 		break;
363e12c5d1SDavid du Colombier 	case 'o':
373e12c5d1SDavid du Colombier 		flag |= Foct;
383e12c5d1SDavid du Colombier 		break;
393e12c5d1SDavid du Colombier 	case 'c':
403e12c5d1SDavid du Colombier 		flag |= Fchar;
413e12c5d1SDavid du Colombier 		break;
423e12c5d1SDavid du Colombier 	case 'r':
433e12c5d1SDavid du Colombier 		flag |= Frune;
443e12c5d1SDavid du Colombier 		break;
453e12c5d1SDavid du Colombier 	}ARGEND
463e12c5d1SDavid du Colombier 	if((flag&(Fdec|Fhex|Foct|Fchar)) == 0)
473e12c5d1SDavid du Colombier 		flag |= Fdec | Fhex | Foct | Fchar;
483e12c5d1SDavid du Colombier 	if(argc < 1) {
493e12c5d1SDavid du Colombier 		freq(0, "-");
503e12c5d1SDavid du Colombier 		exits(0);
513e12c5d1SDavid du Colombier 	}
523e12c5d1SDavid du Colombier 	for(i=0; i<argc; i++) {
533e12c5d1SDavid du Colombier 		f = open(argv[i], 0);
543e12c5d1SDavid du Colombier 		if(f < 0) {
553e12c5d1SDavid du Colombier 			fprint(2, "cannot open %s\n", argv[i]);
563e12c5d1SDavid du Colombier 			continue;
573e12c5d1SDavid du Colombier 		}
583e12c5d1SDavid du Colombier 		freq(f, argv[i]);
593e12c5d1SDavid du Colombier 		close(f);
603e12c5d1SDavid du Colombier 	}
613e12c5d1SDavid du Colombier 	exits(0);
623e12c5d1SDavid du Colombier }
633e12c5d1SDavid du Colombier 
643e12c5d1SDavid du Colombier void
653e12c5d1SDavid du Colombier freq(int f, char *s)
663e12c5d1SDavid du Colombier {
673e12c5d1SDavid du Colombier 	Biobuf bin;
683e12c5d1SDavid du Colombier 	long c, i;
693e12c5d1SDavid du Colombier 
703e12c5d1SDavid du Colombier 	memset(count, 0, sizeof(count));
713e12c5d1SDavid du Colombier 	Binit(&bin, f, OREAD);
723e12c5d1SDavid du Colombier 	if(flag & Frune) {
733e12c5d1SDavid du Colombier 		for(;;) {
743e12c5d1SDavid du Colombier 			c = Bgetrune(&bin);
753e12c5d1SDavid du Colombier 			if(c < 0)
763e12c5d1SDavid du Colombier 				break;
773e12c5d1SDavid du Colombier 			count[c]++;
783e12c5d1SDavid du Colombier 		}
793e12c5d1SDavid du Colombier 	} else {
803e12c5d1SDavid du Colombier 		for(;;) {
813e12c5d1SDavid du Colombier 			c = Bgetc(&bin);
823e12c5d1SDavid du Colombier 			if(c < 0)
833e12c5d1SDavid du Colombier 				break;
843e12c5d1SDavid du Colombier 			count[c]++;
853e12c5d1SDavid du Colombier 		}
863e12c5d1SDavid du Colombier 	}
87*219b2ee8SDavid du Colombier 	Bterm(&bin);
883e12c5d1SDavid du Colombier 	if(c != Beof)
893e12c5d1SDavid du Colombier 		fprint(2, "freq: read error on %s\n", s);
903e12c5d1SDavid du Colombier 
91*219b2ee8SDavid du Colombier 	for(i=0; i<nelem(count); i++) {
923e12c5d1SDavid du Colombier 		if(count[i] == 0)
933e12c5d1SDavid du Colombier 			continue;
943e12c5d1SDavid du Colombier 		if(flag & Fdec)
953e12c5d1SDavid du Colombier 			Bprint(&bout, "%3d ", i);
963e12c5d1SDavid du Colombier 		if(flag & Foct)
973e12c5d1SDavid du Colombier 			Bprint(&bout, "%.3o ", i);
983e12c5d1SDavid du Colombier 		if(flag & Fhex)
993e12c5d1SDavid du Colombier 			Bprint(&bout, "%.2x ", i);
1003e12c5d1SDavid du Colombier 		if(flag & Fchar) {
1013e12c5d1SDavid du Colombier 			if(i <= 0x20 ||
1023e12c5d1SDavid du Colombier 			   i >= 0x7f && i < 0xa0 ||
1033e12c5d1SDavid du Colombier 			   i > 0xff && !(flag & Frune))
1043e12c5d1SDavid du Colombier 				Bprint(&bout, "- ");
1053e12c5d1SDavid du Colombier 			else
1063e12c5d1SDavid du Colombier 				Bprint(&bout, "%C ", i);
1073e12c5d1SDavid du Colombier 		}
1083e12c5d1SDavid du Colombier 		Bprint(&bout, "%8ld\n", count[i]);
1093e12c5d1SDavid du Colombier 	}
1103e12c5d1SDavid du Colombier 	Bflush(&bout);
1113e12c5d1SDavid du Colombier }
112