137da2899SCharles.Forsyth #include "lib9.h"
237da2899SCharles.Forsyth #include "isa.h"
337da2899SCharles.Forsyth #include "interp.h"
437da2899SCharles.Forsyth #include "raise.h"
537da2899SCharles.Forsyth #include "pool.h"
637da2899SCharles.Forsyth
737da2899SCharles.Forsyth #define OP(fn) void fn(void)
837da2899SCharles.Forsyth #define B(r) *((BYTE*)(R.r))
937da2899SCharles.Forsyth #define W(r) *((WORD*)(R.r))
1037da2899SCharles.Forsyth #define F(r) *((REAL*)(R.r))
1137da2899SCharles.Forsyth #define V(r) *((LONG*)(R.r))
1237da2899SCharles.Forsyth #define S(r) *((String**)(R.r))
1337da2899SCharles.Forsyth #define A(r) *((Array**)(R.r))
1437da2899SCharles.Forsyth #define L(r) *((List**)(R.r))
1537da2899SCharles.Forsyth #define P(r) *((WORD**)(R.r))
1637da2899SCharles.Forsyth #define C(r) *((Channel**)(R.r))
1737da2899SCharles.Forsyth #define T(r) *((void**)(R.r))
1837da2899SCharles.Forsyth
OP(indc)1937da2899SCharles.Forsyth OP(indc)
2037da2899SCharles.Forsyth {
2137da2899SCharles.Forsyth int l;
2237da2899SCharles.Forsyth ulong v;
2337da2899SCharles.Forsyth String *ss;
2437da2899SCharles.Forsyth
2537da2899SCharles.Forsyth v = W(m);
2637da2899SCharles.Forsyth ss = S(s);
2737da2899SCharles.Forsyth
2837da2899SCharles.Forsyth if(ss == H)
2937da2899SCharles.Forsyth error(exNilref);
3037da2899SCharles.Forsyth
3137da2899SCharles.Forsyth l = ss->len;
3237da2899SCharles.Forsyth if(l < 0) {
3337da2899SCharles.Forsyth if(v >= -l)
3437da2899SCharles.Forsyth e: error(exBounds);
3537da2899SCharles.Forsyth l = ss->Srune[v];
3637da2899SCharles.Forsyth }
3737da2899SCharles.Forsyth else {
3837da2899SCharles.Forsyth if(v >= l)
3937da2899SCharles.Forsyth goto e;
4037da2899SCharles.Forsyth l = ss->Sascii[v];
4137da2899SCharles.Forsyth }
4237da2899SCharles.Forsyth W(d) = l;
4337da2899SCharles.Forsyth }
4437da2899SCharles.Forsyth
OP(insc)4537da2899SCharles.Forsyth OP(insc)
4637da2899SCharles.Forsyth {
4737da2899SCharles.Forsyth ulong v;
4837da2899SCharles.Forsyth int l, r, expand;
4937da2899SCharles.Forsyth String *ss, *ns, **sp;
5037da2899SCharles.Forsyth
5137da2899SCharles.Forsyth r = W(s);
5237da2899SCharles.Forsyth v = W(m);
5337da2899SCharles.Forsyth ss = S(d);
5437da2899SCharles.Forsyth
5537da2899SCharles.Forsyth expand = r >= Runeself;
5637da2899SCharles.Forsyth
5737da2899SCharles.Forsyth if(ss == H) {
5837da2899SCharles.Forsyth ss = newstring(0);
5937da2899SCharles.Forsyth if(expand) {
6037da2899SCharles.Forsyth l = 0;
6137da2899SCharles.Forsyth ss->max /= sizeof(Rune);
6237da2899SCharles.Forsyth goto r;
6337da2899SCharles.Forsyth }
6437da2899SCharles.Forsyth }
6537da2899SCharles.Forsyth else
6637da2899SCharles.Forsyth if(D2H(ss)->ref > 1 || (expand && ss->len > 0))
6737da2899SCharles.Forsyth ss = splitc(R.d, expand);
6837da2899SCharles.Forsyth
6937da2899SCharles.Forsyth l = ss->len;
7037da2899SCharles.Forsyth if(l < 0 || expand) {
7137da2899SCharles.Forsyth l = -l;
7237da2899SCharles.Forsyth r:
7337da2899SCharles.Forsyth if(v < l)
7437da2899SCharles.Forsyth ss->Srune[v] = r;
7537da2899SCharles.Forsyth else
7637da2899SCharles.Forsyth if(v == l && v < ss->max) {
7737da2899SCharles.Forsyth ss->len = -(v+1);
7837da2899SCharles.Forsyth ss->Srune[v] = r;
7937da2899SCharles.Forsyth }
8037da2899SCharles.Forsyth else {
8137da2899SCharles.Forsyth if(v != l)
8237da2899SCharles.Forsyth error(exBounds);
8337da2899SCharles.Forsyth ns = newstring((v + 1 + v/4)*sizeof(Rune));
8437da2899SCharles.Forsyth memmove(ns->Srune, ss->Srune, -ss->len*sizeof(Rune));
8537da2899SCharles.Forsyth ns->Srune[v] = r;
8637da2899SCharles.Forsyth ns->len = -(v+1);
8737da2899SCharles.Forsyth ns->max /= sizeof(Rune);
8837da2899SCharles.Forsyth ss = ns;
8937da2899SCharles.Forsyth }
9037da2899SCharles.Forsyth }
9137da2899SCharles.Forsyth else {
9237da2899SCharles.Forsyth if(v < l)
9337da2899SCharles.Forsyth ss->Sascii[v] = r;
9437da2899SCharles.Forsyth else
9537da2899SCharles.Forsyth if(v == l && v < ss->max) {
9637da2899SCharles.Forsyth ss->len = v+1;
9737da2899SCharles.Forsyth ss->Sascii[v] = r;
9837da2899SCharles.Forsyth }
9937da2899SCharles.Forsyth else {
10037da2899SCharles.Forsyth if(v != l)
10137da2899SCharles.Forsyth error(exBounds);
10237da2899SCharles.Forsyth ns = newstring(v + 1 + v/4);
10337da2899SCharles.Forsyth memmove(ns->Sascii, ss->Sascii, l);
10437da2899SCharles.Forsyth ns->Sascii[v] = r;
10537da2899SCharles.Forsyth ns->len = v+1;
10637da2899SCharles.Forsyth ss = ns;
10737da2899SCharles.Forsyth }
10837da2899SCharles.Forsyth }
10937da2899SCharles.Forsyth if(ss != S(d)) {
11037da2899SCharles.Forsyth sp = R.d;
11137da2899SCharles.Forsyth destroy(*sp);
11237da2899SCharles.Forsyth *sp = ss;
11337da2899SCharles.Forsyth }
11437da2899SCharles.Forsyth }
11537da2899SCharles.Forsyth
11637da2899SCharles.Forsyth String*
slicer(ulong start,ulong v,String * ds)11737da2899SCharles.Forsyth slicer(ulong start, ulong v, String *ds)
11837da2899SCharles.Forsyth {
11937da2899SCharles.Forsyth String *ns;
12037da2899SCharles.Forsyth int l, nc;
12137da2899SCharles.Forsyth
12237da2899SCharles.Forsyth if(ds == H) {
12337da2899SCharles.Forsyth if(start == 0 && v == 0)
12437da2899SCharles.Forsyth return H;
12537da2899SCharles.Forsyth
12637da2899SCharles.Forsyth error(exBounds);
12737da2899SCharles.Forsyth }
12837da2899SCharles.Forsyth
12937da2899SCharles.Forsyth nc = v - start;
13037da2899SCharles.Forsyth if(ds->len < 0) {
13137da2899SCharles.Forsyth l = -ds->len;
13237da2899SCharles.Forsyth if(v < start || v > l)
13337da2899SCharles.Forsyth error(exBounds);
134*3ca84fa3SCharles.Forsyth if(nc == 0)
135*3ca84fa3SCharles.Forsyth return H;
13637da2899SCharles.Forsyth ns = newrunes(nc);
13737da2899SCharles.Forsyth memmove(ns->Srune, &ds->Srune[start], nc*sizeof(Rune));
13837da2899SCharles.Forsyth }
13937da2899SCharles.Forsyth else {
14037da2899SCharles.Forsyth l = ds->len;
14137da2899SCharles.Forsyth if(v < start || v > l)
14237da2899SCharles.Forsyth error(exBounds);
143*3ca84fa3SCharles.Forsyth if(nc == 0)
144*3ca84fa3SCharles.Forsyth return H;
14537da2899SCharles.Forsyth ns = newstring(nc);
14637da2899SCharles.Forsyth memmove(ns->Sascii, &ds->Sascii[start], nc);
14737da2899SCharles.Forsyth }
14837da2899SCharles.Forsyth
14937da2899SCharles.Forsyth return ns;
15037da2899SCharles.Forsyth }
15137da2899SCharles.Forsyth
OP(slicec)15237da2899SCharles.Forsyth OP(slicec)
15337da2899SCharles.Forsyth {
15437da2899SCharles.Forsyth String *ns, **sp;
15537da2899SCharles.Forsyth
15637da2899SCharles.Forsyth ns = slicer(W(s), W(m), S(d));
15737da2899SCharles.Forsyth sp = R.d;
15837da2899SCharles.Forsyth destroy(*sp);
15937da2899SCharles.Forsyth *sp = ns;
16037da2899SCharles.Forsyth }
16137da2899SCharles.Forsyth
16237da2899SCharles.Forsyth void
cvtup(Rune * r,String * s)16337da2899SCharles.Forsyth cvtup(Rune *r, String *s)
16437da2899SCharles.Forsyth {
16537da2899SCharles.Forsyth uchar *bp, *ep;
16637da2899SCharles.Forsyth
16737da2899SCharles.Forsyth bp = (uchar*)s->Sascii;
16837da2899SCharles.Forsyth ep = bp + s->len;
16937da2899SCharles.Forsyth while(bp < ep)
17037da2899SCharles.Forsyth *r++ = *bp++;
17137da2899SCharles.Forsyth }
17237da2899SCharles.Forsyth
17337da2899SCharles.Forsyth String*
addstring(String * s1,String * s2,int append)17437da2899SCharles.Forsyth addstring(String *s1, String *s2, int append)
17537da2899SCharles.Forsyth {
17637da2899SCharles.Forsyth Rune *r;
17737da2899SCharles.Forsyth String *ns;
17837da2899SCharles.Forsyth int l, l1, l2;
17937da2899SCharles.Forsyth
18037da2899SCharles.Forsyth if(s1 == H) {
18137da2899SCharles.Forsyth if(s2 == H)
18237da2899SCharles.Forsyth return H;
18337da2899SCharles.Forsyth return stringdup(s2);
18437da2899SCharles.Forsyth }
18537da2899SCharles.Forsyth if(D2H(s1)->ref > 1)
18637da2899SCharles.Forsyth append = 0;
18737da2899SCharles.Forsyth if(s2 == H) {
18837da2899SCharles.Forsyth if(append)
18937da2899SCharles.Forsyth return s1;
19037da2899SCharles.Forsyth return stringdup(s1);
19137da2899SCharles.Forsyth }
19237da2899SCharles.Forsyth
19337da2899SCharles.Forsyth if(s1->len < 0) {
19437da2899SCharles.Forsyth l1 = -s1->len;
19537da2899SCharles.Forsyth if(s2->len < 0)
19637da2899SCharles.Forsyth l = l1 - s2->len;
19737da2899SCharles.Forsyth else
19837da2899SCharles.Forsyth l = l1 + s2->len;
19937da2899SCharles.Forsyth if(append && l <= s1->max)
20037da2899SCharles.Forsyth ns = s1;
20137da2899SCharles.Forsyth else {
20237da2899SCharles.Forsyth ns = newrunes(append? (l+l/4): l);
20337da2899SCharles.Forsyth memmove(ns->Srune, s1->Srune, l1*sizeof(Rune));
20437da2899SCharles.Forsyth }
20537da2899SCharles.Forsyth ns->len = -l;
20637da2899SCharles.Forsyth r = &ns->Srune[l1];
20737da2899SCharles.Forsyth if(s2->len < 0)
20837da2899SCharles.Forsyth memmove(r, s2->Srune, -s2->len*sizeof(Rune));
20937da2899SCharles.Forsyth else
21037da2899SCharles.Forsyth cvtup(r, s2);
21137da2899SCharles.Forsyth
21237da2899SCharles.Forsyth return ns;
21337da2899SCharles.Forsyth }
21437da2899SCharles.Forsyth
21537da2899SCharles.Forsyth if(s2->len < 0) {
21637da2899SCharles.Forsyth l2 = -s2->len;
21737da2899SCharles.Forsyth l = s1->len + l2;
21837da2899SCharles.Forsyth ns = newrunes(append? (l+l/4): l);
21937da2899SCharles.Forsyth ns->len = -l;
22037da2899SCharles.Forsyth cvtup(ns->Srune, s1);
22137da2899SCharles.Forsyth memmove(&ns->Srune[s1->len], s2->Srune, l2*sizeof(Rune));
22237da2899SCharles.Forsyth return ns;
22337da2899SCharles.Forsyth }
22437da2899SCharles.Forsyth
22537da2899SCharles.Forsyth l1 = s1->len;
22637da2899SCharles.Forsyth l = l1 + s2->len;
22737da2899SCharles.Forsyth if(append && l <= s1->max)
22837da2899SCharles.Forsyth ns = s1;
22937da2899SCharles.Forsyth else {
23037da2899SCharles.Forsyth ns = newstring(append? (l+l/4): l);
23137da2899SCharles.Forsyth memmove(ns->Sascii, s1->Sascii, l1);
23237da2899SCharles.Forsyth }
23337da2899SCharles.Forsyth ns->len = l;
23437da2899SCharles.Forsyth memmove(ns->Sascii+l1, s2->Sascii, s2->len);
23537da2899SCharles.Forsyth
23637da2899SCharles.Forsyth return ns;
23737da2899SCharles.Forsyth }
23837da2899SCharles.Forsyth
OP(addc)23937da2899SCharles.Forsyth OP(addc)
24037da2899SCharles.Forsyth {
24137da2899SCharles.Forsyth String *ns, **sp;
24237da2899SCharles.Forsyth
24337da2899SCharles.Forsyth ns = addstring(S(m), S(s), R.m == R.d);
24437da2899SCharles.Forsyth
24537da2899SCharles.Forsyth sp = R.d;
24637da2899SCharles.Forsyth if(ns != *sp) {
24737da2899SCharles.Forsyth destroy(*sp);
24837da2899SCharles.Forsyth *sp = ns;
24937da2899SCharles.Forsyth }
25037da2899SCharles.Forsyth }
25137da2899SCharles.Forsyth
OP(cvtca)25237da2899SCharles.Forsyth OP(cvtca)
25337da2899SCharles.Forsyth {
25437da2899SCharles.Forsyth int l;
25537da2899SCharles.Forsyth Rune *r;
25637da2899SCharles.Forsyth char *p;
25737da2899SCharles.Forsyth String *ss;
25837da2899SCharles.Forsyth Array *a, **ap;
25937da2899SCharles.Forsyth
26037da2899SCharles.Forsyth ss = S(s);
26137da2899SCharles.Forsyth if(ss == H) {
26237da2899SCharles.Forsyth a = mem2array(nil, 0);
26337da2899SCharles.Forsyth goto r;
26437da2899SCharles.Forsyth }
26537da2899SCharles.Forsyth if(ss->len < 0) {
26637da2899SCharles.Forsyth l = -ss->len;
26737da2899SCharles.Forsyth a = mem2array(nil, runenlen(ss->Srune, l));
26837da2899SCharles.Forsyth p = (char*)a->data;
26937da2899SCharles.Forsyth r = ss->Srune;
27037da2899SCharles.Forsyth while(l--)
27137da2899SCharles.Forsyth p += runetochar(p, r++);
27237da2899SCharles.Forsyth goto r;
27337da2899SCharles.Forsyth }
27437da2899SCharles.Forsyth a = mem2array(ss->Sascii, ss->len);
27537da2899SCharles.Forsyth
27637da2899SCharles.Forsyth r: ap = R.d;
27737da2899SCharles.Forsyth destroy(*ap);
27837da2899SCharles.Forsyth *ap = a;
27937da2899SCharles.Forsyth }
28037da2899SCharles.Forsyth
OP(cvtac)28137da2899SCharles.Forsyth OP(cvtac)
28237da2899SCharles.Forsyth {
28337da2899SCharles.Forsyth Array *a;
28437da2899SCharles.Forsyth String *ds, **dp;
28537da2899SCharles.Forsyth
28637da2899SCharles.Forsyth ds = H;
28737da2899SCharles.Forsyth a = A(s);
28837da2899SCharles.Forsyth if(a != H)
28937da2899SCharles.Forsyth ds = c2string((char*)a->data, a->len);
29037da2899SCharles.Forsyth
29137da2899SCharles.Forsyth dp = R.d;
29237da2899SCharles.Forsyth destroy(*dp);
29337da2899SCharles.Forsyth *dp = ds;
29437da2899SCharles.Forsyth }
29537da2899SCharles.Forsyth
OP(lenc)29637da2899SCharles.Forsyth OP(lenc)
29737da2899SCharles.Forsyth {
29837da2899SCharles.Forsyth int l;
29937da2899SCharles.Forsyth String *ss;
30037da2899SCharles.Forsyth
30137da2899SCharles.Forsyth l = 0;
30237da2899SCharles.Forsyth ss = S(s);
30337da2899SCharles.Forsyth if(ss != H) {
30437da2899SCharles.Forsyth l = ss->len;
30537da2899SCharles.Forsyth if(l < 0)
30637da2899SCharles.Forsyth l = -l;
30737da2899SCharles.Forsyth }
30837da2899SCharles.Forsyth W(d) = l;
30937da2899SCharles.Forsyth }
31037da2899SCharles.Forsyth
OP(cvtcw)31137da2899SCharles.Forsyth OP(cvtcw)
31237da2899SCharles.Forsyth {
31337da2899SCharles.Forsyth String *s;
31437da2899SCharles.Forsyth
31537da2899SCharles.Forsyth s = S(s);
31637da2899SCharles.Forsyth if(s == H)
31737da2899SCharles.Forsyth W(d) = 0;
31837da2899SCharles.Forsyth else
31937da2899SCharles.Forsyth if(s->len < 0)
32037da2899SCharles.Forsyth W(d) = strtol(string2c(s), nil, 10);
32137da2899SCharles.Forsyth else {
32237da2899SCharles.Forsyth s->Sascii[s->len] = '\0';
32337da2899SCharles.Forsyth W(d) = strtol(s->Sascii, nil, 10);
32437da2899SCharles.Forsyth }
32537da2899SCharles.Forsyth }
32637da2899SCharles.Forsyth
OP(cvtcf)32737da2899SCharles.Forsyth OP(cvtcf)
32837da2899SCharles.Forsyth {
32937da2899SCharles.Forsyth String *s;
33037da2899SCharles.Forsyth
33137da2899SCharles.Forsyth s = S(s);
33237da2899SCharles.Forsyth if(s == H)
33337da2899SCharles.Forsyth F(d) = 0.0;
33437da2899SCharles.Forsyth else
33537da2899SCharles.Forsyth if(s->len < 0)
33637da2899SCharles.Forsyth F(d) = strtod(string2c(s), nil);
33737da2899SCharles.Forsyth else {
33837da2899SCharles.Forsyth s->Sascii[s->len] = '\0';
33937da2899SCharles.Forsyth F(d) = strtod(s->Sascii, nil);
34037da2899SCharles.Forsyth }
34137da2899SCharles.Forsyth }
34237da2899SCharles.Forsyth
OP(cvtwc)34337da2899SCharles.Forsyth OP(cvtwc)
34437da2899SCharles.Forsyth {
34537da2899SCharles.Forsyth String *ds, **dp;
34637da2899SCharles.Forsyth
34737da2899SCharles.Forsyth ds = newstring(16);
34837da2899SCharles.Forsyth ds->len = sprint(ds->Sascii, "%d", W(s));
34937da2899SCharles.Forsyth
35037da2899SCharles.Forsyth dp = R.d;
35137da2899SCharles.Forsyth destroy(*dp);
35237da2899SCharles.Forsyth *dp = ds;
35337da2899SCharles.Forsyth }
35437da2899SCharles.Forsyth
OP(cvtlc)35537da2899SCharles.Forsyth OP(cvtlc)
35637da2899SCharles.Forsyth {
35737da2899SCharles.Forsyth String *ds, **dp;
35837da2899SCharles.Forsyth
35937da2899SCharles.Forsyth ds = newstring(16);
36037da2899SCharles.Forsyth ds->len = sprint(ds->Sascii, "%lld", V(s));
36137da2899SCharles.Forsyth
36237da2899SCharles.Forsyth dp = R.d;
36337da2899SCharles.Forsyth destroy(*dp);
36437da2899SCharles.Forsyth *dp = ds;
36537da2899SCharles.Forsyth }
36637da2899SCharles.Forsyth
OP(cvtfc)36737da2899SCharles.Forsyth OP(cvtfc)
36837da2899SCharles.Forsyth {
36937da2899SCharles.Forsyth String *ds, **dp;
37037da2899SCharles.Forsyth
37137da2899SCharles.Forsyth ds = newstring(32);
37237da2899SCharles.Forsyth ds->len = sprint(ds->Sascii, "%g", F(s));
37337da2899SCharles.Forsyth dp = R.d;
37437da2899SCharles.Forsyth destroy(*dp);
37537da2899SCharles.Forsyth *dp = ds;
37637da2899SCharles.Forsyth }
37737da2899SCharles.Forsyth
37837da2899SCharles.Forsyth char*
string2c(String * s)37937da2899SCharles.Forsyth string2c(String *s)
38037da2899SCharles.Forsyth {
38137da2899SCharles.Forsyth char *p;
38237da2899SCharles.Forsyth int c, l, nc;
38337da2899SCharles.Forsyth Rune *r, *er;
38437da2899SCharles.Forsyth
38537da2899SCharles.Forsyth if(s == H)
38637da2899SCharles.Forsyth return "";
38737da2899SCharles.Forsyth
38837da2899SCharles.Forsyth if(s->len >= 0) {
38937da2899SCharles.Forsyth s->Sascii[s->len] = '\0';
39037da2899SCharles.Forsyth return s->Sascii;
39137da2899SCharles.Forsyth }
39237da2899SCharles.Forsyth
39337da2899SCharles.Forsyth nc = -s->len;
39437da2899SCharles.Forsyth l = (nc * UTFmax) + UTFmax;
39537da2899SCharles.Forsyth if(s->tmp == nil || msize(s->tmp) < l) {
39637da2899SCharles.Forsyth free(s->tmp);
39737da2899SCharles.Forsyth s->tmp = malloc(l);
39837da2899SCharles.Forsyth if(s->tmp == nil)
39937da2899SCharles.Forsyth error(exNomem);
40037da2899SCharles.Forsyth }
40137da2899SCharles.Forsyth
40237da2899SCharles.Forsyth p = s->tmp;
40337da2899SCharles.Forsyth r = s->Srune;
40437da2899SCharles.Forsyth er = r + nc;
40537da2899SCharles.Forsyth while(r < er) {
40637da2899SCharles.Forsyth c = *r++;
40737da2899SCharles.Forsyth if(c < Runeself)
40837da2899SCharles.Forsyth *p++ = c;
40937da2899SCharles.Forsyth else
41037da2899SCharles.Forsyth p += runetochar(p, r-1);
41137da2899SCharles.Forsyth }
41237da2899SCharles.Forsyth
41337da2899SCharles.Forsyth *p = 0;
41437da2899SCharles.Forsyth
41537da2899SCharles.Forsyth return s->tmp;
41637da2899SCharles.Forsyth }
41737da2899SCharles.Forsyth
41837da2899SCharles.Forsyth String*
c2string(char * cs,int len)41937da2899SCharles.Forsyth c2string(char *cs, int len)
42037da2899SCharles.Forsyth {
42137da2899SCharles.Forsyth uchar *p;
42237da2899SCharles.Forsyth char *ecs;
42337da2899SCharles.Forsyth String *s;
42437da2899SCharles.Forsyth Rune *r, junk;
42537da2899SCharles.Forsyth int c, nc, isrune;
42637da2899SCharles.Forsyth
42737da2899SCharles.Forsyth isrune = 0;
42837da2899SCharles.Forsyth ecs = cs+len;
42937da2899SCharles.Forsyth p = (uchar*)cs;
43037da2899SCharles.Forsyth while(len--) {
43137da2899SCharles.Forsyth c = *p++;
43237da2899SCharles.Forsyth if(c >= Runeself) {
43337da2899SCharles.Forsyth isrune = 1;
43437da2899SCharles.Forsyth break;
43537da2899SCharles.Forsyth }
43637da2899SCharles.Forsyth }
43737da2899SCharles.Forsyth
43837da2899SCharles.Forsyth if(isrune == 0) {
43937da2899SCharles.Forsyth nc = ecs - cs;
44037da2899SCharles.Forsyth s = newstring(nc);
44137da2899SCharles.Forsyth memmove(s->Sascii, cs, nc);
44237da2899SCharles.Forsyth return s;
44337da2899SCharles.Forsyth }
44437da2899SCharles.Forsyth
44537da2899SCharles.Forsyth p--;
44637da2899SCharles.Forsyth nc = p - (uchar*)cs;
44737da2899SCharles.Forsyth while(p < (uchar*)ecs) {
44837da2899SCharles.Forsyth c = *p;
44937da2899SCharles.Forsyth if(c < Runeself)
45037da2899SCharles.Forsyth p++;
45137da2899SCharles.Forsyth else if(p+UTFmax<=(uchar*)ecs || fullrune((char*)p, (uchar*)ecs-p))
45237da2899SCharles.Forsyth p += chartorune(&junk, (char*)p);
45337da2899SCharles.Forsyth else
45437da2899SCharles.Forsyth break;
45537da2899SCharles.Forsyth nc++;
45637da2899SCharles.Forsyth }
45737da2899SCharles.Forsyth s = newrunes(nc);
45837da2899SCharles.Forsyth r = s->Srune;
45937da2899SCharles.Forsyth while(nc--)
46037da2899SCharles.Forsyth cs += chartorune(r++, cs);
46137da2899SCharles.Forsyth
46237da2899SCharles.Forsyth return s;
46337da2899SCharles.Forsyth }
46437da2899SCharles.Forsyth
46537da2899SCharles.Forsyth String*
newstring(int nb)46637da2899SCharles.Forsyth newstring(int nb)
46737da2899SCharles.Forsyth {
46837da2899SCharles.Forsyth Heap *h;
46937da2899SCharles.Forsyth String *s;
47037da2899SCharles.Forsyth
47137da2899SCharles.Forsyth h = nheap(sizeof(String)+nb);
47237da2899SCharles.Forsyth h->t = &Tstring;
47337da2899SCharles.Forsyth Tstring.ref++;
47437da2899SCharles.Forsyth s = H2D(String*, h);
47537da2899SCharles.Forsyth s->tmp = nil;
47637da2899SCharles.Forsyth s->len = nb;
47737da2899SCharles.Forsyth s->max = hmsize(h) - (sizeof(String)+sizeof(Heap));
47837da2899SCharles.Forsyth return s;
47937da2899SCharles.Forsyth }
48037da2899SCharles.Forsyth
48137da2899SCharles.Forsyth String*
newrunes(int nr)48237da2899SCharles.Forsyth newrunes(int nr)
48337da2899SCharles.Forsyth {
48437da2899SCharles.Forsyth Heap *h;
48537da2899SCharles.Forsyth String *s;
48637da2899SCharles.Forsyth
48737da2899SCharles.Forsyth if(nr == 0)
48837da2899SCharles.Forsyth return newstring(nr);
48937da2899SCharles.Forsyth if(nr < 0)
49037da2899SCharles.Forsyth nr = -nr;
49137da2899SCharles.Forsyth h = nheap(sizeof(String)+nr*sizeof(Rune));
49237da2899SCharles.Forsyth h->t = &Tstring;
49337da2899SCharles.Forsyth Tstring.ref++;
49437da2899SCharles.Forsyth s = H2D(String*, h);
49537da2899SCharles.Forsyth s->tmp = nil;
49637da2899SCharles.Forsyth s->len = -nr;
49737da2899SCharles.Forsyth s->max = (hmsize(h) - (sizeof(String)+sizeof(Heap)))/sizeof(Rune);
49837da2899SCharles.Forsyth return s;
49937da2899SCharles.Forsyth }
50037da2899SCharles.Forsyth
50137da2899SCharles.Forsyth String*
stringdup(String * s)50237da2899SCharles.Forsyth stringdup(String *s)
50337da2899SCharles.Forsyth {
50437da2899SCharles.Forsyth String *ns;
50537da2899SCharles.Forsyth
50637da2899SCharles.Forsyth if(s == H)
50737da2899SCharles.Forsyth return H;
50837da2899SCharles.Forsyth
50937da2899SCharles.Forsyth if(s->len >= 0) {
51037da2899SCharles.Forsyth ns = newstring(s->len);
51137da2899SCharles.Forsyth memmove(ns->Sascii, s->Sascii, s->len);
51237da2899SCharles.Forsyth return ns;
51337da2899SCharles.Forsyth }
51437da2899SCharles.Forsyth
51537da2899SCharles.Forsyth ns = newrunes(-s->len);
51637da2899SCharles.Forsyth memmove(ns->Srune, s->Srune,-s->len*sizeof(Rune));
51737da2899SCharles.Forsyth
51837da2899SCharles.Forsyth return ns;
51937da2899SCharles.Forsyth }
52037da2899SCharles.Forsyth
52137da2899SCharles.Forsyth int
stringcmp(String * s1,String * s2)52237da2899SCharles.Forsyth stringcmp(String *s1, String *s2)
52337da2899SCharles.Forsyth {
52437da2899SCharles.Forsyth Rune *r1, *r2;
52537da2899SCharles.Forsyth char *a1, *a2;
52637da2899SCharles.Forsyth int v, n, n1, n2, c1, c2;
52737da2899SCharles.Forsyth static String snil = { 0, 0, nil };
52837da2899SCharles.Forsyth
52937da2899SCharles.Forsyth if(s1 == H)
53037da2899SCharles.Forsyth s1 = &snil;
53137da2899SCharles.Forsyth if(s2 == H)
53237da2899SCharles.Forsyth s2 = &snil;
53337da2899SCharles.Forsyth
53437da2899SCharles.Forsyth if(s1 == s2)
53537da2899SCharles.Forsyth return 0;
53637da2899SCharles.Forsyth
53737da2899SCharles.Forsyth v = 0;
53837da2899SCharles.Forsyth n1 = s1->len;
53937da2899SCharles.Forsyth if(n1 < 0) {
54037da2899SCharles.Forsyth n1 = -n1;
54137da2899SCharles.Forsyth v |= 1;
54237da2899SCharles.Forsyth }
54337da2899SCharles.Forsyth n2 = s2->len;
54437da2899SCharles.Forsyth if(n2 < 0) {
54537da2899SCharles.Forsyth n2 = -n2;
54637da2899SCharles.Forsyth v |= 2;
54737da2899SCharles.Forsyth }
54837da2899SCharles.Forsyth
54937da2899SCharles.Forsyth n = n1;
55037da2899SCharles.Forsyth if(n2 < n)
55137da2899SCharles.Forsyth n = n2;
55237da2899SCharles.Forsyth
55337da2899SCharles.Forsyth switch(v) {
55437da2899SCharles.Forsyth case 0: /* Ascii Ascii */
55537da2899SCharles.Forsyth n = memcmp(s1->Sascii, s2->Sascii, n);
55637da2899SCharles.Forsyth if(n == 0)
55737da2899SCharles.Forsyth n = n1 - n2;
55837da2899SCharles.Forsyth return n;
55937da2899SCharles.Forsyth case 1: /* Rune Ascii */
56037da2899SCharles.Forsyth r1 = s1->Srune;
56137da2899SCharles.Forsyth a2 = s2->Sascii;
56237da2899SCharles.Forsyth while(n > 0) {
56337da2899SCharles.Forsyth c1 = *r1++;
56437da2899SCharles.Forsyth c2 = *a2++;
56537da2899SCharles.Forsyth if(c1 != c2)
56637da2899SCharles.Forsyth goto ne;
56737da2899SCharles.Forsyth n--;
56837da2899SCharles.Forsyth }
56937da2899SCharles.Forsyth break;
57037da2899SCharles.Forsyth case 2: /* Ascii Rune */
57137da2899SCharles.Forsyth a1 = s1->Sascii;
57237da2899SCharles.Forsyth r2 = s2->Srune;
57337da2899SCharles.Forsyth while(n > 0) {
57437da2899SCharles.Forsyth c1 = *a1++;
57537da2899SCharles.Forsyth c2 = *r2++;
57637da2899SCharles.Forsyth if(c1 != c2)
57737da2899SCharles.Forsyth goto ne;
57837da2899SCharles.Forsyth n--;
57937da2899SCharles.Forsyth }
58037da2899SCharles.Forsyth break;
58137da2899SCharles.Forsyth case 3: /* Rune Rune */
58237da2899SCharles.Forsyth r1 = s1->Srune;
58337da2899SCharles.Forsyth r2 = s2->Srune;
58437da2899SCharles.Forsyth while(n > 0) {
58537da2899SCharles.Forsyth c1 = *r1++;
58637da2899SCharles.Forsyth c2 = *r2++;
58737da2899SCharles.Forsyth if(c1 != c2)
58837da2899SCharles.Forsyth goto ne;
58937da2899SCharles.Forsyth n--;
59037da2899SCharles.Forsyth }
59137da2899SCharles.Forsyth break;
59237da2899SCharles.Forsyth }
59337da2899SCharles.Forsyth return n1 - n2;
59437da2899SCharles.Forsyth
59537da2899SCharles.Forsyth ne: if(c1 < c2)
59637da2899SCharles.Forsyth return -1;
59737da2899SCharles.Forsyth return 1;
59837da2899SCharles.Forsyth }
59937da2899SCharles.Forsyth
60037da2899SCharles.Forsyth String*
splitc(String ** s,int expand)60137da2899SCharles.Forsyth splitc(String **s, int expand)
60237da2899SCharles.Forsyth {
60337da2899SCharles.Forsyth String *ss, *ns;
60437da2899SCharles.Forsyth
60537da2899SCharles.Forsyth ss = *s;
60637da2899SCharles.Forsyth if(expand && ss->len > 0) {
60737da2899SCharles.Forsyth ns = newrunes(ss->len);
60837da2899SCharles.Forsyth cvtup(ns->Srune, ss);
60937da2899SCharles.Forsyth }
61037da2899SCharles.Forsyth else
61137da2899SCharles.Forsyth ns = stringdup(ss);
61237da2899SCharles.Forsyth
61337da2899SCharles.Forsyth destroy(ss);
61437da2899SCharles.Forsyth *s = ns;
61537da2899SCharles.Forsyth return ns;
61637da2899SCharles.Forsyth }
617