9base

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

commit 6d511bc7ba2f3e6ded8e7429776c6df29ed82300
parent de8d58acf8db7718da376c928cbde0c3a24869a2
Author: anselm@garbe.us <unknown>
Date:   Mon, 22 Mar 2010 08:13:36 +0000

added freq, factor, fortune and primes as well, now is good
Diffstat:
Makefile | 5+++--
factor/Makefile | 11+++++++++++
factor/factor.c | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
fortune/Makefile | 11+++++++++++
fortune/fortune.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
freq/Makefile | 11+++++++++++
freq/freq.c | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
primes/Makefile | 11+++++++++++
primes/primes.c | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 477 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile @@ -2,8 +2,9 @@ include config.mk -SUBDIRS = lib9 yacc awk basename bc cal cat cleanname date dc du echo getflags grep hoc ls \ - mk mkdir mtime rc read sed seq sleep sort tee test touch tr troff uniq +SUBDIRS = lib9 yacc awk basename bc cal cat cleanname date dc du echo \ + factor fortunes freq getflags grep hoc ls mk mkdir mtime \ + primes rc read sed seq sleep sort tee test touch tr troff uniq all: @echo 9base build options: diff --git a/factor/Makefile b/factor/Makefile @@ -0,0 +1,11 @@ +# factor - unix port from plan9 +# +# Depends on ../lib9 + +TARG = factor + +include ../std.mk + +pre-uninstall: + +post-install: diff --git a/factor/factor.c b/factor/factor.c @@ -0,0 +1,96 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +#define whsiz (sizeof(wheel)/sizeof(wheel[0])) + +double wheel[] = +{ + 2,10, 2, 4, 2, 4, 6, 2, 6, 4, + 2, 4, 6, 6, 2, 6, 4, 2, 6, 4, + 6, 8, 4, 2, 4, 2, 4, 8, 6, 4, + 6, 2, 4, 6, 2, 6, 6, 4, 2, 4, + 6, 2, 6, 4, 2, 4, 2,10, +}; + +Biobuf bin; + +void factor(double); + +void +main(int argc, char *argv[]) +{ + double n; + int i; + char *l; + + if(argc > 1) { + for(i=1; i<argc; i++) { + n = atof(argv[i]); + factor(n); + } + exits(0); + } + + Binit(&bin, 0, OREAD); + for(;;) { + l = Brdline(&bin, '\n'); + if(l == 0) + break; + n = atof(l); + if(n <= 0) + break; + factor(n); + } + exits(0); +} + +void +factor(double n) +{ + double quot, d, s; + int i; + + print("%.0f\n", n); + if(n == 0) + return; + s = sqrt(n) + 1; + while(modf(n/2, &quot) == 0) { + print(" 2\n"); + n = quot; + s = sqrt(n) + 1; + } + while(modf(n/3, &quot) == 0) { + print(" 3\n"); + n = quot; + s = sqrt(n) + 1; + } + while(modf(n/5, &quot) == 0) { + print(" 5\n"); + n = quot; + s = sqrt(n) + 1; + } + while(modf(n/7, &quot) == 0) { + print(" 7\n"); + n = quot; + s = sqrt(n) + 1; + } + d = 1; + for(i=1;;) { + d += wheel[i]; + while(modf(n/d, &quot) == 0) { + print(" %.0f\n", d); + n = quot; + s = sqrt(n) + 1; + } + i++; + if(i >= whsiz) { + i = 0; + if(d > s) + break; + } + } + if(n > 1) + print(" %.0f\n",n); + print("\n"); +} diff --git a/fortune/Makefile b/fortune/Makefile @@ -0,0 +1,11 @@ +# fortune - unix port from plan9 +# +# Depends on ../lib9 + +TARG = fortune + +include ../std.mk + +pre-uninstall: + +post-install: diff --git a/fortune/fortune.c b/fortune/fortune.c @@ -0,0 +1,92 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +#define index findex +char choice[2048]; +char *index = "#9/lib/fortunes.index"; +char *fortunes = "#9/lib/fortunes"; + +void +main(int argc, char *argv[]) +{ + int i; + long offs; + uchar off[4]; + int ix, nix; + int newindex, oldindex; + char *p; + Dir *fbuf, *ixbuf; + Biobuf *f, g; + + index = unsharp(index); + fortunes = unsharp(fortunes); + + newindex = 0; + oldindex = 0; + ix = offs = 0; + if((f=Bopen(argc>1?argv[1]:fortunes, OREAD)) == 0){ + print("Misfortune!\n"); + exits("misfortune"); + } + ixbuf = nil; + if(argc == 1){ + ix = open(index, OREAD); + if(ix>=0){ + oldindex = 1; + ixbuf = dirfstat(ix); + fbuf = dirfstat(Bfildes(f)); + if(ixbuf == nil || fbuf == nil){ + print("Misfortune?\n"); + exits("misfortune"); + } + if(fbuf->mtime > ixbuf->mtime){ + nix = create(index, OWRITE, 0666); + if(nix >= 0){ + close(ix); + ix = nix; + newindex = 1; + oldindex = 0; + } + } + }else{ + ix = create(index, OWRITE, 0666); + if(ix >= 0) + newindex = 1; + } + } + if(oldindex){ + srand(getpid()); + seek(ix, lrand()%(ixbuf->length/sizeof(offs))*sizeof(offs), 0); + read(ix, off, sizeof(off)); + Bseek(f, off[0]|(off[1]<<8)|(off[2]<<16)|(off[3]<<24), 0); + p = Brdline(f, '\n'); + if(p){ + p[Blinelen(f)-1] = 0; + strcpy(choice, p); + }else + strcpy(choice, "Misfortune!"); + }else{ + Binit(&g, ix, 1); + srand(getpid()); + for(i=1;;i++){ + if(newindex) + offs = Boffset(f); + p = Brdline(f, '\n'); + if(p == 0) + break; + p[Blinelen(f)-1] = 0; + if(newindex){ + off[0] = offs; + off[1] = offs>>8; + off[2] = offs>>16; + off[3] = offs>>24; + Bwrite(&g, off, sizeof(off)); + } + if(lrand()%i==0) + strcpy(choice, p); + } + } + print("%s\n", choice); + exits(0); +} diff --git a/freq/Makefile b/freq/Makefile @@ -0,0 +1,11 @@ +# freq - unix port from plan9 +# +# Depends on ../lib9 + +TARG = freq + +include ../std.mk + +pre-uninstall: + +post-install: diff --git a/freq/freq.c b/freq/freq.c @@ -0,0 +1,111 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +long count[1<<16]; +Biobuf bout; + +void freq(int, char*); +long flag; +enum +{ + Fdec = 1<<0, + Fhex = 1<<1, + Foct = 1<<2, + Fchar = 1<<3, + Frune = 1<<4 +}; + +void +main(int argc, char *argv[]) +{ + int f, i; + + flag = 0; + Binit(&bout, 1, OWRITE); + ARGBEGIN{ + default: + fprint(2, "freq: unknown option %c\n", ARGC()); + exits("usage"); + case 'd': + flag |= Fdec; + break; + case 'x': + flag |= Fhex; + break; + case 'o': + flag |= Foct; + break; + case 'c': + flag |= Fchar; + break; + case 'r': + flag |= Frune; + break; + }ARGEND + if((flag&(Fdec|Fhex|Foct|Fchar)) == 0) + flag |= Fdec | Fhex | Foct | Fchar; + if(argc < 1) { + freq(0, "-"); + exits(0); + } + for(i=0; i<argc; i++) { + f = open(argv[i], 0); + if(f < 0) { + fprint(2, "cannot open %s\n", argv[i]); + continue; + } + freq(f, argv[i]); + close(f); + } + exits(0); +} + +void +freq(int f, char *s) +{ + Biobuf bin; + long c, i; + + memset(count, 0, sizeof(count)); + Binit(&bin, f, OREAD); + if(flag & Frune) { + for(;;) { + c = Bgetrune(&bin); + if(c < 0) + break; + count[c]++; + } + } else { + for(;;) { + c = Bgetc(&bin); + if(c < 0) + break; + count[c]++; + } + } + Bterm(&bin); + if(c != Beof) + fprint(2, "freq: read error on %s\n", s); + + for(i=0; i<nelem(count); i++) { + if(count[i] == 0) + continue; + if(flag & Fdec) + Bprint(&bout, "%3ld ", i); + if(flag & Foct) + Bprint(&bout, "%.3lo ", i); + if(flag & Fhex) + Bprint(&bout, "%.2lx ", i); + if(flag & Fchar) { + if(i <= 0x20 || + i >= 0x7f && i < 0xa0 || + i > 0xff && !(flag & Frune)) + Bprint(&bout, "- "); + else + Bprint(&bout, "%C ", (int)i); + } + Bprint(&bout, "%8ld\n", count[i]); + } + Bflush(&bout); +} diff --git a/primes/Makefile b/primes/Makefile @@ -0,0 +1,11 @@ +# primes - unix port from plan9 +# +# Depends on ../lib9 + +TARG = primes + +include ../std.mk + +pre-uninstall: + +post-install: diff --git a/primes/primes.c b/primes/primes.c @@ -0,0 +1,131 @@ +#include <u.h> +#include <libc.h> + +#define ptsiz (sizeof(pt)/sizeof(pt[0])) +#define whsiz (sizeof(wheel)/sizeof(wheel[0])) +#define tabsiz (sizeof(table)/sizeof(table[0])) +#define tsiz8 (tabsiz*8) + +double big = 9.007199254740992e15; + +int pt[] = +{ + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, + 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, + 73, 79, 83, 89, 97,101,103,107,109,113, + 127,131,137,139,149,151,157,163,167,173, + 179,181,191,193,197,199,211,223,227,229, +}; +double wheel[] = +{ + 10, 2, 4, 2, 4, 6, 2, 6, 4, 2, + 4, 6, 6, 2, 6, 4, 2, 6, 4, 6, + 8, 4, 2, 4, 2, 4, 8, 6, 4, 6, + 2, 4, 6, 2, 6, 6, 4, 2, 4, 6, + 2, 6, 4, 2, 4, 2,10, 2, +}; +uchar table[1000]; +uchar bittab[] = +{ + 1, 2, 4, 8, 16, 32, 64, 128, +}; + +void mark(double nn, long k); +void ouch(void); + +void +main(int argc, char *argp[]) +{ + int i; + double k, temp, v, limit, nn; + + if(argc <= 1) { + fprint(2, "usage: primes starting [ending]\n"); + exits("usage"); + } + nn = atof(argp[1]); + limit = big; + if(argc > 2) { + limit = atof(argp[2]); + if(limit < nn) + exits(0); + if(limit > big) + ouch(); + } + if(nn < 0 || nn > big) + ouch(); + if(nn == 0) + nn = 1; + + if(nn < 230) { + for(i=0; i<ptsiz; i++) { + if(pt[i] < nn) + continue; + if(pt[i] > limit) + exits(0); + print("%d\n", pt[i]); + if(limit >= big) + exits(0); + } + nn = 230; + } + + modf(nn/2, &temp); + nn = 2.*temp + 1; +/* + * clear the sieve table. + */ + for(;;) { + for(i=0; i<tabsiz; i++) + table[i] = 0; +/* + * run the sieve. + */ + v = sqrt(nn+tsiz8); + mark(nn, 3); + mark(nn, 5); + mark(nn, 7); + for(i=0,k=11; k<=v; k+=wheel[i]) { + mark(nn, k); + i++; + if(i >= whsiz) + i = 0; + } +/* + * now get the primes from the table + * and print them. + */ + for(i=0; i<tsiz8; i+=2) { + if(table[i>>3] & bittab[i&07]) + continue; + temp = nn + i; + if(temp > limit) + exits(0); + print("%.0f\n", temp); + if(limit >= big) + exits(0); + } + nn += tsiz8; + } +} + +void +mark(double nn, long k) +{ + double t1; + long j; + + modf(nn/k, &t1); + j = k*t1 - nn; + if(j < 0) + j += k; + for(; j<tsiz8; j+=k) + table[j>>3] |= bittab[j&07]; +} + +void +ouch(void) +{ + fprint(2, "limits exceeded\n"); + exits("limits"); +}