9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

freq.c (1681B)


      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, "%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);
    107 		}
    108 		Bprint(&bout, "%8ld\n", count[i]);
    109 	}
    110 	Bflush(&bout);
    111 }