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