# To unbundle, sh this file
echo README 1>&2
sed 's/.//' >README <<'//GO.SYSIN DD README'
-this is some source to help you read polyhedra files.
-i am disinclined to put all of the 9th edition clibrary in
-here so i just include getfields. the only problem you might
-have is fio (F* routines). just change
-	Fprint		fprintf
-	sprint		sprintf
-	fprint		fprintf	(unbuffered)
-	Fgetc		getc
-	Fflush		flush
-(its not hard).
-let me know of any comments and i will update this readme
//GO.SYSIN DD README
echo getfields.c 1>&2
sed 's/.//' >getfields.c <<'//GO.SYSIN DD getfields.c'
-#include	<libc.h>
-
-static char is_sep[256], is_field[256];
-static init = 0;
-
-void
-setfields(arg)
-	char *arg;
-{
-	register unsigned char *s = (unsigned char *)arg;
-
-	memset(is_sep, 0, sizeof is_sep);
-	memset(is_field, 1, sizeof is_field);
-	while(*s){
-		is_sep[*s] = 1;
-		is_field[*s++] = 0;
-	}
-	is_field[0] = 0;
-	init = 1;
-}
-
-getfields(ss, sp, nptrs)
-	char *ss;
-	char **sp;
-{
-	register unsigned char *s = (unsigned char *)ss;
-	register unsigned char **p = (unsigned char **)sp;
-	register unsigned c;
-
-	if(init == 0)
-		setfields(" \t");
-	for(;;){
-		if(*s == 0) break;
-		if(--nptrs < 0) break;
-		*p++ = s;
-		while(is_field[c = *s++]);
-		if(c == 0) break;
-		s[-1] = 0;
-	}
-	if(nptrs > 0)
-		*p = 0;
-	else if(--s >= (unsigned char *)ss)
-		*s = c;
-	return(p - (unsigned char **)sp);
-}
-
-getmfields(ss, sp, nptrs)
-	char *ss;
-	char **sp;
-{
-	register unsigned char *s = (unsigned char *)ss;
-	register unsigned char **p = (unsigned char **)sp;
-	register unsigned c;
-	unsigned char *goo;
-
-	if(init == 0)
-		setfields(" \t");
-	if(*s){
-		while(nptrs-- > 0){
-			*p++ = s;
-			while(is_field[*s++]);
-			goo = s-1;
-			if((c = *goo) == 0)
-				break;
-			*goo = 0;
-			while(is_sep[*s]) s++;
-			if(*s == 0) break;
-		}
-	}
-	if(nptrs > 0)	/* plenty of room */
-		*p = 0;
-	else if(*s)	/* no room and we found a trailing non-is_seper */
-		*goo = c;
-	return(p - (unsigned char **)sp);
-}
-
-#ifdef	MAIN
-#include	<fio.h>
-
-main()
-{
-	char *fields[256];
-	char *s;
-	int n, i;
-
-	print("go:\n");
-	while(s = Frdline(0)){
-		n = getmfields(s, fields, 3);
-		for(i = 0; i < n; i++)
-			Fprint(1, ">%s< ", fields[i]);
-		Fputc(1, '\n');
-		Fflush(1);
-	}
-	exit(0);
-}
-#endif
//GO.SYSIN DD getfields.c
echo poly.h 1>&2
sed 's/.//' >poly.h <<'//GO.SYSIN DD poly.h'
-#define	POLYDB		"../poly"
-#define	MAXPOLY		4096
-
-typedef struct Value
-{
-	double v;
-	char *code;
-} Value;
-
-typedef struct Vertex
-{
-	Value x, y, z;
-} Vertex;
-
-typedef struct Dihedral
-{
-	Value d;
-	short sc;		/* if nonzero s, c are set */
-	short count;
-	short *fe;		/* f,e * count */
-	Value s, c;
-} Dihedral;
-
-typedef struct Hinge
-{
-	short f1, s1, f2, s2;
-	Value d;	/* dihedral angle (>PI is reverse fold) */
-} Hinge;
-
-typedef struct Polyhedron
-{
-	short number;
-	char *name;
-	char *comment;
-	char *dual;
-	char *symbol;
-	char *sfaces;
-	char *svertices;
-	short nvertices, nnet;
-	Vertex *vertices;
-	short nface;
-	short maxface;		/* max number of sides in a face */
-	short **net;
-	short **solid;
-	short ndih;
-	Dihedral *dih;
-	short nhinges;
-	Hinge *hinges;
-	short ndgoo;
-	Hinge *dgoo;
-} Polyhedron;
-
-extern char *poly_field();
//GO.SYSIN DD poly.h
echo poly_field.c 1>&2
sed 's/.//' >poly_field.c <<'//GO.SYSIN DD poly_field.c'
-#include	"libc.h"
-#include	"fio.h"
-#include	"poly.h"
-#include	<sys/types.h>
-#include	<sys/stat.h>
-
-static char *buf;
-static long size;
-typedef struct Field
-{
-	char *field;
-	char *start;
-} Field;
-Field poly_ffields[100];
-static nfields;
-
-static
-cmp(a, b)
-	Field *a, *b;
-{
-	return(strcmp(a->field, b->field));
-}
-
-poly_ifield(s)
-	char *s;
-{
-	int fd;
-	struct stat sbuf;
-
-	if((fd = open(s, 0)) < 0){
-		perror(s);
-		return(1);
-	}
-	if(fstat(fd, &sbuf) < 0){
-		perror(s);
-		return(1);
-	}
-	if(sbuf.st_size >= size){
-		if(buf == 0)
-			buf = malloc((unsigned)(size = sbuf.st_size+1));
-		else
-			buf = realloc(buf, (unsigned)(size = sbuf.st_size+1));
-	}
-	if(read(fd, buf, (int)sbuf.st_size) != sbuf.st_size){
-		perror("read");
-		return(1);
-	}
-	close(fd);
-	buf[sbuf.st_size] = 0;
-	for(s = buf; *s; s++)
-		if(*s == '\n') *s = 0;
-	for(s = buf, nfields = 0; *s;){
-		if(*s == ':'){
-			*s++ = 0;
-			if(strcmp(s, "EOF") == 0)
-				break;
-			poly_ffields[nfields].field = s;
-			while(*s++);
-			poly_ffields[nfields++].start = s;
-		}
-		while(*s++);
-	}
-	qsort((char *)poly_ffields, nfields, sizeof(Field), cmp);
-	poly_ffields[nfields].field = 0;
-	return(0);
-}
-
-char *
-poly_field(s)
-	char *s;
-{				/* body duplicated in rfield */
-	register l, m, h;
-
-	if(strcmp(s, poly_ffields[0].field) < 0)
-		return((char *)0);
-	for(l = 0, h = nfields; l != h-1;){
-		m = (l+h)/2;
-		if(strcmp(s, poly_ffields[m].field) < 0)
-			h = m;
-		else
-			l = m;
-	}
-	return(strcmp(s, poly_ffields[l].field)? (char *)0 : poly_ffields[l].start);
-}
-
-poly_rfield(f, s)
-	char *f, *s;
-{				/* body duplicated in field */
-	register l, m, h;
-
-	if(strcmp(s, poly_ffields[0].field) < 0)
-		l = nfields;
-	else {
-		for(l = 0, h = nfields; l != h-1;){
-			m = (l+h)/2;
-			if(strcmp(s, poly_ffields[m].field) < 0)
-				h = m;
-			else
-				l = m;
-		}
-		if(strcmp(s, poly_ffields[l].field))
-			l = nfields;
-	}
-	if(l == nfields){
-		nfields++;
-		poly_ffields[l].field = f;
-	}
-	poly_ffields[l].start = s;
-}
//GO.SYSIN DD poly_field.c
echo poly_lk.c 1>&2
sed 's/.//' >poly_lk.c <<'//GO.SYSIN DD poly_lk.c'
-#include	"libc.h"
-#include	"fio.h"
-#include	"poly.h"
-
-static char names[MAXPOLY][128];
-static int ns;
-
-poly_lk(s)
-	char *s;
-{
-	register i;
-	register char *ss;
-	char buf[128];
-	int n = strlen(s);
-	static doread = 1;
-
-	for(ss = s; *ss; ss++)
-		if((*ss < '0') || (*ss > '9')) break;
-	if(*ss == 0)
-	{
-		n = atoi(s);
-		sprint(buf, "%s/%d", POLYDB, n);
-		if(access(buf, 4) == 0)
-			return(n);
-		fprint(2, "number %d out of range\n", n);
-		return(-1);
-	}
-	if(doread){
-		readnames();
-		doread = 0;
-	}
-	for(i = 0; i < ns; i++)
-		if(strncmp(&names[i][0], s, n) == 0) return(i);
-	fprint(2, "no solid '%s'\n", s);
-	return(-1);
-}
-
-readnames()
-{
-	register i, fd;
-	register char *s;
-	char buf[128];
-
-	sprint(buf, "%s/index", POLYDB);
-	if((fd = open(buf, 0)) < 0){
-		perror(buf);
-		exit(1);
-	}
-	ns = 0;
-	while(s = Frdline(fd)){
-		i = atoi(s);
-		s = strchr(s, '\t');
-		strcpy(&names[i][0], s+1);
-		if(i >= ns)
-			ns = i+1;
-	}
-	close(fd);
-}
//GO.SYSIN DD poly_lk.c
echo poly_read.c 1>&2
sed 's/.//' >poly_read.c <<'//GO.SYSIN DD poly_read.c'
-#include	"libc.h"
-#include	"string.h"
-#include	"fio.h"
-#include	"poly.h"
-
-static short **facelist();
-#define		SPLIT(s)	getmfields(s, ptr, sizeof ptr/sizeof ptr[0])
-
-poly_read(p, dir, n)
-	register Polyhedron *p;
-	char *dir;
-{
-	char buf[128];
-	char *s, *nexts;
-	int i, j, k;
-	short *sp;
-	char *ptr[10];
-
-	sprint(buf, "%s/%d", dir? dir:POLYDB, n);
-	if(poly_ifield(buf))
-		return(1);
-	p->number = atoi(poly_field("number"));
-	p->name = strdup(poly_field("name"));
-	p->comment = strdup(poly_field("comment"));
-	p->symbol = strdup(poly_field("symbol"));
-	p->dual = strdup(poly_field("dual"));
-	p->sfaces = strdup(poly_field("sfaces"));
-	p->svertices = strdup(poly_field("svertices"));
-	s = poly_field("vertices");
-	if(p->nvertices = atoi(s)){
-		p->vertices = (Vertex *)malloc(p->nvertices*sizeof(Vertex));
-		for(nexts = s; *nexts++;);
-		if(SPLIT(s) == 2)
-			p->nnet = atoi(ptr[1]);
-		else
-			p->nnet = p->nvertices;
-		for(i = 0, s = nexts; *s; s = nexts, i++){
-			for(nexts = s; *nexts++;);
-			if(SPLIT(s) != 3){
-				fprint(2, "bad vertex in file %s (next line is %s)\n", buf, nexts);
-				return(1);
-			}
-			rdvalue(&p->vertices[i].x, ptr[0]);
-			rdvalue(&p->vertices[i].y, ptr[1]);
-			rdvalue(&p->vertices[i].z, ptr[2]);
-		}
-		if(i != p->nvertices){
-			fprint(2, "%s: expected %d vertices, read %d\n", buf,
-				p->nvertices, i);
-			return(1);
-		}
-	}
-	p->maxface = 0;
-	p->nface = 0;
-	p->net = facelist(p, "net", buf);
-	p->solid = facelist(p, "solid", buf);
-	s = poly_field("hinges");
-	if(p->nhinges = atoi(s)){
-		p->hinges = (Hinge *)malloc(p->nhinges*sizeof(Hinge));
-		while(*s++);
-		for(i = 0; *s; s = nexts, i++){
-			for(nexts = s; *nexts++;);
-			if(SPLIT(s) != 5){
-				fprint(2, "%s: bad hinge line\n", buf);
-				return(1);
-			}
-			p->hinges[i].f1 = atoi(ptr[0]);
-			p->hinges[i].s1 = atoi(ptr[1]);
-			p->hinges[i].f2 = atoi(ptr[2]);
-			p->hinges[i].s2 = atoi(ptr[3]);
-			rdvalue(&p->hinges[i].d, ptr[4]);
-		}
-		if(i != p->nhinges){
-			fprint(2, "%s: expected %d hinges, read %d\n", buf,
-				p->nhinges, i);
-			return(1);
-		}
-	}
-	s = poly_field("dihedral");
-	if(p->ndih = atoi(s)){
-		p->dih = (Dihedral *)malloc(p->ndih*sizeof(Dihedral));
-		while(*s++);
-		for(i = 0; i < p->ndih; s = nexts, i++){
-			for(nexts = s; *nexts++;);
-			k = SPLIT(s);
-			if(k == 4){
-				rdvalue(&p->dih[i].s, ptr[2]);
-				rdvalue(&p->dih[i].c, ptr[3]);
-				p->dih[i].sc = 1;
-				k -= 2;
-			} else
-				p->dih[i].sc = 0;
-			if(k != 2){
-				fprint(2, "%s: bad dihedral count\n", buf);
-				return(1);
-			}
-			k = p->dih[i].count = atoi(ptr[0]);
-			rdvalue(&p->dih[i].d, ptr[1]);
-			s = nexts;
-			if(k){
-				sp = p->dih[i].fe = (short *)malloc(2*k*sizeof(short));
-				for(j = 0; j < k; s = nexts, j++){
-					for(nexts = s; *nexts++;);
-					if(SPLIT(s) != 2){
-						fprint(2, "%s: bad face-edge\n", buf);
-						return(1);
-					}
-					*sp++ = atoi(ptr[0]);
-					*sp++ = atoi(ptr[1]);
-				}
-			} else
-				p->dih[i].fe = 0;
-		}
-		if(i != p->ndih){
-			fprint(2, "%s: expected %d dihedrals, read %d\n", buf,
-				p->ndih, i);
-			return(1);
-		}
-	}
-	s = poly_field("dih");
-	if(p->ndgoo = atoi(s)){
-		p->dgoo = (Hinge *)malloc(p->ndgoo*sizeof(Hinge));
-		while(*s++);
-		for(i = 0; *s; s = nexts, i++){
-			for(nexts = s; *nexts++;);
-			if(SPLIT(s) != 4){
-				fprint(2, "%s: bad dgoo line\n", buf);
-				return(1);
-			}
-			p->dgoo[i].f1 = atoi(ptr[0]);
-			p->dgoo[i].s1 = atoi(ptr[1]);
-			p->dgoo[i].f2 = atoi(ptr[2]);
-			rdvalue(&p->dgoo[i].d, ptr[3]);
-		}
-		if(i != p->ndgoo){
-			fprint(2, "%s: expected %d dgoo, read %d\n", buf,
-				p->ndgoo, i);
-			return(1);
-		}
-	}
-	return(0);
-}
-
-rdvalue(v, s)
-	Value *v;
-	register char *s;
-{
-	v->v = atof(s);
-	while(*s && (*s != '['))
-		s++;
-	if(*s == '['){
-		char *ss = ++s;
-
-		while(*s && (*s != ']'))
-			s++;
-		*s = 0;
-		v->code = strdup(ss);
-	} else
-		v->code = 0;
-}
-
-static short **
-facelist(p, ss, file)
-	Polyhedron *p;
-	char *ss, *file;
-{
-	char *s, *nexts;
-	char *ptr[100];
-	int i, j, k, n;
-	short **ret;
-
-	s = poly_field(ss);
-	if(atoi(s) == 0)
-		return((short **)0);
-	nexts = strchr(s, 0)+1;
-	if(SPLIT(s) != 2){
-		fprint(2, "%s: bad count line for '%s'\n", file, ss);
-		return((short **)0);
-	}
-	n = atoi(ptr[0]);
-	p->maxface = atoi(ptr[1]);
-	if(p->nface){
-		if(p->nface != n){
-			fprint(2, "%s: nface disagreement: %d vs %d\n", file,
-				p->nface, n);
-			return((short **)0);
-		}
-	} else
-		p->nface = n;
-	ret = (short **)malloc(p->nface*sizeof(short *));
-	s = nexts;
-	for(i = 0; *s && (i < p->nface); i++, s = nexts){
-		nexts = strchr(s, 0)+1;
-		SPLIT(s);
-		k = atoi(ptr[0]);
-		ret[i] = (short *)malloc((k+1)*sizeof(short));
-		for(j = 0; j <= k; j++)
-			ret[i][j] = atoi(ptr[j]);
-	}
-	return(ret);
-}
//GO.SYSIN DD poly_read.c
echo poly_write.c 1>&2
sed 's/.//' >poly_write.c <<'//GO.SYSIN DD poly_write.c'
-#include	"libc.h"
-#include	"fio.h"
-#include	"poly.h"
-
-typedef struct Field
-{
-	char *field;
-	char *start;
-} Field;
-extern Field poly_ffields[];
-
-poly_write(p, fd)
-	register Polyhedron *p;
-{
-	int i, j, k;
-	short *sp;
-
-	Fprint(fd, ":name\n%s\n", p->name);
-	Fprint(fd, ":number\n%d\n", p->number);
-	Fprint(fd, ":comment\n%d\n", p->comment);
-	if(*p->symbol)
-		Fprint(fd, ":symbol\n%s\n", p->symbol);
-	if(*p->dual)
-		Fprint(fd, ":dual\n%s\n", p->dual);
-	if(*p->sfaces)
-		Fprint(fd, ":sfaces\n%s\n", p->sfaces);
-	if(*p->svertices)
-		Fprint(fd, ":svertices\n%s\n", p->svertices);
-	if(p->net)
-		wrlist(p->net, p->nface, p->maxface, "net", fd);
-	if(p->solid)
-		wrlist(p->solid, p->nface, p->maxface, "solid", fd);
-	if(p->nhinges){
-		Fprint(fd, ":hinges\n%d\n", p->nhinges);
-		for(i = 0; i < p->nhinges; i++){
-			Fprint(fd, "%d %d %d %d ", p->hinges[i].f1,
-				p->hinges[i].s1, p->hinges[i].f2, p->hinges[i].s2);
-			wrvalue(&p->hinges[i].d, fd);
-			Fputc(fd, '\n');
-		}
-	}
-	if(p->ndih){
-		Fprint(fd, ":dihedral\n%d\n", p->ndih);
-		for(i = 0; i < p->ndih; i++){
-			Fprint(fd, "%d ", k = p->dih[i].count);
-			wrvalue(&p->dih[i].d, fd);
-			if(p->dih[i].sc){
-				wrvalue(&p->dih[i].s, fd);
-				Fputc(fd, ' ');
-				wrvalue(&p->dih[i].c, fd);
-			}
-			Fputc(fd, '\n');
-			if(k){
-				sp = p->dih[i].fe;
-				for(j = 0; j < k; j++){
-					Fprint(fd, "%d %d\n", sp[0], sp[1]);
-					sp += 2;
-				}
-			}
-		}
-	}
-	if(p->ndgoo){
-		Fprint(fd, ":dih\n%d\n", p->ndgoo);
-		for(i = 0; i < p->ndgoo; i++){
-			Fprint(fd, "%d %d %d ", p->dgoo[i].f1, p->dgoo[i].s1,
-				p->dgoo[i].f2);
-			wrvalue(&p->dgoo[i].d, fd);
-			Fputc(fd, '\n');
-		}
-	}
-	if(p->nvertices){
-		Fprint(fd, ":vertices\n%d %d\n", p->nvertices, p->nnet);
-		for(i = 0; i < p->nvertices; i++){
-			wrvalue(&p->vertices[i].x, fd);
-			Fputc(fd, ' ');
-			wrvalue(&p->vertices[i].y, fd);
-			Fputc(fd, ' ');
-			wrvalue(&p->vertices[i].z, fd);
-			Fputc(fd, '\n');
-		}
-	}
-	Fprint(fd, ":EOF\n");
-	Fflush(fd);
-	return(0);
-}
-
-wrvalue(v, fd)
-	Value *v;
-{
-	Fprint(fd, "%.17g", v->v);
-	if(v->code)
-		Fprint(fd, "[%s]", v->code);
-}
-
-wrlist(list, n, max, str, fd)
-	register short **list;
-	char *str;
-{
-	register short *p;
-	register i, k;
-
-	Fprint(fd, ":%s\n%d %d\n", str, n, max);
-	for(i = 0; i < n; i++){
-		p = list[i];
-		Fprint(fd, "%d", k = *p++);
-		while(k--)
-			Fprint(fd, " %d", *p++);
-		Fputc(fd, '\n');
-	}
-}
//GO.SYSIN DD poly_write.c
