Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
5 uvlong count[Runemax+1];
6 Biobuf bout;
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 };
19 void
20 main(int argc, char *argv[])
21 {
22 int f, i;
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 }
64 void
65 freq(int f, char *s)
66 {
67 Biobuf bin;
68 long c, i;
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);
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);
108 Bprint(&bout, "%8llud\n", count[i]);
110 Bflush(&bout);