added freq, factor, fortune and primes as well, now is good - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 6d511bc7ba2f3e6ded8e7429776c6df29ed82300
 (DIR) parent de8d58acf8db7718da376c928cbde0c3a24869a2
 (HTM) 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:
         M Makefile                            |       5 +++--
         A factor/Makefile                     |      11 +++++++++++
         A factor/factor.c                     |      96 +++++++++++++++++++++++++++++++
         A fortune/Makefile                    |      11 +++++++++++
         A fortune/fortune.c                   |      92 +++++++++++++++++++++++++++++++
         A freq/Makefile                       |      11 +++++++++++
         A freq/freq.c                         |     111 ++++++++++++++++++++++++++++++
         A primes/Makefile                     |      11 +++++++++++
         A primes/primes.c                     |     131 +++++++++++++++++++++++++++++++
       
       9 files changed, 477 insertions(+), 2 deletions(-)
       ---
 (DIR) 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:
 (DIR) 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:
 (DIR) 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");
       +}
 (DIR) 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:
 (DIR) 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);
       +}
 (DIR) 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:
 (DIR) 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);
       +}
 (DIR) 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:
 (DIR) 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");
       +}