version 1.52, 2020/06/10 21:03:12 |
version 1.53, 2020/06/10 21:03:36 |
|
|
/* round up to next multiple of quantum */ |
/* round up to next multiple of quantum */ |
if (rminlen) |
if (rminlen) |
minlen += quantum - rminlen; |
minlen += quantum - rminlen; |
tbuf = (char *) realloc(*pbuf, minlen); |
tbuf = realloc(*pbuf, minlen); |
DPRINTF( ("adjbuf %s: %d %d (pbuf=%p, tbuf=%p)\n", whatrtn, *psiz, minlen, (void *) *pbuf, (void *) tbuf) ); |
DPRINTF( ("adjbuf %s: %d %d (pbuf=%p, tbuf=%p)\n", whatrtn, *psiz, minlen, *pbuf, tbuf) ); |
if (tbuf == NULL) { |
if (tbuf == NULL) { |
if (whatrtn) |
if (whatrtn) |
FATAL("out of memory in %s", whatrtn); |
FATAL("out of memory in %s", whatrtn); |
|
|
if (!isfcn(fcn)) |
if (!isfcn(fcn)) |
FATAL("calling undefined function %s", s); |
FATAL("calling undefined function %s", s); |
if (frame == NULL) { |
if (frame == NULL) { |
fp = frame = (struct Frame *) calloc(nframe += 100, sizeof(struct Frame)); |
fp = frame = calloc(nframe += 100, sizeof(*frame)); |
if (frame == NULL) |
if (frame == NULL) |
FATAL("out of space for stack frames calling %s", s); |
FATAL("out of space for stack frames calling %s", s); |
} |
} |
|
|
if (fp >= frame + nframe) { |
if (fp >= frame + nframe) { |
int dfp = fp - frame; /* old index */ |
int dfp = fp - frame; /* old index */ |
frame = reallocarray(frame, (nframe += 100), |
frame = reallocarray(frame, (nframe += 100), |
sizeof(struct Frame)); |
sizeof(*frame)); |
if (frame == NULL) |
if (frame == NULL) |
FATAL("out of space for stack frames in %s", s); |
FATAL("out of space for stack frames in %s", s); |
fp = frame + dfp; |
fp = frame + dfp; |
|
|
int bufsize = recsize; |
int bufsize = recsize; |
int mode; |
int mode; |
|
|
if ((buf = (char *) malloc(bufsize)) == NULL) |
if ((buf = malloc(bufsize)) == NULL) |
FATAL("out of memory in getline"); |
FATAL("out of memory in getline"); |
|
|
fflush(stdout); /* in case someone is waiting for a prompt */ |
fflush(stdout); /* in case someone is waiting for a prompt */ |
|
|
return (Cell *) a[0]; |
return (Cell *) a[0]; |
} |
} |
|
|
Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ |
static char * |
|
makearraystring(Node *p, const char *func) |
{ |
{ |
Cell *x, *y, *z; |
|
char *s; |
|
Node *np; |
|
char *buf; |
char *buf; |
int bufsz = recsize; |
int bufsz = recsize; |
int nsub; |
size_t blen, seplen; |
|
|
if ((buf = (char *) malloc(bufsz)) == NULL) |
if ((buf = malloc(bufsz)) == NULL) { |
FATAL("out of memory in array"); |
FATAL("%s: out of memory", func); |
|
} |
|
|
x = execute(a[0]); /* Cell* for symbol table */ |
blen = 0; |
buf[0] = 0; |
buf[blen] = '\0'; |
for (np = a[1]; np; np = np->nnext) { |
seplen = strlen(getsval(subseploc)); |
y = execute(np); /* subscript */ |
|
s = getsval(y); |
for (; p; p = p->nnext) { |
nsub = strlen(getsval(subseploc)); |
Cell *x = execute(p); /* expr */ |
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "array")) |
char *s = getsval(x); |
FATAL("out of memory for %s[%s...]", x->nval, buf); |
size_t nsub = p->nnext ? seplen : 0; |
strlcat(buf, s, bufsz); |
size_t slen = strlen(s); |
if (np->nnext) |
size_t tlen = blen + slen + nsub; |
strlcat(buf, *SUBSEP, bufsz); |
|
tempfree(y); |
if (!adjbuf(&buf, &bufsz, tlen + 1, recsize, 0, func)) { |
|
FATAL("%s: out of memory %s[%s...]", |
|
func, x->nval, buf); |
|
} |
|
memcpy(buf + blen, s, slen); |
|
if (nsub) { |
|
memcpy(buf + blen + slen, *SUBSEP, nsub); |
|
} |
|
buf[tlen] = '\0'; |
|
blen = tlen; |
|
tempfree(x); |
} |
} |
|
return buf; |
|
} |
|
|
|
Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ |
|
{ |
|
Cell *x, *z; |
|
char *buf; |
|
|
|
x = execute(a[0]); /* Cell* for symbol table */ |
|
buf = makearraystring(a[1], __func__); |
if (!isarr(x)) { |
if (!isarr(x)) { |
DPRINTF( ("making %s into an array\n", NN(x->nval)) ); |
DPRINTF( ("making %s into an array\n", NN(x->nval)) ); |
if (freeable(x)) |
if (freeable(x)) |
|
|
|
|
Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ |
Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ |
{ |
{ |
Cell *x, *y; |
Cell *x; |
Node *np; |
|
char *s; |
|
int nsub; |
|
|
|
x = execute(a[0]); /* Cell* for symbol table */ |
x = execute(a[0]); /* Cell* for symbol table */ |
if (x == symtabloc) { |
if (x == symtabloc) { |
|
|
x->tval |= ARR; |
x->tval |= ARR; |
x->sval = (char *) makesymtab(NSYMTAB); |
x->sval = (char *) makesymtab(NSYMTAB); |
} else { |
} else { |
int bufsz = recsize; |
char *buf = makearraystring(a[1], __func__); |
char *buf; |
|
if ((buf = (char *) malloc(bufsz)) == NULL) |
|
FATAL("out of memory in adelete"); |
|
buf[0] = 0; |
|
for (np = a[1]; np; np = np->nnext) { |
|
y = execute(np); /* subscript */ |
|
s = getsval(y); |
|
nsub = strlen(getsval(subseploc)); |
|
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "awkdelete")) |
|
FATAL("out of memory deleting %s[%s...]", x->nval, buf); |
|
strlcat(buf, s, bufsz); |
|
if (np->nnext) |
|
strlcat(buf, *SUBSEP, bufsz); |
|
tempfree(y); |
|
} |
|
freeelem(x, buf); |
freeelem(x, buf); |
free(buf); |
free(buf); |
} |
} |
|
|
|
|
Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */ |
Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */ |
{ |
{ |
Cell *x, *ap, *k; |
Cell *ap, *k; |
Node *p; |
|
char *buf; |
char *buf; |
char *s; |
|
int bufsz = recsize; |
|
int nsub; |
|
|
|
ap = execute(a[1]); /* array name */ |
ap = execute(a[1]); /* array name */ |
if (!isarr(ap)) { |
if (!isarr(ap)) { |
|
|
ap->tval |= ARR; |
ap->tval |= ARR; |
ap->sval = (char *) makesymtab(NSYMTAB); |
ap->sval = (char *) makesymtab(NSYMTAB); |
} |
} |
if ((buf = (char *) malloc(bufsz)) == NULL) { |
buf = makearraystring(a[0], __func__); |
FATAL("out of memory in intest"); |
|
} |
|
buf[0] = 0; |
|
for (p = a[0]; p; p = p->nnext) { |
|
x = execute(p); /* expr */ |
|
s = getsval(x); |
|
nsub = strlen(getsval(subseploc)); |
|
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "intest")) |
|
FATAL("out of memory deleting %s[%s...]", x->nval, buf); |
|
strlcat(buf, s, bufsz); |
|
tempfree(x); |
|
if (p->nnext) |
|
strlcat(buf, *SUBSEP, bufsz); |
|
} |
|
k = lookup(buf, (Array *) ap->sval); |
k = lookup(buf, (Array *) ap->sval); |
tempfree(ap); |
tempfree(ap); |
free(buf); |
free(buf); |
|
|
Cell *x; |
Cell *x; |
|
|
if (!tmps) { |
if (!tmps) { |
tmps = (Cell *) calloc(100, sizeof(Cell)); |
tmps = calloc(100, sizeof(*tmps)); |
if (!tmps) |
if (!tmps) |
FATAL("out of space for temporaries"); |
FATAL("out of space for temporaries"); |
for (i = 1; i < 100; i++) |
for (i = 1; i < 100; i++) |
|
|
int fmtsz = recsize; |
int fmtsz = recsize; |
char *buf = *pbuf; |
char *buf = *pbuf; |
int bufsize = *pbufsize; |
int bufsize = *pbufsize; |
|
#define FMTSZ(a) (fmtsz - ((a) - fmt)) |
|
#define BUFSZ(a) (bufsize - ((a) - buf)) |
|
|
static int first = 1; |
static int first = 1; |
static int have_a_format = 0; |
static int have_a_format = 0; |
|
|
|
|
os = s; |
os = s; |
p = buf; |
p = buf; |
if ((fmt = (char *) malloc(fmtsz)) == NULL) |
if ((fmt = malloc(fmtsz)) == NULL) |
FATAL("out of memory in format()"); |
FATAL("out of memory in format()"); |
while (*s) { |
while (*s) { |
adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format1"); |
adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format1"); |
|
|
} |
} |
x = execute(a); |
x = execute(a); |
a = a->nnext; |
a = a->nnext; |
snprintf(t-1, fmt + fmtsz - (t-1), "%d", fmtwd=(int) getfval(x)); |
snprintf(t - 1, FMTSZ(t - 1), |
|
"%d", fmtwd=(int) getfval(x)); |
if (fmtwd < 0) |
if (fmtwd < 0) |
fmtwd = -fmtwd; |
fmtwd = -fmtwd; |
adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format"); |
adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format"); |
|
|
case 'd': case 'i': |
case 'd': case 'i': |
flag = 'd'; |
flag = 'd'; |
if(*(s-1) == 'l') break; |
if(*(s-1) == 'l') break; |
*(t-1) = 'l'; |
*(t-1) = 'j'; |
*t = 'd'; |
*t = 'd'; |
*++t = '\0'; |
*++t = '\0'; |
break; |
break; |
case 'o': case 'x': case 'X': case 'u': |
case 'o': case 'x': case 'X': case 'u': |
flag = *(s-1) == 'l' ? 'd' : 'u'; |
flag = *(s-1) == 'l' ? 'd' : 'u'; |
|
*(t-1) = 'l'; |
|
*t = *s; |
|
*++t = '\0'; |
break; |
break; |
case 's': |
case 's': |
flag = 's'; |
flag = 's'; |
|
|
adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format5"); |
adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format5"); |
switch (flag) { |
switch (flag) { |
case '?': /* unknown, so dump it too */ |
case '?': /* unknown, so dump it too */ |
snprintf(p, buf + bufsize - p, "%s", fmt); |
snprintf(p, BUFSZ(p), "%s", fmt); |
t = getsval(x); |
t = getsval(x); |
n = strlen(t); |
n = strlen(t); |
if (fmtwd > n) |
if (fmtwd > n) |
n = fmtwd; |
n = fmtwd; |
adjbuf(&buf, &bufsize, 1+strlen(p)+n+p-buf, recsize, &p, "format6"); |
adjbuf(&buf, &bufsize, 1+strlen(p)+n+p-buf, recsize, &p, "format6"); |
p += strlen(p); |
p += strlen(p); |
snprintf(p, buf + bufsize - p, "%s", t); |
snprintf(p, BUFSZ(p), "%s", t); |
break; |
break; |
case 'a': |
case 'a': |
case 'A': |
case 'A': |
case 'f': snprintf(p, buf + bufsize - p, fmt, getfval(x)); break; |
case 'f': snprintf(p, BUFSZ(p), fmt, getfval(x)); break; |
case 'd': snprintf(p, buf + bufsize - p, fmt, (long) getfval(x)); break; |
case 'd': snprintf(p, BUFSZ(p), fmt, (long) getfval(x)); break; |
case 'u': snprintf(p, buf + bufsize - p, fmt, (int) getfval(x)); break; |
case 'u': snprintf(p, BUFSZ(p), fmt, (int) getfval(x)); break; |
case 's': |
case 's': |
t = getsval(x); |
t = getsval(x); |
n = strlen(t); |
n = strlen(t); |
|
|
n = fmtwd; |
n = fmtwd; |
if (!adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format7")) |
if (!adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format7")) |
FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t); |
FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t); |
snprintf(p, buf + bufsize - p, fmt, t); |
snprintf(p, BUFSZ(p), fmt, t); |
break; |
break; |
case 'c': |
case 'c': |
if (isnum(x)) { |
if (isnum(x)) { |
if ((int)getfval(x)) |
if ((int)getfval(x)) |
snprintf(p, buf + bufsize - p, fmt, (int) getfval(x)); |
snprintf(p, BUFSZ(p), fmt, (int) getfval(x)); |
else { |
else { |
*p++ = '\0'; /* explicit null byte */ |
*p++ = '\0'; /* explicit null byte */ |
*p = '\0'; /* next output will start here */ |
*p = '\0'; /* next output will start here */ |
} |
} |
} else |
} else |
snprintf(p, buf + bufsize - p, fmt, getsval(x)[0]); |
snprintf(p, BUFSZ(p), fmt, getsval(x)[0]); |
break; |
break; |
default: |
default: |
FATAL("can't happen: bad conversion %c in format()", flag); |
FATAL("can't happen: bad conversion %c in format()", flag); |
|
|
char *buf; |
char *buf; |
int bufsz=3*recsize; |
int bufsz=3*recsize; |
|
|
if ((buf = (char *) malloc(bufsz)) == NULL) |
if ((buf = malloc(bufsz)) == NULL) |
FATAL("out of memory in awksprintf"); |
FATAL("out of memory in awksprintf"); |
y = a[0]->nnext; |
y = a[0]->nnext; |
x = execute(a[0]); |
x = execute(a[0]); |
|
|
int len; |
int len; |
int bufsz=3*recsize; |
int bufsz=3*recsize; |
|
|
if ((buf = (char *) malloc(bufsz)) == NULL) |
if ((buf = malloc(bufsz)) == NULL) |
FATAL("out of memory in awkprintf"); |
FATAL("out of memory in awkprintf"); |
y = a[0]->nnext; |
y = a[0]->nnext; |
x = execute(a[0]); |
x = execute(a[0]); |
|
|
|
|
x = execute(a[0]); |
x = execute(a[0]); |
n1 = strlen(getsval(x)); |
n1 = strlen(getsval(x)); |
adjbuf(&s, &ssz, n1 + 1, recsize, 0, "cat1"); |
|
strlcpy(s, x->sval, ssz); |
|
|
|
y = execute(a[1]); |
y = execute(a[1]); |
n2 = strlen(getsval(y)); |
n2 = strlen(getsval(y)); |
adjbuf(&s, &ssz, n1 + n2 + 1, recsize, 0, "cat2"); |
|
strlcpy(s + n1, y->sval, ssz - n1); |
|
|
|
|
adjbuf(&s, &ssz, n1 + n2 + 1, recsize, 0, "cat"); |
|
memcpy(s, x->sval, n1); |
|
memcpy(s + n1, y->sval, n2); |
|
s[n1 + n2] = '\0'; |
|
|
tempfree(x); |
tempfree(x); |
tempfree(y); |
tempfree(y); |
|
|
|
|
Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */ |
Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */ |
{ |
{ |
Cell *x = NULL, *y, *ap; |
Cell *x = NULL, *y, *ap; |
char *s, *origs; |
const char *s, *origs, *t; |
char *fs = NULL, *origfs = NULL; |
char *fs = NULL, *origfs = NULL; |
int sep; |
int sep; |
char *t, temp, num[50]; |
char temp, num[50]; |
int n, tempstat, arg3type; |
int n, tempstat, arg3type; |
|
|
y = execute(a[0]); /* source string */ |
y = execute(a[0]); /* source string */ |
|
|
pfa->initstat = 2; |
pfa->initstat = 2; |
do { |
do { |
n++; |
n++; |
snprintf(num, sizeof num, "%d", n); |
snprintf(num, sizeof(num), "%d", n); |
temp = *patbeg; |
temp = *patbeg; |
*patbeg = '\0'; |
setptr(patbeg, '\0'); |
if (is_number(s)) |
if (is_number(s)) |
setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); |
setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); |
else |
else |
setsymtab(num, s, 0.0, STR, (Array *) ap->sval); |
setsymtab(num, s, 0.0, STR, (Array *) ap->sval); |
*patbeg = temp; |
setptr(patbeg, temp); |
s = patbeg + patlen; |
s = patbeg + patlen; |
if (*(patbeg+patlen-1) == 0 || *s == 0) { |
if (*(patbeg+patlen-1) == 0 || *s == 0) { |
n++; |
n++; |
snprintf(num, sizeof num, "%d", n); |
snprintf(num, sizeof(num), "%d", n); |
setsymtab(num, "", 0.0, STR, (Array *) ap->sval); |
setsymtab(num, "", 0.0, STR, (Array *) ap->sval); |
pfa->initstat = tempstat; |
pfa->initstat = tempstat; |
goto spdone; |
goto spdone; |
|
|
/* cf gsub and refldbld */ |
/* cf gsub and refldbld */ |
} |
} |
n++; |
n++; |
snprintf(num, sizeof num, "%d", n); |
snprintf(num, sizeof(num), "%d", n); |
if (is_number(s)) |
if (is_number(s)) |
setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); |
setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); |
else |
else |
|
|
s++; |
s++; |
while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); |
while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); |
temp = *s; |
temp = *s; |
*s = '\0'; |
setptr(s, '\0'); |
snprintf(num, sizeof num, "%d", n); |
snprintf(num, sizeof(num), "%d", n); |
if (is_number(t)) |
if (is_number(t)) |
setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); |
setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); |
else |
else |
setsymtab(num, t, 0.0, STR, (Array *) ap->sval); |
setsymtab(num, t, 0.0, STR, (Array *) ap->sval); |
*s = temp; |
setptr(s, temp); |
if (*s != 0) |
if (*s != 0) |
s++; |
s++; |
} |
} |
|
|
for (n = 0; *s != 0; s++) { |
for (n = 0; *s != 0; s++) { |
char buf[2]; |
char buf[2]; |
n++; |
n++; |
snprintf(num, sizeof num, "%d", n); |
snprintf(num, sizeof(num), "%d", n); |
buf[0] = *s; |
buf[0] = *s; |
buf[1] = 0; |
buf[1] = 0; |
if (isdigit((uschar)buf[0])) |
if (isdigit((uschar)buf[0])) |
|
|
while (*s != sep && *s != '\n' && *s != '\0') |
while (*s != sep && *s != '\n' && *s != '\0') |
s++; |
s++; |
temp = *s; |
temp = *s; |
*s = '\0'; |
setptr(s, '\0'); |
snprintf(num, sizeof num, "%d", n); |
snprintf(num, sizeof(num), "%d", n); |
if (is_number(t)) |
if (is_number(t)) |
setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); |
setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); |
else |
else |
setsymtab(num, t, 0.0, STR, (Array *) ap->sval); |
setsymtab(num, t, 0.0, STR, (Array *) ap->sval); |
*s = temp; |
setptr(s, temp); |
if (*s++ == 0) |
if (*s++ == 0) |
break; |
break; |
} |
} |
} |
} |
tempfree(ap); |
tempfree(ap); |
tempfree(y); |
tempfree(y); |
free(origs); |
xfree(origs); |
free(origfs); |
xfree(origfs); |
x = gettemp(); |
x = gettemp(); |
x->tval = NUM; |
x->tval = NUM; |
x->fval = n; |
x->fval = n; |
|
|
fflush(files[i].fp); |
fflush(files[i].fp); |
} |
} |
|
|
void backsub(char **pb_ptr, char **sptr_ptr); |
void backsub(char **pb_ptr, const char **sptr_ptr); |
|
|
Cell *sub(Node **a, int nnn) /* substitute command */ |
Cell *sub(Node **a, int nnn) /* substitute command */ |
{ |
{ |
char *sptr, *pb, *q; |
const char *sptr, *q; |
Cell *x, *y, *result; |
Cell *x, *y, *result; |
char *t, *buf; |
char *t, *buf, *pb; |
fa *pfa; |
fa *pfa; |
int bufsz = recsize; |
int bufsz = recsize; |
|
|
if ((buf = (char *) malloc(bufsz)) == NULL) |
if ((buf = malloc(bufsz)) == NULL) |
FATAL("out of memory in sub"); |
FATAL("out of memory in sub"); |
x = execute(a[3]); /* target string */ |
x = execute(a[3]); /* target string */ |
t = getsval(x); |
t = getsval(x); |
|
|
Cell *gsub(Node **a, int nnn) /* global substitute */ |
Cell *gsub(Node **a, int nnn) /* global substitute */ |
{ |
{ |
Cell *x, *y; |
Cell *x, *y; |
char *rptr, *sptr, *t, *pb, *q; |
char *rptr, *pb; |
|
const char *q, *t, *sptr; |
char *buf; |
char *buf; |
fa *pfa; |
fa *pfa; |
int mflag, tempstat, num; |
int mflag, tempstat, num; |
int bufsz = recsize; |
int bufsz = recsize; |
|
|
if ((buf = (char *) malloc(bufsz)) == NULL) |
if ((buf = malloc(bufsz)) == NULL) |
FATAL("out of memory in gsub"); |
FATAL("out of memory in gsub"); |
mflag = 0; /* if mflag == 0, can replace empty string */ |
mflag = 0; /* if mflag == 0, can replace empty string */ |
num = 0; |
num = 0; |
|
|
return(x); |
return(x); |
} |
} |
|
|
void backsub(char **pb_ptr, char **sptr_ptr) /* handle \\& variations */ |
void backsub(char **pb_ptr, const char **sptr_ptr) /* handle \\& variations */ |
{ /* sptr[0] == '\\' */ |
{ /* sptr[0] == '\\' */ |
char *pb = *pb_ptr, *sptr = *sptr_ptr; |
char *pb = *pb_ptr; |
|
const char *sptr = *sptr_ptr; |
|
|
if (sptr[1] == '\\') { |
if (sptr[1] == '\\') { |
if (sptr[2] == '\\' && sptr[3] == '&') { /* \\\& -> \& */ |
if (sptr[2] == '\\' && sptr[3] == '&') { /* \\\& -> \& */ |