xref: /plan9-contrib/sys/src/cmd/freq.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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, "%3d ", i);
96 		if(flag & Foct)
97 			Bprint(&bout, "%.3o ", i);
98 		if(flag & Fhex)
99 			Bprint(&bout, "%.2x ", 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 ", i);
107 		}
108 		Bprint(&bout, "%8ld\n", count[i]);
109 	}
110 	Bflush(&bout);
111 }
112