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