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