|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <bio.h> | 
|  |  | 
|  | long	count[1<<16]; | 
|  | Biobuf	bout; | 
|  |  | 
|  | 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{ | 
|  | default: | 
|  | fprint(2, "freq: unknown option %c\n", ARGC()); | 
|  | exits("usage"); | 
|  | 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; | 
|  | }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, "cannot open %s\n", argv[i]); | 
|  | continue; | 
|  | } | 
|  | freq(f, argv[i]); | 
|  | close(f); | 
|  | } | 
|  | exits(0); | 
|  | } | 
|  |  | 
|  | 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, "%8ld\n", count[i]); | 
|  | } | 
|  | Bflush(&bout); | 
|  | } |