shithub: battleship

Download patch

ref: a39951d8f69209cfea2b7051832b851914e662ef
author: rodri <rgl@antares-labs.eu>
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);
+}