1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 5 uvlong count[1<<16]; 6 Biobuf bout; 7 8 void usage(void); 9 void freq(int, char*); 10 long flag; 11 enum 12 { 13 Fdec = 1<<0, 14 Fhex = 1<<1, 15 Foct = 1<<2, 16 Fchar = 1<<3, 17 Frune = 1<<4, 18 }; 19 20 void 21 main(int argc, char *argv[]) 22 { 23 int f, i; 24 25 flag = 0; 26 Binit(&bout, 1, OWRITE); 27 ARGBEGIN{ 28 case 'd': 29 flag |= Fdec; 30 break; 31 case 'x': 32 flag |= Fhex; 33 break; 34 case 'o': 35 flag |= Foct; 36 break; 37 case 'c': 38 flag |= Fchar; 39 break; 40 case 'r': 41 flag |= Frune; 42 break; 43 default: 44 usage(); 45 }ARGEND 46 if((flag&(Fdec|Fhex|Foct|Fchar)) == 0) 47 flag |= Fdec | Fhex | Foct | Fchar; 48 if(argc < 1) { 49 freq(0, "-"); 50 exits(0); 51 } 52 for(i=0; i<argc; i++) { 53 f = open(argv[i], 0); 54 if(f < 0) { 55 fprint(2, "open %s: %r\n", argv[i]); 56 continue; 57 } 58 freq(f, argv[i]); 59 close(f); 60 } 61 exits(0); 62 } 63 64 void 65 usage(void) 66 { 67 fprint(2, "usage: freq [-cdorx] [file ...]\n"); 68 exits("usage"); 69 } 70 71 void 72 freq(int f, char *s) 73 { 74 Biobuf bin; 75 long c, i; 76 77 memset(count, 0, sizeof(count)); 78 Binit(&bin, f, OREAD); 79 if(flag & Frune) { 80 for(;;) { 81 c = Bgetrune(&bin); 82 if(c < 0) 83 break; 84 count[c]++; 85 } 86 } else { 87 for(;;) { 88 c = Bgetc(&bin); 89 if(c < 0) 90 break; 91 count[c]++; 92 } 93 } 94 Bterm(&bin); 95 if(c != Beof) 96 fprint(2, "freq: read error on %s\n", s); 97 98 for(i=0; i<nelem(count); i++) { 99 if(count[i] == 0) 100 continue; 101 if(flag & Fdec) 102 Bprint(&bout, "%3ld ", i); 103 if(flag & Foct) 104 Bprint(&bout, "%.3lo ", i); 105 if(flag & Fhex) 106 Bprint(&bout, "%.2lx ", i); 107 if(flag & Fchar) { 108 if(i <= 0x20 || 109 i >= 0x7f && i < 0xa0 || 110 i > 0xff && !(flag & Frune)) 111 Bprint(&bout, "- "); 112 else 113 Bprint(&bout, "%C ", (int)i); 114 } 115 Bprint(&bout, "%8llud\n", count[i]); 116 } 117 Bflush(&bout); 118 } 119