ref: a39951d8f69209cfea2b7051832b851914e662ef
author: rodri <[email protected]>
date: Sat Feb 22 04:56:09 EST 2020
now version controlled.
--- /dev/null
+++ b/battfmt.c
@@ -1,0 +1,28 @@
+#include <u.h>
+#include <libc.h>
+#include <ctype.h>
+
+void
+battfmt(char *buf, long buflen)
+{
+ char *s;
+
+ for(s = buf; (s-buf) < buflen; s++)
+ if(!isdigit(*s)){
+ for(;(s-buf) < buflen; s++)
+ *s = '\0';
+ break;
+ }
+}
+
+void
+main(void)
+{
+ char str[] = "30 m";
+
+ battfmt(str, 4);
+
+ print("%s\n", str);
+
+ exits("done");
+}
--- /dev/null
+++ b/beatform.c
@@ -1,0 +1,26 @@
+#include <u.h>
+#include <libc.h>
+
+uvlong
+next(uvlong t)
+{
+ print("t0: %llud ", t);
+ t = t * 8000 / 44100;
+ print("t1: %llud ", t);
+ t = t*(42&t>>10);
+ print("t2: %llud ", t);
+ print("t3: %llud ", t<<8);
+ return t<<8;
+}
+
+void
+main()
+{
+ uvlong t;
+ short sl;
+
+ for(t = 20000;; t++){
+ sl = next(t);
+ print("%2d\t", sl);
+ }
+}
--- /dev/null
+++ b/bgetceofindeed.c
@@ -1,0 +1,23 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+
+void
+main()
+{
+ Biobuf *bin;
+ char c;
+
+ bin = Bfdopen(0, OREAD);
+ if(bin == nil)
+ sysfatal("Bfdopen: %r");
+ while((c = Bgetc(bin)) != Beof)
+ ;
+ USED(c);
+ c = Bgetc(bin);
+ if(c == Beof)
+ print("eof indeed\n");
+ else
+ print("no eof after eof\n");
+ exits(0);
+}
--- /dev/null
+++ b/bgetding.c
@@ -1,0 +1,46 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+
+typedef struct
+{
+ double x, y, z;
+} Vec;
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s [file]\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ Biobuf *bin;
+ Vec v;
+ int fd, r;
+
+ fd = 0;
+ ARGBEGIN{
+ default: usage();
+ }ARGEND;
+ if(argc > 1)
+ usage();
+ else if(argc == 1){
+ fd = open(argv[0], OREAD);
+ if(fd < 0)
+ sysfatal("open: %r");
+ }
+ bin = Bfdopen(fd, OREAD);
+ if(bin == nil)
+ sysfatal("Bfdopen: %r");
+ r = Bgetd(bin, &v.x);
+ print("got %g r=%d\n", v.x, r);
+ r = Bgetd(bin, &v.y);
+ print("got %g r=%d\n", v.y, r);
+ r = Bgetd(bin, &v.z);
+ print("got %g r=%d\n", v.z, r);
+ Bterm(bin);
+ exits(0);
+}
--- /dev/null
+++ b/bincoeff.c
@@ -1,0 +1,63 @@
+#include <u.h>
+#include <libc.h>
+
+vlong t0, Δt;
+
+double
+fac(double n)
+{
+ double Π;
+
+ Π = 1;
+ assert(n > 0);
+ while(n > 1)
+ Π *= n--;
+ return Π;
+}
+
+double
+bincoeff(double n, double k)
+{
+ assert(k <= n);
+ return fac(n)/(fac(k)*fac(n-k));
+}
+
+double
+bincoeffmul(double n, double k)
+{
+ double Π;
+ int i;
+
+ assert(k <= n);
+ Π = 1;
+ for(i = 1; i <= k; i++)
+ Π *= (n + 1 - i)/i;
+ return Π;
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: bincoeff n k\n");
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ double n, k, bc;
+
+ if(argc != 3)
+ usage();
+ n = strtod(argv[1], nil);
+ k = strtod(argv[2], nil);
+ t0 = nsec();
+ bc = bincoeff(n, k);
+ Δt = nsec()-t0;
+ print("method 1: %g (%lldns)\n", bc, Δt);
+ t0 = nsec();
+ bc = bincoeffmul(n, k);
+ Δt = nsec()-t0;
+ print("method 2: %g (%lldns)\n", bc, Δt);
+ exits(nil);
+}
--- /dev/null
+++ b/bitround.c
@@ -1,0 +1,25 @@
+#include <u.h>
+#include <libc.h>
+
+#define round(s, sz) ((s)+((sz)-1)&~((sz)-1))
+
+static void
+usage(void)
+{
+ fprint(2, "usage: bitround number\n");
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ int i;
+
+ if(argc != 2)
+ usage();
+ i = strtol(argv[1], nil, 0);
+ print("i0 %b (%d)\n", i, i);
+ i = round(i, sizeof(int));
+ print("i1 %b (%d)\n", i, i);
+ exits(0);
+}
--- /dev/null
+++ b/bracketop.c
@@ -1,0 +1,11 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+ int a[] = {1, 2};
+
+ print("%d\n", 1[a]);
+ exits(nil);
+}
--- /dev/null
+++ b/colgrad.c
@@ -1,0 +1,83 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+
+enum { SEC = 1000 };
+
+enum {
+ Cred,
+ Cgrn,
+ Cblu,
+
+ Cgx,
+ Cgy,
+ Cend
+};
+Image *col[Cend];
+
+int dx, dy;
+
+void *
+emalloc(ulong n)
+{
+ void *p;
+
+ p = malloc(n);
+ if(p == nil)
+ sysfatal("malloc: %r");
+ memset(p, 0, n);
+ setmalloctag(p, getcallerpc(&n));
+ return p;
+}
+
+Image *
+eallocimage(Display *d, Rectangle r, ulong chan, int repl, ulong col)
+{
+ Image *i;
+
+ i = allocimage(d, r, chan, repl, col);
+ if(i == nil)
+ sysfatal("allocimage: %r");
+ return i;
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: colgrad\n");
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ int i;
+ uchar *gx, *gy;
+
+ ARGBEGIN{
+ default: usage();
+ }ARGEND;
+
+ if(initdraw(nil, nil, "colgrad") < 0)
+ sysfatal("initdraw: %r");
+ dx = Dx(screen->r), dy = Dy(screen->r);
+ col[Cred] = eallocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DRed);
+ col[Cgrn] = eallocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DGreen);
+ col[Cblu] = eallocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DBlue);
+ col[Cgx] = eallocimage(display, Rect(0, 0, dx, 1), GREY8, 1, DNofill);
+ col[Cgy] = eallocimage(display, Rect(0, 0, 1, dy), GREY8, 1, DNofill);
+ gx = emalloc(dx);
+ gy = emalloc(dy);
+ for(i = 0; i < dx; i++)
+ gx[i] = 255.0 * i/(dx-1);
+ for(i = 0; i < dy; i++)
+ gy[i] = 255.0 * i/(dy-1);
+ loadimage(col[Cgx], col[Cgx]->r, gx, dx);
+ loadimage(col[Cgy], col[Cgy]->r, gy, dy);
+ draw(screen, screen->r, col[Cred], nil, ZP);
+ draw(screen, screen->r, col[Cgrn], col[Cgx], ZP);
+ draw(screen, screen->r, col[Cblu], col[Cgy], ZP);
+ flushimage(display, 1);
+ sleep(5*SEC);
+ exits(0);
+}
--- /dev/null
+++ b/consreadnum.c
@@ -1,0 +1,17 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+ char tmp[64];
+ int size;
+
+ size = 2*1024*1024*1024;
+ if(size > sizeof tmp || size < 0)
+ size = sizeof tmp;
+ snprint(tmp, sizeof tmp, "%*lud", size-1, 409234UL);
+ tmp[size-1] = ' ';
+ print("%s\n", tmp);
+ exits(nil);
+}
--- /dev/null
+++ b/const.c
@@ -1,0 +1,15 @@
+#include <u.h>
+#include <libc.h>
+
+char *p = "gooseberry";
+char a[] = "gooseberry";
+
+void
+main()
+{
+ print("%s\n%s\n", p, a);
+ strncpy(p, "black", 5);
+ strncpy(a, "black", 5);
+ print("%s\n%s\n", p, a);
+ exits(nil);
+}
--- /dev/null
+++ b/constructor.c
@@ -1,0 +1,49 @@
+#include <u.h>
+#include <libc.h>
+
+typedef struct Point Point;
+struct Point
+{
+ int x, y;
+};
+
+typedef struct Pointd Pointd;
+struct Pointd
+{
+ double x, y, w;
+};
+
+Point
+Pt(int x, int y)
+{
+ return (Point){x, y};
+}
+
+Pointd
+Ptd(double x, double y, double w)
+{
+ return (Pointd){x, y, w};
+}
+
+vlong t0;
+
+void
+main()
+{
+ Point p;
+ Pointd pd;
+
+ t0 = nsec();
+ p = (Point){2, 3};
+ fprint(2, "p1 %lldnsec\n", nsec()-t0);
+ t0 = nsec();
+ p = Pt(2, 3);
+ fprint(2, "p2 %lldnsec\n", nsec()-t0);
+ t0 = nsec();
+ pd = (Pointd){2.0, 3.0, 1.0};
+ fprint(2, "pd1 %lldnsec\n", nsec()-t0);
+ t0 = nsec();
+ pd = Ptd(2.0, 3.0, 1.0);
+ fprint(2, "pd2 %lldnsec\n", nsec()-t0);
+ exits(0);
+}
--- /dev/null
+++ b/dichotomy.c
@@ -1,0 +1,36 @@
+#include <u.h>
+#include <libc.h>
+
+void *
+emalloc(ulong n)
+{
+ void *p;
+
+ p = malloc(n);
+ if(p == nil)
+ sysfatal("malloc: %r");
+ memset(p, 0, n);
+ setmalloctag(p, getcallerpc(&n));
+ return p;
+}
+
+char **listp;
+char *lista[] = {
+ "just",
+ "a",
+ "couple",
+ "of",
+ "words"
+};
+char s[] = "ignore this and keep going";
+
+void
+main()
+{
+ print("listp size pre-alloc: %d\n", sizeof(listp));
+ listp = emalloc(4096);
+ print("listp size post-alloc: %d\n", sizeof(listp));
+ print("lista size: %d & len: %d\n", sizeof(lista), nelem(lista));
+ print("s size: %d & len: %ld\n", sizeof(s), strlen(s));
+ exits(0);
+}
--- /dev/null
+++ b/doubleparse.c
@@ -1,0 +1,20 @@
+#include <u.h>
+#include <libc.h>
+#include <ctype.h>
+
+void
+main()
+{
+ char *s, buf[512];
+ double n[2];
+
+ read(0, buf, sizeof(buf)-1);
+ buf[sizeof(buf)-1] = 0;
+ s = buf;
+ n[0] = strtod(s, &s);
+ while(isspace(*++s))
+ ;
+ n[1] = strtod(s, &s);
+ print("n0: %g\nn1: %g\n", n[0], n[1]);
+ exits(0);
+}
--- /dev/null
+++ b/dprom.c
@@ -1,0 +1,10 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+ if(0.00001 > 0) print("ok\n");
+ else print("ko\n");
+ exits(0);
+}
--- /dev/null
+++ b/dynarray.c
@@ -1,0 +1,12 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+ char buf[];
+
+ buf = malloc(128);
+ print("%d\n", nelem(buf));
+ exits(nil);
+}
--- /dev/null
+++ b/dynsubscript.c
@@ -1,0 +1,25 @@
+#include <u.h>
+#include <libc.h>
+
+typedef struct Num Num;
+
+struct Num {
+ int v;
+};
+
+Num one = {1};
+Num three = {3};
+Num fourteen = {14};
+
+char *list[] = {
+[one.v] "ein",
+[three.v] "drei",
+[fourteen.v] "vierzehn"
+};
+
+void
+main()
+{
+ print("%s\n", list[one.v]);
+ exits(0);
+}
--- /dev/null
+++ b/extorlocal.c
@@ -1,0 +1,19 @@
+#include <u.h>
+#include <libc.h>
+
+static char s[] = "hello ";
+char t[] = "world\n";
+
+void
+greet(void)
+{
+ write(1, s, 6);
+ write(1, t, 6);
+}
+
+void
+main()
+{
+ greet();
+ //exits(0);
+}
--- /dev/null
+++ b/extorlocal.s
@@ -1,0 +1,12 @@
+DATA s+0(SB)/8,$"hello wo"
+DATA s+8(SB)/4,$"rld\n"
+GLOBL s(SB),$13
+
+TEXT greet(SB), $32
+ MOVL $1, BP
+ MOVQ $s+0(SB), DI
+ MOVQ DI, 8(SP)
+ MOVL $12, DI
+ MOVL DI, 16(SP)
+ CALL write(SB)
+ RET
--- /dev/null
+++ b/extorlocalmain.c
@@ -1,0 +1,11 @@
+#include <u.h>
+#include <libc.h>
+
+void greet(void);
+
+void
+main()
+{
+ greet();
+ //exits(0);
+}
--- /dev/null
+++ b/frisvadonb.c
@@ -1,0 +1,110 @@
+/*
+ * Implementation of the techniques described in †.
+ *
+ * † Tom Duff, James Burgess, Per Christensen, Christophe Hery, Andrew
+ * Kensler, Max Liani, and Ryusuke Villemin, Building an Orthonormal
+ * Basis, Revisited, Journal of Computer Graphics Techniques (JCGT), vol. 6,
+ * no. 1, 1-8, 2017. Available online at http://jcgt.org/published/0006/01/01/
+*/
+
+#include <u.h>
+#include <libc.h>
+
+typedef struct Vec Vec;
+struct Vec {
+ double x, y, z;
+};
+
+vlong t0;
+
+Vec
+Vect(double x, double y, double z)
+{
+ return (Vec){x, y, z};
+}
+
+void
+frisvadONB(Vec b[3])
+{
+ double p, q;
+
+ if(b[0].z < -0.9999999){ /* handle singularity */
+ b[1] = Vect(0, -1, 0);
+ b[2] = Vect(-1, 0, 0);
+ return;
+ }
+ p = 1/(1 + b[0].z);
+ q = -b[0].x*b[0].y*p;
+ b[1] = Vect(1 - b[0].x*b[0].x*p, q, -b[0].x);
+ b[2] = Vect(q, 1 - b[0].y*b[0].y*p, -b[0].y);
+}
+
+void
+revisedONB(Vec b[3])
+{
+ double p, q;
+
+ if(b[0].z < 0){
+ p = 1/(1 - b[0].z);
+ q = b[0].x*b[0].y*p;
+ b[1] = Vect(1 - b[0].x*b[0].x*p, -q, b[0].x);
+ b[2] = Vect(q, b[0].y*b[0].y*p - 1, -b[0].y);
+ return;
+ }
+ p = 1/(1 + b[0].z);
+ q = -b[0].x*b[0].y*p;
+ b[1] = Vect(1 - b[0].x*b[0].x*p, q, -b[0].x);
+ b[2] = Vect(q, 1 - b[0].y*b[0].y*p, -b[0].y);
+}
+
+void
+revisedaONB(Vec b[3])
+{
+ double p, q, σ;
+
+ σ = b[0].z >= 0 ? 1 : -1;
+ p = -1/(σ + b[0].z);
+ q = b[0].x*b[0].y*p;
+ b[1] = Vect(1 + σ*b[0].x*b[0].x*p, σ*q, -σ*b[0].x);
+ b[2] = Vect(q, σ + b[0].y*b[0].y*p, -b[0].y);
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s x y z\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ Vec b[3];
+ int i;
+
+ ARGBEGIN{
+ default: usage();
+ }ARGEND;
+ if(argc != 3)
+ usage();
+ b[0].x = strtod(argv[0], nil);
+ b[0].y = strtod(argv[1], nil);
+ b[0].z = strtod(argv[2], nil);
+ //b[0] = Vect(0.00038527316, 0.00038460016, -0.99999988079);
+ t0 = nsec();
+ frisvadONB(b);
+ print("Frisvad's (took %lldns)\n", nsec()-t0);
+ for(i = 0; i < nelem(b); i++)
+ print("\tB%d [%g %g %g]\n", i+1, b[i].x, b[i].y, b[i].z);
+ t0 = nsec();
+ revisedONB(b);
+ print("Revised (took %lldns)\n", nsec()-t0);
+ for(i = 0; i < nelem(b); i++)
+ print("\tB%d [%g %g %g]\n", i+1, b[i].x, b[i].y, b[i].z);
+ t0 = nsec();
+ revisedaONB(b);
+ print("Revised Adv. (took %lldns)\n", nsec()-t0);
+ for(i = 0; i < nelem(b); i++)
+ print("\tB%d [%g %g %g]\n", i+1, b[i].x, b[i].y, b[i].z);
+ exits(nil);
+}
--- /dev/null
+++ b/gcd.c
@@ -1,0 +1,68 @@
+#include <u.h>
+#include <libc.h>
+
+enum {
+ Tgcd,
+ Tmod,
+ Te
+};
+vlong t[Te];
+vlong t0;
+
+void
+swap(int *a, int *b)
+{
+ int tmp;
+
+ tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+int
+gcd(int u, int v)
+{
+ while(u > 0){
+ if(u < v)
+ swap(&u, &v);
+ u = u-v;
+ }
+ return v;
+}
+
+int
+modgcd(int u, int v)
+{
+ while(u > 0){
+ if(u < v)
+ swap(&u, &v);
+ u = u % v;
+ }
+ return v;
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: gcd num den\n");
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ int n, m;
+
+ if(argc != 3)
+ sysfatal("not enough arguments");
+ n = strtol(argv[1], nil, 0);
+ m = strtol(argv[2], nil, 0);
+ t0 = nsec();
+ print("GCD %d %d = %d\n", n, m, gcd(n, m));
+ t[Tgcd] = nsec()-t0;
+ t0 = nsec();
+ print("MODGCD %d %d = %d\n", n, m, modgcd(n, m));
+ t[Tmod] = nsec()-t0;
+ print("\tgcd: %lld | mod: %lld\n", t[Tgcd], t[Tmod]);
+ exits(nil);
+}
--- /dev/null
+++ b/genrandname.c
@@ -1,0 +1,57 @@
+#include <u.h>
+#include <libc.h>
+
+enum {
+ NF,
+ NM
+};
+
+typedef struct Name Name;
+struct Name
+{
+ char *name;
+ int sex;
+};
+
+void
+genrandname(char *d, ulong len)
+{
+ Name names[] = {
+ "mariana", NF,
+ "jerca", NF,
+ "repa", NF,
+ "jaca", NF,
+ "pinta", NF,
+ "manolo", NM,
+ "eustaquio", NM,
+ "aberroncho", NM,
+ "merovingio", NM,
+ "trudi", NM
+ };
+ char *adjectives[] = {
+ "atropelladX",
+ "bacaladX",
+ "acojonadX",
+ "estrictX",
+ "diarreas",
+ "gordacX"
+ }, buf[256], *p;
+ int i;
+
+ i = ntruerand(nelem(adjectives));
+ snprint(buf, sizeof buf, "%s", adjectives[i]);
+ i = ntruerand(nelem(names));
+ if((p = strchr(buf, 'X')) != nil)
+ *p = names[i].sex == NF ? 'a' : 'o';
+ snprint(d, len, "%s%s", names[i].name, buf);
+}
+
+void
+main()
+{
+ char buf[256];
+
+ genrandname(buf, sizeof buf);
+ print("%s\n", buf);
+ exits(0);
+}
--- /dev/null
+++ b/hashing.c
@@ -1,0 +1,85 @@
+#include <u.h>
+#include <libc.h>
+
+enum {
+ MULT = 31,
+ NHASH = 37,
+};
+
+uint
+hash(char *s)
+{
+ uint h;
+
+ h = 0;
+ while(*s != 0)
+ h = MULT * h + (uchar)*s++;
+ return h % NHASH;
+}
+
+uint
+djb2(char *s)
+{
+ uint h;
+
+ h = 5381;
+ while(*s != 0)
+ h = ((h << 5) + h) + (uchar)*s++;
+ return h % NHASH;
+}
+
+uint
+djb2a(char *s)
+{
+ uint h;
+
+ h = 5381;
+ while(*s != 0)
+ h = ((h << 5) + h) ^ (uchar)*s++;
+ return h % NHASH;
+}
+
+uint
+fnv1(char *s)
+{
+ uint h;
+
+ h = 0x811c9dc5;
+ while(*s != 0)
+ h = (h*0x1000193) ^ (uchar)*s++;
+ return h % NHASH;
+}
+
+uint
+fnv1a(char *s)
+{
+ uint h;
+
+ h = 0x811c9dc5;
+ while(*s != 0)
+ h = (h^(uchar)*s++) * 0x1000193;
+ return h % NHASH;
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s word\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ ARGBEGIN{
+ default: usage();
+ }ARGEND;
+ if(argc != 1)
+ usage();
+ print("tpop:\t%ud\n", hash(*argv));
+ print("djb2:\t%ud\n", djb2(*argv));
+ print("djb2a:\t%ud\n", djb2a(*argv));
+ print("fnv1:\t%ud\n", fnv1(*argv));
+ print("fnv1a:\t%ud\n", fnv1a(*argv));
+ exits(0);
+}
--- /dev/null
+++ b/hello.c
@@ -1,0 +1,9 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+ print("Hello world\n");
+ exits(0);
+}
--- /dev/null
+++ b/hypotenuse.c
@@ -1,0 +1,59 @@
+#include <u.h>
+#include <libc.h>
+
+double
+hypot2(double p, double q)
+{
+ return sqrt(p*p + q*q);
+}
+
+double
+hypot3(double x, double y, double z)
+{
+ return sqrt(x*x + y*y + z*z);
+}
+
+double
+hypot3from2(double x, double y, double z)
+{
+ return hypot(hypot(x, z), y);
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: hypotenuse x y z\n");
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ double x, y, z, r;
+ vlong t0, t;
+
+ if(argc < 4)
+ usage();
+ x = strtod(argv[1], nil);
+ y = strtod(argv[2], nil);
+ z = strtod(argv[3], nil);
+ /*print("\t2D\n");
+ t0 = nsec();
+ r = hypot2(x, y);
+ t = nsec();
+ print("1st method: %g (%lld ns)\n", r, t-t0);
+ t0 = nsec();
+ r = hypot(x, y);
+ t = nsec();
+ print("2nd method: %g (%lld ns)\n", r, t-t0);
+ print("\t3D\n");
+ t0 = nsec();
+ r = hypot3(x, y, z);
+ t = nsec();
+ print("1st method: %g (%lld ns)\n", r, t-t0);*/
+ t0 = nsec();
+ r = hypot3from2(x, y, z);
+ t = nsec();
+ print("2nd method: %g (%lld ns)\n", r, t-t0);
+ exits(0);
+}
--- /dev/null
+++ b/imgp.c
@@ -1,0 +1,8 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+
+}
--- /dev/null
+++ b/isptrmod.c
@@ -1,0 +1,27 @@
+#include <u.h>
+#include <libc.h>
+
+/*
+ * this program proofs that effectively, pointer arguments are passed by
+ * value and its modification doesn't extend beyond the scope of the
+ * currently running procedure.
+ */
+
+void
+incptr(char *p)
+{
+ p += 3;
+ print("%s\n", p);
+}
+
+void
+main()
+{
+ char *s;
+
+ s = "hi there!";
+ print("%s\n", s);
+ incptr(s);
+ print("%s\n", s);
+ exits(0);
+}
--- /dev/null
+++ b/matrixinv.c
@@ -1,0 +1,377 @@
+#include <u.h>
+#include <libc.h>
+
+typedef double Matrix[3][3];
+typedef double Matrix3[4][4];
+
+void
+identity(Matrix m)
+{
+ memset(m, 0, 3*3*sizeof(double));
+ m[0][0] = m[1][1] = m[2][2] = 1;
+}
+
+void
+addm(Matrix a, Matrix b)
+{
+ int i, j;
+
+ for(i = 0; i < 3; i++)
+ for(j = 0; j < 3; j++)
+ a[i][j] += b[i][j];
+}
+
+void
+subm(Matrix a, Matrix b)
+{
+ int i, j;
+
+ for(i = 0; i < 3; i++)
+ for(j = 0; j < 3; j++)
+ a[i][j] -= b[i][j];
+}
+
+void
+mulm(Matrix a, Matrix b)
+{
+ int i, j, k;
+ Matrix tmp;
+
+ for(i = 0; i < 3; i++)
+ for(j = 0; j < 3; j++){
+ tmp[i][j] = 0;
+ for(k = 0; k < 3; k++)
+ tmp[i][j] += a[i][k]*b[k][j];
+ }
+ memmove(a, tmp, 3*3*sizeof(double));
+}
+
+void
+smulm(Matrix m, double s)
+{
+ int i, j;
+
+ for(i = 0; i < 3; i++)
+ for(j = 0; j < 3; j++)
+ m[i][j] *= s;
+}
+
+double
+detm(Matrix m)
+{
+ return m[0][0]*(m[1][1]*m[2][2] - m[1][2]*m[2][1])+
+ m[0][1]*(m[1][2]*m[2][0] - m[1][0]*m[2][2])+
+ m[0][2]*(m[1][0]*m[2][1] - m[1][1]*m[2][0]);
+}
+
+double
+tracem(Matrix m)
+{
+ return m[0][0] + m[1][1] + m[2][2];
+}
+
+/* Cayley-Hamilton */
+void
+invertm(Matrix m)
+{
+ Matrix m², r;
+ double det, trm, trm²;
+
+ det = detm(m);
+ if(det == 0)
+ return; /* singular matrices are not invertible */
+ trm = tracem(m);
+ memmove(m², m, 3*3*sizeof(double));
+ mulm(m², m²);
+ trm² = tracem(m²);
+ identity(r);
+ smulm(r, (trm*trm - trm²)/2);
+ smulm(m, trm);
+ subm(r, m);
+ addm(r, m²);
+ smulm(r, 1/det);
+ memmove(m, r, 3*3*sizeof(double));
+}
+
+/* Cramer's */
+void
+adjm(Matrix m)
+{
+ Matrix tmp;
+
+ tmp[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1];
+ tmp[0][1] = -m[0][1]*m[2][2] + m[0][2]*m[2][1];
+ tmp[0][2] = m[0][1]*m[1][2] - m[0][2]*m[1][1];
+ tmp[1][0] = -m[1][0]*m[2][2] + m[1][2]*m[2][0];
+ tmp[1][1] = m[0][0]*m[2][2] - m[0][2]*m[2][0];
+ tmp[1][2] = -m[0][0]*m[1][2] + m[0][2]*m[1][0];
+ tmp[2][0] = m[1][0]*m[2][1] - m[1][1]*m[2][0];
+ tmp[2][1] = -m[0][0]*m[2][1] + m[0][1]*m[2][0];
+ tmp[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0];
+ memmove(m, tmp, 3*3*sizeof(double));
+}
+
+void
+cinvertm(Matrix m)
+{
+ double det;
+
+ det = detm(m);
+ if(det == 0)
+ return; /* singular matrices are not invertible */
+ adjm(m);
+ smulm(m, 1/det);
+}
+
+void
+identity3(Matrix3 m)
+{
+ memset(m, 0, 4*4*sizeof(double));
+ m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1;
+}
+
+void
+addm3(Matrix3 a, Matrix3 b)
+{
+ int i, j;
+
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < 4; j++)
+ a[i][j] += b[i][j];
+}
+
+void
+subm3(Matrix3 a, Matrix3 b)
+{
+ int i, j;
+
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < 4; j++)
+ a[i][j] -= b[i][j];
+}
+
+void
+mulm3(Matrix3 a, Matrix3 b)
+{
+ int i, j, k;
+ Matrix3 tmp;
+
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < 4; j++){
+ tmp[i][j] = 0;
+ for(k = 0; k < 4; k++)
+ tmp[i][j] += a[i][k]*b[k][j];
+ }
+ memmove(a, tmp, 4*4*sizeof(double));
+}
+
+void
+smulm3(Matrix3 m, double s)
+{
+ int i, j;
+
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < 4; j++)
+ m[i][j] *= s;
+}
+
+double
+detm3(Matrix3 m)
+{
+ return m[0][0]*(m[1][1]*(m[2][2]*m[3][3] - m[2][3]*m[3][2])+
+ m[1][2]*(m[2][3]*m[3][1] - m[2][1]*m[3][3])+
+ m[1][3]*(m[2][1]*m[3][2] - m[2][2]*m[3][1]))
+ -m[0][1]*(m[1][0]*(m[2][2]*m[3][3] - m[2][3]*m[3][2])+
+ m[1][2]*(m[2][3]*m[3][0] - m[2][0]*m[3][3])+
+ m[1][3]*(m[2][0]*m[3][2] - m[2][2]*m[3][0]))
+ +m[0][2]*(m[1][0]*(m[2][1]*m[3][3] - m[2][3]*m[3][1])+
+ m[1][1]*(m[2][3]*m[3][0] - m[2][0]*m[3][3])+
+ m[1][3]*(m[2][0]*m[3][1] - m[2][1]*m[3][0]))
+ -m[0][3]*(m[1][0]*(m[2][1]*m[3][2] - m[2][2]*m[3][1])+
+ m[1][1]*(m[2][2]*m[3][0] - m[2][0]*m[3][2])+
+ m[1][2]*(m[2][0]*m[3][1] - m[2][1]*m[3][0]));
+}
+
+double
+tracem3(Matrix3 m)
+{
+ return m[0][0] + m[1][1] + m[2][2] + m[3][3];
+}
+
+void
+adjm3(Matrix3 m)
+{
+ Matrix3 tmp;
+
+ tmp[0][0]=m[1][1]*(m[2][2]*m[3][3] - m[2][3]*m[3][2])+
+ m[2][1]*(m[1][3]*m[3][2] - m[1][2]*m[3][3])+
+ m[3][1]*(m[1][2]*m[2][3] - m[1][3]*m[2][2]);
+ tmp[0][1]=m[0][1]*(m[2][3]*m[3][2] - m[2][2]*m[3][3])+
+ m[2][1]*(m[0][2]*m[3][3] - m[0][3]*m[3][2])+
+ m[3][1]*(m[0][3]*m[2][2] - m[0][2]*m[2][3]);
+ tmp[0][2]=m[0][1]*(m[1][2]*m[3][3] - m[1][3]*m[3][2])+
+ m[1][1]*(m[0][3]*m[3][2] - m[0][2]*m[3][3])+
+ m[3][1]*(m[0][2]*m[1][3] - m[0][3]*m[1][2]);
+ tmp[0][3]=m[0][1]*(m[1][3]*m[2][2] - m[1][2]*m[2][3])+
+ m[1][1]*(m[0][2]*m[2][3] - m[0][3]*m[2][2])+
+ m[2][1]*(m[0][3]*m[1][2] - m[0][2]*m[1][3]);
+ tmp[1][0]=m[1][0]*(m[2][3]*m[3][2] - m[2][2]*m[3][3])+
+ m[2][0]*(m[1][2]*m[3][3] - m[1][3]*m[3][2])+
+ m[3][0]*(m[1][3]*m[2][2] - m[1][2]*m[2][3]);
+ tmp[1][1]=m[0][0]*(m[2][2]*m[3][3] - m[2][3]*m[3][2])+
+ m[2][0]*(m[0][3]*m[3][2] - m[0][2]*m[3][3])+
+ m[3][0]*(m[0][2]*m[2][3] - m[0][3]*m[2][2]);
+ tmp[1][2]=m[0][0]*(m[1][3]*m[3][2] - m[1][2]*m[3][3])+
+ m[1][0]*(m[0][2]*m[3][3] - m[0][3]*m[3][2])+
+ m[3][0]*(m[0][3]*m[1][2] - m[0][2]*m[1][3]);
+ tmp[1][3]=m[0][0]*(m[1][2]*m[2][3] - m[1][3]*m[2][2])+
+ m[1][0]*(m[0][3]*m[2][2] - m[0][2]*m[2][3])+
+ m[2][0]*(m[0][2]*m[1][3] - m[0][3]*m[1][2]);
+ tmp[2][0]=m[1][0]*(m[2][1]*m[3][3] - m[2][3]*m[3][1])+
+ m[2][0]*(m[1][3]*m[3][1] - m[1][1]*m[3][3])+
+ m[3][0]*(m[1][1]*m[2][3] - m[1][3]*m[2][1]);
+ tmp[2][1]=m[0][0]*(m[2][3]*m[3][1] - m[2][1]*m[3][3])+
+ m[2][0]*(m[0][1]*m[3][3] - m[0][3]*m[3][1])+
+ m[3][0]*(m[0][3]*m[2][1] - m[0][1]*m[2][3]);
+ tmp[2][2]=m[0][0]*(m[1][1]*m[3][3] - m[1][3]*m[3][1])+
+ m[1][0]*(m[0][3]*m[3][1] - m[0][1]*m[3][3])+
+ m[3][0]*(m[0][1]*m[1][3] - m[0][3]*m[1][1]);
+ tmp[2][3]=m[0][0]*(m[1][3]*m[2][1] - m[1][1]*m[2][3])+
+ m[1][0]*(m[0][1]*m[2][3] - m[0][3]*m[2][1])+
+ m[2][0]*(m[0][3]*m[1][1] - m[0][1]*m[1][3]);
+ tmp[3][0]=m[1][0]*(m[2][2]*m[3][1] - m[2][1]*m[3][2])+
+ m[2][0]*(m[1][1]*m[3][2] - m[1][2]*m[3][1])+
+ m[3][0]*(m[1][2]*m[2][1] - m[1][1]*m[2][2]);
+ tmp[3][1]=m[0][0]*(m[2][1]*m[3][2] - m[2][2]*m[3][1])+
+ m[2][0]*(m[0][2]*m[3][1] - m[0][1]*m[3][2])+
+ m[3][0]*(m[0][1]*m[2][2] - m[0][2]*m[2][1]);
+ tmp[3][2]=m[0][0]*(m[1][2]*m[3][1] - m[1][1]*m[3][2])+
+ m[1][0]*(m[0][1]*m[3][2] - m[0][2]*m[3][1])+
+ m[3][0]*(m[0][2]*m[1][1] - m[0][1]*m[1][2]);
+ tmp[3][3]=m[0][0]*(m[1][1]*m[2][2] - m[1][2]*m[2][1])+
+ m[1][0]*(m[0][2]*m[2][1] - m[0][1]*m[2][2])+
+ m[2][0]*(m[0][1]*m[1][2] - m[0][2]*m[1][1]);
+ memmove(m, tmp, 4*4*sizeof(double));
+}
+
+void
+invertm3(Matrix3 m)
+{
+ Matrix3 m², m³, r;
+ double det, trm, trm², trm³;
+
+ det = detm3(m);
+ if(det == 0)
+ return; /* singular matrices are not invertible */
+ trm = tracem3(m);
+ memmove(m³, m, 4*4*sizeof(double));
+ mulm3(m³, m³);
+ mulm3(m³, m);
+ trm³ = tracem3(m³);
+ memmove(m², m, 4*4*sizeof(double));
+ mulm3(m², m²);
+ trm² = tracem3(m²);
+ identity3(r);
+ smulm3(r, (trm*trm*trm - 3*trm*trm² + 2*trm³)/6);
+ smulm3(m, (trm*trm - trm²)/2);
+ smulm3(m², trm);
+ subm3(r, m);
+ addm3(r, m²);
+ subm3(r, m³);
+ smulm3(r, 1/det);
+ memmove(m, r, 4*4*sizeof(double));
+}
+
+void
+cinvertm3(Matrix3 m)
+{
+ double det;
+
+ det = detm3(m);
+ if(det == 0)
+ return; /* singular matrices are not invertible */
+ adjm3(m);
+ smulm3(m, 1/det);
+}
+
+void
+printm(Matrix m)
+{
+ int i, j;
+
+ for(i = 0; i < 3; i++){
+ for(j = 0; j < 3; j++)
+ print("\t%g", m[i][j]);
+ print("\n");
+ }
+}
+
+void
+printm3(Matrix3 m)
+{
+ int i, j;
+
+ for(i = 0; i < 4; i++){
+ for(j = 0; j < 4; j++)
+ print("\t%g", m[i][j]);
+ print("\n");
+ }
+}
+
+vlong t0, t;
+
+void
+main()
+{
+ Matrix m = {
+ // 7, 2, 1,
+ // 0, 3, -1,
+ // -3, 4, -2
+ /* near-singular */
+ 1, 1, 1,
+ 0, 1, 0,
+ 1, 0, 1.01
+ }, invm, cinvm;
+ Matrix3 M = {
+ 1, 1, 1, -1,
+ 1, 1, -1, 1,
+ 1, -1, 1, 1,
+ -1, 1, 1, 1
+ }, invM, cinvM;
+
+ memmove(invm, m, 3*3*sizeof(double));
+ memmove(cinvm, m, 3*3*sizeof(double));
+ print("M:\n");
+ printm(m);
+ t0 = nsec();
+ invertm(invm);
+ t = nsec()-t0;
+ print("M⁻¹(%lldns):\n", t);
+ printm(invm);
+ t0 = nsec();
+ cinvertm(cinvm);
+ t = nsec()-t0;
+ print("CM⁻¹(%lldns):\n", t);
+ printm(cinvm);
+ mulm(m, invm);
+ print("MM⁻¹:\n");
+ printm(m);
+ memmove(invM, M, 4*4*sizeof(double));
+ memmove(cinvM, M, 4*4*sizeof(double));
+ print("M:\n");
+ printm3(M);
+ t0 = nsec();
+ invertm3(invM);
+ t = nsec()-t0;
+ print("M⁻¹(%lldns):\n", t);
+ printm3(invM);
+ t0 = nsec();
+ cinvertm3(cinvM);
+ t = nsec()-t0;
+ print("CM⁻¹(%lldns):\n", t);
+ printm3(cinvM);
+ mulm3(M, invM);
+ print("MM⁻¹:\n");
+ printm3(M);
+ exits(nil);
+}
--- /dev/null
+++ b/matrixmul.c
@@ -1,0 +1,53 @@
+#include <u.h>
+#include <libc.h>
+
+typedef double Matrix[4][4];
+
+void
+mulm(Matrix a, Matrix b)
+{
+ int i, j, k;
+ Matrix r;
+
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < 4; j++){
+ r[i][j] = 0;
+ for(k = 0; k < 4; k++)
+ r[i][j] += a[i][k]*b[k][j];
+ }
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < 4; j++)
+ a[i][j] = r[i][j];
+}
+
+void
+printm(Matrix m)
+{
+ int i, j;
+
+ for(i = 0; i < 4; i++){
+ for(j = 0; j < 4; j++)
+ print("%g\t", m[i][j]);
+ print("\n");
+ }
+}
+
+void
+main()
+{
+ Matrix m1 = {
+ 1, 2, -1, 0,
+ 2, 0, 1, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0
+ };
+ Matrix m2 = {
+ 3, 1, 0, 0,
+ 0, -1, 0, 0,
+ -2, 3, 0, 0,
+ 0, 0, 0, 0
+ };
+ mulm(m1, m2);
+ printm(m1);
+ exits(0);
+}
--- /dev/null
+++ b/minhello.c
@@ -1,0 +1,9 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+ write(1, "Hello world\n", 12);
+ exits(0);
+}
--- /dev/null
+++ b/multibatt.c
@@ -1,0 +1,30 @@
+#include <u.h>
+#include <libc.h>
+
+char f[] = "/mnt/acpi/battery";
+char buf[512];
+char *s;
+int nb = 0;
+
+void
+main(void)
+{
+ int fd;
+
+ fd = open(f, OREAD);
+ if(fd < 0)
+ sysfatal("open: %r");
+
+ read(fd, buf, sizeof buf);
+
+ buf[strlen(buf)-1] = '\0';
+
+ print("%d\n", atoi(buf)); nb++;
+ for(s = buf; *s != '\0'; s++)
+ if(*s == '\n'){
+ nb++;
+ print("%d\n", atoi(++s));
+ }
+ print("batteries: %d\n", nb);
+ exits("done");
+}
--- /dev/null
+++ b/nhello.c
@@ -1,0 +1,15 @@
+#include <u.h>
+#include <libc.h>
+
+char c;
+int n;
+
+void
+main()
+{
+ read(0, &c, 1);
+ n = c-'0';
+ while(n-- > 0)
+ write(1, "Hola mundo.\n", 12);
+ exits(0);
+}
--- /dev/null
+++ b/nonrecurfact.c
@@ -1,0 +1,58 @@
+/* non-recursive factorial */
+#include <u.h>
+#include <libc.h>
+
+void
+printdec(int n)
+{
+ char s[16], *p;
+ int r;
+
+ p = s+16;
+ *--p = '\n';
+ for(;;){
+ r = n%10;
+ *--p = '0'+r;
+ n /= 10;
+ if(n == 0 || p == s)
+ break;
+ }
+ write(1, p, s+sizeof(s)-p);
+}
+
+int
+fact(int n)
+{
+ int a;
+
+ a = n;
+repeat:
+ if(n <= 0)
+ return 0;
+ else if(n == 1)
+ return a;
+ a *= --n;
+ goto repeat;
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s n\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ int n;
+
+ ARGBEGIN{
+ default: usage();
+ }ARGEND;
+ if(argc != 1)
+ usage();
+ n = strtol(argv[0], nil, 0);
+ printdec(fact(n));
+ exits(0);
+}
--- /dev/null
+++ b/prec.c
@@ -1,0 +1,14 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+ char s[] = ",.";
+ char *p;
+
+ p = s;
+ while(*p++ == '.' || *p == '.')
+ print("dot");
+ exits(0);
+}
--- /dev/null
+++ b/prec2.c
@@ -1,0 +1,15 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+ int n;
+ int *p;
+
+ n = 4;
+ p = &n;
+ print("%d\n", ++*p);
+ print("%d\n", n);
+ exits(0);
+}
--- /dev/null
+++ b/printdec.c
@@ -1,0 +1,60 @@
+#include <u.h>
+#include <libc.h>
+
+void
+swap(char *a, char *b)
+{
+ char tmp;
+
+ tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+void
+srev(char *s, char *e)
+{
+ while(s < e)
+ swap(s++, e--);
+}
+
+void
+printdec(int n)
+{
+ char buf[16];
+ char *p, *e;
+ int r;
+
+ p = buf;
+ e = buf+sizeof(buf)-1;
+ while(n > 0 && p < e){
+ r = n%10;
+ *p++ = '0'+r;
+ n /= 10;
+ }
+ *p = 0;
+ print("%s\n", buf);
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s number\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ int n;
+
+ ARGBEGIN{
+ default: usage();
+ }ARGEND
+ if(argc != 1)
+ usage();
+ srev(argv[0], argv[0]+strlen(argv[0])-1);
+ n = strtol(argv[0], nil, 10);
+ printdec(n);
+ exits(0);
+}
--- /dev/null
+++ b/qrot.c
@@ -1,0 +1,94 @@
+#include <u.h>
+#include <libc.h>
+
+#define DEG 0.01745329251994330
+
+typedef struct Quaternion Quaternion;
+struct Quaternion {
+ double r, i, j, k;
+};
+typedef struct Point3 Point3;
+struct Point3 {
+ double x, y, z, w;
+};
+
+Point3
+Vec3(double x, double y, double z)
+{
+ return (Point3){x, y, z, 0};
+}
+
+Point3
+addpt3(Point3 a, Point3 b)
+{
+ return (Point3){a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w};
+}
+
+Point3
+mulpt3(Point3 p, double s)
+{
+ return (Point3){p.x*s, p.y*s, p.z*s, p.w*s};
+}
+
+double
+dotvec3(Point3 a, Point3 b)
+{
+ return a.x*b.x + a.y*b.y + a.z*b.z;
+}
+
+Point3
+crossvec3(Point3 a, Point3 b)
+{
+ return (Point3){
+ a.y*b.z - a.z*b.y,
+ a.z*b.x - a.x*b.z,
+ a.x*b.y - a.y*b.x,
+ 0
+ };
+}
+
+Quaternion
+mulq(Quaternion q, Quaternion r)
+{
+ Point3 qv, rv, tmp;
+
+ qv = Vec3(q.i, q.j, q.k);
+ rv = Vec3(r.i, r.j, r.k);
+ tmp = addpt3(addpt3(mulpt3(rv, q.r), mulpt3(qv, r.r)), crossvec3(qv, rv));
+ return (Quaternion){q.r*r.r - dotvec3(qv, rv), tmp.x, tmp.y, tmp.z};
+}
+
+Quaternion
+invq(Quaternion q)
+{
+ double len²;
+
+ len² = q.r*q.r + q.i*q.i + q.j*q.j + q.k*q.k;
+ if(len² == 0)
+ return (Quaternion){0, 0, 0, 0};
+ return (Quaternion){q.r/len², -q.i/len², -q.j/len², -q.k/len²};
+}
+
+#pragma varargck type "q" Quaternion
+int
+qfmt(Fmt *f)
+{
+ Quaternion q;
+
+ q = va_arg(f->args, Quaternion);
+ return fmtprint(f, "[%g %g %g %g]", q.r, q.i, q.j, q.k);
+}
+
+void
+main()
+{
+ Quaternion q;
+ double c, s;
+
+ fmtinstall('q', qfmt);
+ c = cos(45*DEG);
+ s = sin(45*DEG);
+ q = (Quaternion){c, s, s, s};
+ print("q %q\nq⁻¹ %q\nqq⁻¹ %q\n", q, invq(q), mulq(q, invq(q)));
+ exits(nil);
+}
--- /dev/null
+++ b/que.c
@@ -1,0 +1,70 @@
+#include <u.h>
+#include <libc.h>
+
+typedef struct Node Node;
+struct Node {
+ int n;
+ Node *next;
+};
+
+Node *head, *tail;
+
+void *
+emalloc(ulong n)
+{
+ void *p;
+
+ p = malloc(n);
+ if(p == nil)
+ sysfatal("malloc: %r");
+ memset(p, 0, n);
+ setmalloctag(p, getcallerpc(&n));
+ return p;
+}
+
+void
+put(int n)
+{
+ if(tail == nil){
+ tail = emalloc(sizeof(Node));
+ tail->n = n;
+ head = tail;
+ return;
+ }
+ tail->next = emalloc(sizeof(Node));
+ tail = tail->next;
+ tail->n = n;
+}
+
+int
+get(void)
+{
+ Node *nn;
+ int n;
+
+ if(head == nil)
+ return -1;
+ nn = head->next;
+ n = head->n;
+ free(head);
+ head = nn;
+ return n;
+}
+
+int
+isemtpy(void)
+{
+ return head == nil;
+}
+
+void
+main()
+{
+ int i;
+
+ for(i = 0; i < 10; i++)
+ put(i*3);
+ while(!isemtpy())
+ print("%d\n", get());
+ exits(nil);
+}
--- /dev/null
+++ b/ret.c
@@ -1,0 +1,19 @@
+#include <u.h>
+#include <libc.h>
+
+int
+ret(void)
+{
+ if(2 > 3)
+ return 2;
+ else
+ exits("error");
+ return -1;
+}
+
+void
+main()
+{
+ ret();
+ exits(0);
+}
--- /dev/null
+++ b/rev.c
@@ -1,0 +1,48 @@
+#include <u.h>
+#include <libc.h>
+
+void
+swap(char *a, char *b)
+{
+ char tmp;
+
+ tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+void
+rev(char *s, ulong len)
+{
+ char *e;
+
+ e = s+len;
+ while(s < e)
+ swap(s++, --e);
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s text ...\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ int first;
+
+ first = 1;
+ ARGBEGIN{
+ default: usage();
+ }ARGEND;
+ if(argc < 1)
+ usage();
+ while(argc--){
+ rev(argv[argc], strlen(argv[argc]));
+ print(first ? first--, "%s" : " %s", argv[argc]);
+ }
+ print("\n");
+ exits(nil);
+}
--- /dev/null
+++ b/revdonewrong.c
@@ -1,0 +1,42 @@
+#include <u.h>
+#include <libc.h>
+
+void
+swap(char *a, char *b)
+{
+ char tmp;
+
+ tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+void
+rev(char *s, ulong len)
+{
+ char *e;
+
+ e = s+len;
+ while(s != e)
+ swap(s++, --e);
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s text\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ ARGBEGIN{
+ default: usage();
+ }ARGEND;
+ if(argc != 1)
+ usage();
+ rev(argv[0], strlen(argv[0]));
+ print("%s\n", argv[0]);
+ exits(nil);
+}
--- /dev/null
+++ b/reverse.c
@@ -1,0 +1,42 @@
+#include <u.h>
+#include <libc.h>
+
+char *
+reverse(char *s, int n)
+{
+ int i;
+ char tmp;
+
+ for(i = 0; i < n/2; i++){
+ tmp = s[i];
+ s[i] = s[n-i-1];
+ s[n-i-1] = tmp;
+ }
+ return s;
+}
+
+char *
+reversep(char *s, int n)
+{
+ char *bp, *ep;
+ char tmp;
+
+ for(bp = s, ep = s+n-1; bp != ep; bp++, ep--){
+ tmp = *bp;
+ *bp = *ep;
+ *ep = tmp;
+ }
+ return s;
+}
+
+void
+main()
+{
+ char s[] = "hello";
+
+ print("%s → ", s);
+ print("%s\n", reverse(s, strlen(s)));
+ print("%s → ", s);
+ print("%s\n", reversep(s, strlen(s)));
+ exits(0);
+}
--- /dev/null
+++ b/rounding.c
@@ -1,0 +1,37 @@
+#include <u.h>
+#include <libc.h>
+
+double
+roundf(double n)
+{
+ return floor(n + 0.5);
+}
+
+int
+roundi(double n)
+{
+ return n+0.5;
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s number\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ double n;
+
+ ARGBEGIN{
+ default: usage();
+ }ARGEND;
+ if(argc != 1)
+ usage();
+ n = strtod(argv[0], nil);
+ print("%g\n", roundf(n));
+ print("%d\n", roundi(n));
+ exits(0);
+}
--- /dev/null
+++ b/rpn.c
@@ -1,0 +1,51 @@
+#include <u.h>
+#include <libc.h>
+#include <ctype.h>
+#include <bio.h>
+
+int stk[256], sp;
+Biobuf *bin;
+
+void
+push(int n)
+{
+ if(sp >= sizeof stk)
+ sp = sizeof(stk)-1;
+ fprint(2, "push [%d] %d\n", sp, n);
+ stk[sp++] = n;
+}
+
+int
+pop(void)
+{
+ if(sp <= 0)
+ sp = 1;
+ fprint(2, "pop [%d] %d\n", sp-1, stk[sp-1]);
+ return stk[--sp];
+}
+
+void
+main()
+{
+ int x;
+ char c;
+
+ bin = Bfdopen(0, OREAD);
+ if(bin == nil)
+ sysfatal("Bfdopen: %r");
+ while((c = Bgetc(bin)) != Beof){
+ x = 0;
+ switch(c){
+ case '+': x = pop() + pop(); break;
+ case '*': x = pop() * pop(); break;
+ default:
+ while(isdigit(c)){
+ x = x*10 + c-'0';
+ c = Bgetc(bin);
+ }
+ }
+ push(x);
+ }
+ print("%d\n", pop());
+ exits(nil);
+}
--- /dev/null
+++ b/seeking.c
@@ -1,0 +1,24 @@
+#include <u.h>
+#include <libc.h>
+
+#define MAXREADS 3
+
+void
+main(void)
+{
+ int fd, i;
+ char buf[4];
+
+ fd = open("/mnt/acpi/battery", OREAD);
+ if(fd < 0)
+ sysfatal("couldn't open it");
+
+ for(i = 0; i < MAXREADS; i++){
+ pread(fd, buf, sizeof buf, 0);
+ buf[sizeof(buf)-1] = '\0';
+ print(buf);
+ }
+
+ close(fd);
+ exits("done");
+}
--- /dev/null
+++ b/signed.c
@@ -1,0 +1,14 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+ int x;
+
+ x = 25;
+ print("n:%d,s:%d\n", x, (x>>31));
+ x *= -1;
+ print("n:%d,s:%d\n", x, (x>>31));
+ exits(0);
+}
--- /dev/null
+++ b/sizeof2d.c
@@ -1,0 +1,11 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+ char m[10][5];
+
+ print("%d\n", sizeof(m));
+ exits(nil);
+}
--- /dev/null
+++ b/smiley.pic
@@ -1,0 +1,26 @@
+.PS
+define smiley {
+ # takes three arguments: x, y and size (radius)
+
+ r0 = $3 # Face
+ r1 = 0.4*r0 # Radius of mouth and eye locations
+ r2 = 0.04*r0 # Radius of eyes
+
+C: circle rad r0 at ( $1, $2 )
+
+ circle rad r2 filled at last circle + ( r1, r1 ) # Right eye
+ circle rad r2 filled at 2nd last circle + ( -r1, r1 ) # Left eye
+
+ pi = atan2( 0, -1 )
+S: C + ( r1 * cos(1.25*pi), r1 * sin(1.25*pi) )
+ line from S to S
+ for phi=1.25*pi to 1.75*pi by 0.1 do {
+ line to C + ( r1 * cos(phi), r1 * sin(phi) ) # Mouth
+ }
+}
+
+pi2 = 2 * atan2( 0, -1 )
+for x=0.1 to 1.3 by 0.08 do {
+ smiley( 1.5 * x * cos(x*pi2), 1.1 * x * sin(x*pi2), 0.23 * x )
+}
+.PE
--- /dev/null
+++ b/snprintandf.c
@@ -1,0 +1,18 @@
+#include <u.h>
+#include <libc.h>
+#include <stdio.h>
+
+void
+main()
+{
+ char *s;
+ int l;
+
+ s = malloc(128);
+ l = snprint(s, 128, "%s%s", "hi", "there");
+ print("%s(%d)\n", s, l);
+ l = snprintf(s, 128, "%s%s", "hi", "there");
+ print("%s(%d)\n", s, l);
+ free(s);
+ exits(0);
+}
--- /dev/null
+++ b/snprinting.c
@@ -1,0 +1,13 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+ char buf[128];
+ int n;
+
+ n = snprint(buf, sizeof buf, "%s:%d\n", "actual.out", 2);
+ print("%d\n", n);
+ exits(0);
+}
--- /dev/null
+++ b/spranimate.c
@@ -1,0 +1,98 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+
+enum { SEC = 1000 };
+
+enum {
+ Cred,
+ Cgrn,
+
+ Cbg,
+
+ Cgx,
+ Cend
+};
+Image *col[Cend];
+
+int dx, dy;
+
+void *
+emalloc(ulong n)
+{
+ void *p;
+
+ p = malloc(n);
+ if(p == nil)
+ sysfatal("malloc: %r");
+ memset(p, 0, n);
+ setmalloctag(p, getcallerpc(&n));
+ return p;
+}
+
+Image *
+eallocimage(Display *d, Rectangle r, ulong chan, int repl, ulong col)
+{
+ Image *i;
+
+ i = allocimage(d, r, chan, repl, col);
+ if(i == nil)
+ sysfatal("allocimage: %r");
+ return i;
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: spranimate\n");
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ Image *spnr, *spnmsk;
+ double θ;
+ uchar *gx;
+ int ds, i, x, y, inc, frame;
+
+ ARGBEGIN{
+ default: usage();
+ }ARGEND;
+
+ if(initdraw(nil, nil, "spranimate") < 0)
+ sysfatal("initdraw: %r");
+ dx = Dx(screen->r), dy = Dy(screen->r);
+ col[Cred] = eallocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DRed);
+ col[Cgrn] = eallocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DGreen);
+ col[Cbg] = eallocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DNofill);
+ ds = dx > dy ? dy : dx;
+ spnr = eallocimage(display, Rect(0, 0, ds*60, ds), RGBA32, 0, DTransparent);
+ spnmsk = eallocimage(display, Rect(0, 0, ds, ds), GREY1, 0, DWhite);
+ col[Cgx] = eallocimage(display, Rect(0, 0, 60, 1), GREY8, 1, DNofill);
+ gx = emalloc(60);
+ for(i = 0; i < 60; i++)
+ gx[i] = 255.0 * i/(60-1);
+ for(i = 0; i < 60; i++){
+ θ = 2*PI * i/60;
+ x = (ds/2 - 5) * cos(θ);
+ y = (ds/2 - 5) * sin(θ);
+ line(spnr, Pt(x + ds/2 + ds*i, y + ds/2), Pt(-x + ds/2 + ds*i, -y + ds/2), Endarrow, Endsquare, 1, display->black, ZP);
+ }
+ loadimage(col[Cgx], col[Cgx]->r, gx, dx);
+ x = inc = frame = 0;
+ for(;;){
+ draw(col[Cbg], col[Cbg]->r, col[Cred], nil, ZP);
+ if(x == 0)
+ inc = 1;
+ else if(x == 60-1)
+ inc = -1;
+ x += inc;
+ gendraw(col[Cbg], col[Cbg]->r, col[Cgrn], ZP, col[Cgx], Pt(x, 0));
+ draw(screen, screen->r, col[Cbg], nil, ZP);
+ frame = (frame+1) % 60;
+ gendraw(screen, screen->r, spnr, Pt(frame*ds, 0), spnmsk, ZP);
+ flushimage(display, 1);
+ sleep(SEC/60);
+ }
+}
--- /dev/null
+++ b/strlen.c
@@ -1,0 +1,11 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+ char txt[] = "i'm here now\n";
+
+ print("len: %ld, lastchar: %c\n", strlen(txt), txt[strlen(txt)-1]);
+ exits(nil);
+}
--- /dev/null
+++ b/structcmp.c
@@ -1,0 +1,32 @@
+#include <u.h>
+#include <libc.h>
+
+enum {
+ A = 1,
+ B = 2,
+ C = 4,
+ D = 8
+};
+
+typedef struct Fruit Fruit;
+struct Fruit {
+ char *name;
+ int vitamins;
+};
+
+void
+main()
+{
+ Fruit apple, lemon, apple2;
+
+ apple = (Fruit){"apple", C};
+ lemon = (Fruit){"lemon", B|C};
+ apple2 = (Fruit){"apple", C};
+ if(apple == apple)
+ fprint(2, "apple equals apple\n");
+ if(apple == apple2)
+ fprint(2, "apple equals apple2\n");
+ if(apple == lemon)
+ fprint(2, "apple equals lemon, really?\n");
+ exits(0);
+}
--- /dev/null
+++ b/structvsarray.c
@@ -1,0 +1,61 @@
+#include <u.h>
+#include <libc.h>
+
+enum {
+ Ts,
+ Tp,
+ Ta,
+ Tend
+};
+
+typedef struct Vec Vec;
+struct Vec {
+ double x, y, z;
+};
+
+typedef double Veca[3];
+
+vlong t[Tend], t0;
+
+Vec
+addvec(Vec a, Vec b)
+{
+ return (Vec){a.x+b.x, a.y+b.y, a.z+b.z};
+}
+
+void
+addvecp(Vec *a, Vec *b)
+{
+ a->x += b->x;
+ a->y += b->y;
+ a->z += b->z;
+}
+
+void
+addveca(Veca a, Veca b)
+{
+ a[0] += b[0];
+ a[1] += b[1];
+ a[2] += b[2];
+}
+
+void
+main()
+{
+ Vec a = {5, 2, 19};
+ Vec b = {213, 30, -12};
+ Veca aa = {2, 9, -1};
+ Veca ab = {-10, 20, 30};
+
+ t0 = nsec();
+ a = addvec(a, b);
+ t[Ts] = nsec()-t0;
+ t0 = nsec();
+ addvecp(&a, &b);
+ t[Tp] = nsec()-t0;
+ t0 = nsec();
+ addveca(aa, ab);
+ t[Ta] = nsec()-t0;
+ print("struct\t%lldns\nstruct*\t%lldns\narray\t%lldns\n", t[Ts], t[Tp], t[Ta]);
+ exits(nil);
+}
--- /dev/null
+++ b/sum.s
@@ -1,0 +1,4 @@
+TEXT sum(SB), $0
+ MOVL b+8(FP), AX
+ ADDL BP, AX
+ RET
--- /dev/null
+++ b/sumain.c
@@ -1,0 +1,14 @@
+#include <u.h>
+#include <libc.h>
+
+int sum(int, int);
+
+void
+main()
+{
+ int n;
+
+ n = sum(24, 30);
+ print("Σ = %d\n", n);
+ exits(nil);
+}
--- /dev/null
+++ b/t.c
@@ -1,0 +1,48 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <thread.h>
+
+Channel *spamchan;
+
+void
+freethread(void *)
+{
+ char *v = nil;
+
+ threadsetname("freethread");
+Loop:
+ recv(spamchan, &v);
+ if(v == nil){
+ print("nothing to free\n");
+ threadexitsall(0);
+ }
+ print("freeing %s\n", v);
+ free(v);
+ goto Loop;
+}
+
+void
+spammer(void*)
+{
+ int i;
+ char *s;
+
+ threadsetname("spammer");
+ for(i = 0; i < 10; ++i){
+ s = smprint("%d", i);
+ send(spamchan, &s);
+ }
+ send(spamchan, nil);
+}
+
+void
+threadmain(int argc, char *argv[])
+{
+ print("acid -l thread %d\n", getpid());
+ threadsetname("main");
+ spamchan = chancreate(sizeof(char*), 0);
+ threadcreate(spammer, nil, 8192);
+ threadcreate(freethread, nil, 8192);
+ yield();
+}
--- /dev/null
+++ b/test.c
@@ -1,0 +1,14 @@
+#include <u.h>
+#include <libc.h>
+
+void
+greet(void)
+{
+ write(1, "hello world\n", 12);
+}
+
+void
+main()
+{
+ greet();
+}
--- /dev/null
+++ b/tok.c
@@ -1,0 +1,16 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main()
+{
+ char buf[256], *f[10];
+ int nf, i;
+
+ while(read(0, buf, sizeof(buf)-1) > 0){
+ nf = tokenize(buf, f, nelem(f));
+ for(i = 0; i < nf; i++)
+ fprint(2, "%d: %s\n", i, f[i]);
+ }
+ exits(0);
+}
--- /dev/null
+++ b/transpose.c
@@ -1,0 +1,49 @@
+#include <u.h>
+#include <libc.h>
+
+#define N 4
+
+typedef double Matrix[N][N];
+
+void
+transpose(Matrix a)
+{
+ int i, j;
+ double tmp;
+
+ for(i = 0; i < N; i++)
+ for(j = i; j < N; j++){
+ tmp = a[i][j];
+ a[i][j] = a[j][i];
+ a[j][i] = tmp;
+ }
+}
+
+void
+printm(Matrix m)
+{
+ int i, j;
+
+ for(i = 0; i < N; i++){
+ for(j = 0; j < N; j++)
+ print("%g ", m[i][j]);
+ print("\n");
+ }
+ print("\n");
+}
+
+void
+main()
+{
+ Matrix m = {
+ 11, 12, 13, 14,
+ 21, 22, 23, 24,
+ 31, 32, 33, 34,
+ 41, 42, 43, 44,
+ };
+
+ printm(m);
+ transpose(m);
+ printm(m);
+ exits(0);
+}
--- /dev/null
+++ b/vec.c
@@ -1,0 +1,26 @@
+#include <u.h>
+#include <libc.h>
+
+typedef struct Vec Vec;
+struct Vec {
+ double x, y, z;
+};
+
+Vec
+addvec(Vec a, Vec b)
+{
+ a.x += b.x;
+ a.y += b.y;
+ a.z += b.z;
+ return a;
+}
+
+void
+main()
+{
+ Vec a = {20, 5, 3};
+ Vec b = {6, -2, 19};
+
+ a = addvec(a, b);
+ exits(nil);
+}