xref: /inferno-os/appl/cmd/freq.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1implement Freq;
2
3#
4#	Copyright © 2002 Lucent Technologies Inc.
5# 	transliteration of the Plan 9 command; subject to the Lucent Public License 1.02
6#
7
8include "sys.m";
9	sys: Sys;
10
11include "draw.m";
12
13include "bufio.m";
14	bufio: Bufio;
15	Iobuf: import bufio;
16
17include "arg.m";
18
19Freq: module
20{
21	init: fn(nil: ref Draw->Context, args: list of string);
22};
23
24count := array[1<<16] of big;
25flag := 0;
26
27Fdec, Fhex, Foct, Fchar, Frune: con 1<<iota;
28
29init(nil: ref Draw->Context, args: list of string)
30{
31	sys = load Sys Sys->PATH;
32	bufio = load Bufio Bufio->PATH;
33	arg := load Arg Arg->PATH;
34
35	arg->init(args);
36	while((c := arg->opt()) != 0)
37		case c {
38		* =>
39			sys->fprint(sys->fildes(2), "freq: unknown option %c\n", c);
40			raise "fail:usage";
41		'd' =>
42			flag |= Fdec;
43		'x' =>
44			flag |= Fhex;
45		'o' =>
46			flag |= Foct;
47		'c' =>
48			flag |= Fchar;
49		'r' =>
50			flag |= Frune;
51		}
52	args = arg->argv();
53	arg = nil;
54
55	bout := bufio->fopen(sys->fildes(1), Sys->OWRITE);
56	if((flag&(Fdec|Fhex|Foct|Fchar)) == 0)
57		flag |= Fdec|Fhex|Foct|Fchar;
58	if(args == nil){
59		freq(sys->fildes(0), "-", bout);
60		exit;
61	}
62	for(; args != nil; args = tl args){
63		f := sys->open(hd args, Sys->OREAD);
64		if(f == nil){
65			sys->fprint(sys->fildes(2), "cannot open %s\n", hd args);
66			continue;
67		}
68		freq(f, hd args, bout);
69		f = nil;
70	}
71}
72
73freq(f: ref Sys->FD, s: string, bout: ref Iobuf)
74{
75	c: int;
76
77	bin := bufio->fopen(f, Sys->OREAD);
78	if(flag&Frune)
79		for(;;){
80			c = bin.getc();
81			if(c < 0)
82				break;
83			count[c]++;
84		}
85	else
86		for(;;){
87			c = bin.getb();
88			if(c < 0)
89				break;
90			count[c]++;
91		}
92	if(c != Bufio->EOF)
93		sys->fprint(sys->fildes(2), "freq: read error on %s: %r\n", s);
94	for(i := 0; i < (len count)/4; i++){
95		if(count[i] == big 0)
96			continue;
97		if(flag&Fdec)
98			bout.puts(sys->sprint("%3d ", i));
99		if(flag&Foct)
100			bout.puts(sys->sprint("%.3o ", i));
101		if(flag&Fhex)
102			bout.puts(sys->sprint("%.2x ", i));
103		if(flag&Fchar)
104			if(i <= 16r20 || i >= 16r7f && i < 16ra0 || i > 16rff && !(flag&Frune))
105				bout.puts("- ");
106			else
107				bout.puts(sys->sprint("%c ", i));
108		bout.puts(sys->sprint("%8bd\n", count[i]));
109	}
110	bout.flush();
111}
112
113