ref: a79465e118a0469bbda928f86b9eef6b42d18593
dir: /sys/src/cmd/freq.c/
#include <u.h> #include <libc.h> #include <bio.h> uvlong count[Runemax+1]; Biobuf bout; void usage(void); void freq(int, char*); long flag; enum { Fdec = 1<<0, Fhex = 1<<1, Foct = 1<<2, Fchar = 1<<3, Frune = 1<<4, }; void main(int argc, char *argv[]) { int f, i; flag = 0; Binit(&bout, 1, OWRITE); ARGBEGIN{ case 'd': flag |= Fdec; break; case 'x': flag |= Fhex; break; case 'o': flag |= Foct; break; case 'c': flag |= Fchar; break; case 'r': flag |= Frune; break; default: usage(); }ARGEND if((flag&(Fdec|Fhex|Foct|Fchar)) == 0) flag |= Fdec | Fhex | Foct | Fchar; if(argc < 1) { freq(0, "-"); exits(0); } for(i=0; i<argc; i++) { f = open(argv[i], 0); if(f < 0) { fprint(2, "open %s: %r\n", argv[i]); continue; } freq(f, argv[i]); close(f); } exits(0); } void usage(void) { fprint(2, "usage: freq [-cdorx] [file ...]\n"); exits("usage"); } void freq(int f, char *s) { Biobuf bin; long c, i; memset(count, 0, sizeof(count)); Binit(&bin, f, OREAD); if(flag & Frune) { for(;;) { c = Bgetrune(&bin); if(c < 0) break; count[c]++; } } else { for(;;) { c = Bgetc(&bin); if(c < 0) break; count[c]++; } } Bterm(&bin); if(c != Beof) fprint(2, "freq: read error on %s\n", s); for(i=0; i<nelem(count); i++) { if(count[i] == 0) continue; if(flag & Fdec) Bprint(&bout, "%3ld ", i); if(flag & Foct) Bprint(&bout, "%.3lo ", i); if(flag & Fhex) Bprint(&bout, "%.2lx ", i); if(flag & Fchar) { if(i <= 0x20 || i >= 0x7f && i < 0xa0 || i > 0xff && !(flag & Frune)) Bprint(&bout, "- "); else Bprint(&bout, "%C ", (int)i); } Bprint(&bout, "%8llud\n", count[i]); } Bflush(&bout); }