Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
 
5
uvlong	count[Runemax+1];
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
}