xref: /inferno-os/libinterp/runt.c (revision 4a062f32e3dd93bf371feb27f3ccc28d7930099e)
137da2899SCharles.Forsyth #include "lib9.h"
237da2899SCharles.Forsyth #include "isa.h"
337da2899SCharles.Forsyth #include "interp.h"
437da2899SCharles.Forsyth #include "runt.h"
537da2899SCharles.Forsyth #include "sysmod.h"
637da2899SCharles.Forsyth #include "raise.h"
737da2899SCharles.Forsyth 
837da2899SCharles.Forsyth 
937da2899SCharles.Forsyth static	int		utfnleng(char*, int, int*);
1037da2899SCharles.Forsyth 
1137da2899SCharles.Forsyth void
sysmodinit(void)1237da2899SCharles.Forsyth sysmodinit(void)
1337da2899SCharles.Forsyth {
1437da2899SCharles.Forsyth 	sysinit();
1537da2899SCharles.Forsyth 	builtinmod("$Sys", Sysmodtab, Sysmodlen);
1637da2899SCharles.Forsyth }
1737da2899SCharles.Forsyth 
1837da2899SCharles.Forsyth int
xprint(Prog * xp,void * vfp,void * vva,String * s1,char * buf,int n)1937da2899SCharles.Forsyth xprint(Prog *xp, void *vfp, void *vva, String *s1, char *buf, int n)
2037da2899SCharles.Forsyth {
2137da2899SCharles.Forsyth 	WORD i;
2237da2899SCharles.Forsyth 	void *p;
2337da2899SCharles.Forsyth 	LONG bg;
2437da2899SCharles.Forsyth 	Type *t;
2537da2899SCharles.Forsyth 	double d;
2637da2899SCharles.Forsyth 	String *ss;
2737da2899SCharles.Forsyth 	ulong *ptr;
2837da2899SCharles.Forsyth 	uchar *fp, *va;
2937da2899SCharles.Forsyth 	int nc, c, isbig, isr, sip;
3037da2899SCharles.Forsyth 	char *b, *eb, *f, fmt[32];
3137da2899SCharles.Forsyth 	Rune r;
3237da2899SCharles.Forsyth 
3337da2899SCharles.Forsyth 	fp = vfp;
3437da2899SCharles.Forsyth 	va = vva;
3537da2899SCharles.Forsyth 
3637da2899SCharles.Forsyth 	sip = 0;
3737da2899SCharles.Forsyth 	isr = 0;
3837da2899SCharles.Forsyth 	if(s1 == H)
3937da2899SCharles.Forsyth 		return 0;
4037da2899SCharles.Forsyth 	nc = s1->len;
4137da2899SCharles.Forsyth 	if(nc < 0) {
4237da2899SCharles.Forsyth 		nc = -nc;
4337da2899SCharles.Forsyth 		isr = 1;
4437da2899SCharles.Forsyth 	}
4537da2899SCharles.Forsyth 
4637da2899SCharles.Forsyth 	b = buf;
4737da2899SCharles.Forsyth 	eb = buf+n-1;
4837da2899SCharles.Forsyth 	while(nc--) {
4937da2899SCharles.Forsyth 		c = isr ? s1->Srune[sip] : s1->Sascii[sip];
5037da2899SCharles.Forsyth 		sip++;
5137da2899SCharles.Forsyth 		if(c != '%') {
5237da2899SCharles.Forsyth 			if(b < eb) {
5337da2899SCharles.Forsyth 				if(c < Runeself)
5437da2899SCharles.Forsyth 					*b++ = c;
5537da2899SCharles.Forsyth 				else
5637da2899SCharles.Forsyth 					b += snprint(b, eb-b, "%C", c);
5737da2899SCharles.Forsyth 			}
5837da2899SCharles.Forsyth 			continue;
5937da2899SCharles.Forsyth 		}
6037da2899SCharles.Forsyth 		f = fmt;
6137da2899SCharles.Forsyth 		*f++ = c;
6237da2899SCharles.Forsyth 		isbig = 0;
6337da2899SCharles.Forsyth 		while(nc--) {
6437da2899SCharles.Forsyth 			c = isr ? s1->Srune[sip] : s1->Sascii[sip];
6537da2899SCharles.Forsyth 			sip++;
6637da2899SCharles.Forsyth 			*f++ = c;
6737da2899SCharles.Forsyth 			*f = '\0';
6837da2899SCharles.Forsyth 			switch(c) {
6937da2899SCharles.Forsyth 			default:
7037da2899SCharles.Forsyth 				continue;
7137da2899SCharles.Forsyth 			case '*':
7237da2899SCharles.Forsyth 				i = *(WORD*)va;
7337da2899SCharles.Forsyth 				f--;
7437da2899SCharles.Forsyth 				f += snprint(f, sizeof(fmt)-(f-fmt), "%d", i);
7537da2899SCharles.Forsyth 				va += IBY2WD;
7637da2899SCharles.Forsyth 				continue;
7737da2899SCharles.Forsyth 			case 'b':
7837da2899SCharles.Forsyth 				f[-1] = 'l';
7937da2899SCharles.Forsyth 				*f++ = 'l';
8037da2899SCharles.Forsyth 				*f = '\0';
8137da2899SCharles.Forsyth 				isbig = 1;
8237da2899SCharles.Forsyth 				continue;
8337da2899SCharles.Forsyth 			case '%':
8437da2899SCharles.Forsyth 				if(b < eb)
8537da2899SCharles.Forsyth 					*b++ = '%';
8637da2899SCharles.Forsyth 				break;
8737da2899SCharles.Forsyth 			case 'q':
8837da2899SCharles.Forsyth 			case 's':
8937da2899SCharles.Forsyth 				ss = *(String**)va;
9037da2899SCharles.Forsyth 				va += IBY2WD;
9137da2899SCharles.Forsyth 				if(ss == H)
9237da2899SCharles.Forsyth 					p = "";
9337da2899SCharles.Forsyth 				else
9437da2899SCharles.Forsyth 				if(ss->len < 0) {
9537da2899SCharles.Forsyth 					f[-1] += 'A'-'a';
9637da2899SCharles.Forsyth 					ss->Srune[-ss->len] = L'\0';
9737da2899SCharles.Forsyth 					p = ss->Srune;
9837da2899SCharles.Forsyth 				}
9937da2899SCharles.Forsyth 				else {
10037da2899SCharles.Forsyth 					ss->Sascii[ss->len] = '\0';
10137da2899SCharles.Forsyth 					p = ss->Sascii;
10237da2899SCharles.Forsyth 				}
10337da2899SCharles.Forsyth 				b += snprint(b, eb-b, fmt, p);
10437da2899SCharles.Forsyth 				break;
10537da2899SCharles.Forsyth 			case 'E':
10637da2899SCharles.Forsyth 				f--;
10737da2899SCharles.Forsyth 				r = 0x00c9;	/* L'É' */
10837da2899SCharles.Forsyth 				f += runetochar(f, &r);	/* avoid clash with ether address */
10937da2899SCharles.Forsyth 				*f = '\0';
11037da2899SCharles.Forsyth 				/* fall through */
11137da2899SCharles.Forsyth 			case 'e':
11237da2899SCharles.Forsyth 			case 'f':
11337da2899SCharles.Forsyth 			case 'g':
11437da2899SCharles.Forsyth 			case 'G':
11537da2899SCharles.Forsyth 				while((va - fp) & (sizeof(REAL)-1))
11637da2899SCharles.Forsyth 					va++;
11737da2899SCharles.Forsyth 				d = *(REAL*)va;
11837da2899SCharles.Forsyth 				b += snprint(b, eb-b, fmt, d);
11937da2899SCharles.Forsyth 				va += sizeof(REAL);
12037da2899SCharles.Forsyth 				break;
12137da2899SCharles.Forsyth 			case 'd':
12237da2899SCharles.Forsyth 			case 'o':
12337da2899SCharles.Forsyth 			case 'x':
12437da2899SCharles.Forsyth 			case 'X':
12537da2899SCharles.Forsyth 			case 'c':
12637da2899SCharles.Forsyth 				if(isbig) {
12737da2899SCharles.Forsyth 					while((va - fp) & (IBY2LG-1))
12837da2899SCharles.Forsyth 						va++;
12937da2899SCharles.Forsyth 					bg = *(LONG*)va;
13037da2899SCharles.Forsyth 					b += snprint(b, eb-b, fmt, bg);
13137da2899SCharles.Forsyth 					va += IBY2LG;
13237da2899SCharles.Forsyth 				}
13337da2899SCharles.Forsyth 				else {
13437da2899SCharles.Forsyth 					i = *(WORD*)va;
13537da2899SCharles.Forsyth 					/* always a unicode character */
13637da2899SCharles.Forsyth 					if(c == 'c')
13737da2899SCharles.Forsyth 						f[-1] = 'C';
13837da2899SCharles.Forsyth 					b += snprint(b, eb-b, fmt, i);
13937da2899SCharles.Forsyth 					va += IBY2WD;
14037da2899SCharles.Forsyth 				}
14137da2899SCharles.Forsyth 				break;
14237da2899SCharles.Forsyth 			case 'r':
14337da2899SCharles.Forsyth 				b = syserr(b, eb, xp);
14437da2899SCharles.Forsyth 				break;
14537da2899SCharles.Forsyth /* Debugging formats - may disappear */
14637da2899SCharles.Forsyth 			case 'H':
14737da2899SCharles.Forsyth 				ptr = *(ulong**)va;
14837da2899SCharles.Forsyth 				c = -1;
14937da2899SCharles.Forsyth 				t = nil;
15037da2899SCharles.Forsyth 				if(ptr != H) {
15137da2899SCharles.Forsyth 					c = D2H(ptr)->ref;
15237da2899SCharles.Forsyth 					t = D2H(ptr)->t;
15337da2899SCharles.Forsyth 				}
15437da2899SCharles.Forsyth 				b += snprint(b, eb-b, "%d.%.8lux", c, (ulong)t);
15537da2899SCharles.Forsyth 				va += IBY2WD;
15637da2899SCharles.Forsyth 				break;
15737da2899SCharles.Forsyth 			}
15837da2899SCharles.Forsyth 			break;
15937da2899SCharles.Forsyth 		}
16037da2899SCharles.Forsyth 	}
16137da2899SCharles.Forsyth 	return b - buf;
16237da2899SCharles.Forsyth }
16337da2899SCharles.Forsyth 
16437da2899SCharles.Forsyth int
bigxprint(Prog * xp,void * vfp,void * vva,String * s1,char ** buf,int s)16537da2899SCharles.Forsyth bigxprint(Prog *xp, void *vfp, void *vva, String *s1, char **buf, int s)
16637da2899SCharles.Forsyth {
16737da2899SCharles.Forsyth 	char *b;
16837da2899SCharles.Forsyth 	int m, n;
16937da2899SCharles.Forsyth 
17037da2899SCharles.Forsyth 	m = s;
17137da2899SCharles.Forsyth 	for (;;) {
17237da2899SCharles.Forsyth 		m *= 2;
17337da2899SCharles.Forsyth 		b = malloc(m);
17437da2899SCharles.Forsyth 		if (b == nil)
17537da2899SCharles.Forsyth 			error(exNomem);
17637da2899SCharles.Forsyth 		n = xprint(xp, vfp, vva, s1, b, m);
17737da2899SCharles.Forsyth 		if (n < m-UTFmax-2)
17837da2899SCharles.Forsyth 			break;
17937da2899SCharles.Forsyth 		free(b);
18037da2899SCharles.Forsyth 	}
18137da2899SCharles.Forsyth 	*buf = b;
18237da2899SCharles.Forsyth 	return n;
18337da2899SCharles.Forsyth }
18437da2899SCharles.Forsyth 
18537da2899SCharles.Forsyth void
Sys_sprint(void * fp)18637da2899SCharles.Forsyth Sys_sprint(void *fp)
18737da2899SCharles.Forsyth {
18837da2899SCharles.Forsyth 	int n;
18937da2899SCharles.Forsyth 	char buf[256], *b = buf;
19037da2899SCharles.Forsyth 	F_Sys_sprint *f;
19137da2899SCharles.Forsyth 
19237da2899SCharles.Forsyth 	f = fp;
19337da2899SCharles.Forsyth 	n = xprint(currun(), f, &f->vargs, f->s, buf, sizeof(buf));
19437da2899SCharles.Forsyth 	if (n >= sizeof(buf)-UTFmax-2)
19537da2899SCharles.Forsyth 		n = bigxprint(currun(), f, &f->vargs, f->s, &b, sizeof(buf));
19637da2899SCharles.Forsyth 	b[n] = '\0';
19737da2899SCharles.Forsyth 	retstr(b, f->ret);
19837da2899SCharles.Forsyth 	if (b != buf)
19937da2899SCharles.Forsyth 		free(b);
20037da2899SCharles.Forsyth }
20137da2899SCharles.Forsyth 
20237da2899SCharles.Forsyth void
Sys_aprint(void * fp)20337da2899SCharles.Forsyth Sys_aprint(void *fp)
20437da2899SCharles.Forsyth {
20537da2899SCharles.Forsyth 	int n;
20637da2899SCharles.Forsyth 	char buf[256], *b = buf;
20737da2899SCharles.Forsyth 	F_Sys_aprint *f;
20837da2899SCharles.Forsyth 
20937da2899SCharles.Forsyth 	f = fp;
21037da2899SCharles.Forsyth 	n = xprint(currun(), f, &f->vargs, f->s, buf, sizeof(buf));
21137da2899SCharles.Forsyth 	if (n >= sizeof(buf)-UTFmax-2)
21237da2899SCharles.Forsyth 		n = bigxprint(currun(), f, &f->vargs, f->s, &b, sizeof(buf));
21337da2899SCharles.Forsyth 	destroy(*f->ret);
21437da2899SCharles.Forsyth 	*f->ret = mem2array(b, n);
21537da2899SCharles.Forsyth 	if (b != buf)
21637da2899SCharles.Forsyth 		free(b);
21737da2899SCharles.Forsyth }
21837da2899SCharles.Forsyth 
21937da2899SCharles.Forsyth static int
tokdelim(int c,String * d)22037da2899SCharles.Forsyth tokdelim(int c, String *d)
22137da2899SCharles.Forsyth {
22237da2899SCharles.Forsyth 	int l;
22337da2899SCharles.Forsyth 	char *p;
22437da2899SCharles.Forsyth 	Rune *r;
22537da2899SCharles.Forsyth 
22637da2899SCharles.Forsyth 	l = d->len;
22737da2899SCharles.Forsyth 	if(l < 0) {
22837da2899SCharles.Forsyth 		l = -l;
22937da2899SCharles.Forsyth 		for(r = d->Srune; l != 0; l--)
23037da2899SCharles.Forsyth 			if(*r++ == c)
23137da2899SCharles.Forsyth 				return 1;
23237da2899SCharles.Forsyth 		return 0;
23337da2899SCharles.Forsyth 	}
23437da2899SCharles.Forsyth 	for(p = d->Sascii; l != 0; l--)
23537da2899SCharles.Forsyth 		if(*p++ == c)
23637da2899SCharles.Forsyth 			return 1;
23737da2899SCharles.Forsyth 	return 0;
23837da2899SCharles.Forsyth }
23937da2899SCharles.Forsyth 
24037da2899SCharles.Forsyth void
Sys_tokenize(void * fp)24137da2899SCharles.Forsyth Sys_tokenize(void *fp)
24237da2899SCharles.Forsyth {
24337da2899SCharles.Forsyth 	String *s, *d;
24437da2899SCharles.Forsyth 	List **h, *l, *nl;
24537da2899SCharles.Forsyth 	F_Sys_tokenize *f;
24637da2899SCharles.Forsyth 	int n, c, nc, first, last, srune;
24737da2899SCharles.Forsyth 
24837da2899SCharles.Forsyth 	f = fp;
24937da2899SCharles.Forsyth 	s = f->s;
25037da2899SCharles.Forsyth 	d = f->delim;
25137da2899SCharles.Forsyth 
25237da2899SCharles.Forsyth 	if(s == H || d == H) {
25337da2899SCharles.Forsyth 		f->ret->t0 = 0;
25437da2899SCharles.Forsyth 		destroy(f->ret->t1);
25537da2899SCharles.Forsyth 		f->ret->t1 = H;
25637da2899SCharles.Forsyth 		return;
25737da2899SCharles.Forsyth 	}
25837da2899SCharles.Forsyth 
25937da2899SCharles.Forsyth 	n = 0;
26037da2899SCharles.Forsyth 	l = H;
26137da2899SCharles.Forsyth 	h = &l;
26237da2899SCharles.Forsyth 	first = 0;
26337da2899SCharles.Forsyth 	srune = 0;
26437da2899SCharles.Forsyth 
26537da2899SCharles.Forsyth 	nc = s->len;
26637da2899SCharles.Forsyth 	if(nc < 0) {
26737da2899SCharles.Forsyth 		nc = -nc;
26837da2899SCharles.Forsyth 		srune = 1;
26937da2899SCharles.Forsyth 	}
27037da2899SCharles.Forsyth 
27137da2899SCharles.Forsyth 	while(first < nc) {
27237da2899SCharles.Forsyth 		while(first < nc) {
27337da2899SCharles.Forsyth 			c = srune ? s->Srune[first] : s->Sascii[first];
27437da2899SCharles.Forsyth 			if(tokdelim(c, d) == 0)
27537da2899SCharles.Forsyth 				break;
27637da2899SCharles.Forsyth 			first++;
27737da2899SCharles.Forsyth 		}
27837da2899SCharles.Forsyth 
27937da2899SCharles.Forsyth 		last = first;
28037da2899SCharles.Forsyth 
28137da2899SCharles.Forsyth 		while(last < nc) {
28237da2899SCharles.Forsyth 			c = srune ? s->Srune[last] : s->Sascii[last];
28337da2899SCharles.Forsyth 			if(tokdelim(c, d) != 0)
28437da2899SCharles.Forsyth 				break;
28537da2899SCharles.Forsyth 			last++;
28637da2899SCharles.Forsyth 		}
28737da2899SCharles.Forsyth 
28837da2899SCharles.Forsyth 		if(first == last)
28937da2899SCharles.Forsyth 			break;
29037da2899SCharles.Forsyth 
29137da2899SCharles.Forsyth 		nl = cons(IBY2WD, h);
29237da2899SCharles.Forsyth 		nl->tail = H;
29337da2899SCharles.Forsyth 		nl->t = &Tptr;
29437da2899SCharles.Forsyth 		Tptr.ref++;
29537da2899SCharles.Forsyth 		*(String**)nl->data = slicer(first, last, s);
29637da2899SCharles.Forsyth 		h = &nl->tail;
29737da2899SCharles.Forsyth 
29837da2899SCharles.Forsyth 		first = last;
29937da2899SCharles.Forsyth 		n++;
30037da2899SCharles.Forsyth 	}
30137da2899SCharles.Forsyth 
30237da2899SCharles.Forsyth 	f->ret->t0 = n;
30337da2899SCharles.Forsyth 	destroy(f->ret->t1);
30437da2899SCharles.Forsyth 	f->ret->t1 = l;
30537da2899SCharles.Forsyth }
30637da2899SCharles.Forsyth 
30737da2899SCharles.Forsyth void
Sys_utfbytes(void * fp)30837da2899SCharles.Forsyth Sys_utfbytes(void *fp)
30937da2899SCharles.Forsyth {
31037da2899SCharles.Forsyth 	Array *a;
31137da2899SCharles.Forsyth 	int nbyte;
31237da2899SCharles.Forsyth 	F_Sys_utfbytes *f;
31337da2899SCharles.Forsyth 
31437da2899SCharles.Forsyth 	f = fp;
31537da2899SCharles.Forsyth 	a = f->buf;
31637da2899SCharles.Forsyth 	if(a == H || (UWORD)f->n > a->len)
31737da2899SCharles.Forsyth 		error(exBounds);
31837da2899SCharles.Forsyth 
31937da2899SCharles.Forsyth 	utfnleng((char*)a->data, f->n, &nbyte);
32037da2899SCharles.Forsyth 	*f->ret = nbyte;
32137da2899SCharles.Forsyth }
32237da2899SCharles.Forsyth 
32337da2899SCharles.Forsyth void
Sys_byte2char(void * fp)32437da2899SCharles.Forsyth Sys_byte2char(void *fp)
32537da2899SCharles.Forsyth {
32637da2899SCharles.Forsyth 	Rune r;
32737da2899SCharles.Forsyth 	char *p;
32837da2899SCharles.Forsyth 	int n, w;
32937da2899SCharles.Forsyth 	Array *a;
33037da2899SCharles.Forsyth 	F_Sys_byte2char *f;
33137da2899SCharles.Forsyth 
33237da2899SCharles.Forsyth 	f = fp;
33337da2899SCharles.Forsyth 	a = f->buf;
33437da2899SCharles.Forsyth 	n = f->n;
33537da2899SCharles.Forsyth 	if(a == H || (UWORD)n >= a->len)
33637da2899SCharles.Forsyth 		error(exBounds);
33737da2899SCharles.Forsyth 	r = a->data[n];
33837da2899SCharles.Forsyth 	if(r < Runeself){
33937da2899SCharles.Forsyth 		f->ret->t0 = r;
34037da2899SCharles.Forsyth 		f->ret->t1 = 1;
34137da2899SCharles.Forsyth 		f->ret->t2 = 1;
34237da2899SCharles.Forsyth 		return;
34337da2899SCharles.Forsyth 	}
34437da2899SCharles.Forsyth 	p = (char*)a->data+n;
34537da2899SCharles.Forsyth 	if(n+UTFmax <= a->len || fullrune(p, a->len-n))
34637da2899SCharles.Forsyth 		w = chartorune(&r, p);
34737da2899SCharles.Forsyth 	else {
34837da2899SCharles.Forsyth 		/* insufficient data */
34937da2899SCharles.Forsyth 		f->ret->t0 = Runeerror;
35037da2899SCharles.Forsyth 		f->ret->t1 = 0;
35137da2899SCharles.Forsyth 		f->ret->t2 = 0;
35237da2899SCharles.Forsyth 		return;
35337da2899SCharles.Forsyth 	}
35437da2899SCharles.Forsyth 	if(r == Runeerror && w==1){	/* encoding error */
35537da2899SCharles.Forsyth 		f->ret->t0 = Runeerror;
35637da2899SCharles.Forsyth 		f->ret->t1 = 1;
35737da2899SCharles.Forsyth 		f->ret->t2 = 0;
35837da2899SCharles.Forsyth 		return;
35937da2899SCharles.Forsyth 	}
36037da2899SCharles.Forsyth 	f->ret->t0 = r;
36137da2899SCharles.Forsyth 	f->ret->t1 = w;
36237da2899SCharles.Forsyth 	f->ret->t2 = 1;
36337da2899SCharles.Forsyth }
36437da2899SCharles.Forsyth 
36537da2899SCharles.Forsyth void
Sys_char2byte(void * fp)36637da2899SCharles.Forsyth Sys_char2byte(void *fp)
36737da2899SCharles.Forsyth {
36837da2899SCharles.Forsyth 	F_Sys_char2byte *f;
36937da2899SCharles.Forsyth 	Array *a;
37037da2899SCharles.Forsyth 	int n, c;
37137da2899SCharles.Forsyth 	Rune r;
37237da2899SCharles.Forsyth 
37337da2899SCharles.Forsyth 	f = fp;
37437da2899SCharles.Forsyth 	a = f->buf;
37537da2899SCharles.Forsyth 	n = f->n;
37637da2899SCharles.Forsyth 	c = f->c;
37737da2899SCharles.Forsyth 	if(a == H || (UWORD)n>=a->len)
37837da2899SCharles.Forsyth 		error(exBounds);
379*dd44a835SYaroslav Kolomiiets 	if(c<0 || c>=Runemax)
38037da2899SCharles.Forsyth 		c = Runeerror;
38137da2899SCharles.Forsyth 	if(c < Runeself){
38237da2899SCharles.Forsyth 		a->data[n] = c;
38337da2899SCharles.Forsyth 		*f->ret = 1;
38437da2899SCharles.Forsyth 		return;
38537da2899SCharles.Forsyth 	}
38637da2899SCharles.Forsyth 	r = c;
38737da2899SCharles.Forsyth 	if(n+UTFmax<=a->len || runelen(c)<=a->len-n){
38837da2899SCharles.Forsyth 		*f->ret = runetochar((char*)a->data+n, &r);
38937da2899SCharles.Forsyth 		return;
39037da2899SCharles.Forsyth 	}
39137da2899SCharles.Forsyth 	*f->ret = 0;
39237da2899SCharles.Forsyth }
39337da2899SCharles.Forsyth 
39437da2899SCharles.Forsyth Module *
builtinmod(char * name,void * vr,int rlen)39537da2899SCharles.Forsyth builtinmod(char *name, void *vr, int rlen)
39637da2899SCharles.Forsyth {
39737da2899SCharles.Forsyth 	Runtab *r = vr;
39837da2899SCharles.Forsyth 	Type *t;
39937da2899SCharles.Forsyth 	Module *m;
40037da2899SCharles.Forsyth 	Link *l;
40137da2899SCharles.Forsyth 
40237da2899SCharles.Forsyth 	m = newmod(name);
40337da2899SCharles.Forsyth 	if(rlen == 0){
40437da2899SCharles.Forsyth 		while(r->name){
40537da2899SCharles.Forsyth 			rlen++;
40637da2899SCharles.Forsyth 			r++;
40737da2899SCharles.Forsyth 		}
40837da2899SCharles.Forsyth 		r = vr;
40937da2899SCharles.Forsyth 	}
41037da2899SCharles.Forsyth 	l = m->ext = (Link*)malloc((rlen+1)*sizeof(Link));
41137da2899SCharles.Forsyth 	if(l == nil){
41237da2899SCharles.Forsyth 		freemod(m);
41337da2899SCharles.Forsyth 		return nil;
41437da2899SCharles.Forsyth 	}
41537da2899SCharles.Forsyth 	while(r->name) {
41637da2899SCharles.Forsyth 		t = dtype(freeheap, r->size, r->map, r->np);
41737da2899SCharles.Forsyth 		runtime(m, l, r->name, r->sig, r->fn, t);
41837da2899SCharles.Forsyth 		r++;
41937da2899SCharles.Forsyth 		l++;
42037da2899SCharles.Forsyth 	}
42137da2899SCharles.Forsyth 	l->name = nil;
42237da2899SCharles.Forsyth 	return m;
42337da2899SCharles.Forsyth }
42437da2899SCharles.Forsyth 
42537da2899SCharles.Forsyth void
retnstr(char * s,int n,String ** d)42637da2899SCharles.Forsyth retnstr(char *s, int n, String **d)
42737da2899SCharles.Forsyth {
42837da2899SCharles.Forsyth 	String *s1;
42937da2899SCharles.Forsyth 
43037da2899SCharles.Forsyth 	s1 = H;
43137da2899SCharles.Forsyth 	if(n != 0)
43237da2899SCharles.Forsyth 		s1 = c2string(s, n);
43337da2899SCharles.Forsyth 	destroy(*d);
43437da2899SCharles.Forsyth 	*d = s1;
43537da2899SCharles.Forsyth }
43637da2899SCharles.Forsyth 
43737da2899SCharles.Forsyth void
retstr(char * s,String ** d)43837da2899SCharles.Forsyth retstr(char *s, String **d)
43937da2899SCharles.Forsyth {
44037da2899SCharles.Forsyth 	String *s1;
44137da2899SCharles.Forsyth 
44237da2899SCharles.Forsyth 	s1 = H;
44337da2899SCharles.Forsyth 	if(s != nil)
44437da2899SCharles.Forsyth 		s1 = c2string(s, strlen(s));
44537da2899SCharles.Forsyth 	destroy(*d);
44637da2899SCharles.Forsyth 	*d = s1;
44737da2899SCharles.Forsyth }
44837da2899SCharles.Forsyth 
44937da2899SCharles.Forsyth Array*
mem2array(void * va,int n)45037da2899SCharles.Forsyth mem2array(void *va, int n)
45137da2899SCharles.Forsyth {
45237da2899SCharles.Forsyth 	Heap *h;
45337da2899SCharles.Forsyth 	Array *a;
45437da2899SCharles.Forsyth 
45537da2899SCharles.Forsyth 	if(n < 0)
45637da2899SCharles.Forsyth 		n = 0;
45737da2899SCharles.Forsyth 	h = nheap(sizeof(Array)+n);
45837da2899SCharles.Forsyth 	h->t = &Tarray;
45937da2899SCharles.Forsyth 	h->t->ref++;
46037da2899SCharles.Forsyth 	a = H2D(Array*, h);
46137da2899SCharles.Forsyth 	a->t = &Tbyte;
46237da2899SCharles.Forsyth 	Tbyte.ref++;
46337da2899SCharles.Forsyth 	a->len = n;
46437da2899SCharles.Forsyth 	a->root = H;
46537da2899SCharles.Forsyth 	a->data = (uchar*)a+sizeof(Array);
46637da2899SCharles.Forsyth 	if(va != 0)
46737da2899SCharles.Forsyth 		memmove(a->data, va, n);
46837da2899SCharles.Forsyth 
46937da2899SCharles.Forsyth 	return a;
47037da2899SCharles.Forsyth }
47137da2899SCharles.Forsyth 
47237da2899SCharles.Forsyth static int
utfnleng(char * s,int nb,int * ngood)47337da2899SCharles.Forsyth utfnleng(char *s, int nb, int *ngood)
47437da2899SCharles.Forsyth {
47537da2899SCharles.Forsyth 	int c;
47637da2899SCharles.Forsyth 	long n;
47737da2899SCharles.Forsyth 	Rune rune;
47837da2899SCharles.Forsyth 	char *es, *starts;
47937da2899SCharles.Forsyth 
48037da2899SCharles.Forsyth 	starts = s;
48137da2899SCharles.Forsyth 	es = s+nb;
48237da2899SCharles.Forsyth 	for(n = 0; s < es; n++) {
48337da2899SCharles.Forsyth 		c = *(uchar*)s;
48437da2899SCharles.Forsyth 		if(c < Runeself)
48537da2899SCharles.Forsyth 			s++;
48637da2899SCharles.Forsyth 		else {
48737da2899SCharles.Forsyth 			if(s+UTFmax<=es || fullrune(s, es-s))
48837da2899SCharles.Forsyth 				s += chartorune(&rune, s);
48937da2899SCharles.Forsyth 			else
49037da2899SCharles.Forsyth 				break;
49137da2899SCharles.Forsyth 		}
49237da2899SCharles.Forsyth 	}
49337da2899SCharles.Forsyth 	if(ngood)
49437da2899SCharles.Forsyth 		*ngood = s-starts;
49537da2899SCharles.Forsyth 	return n;
49637da2899SCharles.Forsyth }
497