13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
43e12c5d1SDavid du Colombier
5*82726826SDavid du Colombier uvlong count[Runemax+1];
63e12c5d1SDavid du Colombier Biobuf bout;
73e12c5d1SDavid du Colombier
8a7529a1dSDavid du Colombier void usage(void);
93e12c5d1SDavid du Colombier void freq(int, char*);
103e12c5d1SDavid du Colombier long flag;
113e12c5d1SDavid du Colombier enum
123e12c5d1SDavid du Colombier {
133e12c5d1SDavid du Colombier Fdec = 1<<0,
143e12c5d1SDavid du Colombier Fhex = 1<<1,
153e12c5d1SDavid du Colombier Foct = 1<<2,
163e12c5d1SDavid du Colombier Fchar = 1<<3,
173e12c5d1SDavid du Colombier Frune = 1<<4,
183e12c5d1SDavid du Colombier };
193e12c5d1SDavid du Colombier
203e12c5d1SDavid du Colombier void
main(int argc,char * argv[])213e12c5d1SDavid du Colombier main(int argc, char *argv[])
223e12c5d1SDavid du Colombier {
233e12c5d1SDavid du Colombier int f, i;
243e12c5d1SDavid du Colombier
253e12c5d1SDavid du Colombier flag = 0;
263e12c5d1SDavid du Colombier Binit(&bout, 1, OWRITE);
273e12c5d1SDavid du Colombier ARGBEGIN{
283e12c5d1SDavid du Colombier case 'd':
293e12c5d1SDavid du Colombier flag |= Fdec;
303e12c5d1SDavid du Colombier break;
313e12c5d1SDavid du Colombier case 'x':
323e12c5d1SDavid du Colombier flag |= Fhex;
333e12c5d1SDavid du Colombier break;
343e12c5d1SDavid du Colombier case 'o':
353e12c5d1SDavid du Colombier flag |= Foct;
363e12c5d1SDavid du Colombier break;
373e12c5d1SDavid du Colombier case 'c':
383e12c5d1SDavid du Colombier flag |= Fchar;
393e12c5d1SDavid du Colombier break;
403e12c5d1SDavid du Colombier case 'r':
413e12c5d1SDavid du Colombier flag |= Frune;
423e12c5d1SDavid du Colombier break;
43a7529a1dSDavid du Colombier default:
44a7529a1dSDavid du Colombier usage();
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) {
55a7529a1dSDavid du Colombier fprint(2, "open %s: %r\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
usage(void)65a7529a1dSDavid du Colombier usage(void)
66a7529a1dSDavid du Colombier {
67a7529a1dSDavid du Colombier fprint(2, "usage: freq [-cdorx] [file ...]\n");
68a7529a1dSDavid du Colombier exits("usage");
69a7529a1dSDavid du Colombier }
70a7529a1dSDavid du Colombier
71a7529a1dSDavid du Colombier void
freq(int f,char * s)723e12c5d1SDavid du Colombier freq(int f, char *s)
733e12c5d1SDavid du Colombier {
743e12c5d1SDavid du Colombier Biobuf bin;
753e12c5d1SDavid du Colombier long c, i;
763e12c5d1SDavid du Colombier
773e12c5d1SDavid du Colombier memset(count, 0, sizeof(count));
783e12c5d1SDavid du Colombier Binit(&bin, f, OREAD);
793e12c5d1SDavid du Colombier if(flag & Frune) {
803e12c5d1SDavid du Colombier for(;;) {
813e12c5d1SDavid du Colombier c = Bgetrune(&bin);
823e12c5d1SDavid du Colombier if(c < 0)
833e12c5d1SDavid du Colombier break;
843e12c5d1SDavid du Colombier count[c]++;
853e12c5d1SDavid du Colombier }
863e12c5d1SDavid du Colombier } else {
873e12c5d1SDavid du Colombier for(;;) {
883e12c5d1SDavid du Colombier c = Bgetc(&bin);
893e12c5d1SDavid du Colombier if(c < 0)
903e12c5d1SDavid du Colombier break;
913e12c5d1SDavid du Colombier count[c]++;
923e12c5d1SDavid du Colombier }
933e12c5d1SDavid du Colombier }
94219b2ee8SDavid du Colombier Bterm(&bin);
953e12c5d1SDavid du Colombier if(c != Beof)
963e12c5d1SDavid du Colombier fprint(2, "freq: read error on %s\n", s);
973e12c5d1SDavid du Colombier
98219b2ee8SDavid du Colombier for(i=0; i<nelem(count); i++) {
993e12c5d1SDavid du Colombier if(count[i] == 0)
1003e12c5d1SDavid du Colombier continue;
1013e12c5d1SDavid du Colombier if(flag & Fdec)
1027dd7cddfSDavid du Colombier Bprint(&bout, "%3ld ", i);
1033e12c5d1SDavid du Colombier if(flag & Foct)
1047dd7cddfSDavid du Colombier Bprint(&bout, "%.3lo ", i);
1053e12c5d1SDavid du Colombier if(flag & Fhex)
1067dd7cddfSDavid du Colombier Bprint(&bout, "%.2lx ", i);
1073e12c5d1SDavid du Colombier if(flag & Fchar) {
1083e12c5d1SDavid du Colombier if(i <= 0x20 ||
1093e12c5d1SDavid du Colombier i >= 0x7f && i < 0xa0 ||
1103e12c5d1SDavid du Colombier i > 0xff && !(flag & Frune))
1113e12c5d1SDavid du Colombier Bprint(&bout, "- ");
1123e12c5d1SDavid du Colombier else
1137dd7cddfSDavid du Colombier Bprint(&bout, "%C ", (int)i);
1143e12c5d1SDavid du Colombier }
115b2495906SDavid du Colombier Bprint(&bout, "%8llud\n", count[i]);
1163e12c5d1SDavid du Colombier }
1173e12c5d1SDavid du Colombier Bflush(&bout);
1183e12c5d1SDavid du Colombier }
119