move magic constants into definitions

This commit is contained in:
tg 2017-05-03 15:33:16 +00:00
parent 4c5d033f75
commit c4bcfd944e

126
eval.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.210 2017/05/03 14:51:25 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.211 2017/05/03 15:33:16 tg Exp $");
/* /*
* string expansion * string expansion
@ -65,6 +65,12 @@ typedef struct {
#define IFS_IWS 3 /* beginning of word, ignore IFS WS */ #define IFS_IWS 3 /* beginning of word, ignore IFS WS */
#define IFS_QUOTE 4 /* beg.w/quote, become IFS_WORD unless "$@" */ #define IFS_QUOTE 4 /* beg.w/quote, become IFS_WORD unless "$@" */
#define STYPE_CHAR 0x7F
#define STYPE_DBL 0x80
#define STYPE_AT 0x100
#define STYPE_SINGLE 0x17F
#define STYPE_MASK 0x180
static int varsub(Expand *, const char *, const char *, int *, int *); static int varsub(Expand *, const char *, const char *, int *, int *);
static int comsub(Expand *, const char *, int); static int comsub(Expand *, const char *, int);
static char *valsub(struct op *, Area *); static char *valsub(struct op *, Area *);
@ -429,12 +435,12 @@ expand(
/* skip qualifier(s) */ /* skip qualifier(s) */
if (stype) if (stype)
sp += slen; sp += slen;
switch (stype & 0x17F) { switch (stype & STYPE_SINGLE) {
case 0x100 | '#': case ord('#') | STYPE_AT:
x.str = shf_smprintf("%08X", x.str = shf_smprintf("%08X",
(unsigned int)hash(str_val(st->var))); (unsigned int)hash(str_val(st->var)));
break; break;
case 0x100 | 'Q': { case ord('Q') | STYPE_AT: {
struct shf shf; struct shf shf;
shf_sopen(NULL, 0, SHF_WR|SHF_DYNAMIC, &shf); shf_sopen(NULL, 0, SHF_WR|SHF_DYNAMIC, &shf);
@ -442,7 +448,7 @@ expand(
x.str = shf_sclose(&shf); x.str = shf_sclose(&shf);
break; break;
} }
case '0': { case ord('0'): {
char *beg, *mid, *end, *stg; char *beg, *mid, *end, *stg;
mksh_ari_t from = 0, num = -1, flen, finc = 0; mksh_ari_t from = 0, num = -1, flen, finc = 0;
@ -450,13 +456,13 @@ expand(
mid = beg + (wdscan(sp, ADELIM) - sp); mid = beg + (wdscan(sp, ADELIM) - sp);
stg = beg + (wdscan(sp, CSUBST) - sp); stg = beg + (wdscan(sp, CSUBST) - sp);
mid[-2] = EOS; mid[-2] = EOS;
if (mid[-1] == /*{*/'}') { if (ord(mid[-1]) == ord(/*{*/'}')) {
sp += mid - beg - 1; sp += mid - beg - 1;
end = NULL; end = NULL;
} else { } else {
end = mid + end = mid +
(wdscan(mid, ADELIM) - mid); (wdscan(mid, ADELIM) - mid);
if (end[-1] != /*{*/ '}') if (ord(end[-1]) != ord(/*{*/'}'))
/* more than max delimiters */ /* more than max delimiters */
goto unwind_substsyn; goto unwind_substsyn;
end[-2] = EOS; end[-2] = EOS;
@ -489,8 +495,8 @@ expand(
strndupx(x.str, beg, num, ATEMP); strndupx(x.str, beg, num, ATEMP);
goto do_CSUBST; goto do_CSUBST;
} }
case 0x100 | '/': case ord('/') | STYPE_AT:
case '/': { case ord('/'): {
char *s, *p, *d, *sbeg, *end; char *s, *p, *d, *sbeg, *end;
char *pat = NULL, *rrep = null; char *pat = NULL, *rrep = null;
char fpat = 0, *tpat1, *tpat2; char fpat = 0, *tpat1, *tpat2;
@ -500,18 +506,18 @@ expand(
p = s + (wdscan(sp, ADELIM) - sp); p = s + (wdscan(sp, ADELIM) - sp);
d = s + (wdscan(sp, CSUBST) - sp); d = s + (wdscan(sp, CSUBST) - sp);
p[-2] = EOS; p[-2] = EOS;
if (p[-1] == /*{*/'}') if (ord(p[-1]) == ord(/*{*/'}'))
d = NULL; d = NULL;
else else
d[-2] = EOS; d[-2] = EOS;
sp += (d ? d : p) - s - 1; sp += (d ? d : p) - s - 1;
if (!(stype & 0x180) && if (!(stype & STYPE_MASK) &&
s[0] == CHAR && s[0] == CHAR &&
ctype(s[1], C_SUB2)) ctype(s[1], C_SUB2))
fpat = s[1]; fpat = s[1];
wpat = s + (fpat ? 2 : 0); wpat = s + (fpat ? 2 : 0);
wrep = d ? p : NULL; wrep = d ? p : NULL;
if (!(stype & 0x100)) { if (!(stype & STYPE_AT)) {
rrep = wrep ? evalstr(wrep, rrep = wrep ? evalstr(wrep,
DOTILDE | DOSCALAR) : DOTILDE | DOSCALAR) :
null; null;
@ -531,21 +537,21 @@ expand(
*/ */
goto no_repl; goto no_repl;
} }
if ((stype & 0x180) && if ((stype & STYPE_MASK) &&
gmatchx(null, pat, false)) { gmatchx(null, pat, false)) {
/* /*
* pattern matches empty * pattern matches empty
* string => don't loop * string => don't loop
*/ */
stype &= ~0x180; stype &= ~STYPE_MASK;
} }
/* first see if we have any match at all */ /* first see if we have any match at all */
if (fpat == '#') { if (ord(fpat) == ord('#')) {
/* anchor at the beginning */ /* anchor at the beginning */
tpat1 = shf_smprintf("%s%c*", pat, MAGIC); tpat1 = shf_smprintf("%s%c*", pat, MAGIC);
tpat2 = tpat1; tpat2 = tpat1;
} else if (fpat == '%') { } else if (ord(fpat) == ord('%')) {
/* anchor at the end */ /* anchor at the end */
tpat1 = shf_smprintf("%c*%s", MAGIC, pat); tpat1 = shf_smprintf("%c*%s", MAGIC, pat);
tpat2 = pat; tpat2 = pat;
@ -563,7 +569,7 @@ expand(
goto end_repl; goto end_repl;
end = strnul(s); end = strnul(s);
/* now anchor the beginning of the match */ /* now anchor the beginning of the match */
if (fpat != '#') if (ord(fpat) != ord('#'))
while (sbeg <= end) { while (sbeg <= end) {
if (gmatchx(sbeg, tpat2, false)) if (gmatchx(sbeg, tpat2, false))
break; break;
@ -572,7 +578,7 @@ expand(
} }
/* now anchor the end of the match */ /* now anchor the end of the match */
p = end; p = end;
if (fpat != '%') if (ord(fpat) != ord('%'))
while (p >= sbeg) { while (p >= sbeg) {
bool gotmatch; bool gotmatch;
@ -587,7 +593,7 @@ expand(
strndupx(end, sbeg, p - sbeg, ATEMP); strndupx(end, sbeg, p - sbeg, ATEMP);
record_match(end); record_match(end);
afree(end, ATEMP); afree(end, ATEMP);
if (stype & 0x100) { if (stype & STYPE_AT) {
if (rrep != null) if (rrep != null)
afree(rrep, ATEMP); afree(rrep, ATEMP);
rrep = wrep ? evalstr(wrep, rrep = wrep ? evalstr(wrep,
@ -600,11 +606,11 @@ expand(
sbeg = d + (sbeg - s) + strlen(rrep); sbeg = d + (sbeg - s) + strlen(rrep);
afree(s, ATEMP); afree(s, ATEMP);
s = d; s = d;
if (stype & 0x100) { if (stype & STYPE_AT) {
afree(tpat1, ATEMP); afree(tpat1, ATEMP);
afree(pat, ATEMP); afree(pat, ATEMP);
goto again_search; goto again_search;
} else if (stype & 0x80) } else if (stype & STYPE_DBL)
goto again_repl; goto again_repl;
end_repl: end_repl:
afree(tpat1, ATEMP); afree(tpat1, ATEMP);
@ -616,8 +622,8 @@ expand(
afree(ws, ATEMP); afree(ws, ATEMP);
goto do_CSUBST; goto do_CSUBST;
} }
case '#': case ord('#'):
case '%': case ord('%'):
/* ! DOBLANK,DOBRACE */ /* ! DOBLANK,DOBRACE */
f = (f & DONTRUNCOMMAND) | f = (f & DONTRUNCOMMAND) |
DOPAT | DOTILDE | DOPAT | DOTILDE |
@ -634,7 +640,7 @@ expand(
*dp++ = 0x80 | '@'; *dp++ = 0x80 | '@';
} }
break; break;
case '=': case ord('='):
/* /*
* Tilde expansion for string * Tilde expansion for string
* variables in POSIX mode is * variables in POSIX mode is
@ -658,7 +664,7 @@ expand(
f &= ~(DOBLANK|DOGLOB|DOBRACE); f &= ~(DOBLANK|DOGLOB|DOBRACE);
tilde_ok = 1; tilde_ok = 1;
break; break;
case '?': case ord('?'):
if (*sp == CSUBST) if (*sp == CSUBST)
errorf("%s: parameter null or not set", errorf("%s: parameter null or not set",
st->var->name); st->var->name);
@ -692,9 +698,9 @@ expand(
f = st->f; f = st->f;
if (f & DOBLANK) if (f & DOBLANK)
doblank--; doblank--;
switch (st->stype & 0x17F) { switch (st->stype & STYPE_SINGLE) {
case '#': case ord('#'):
case '%': case ord('%'):
if (!Flag(FSH)) { if (!Flag(FSH)) {
/* Append end-pattern */ /* Append end-pattern */
*dp++ = MAGIC; *dp++ = MAGIC;
@ -724,7 +730,7 @@ expand(
doblank++; doblank++;
st = st->prev; st = st->prev;
continue; continue;
case '=': case ord('='):
/* /*
* Restore our position and substitute * Restore our position and substitute
* the value of st->var (may not be * the value of st->var (may not be
@ -757,17 +763,17 @@ expand(
st = st->prev; st = st->prev;
word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS; word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
continue; continue;
case '?': case ord('?'):
dp = Xrestpos(ds, dp, st->base); dp = Xrestpos(ds, dp, st->base);
errorf(Tf_sD_s, st->var->name, errorf(Tf_sD_s, st->var->name,
debunk(dp, dp, strlen(dp) + 1)); debunk(dp, dp, strlen(dp) + 1));
break; break;
case '0': case ord('0'):
case 0x100 | '/': case ord('/') | STYPE_AT:
case '/': case ord('/'):
case 0x100 | '#': case ord('#') | STYPE_AT:
case 0x100 | 'Q': case ord('Q') | STYPE_AT:
dp = Xrestpos(ds, dp, st->base); dp = Xrestpos(ds, dp, st->base);
type = XSUB; type = XSUB;
word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS; word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
@ -1209,7 +1215,7 @@ varsub(Expand *xp, const char *sp, const char *word,
c = word[slen + 0] == CHAR ? ord(word[slen + 1]) : 0; c = word[slen + 0] == CHAR ? ord(word[slen + 1]) : 0;
if (c == ord(':')) { if (c == ord(':')) {
slen += 2; slen += 2;
stype = 0x80; stype = STYPE_DBL;
c = word[slen + 0] == CHAR ? ord(word[slen + 1]) : 0; c = word[slen + 0] == CHAR ? ord(word[slen + 1]) : 0;
} }
if (!stype && c == ord('/')) { if (!stype && c == ord('/')) {
@ -1218,10 +1224,10 @@ varsub(Expand *xp, const char *sp, const char *word,
if (word[slen] == ADELIM && if (word[slen] == ADELIM &&
ord(word[slen + 1]) == (unsigned int)c) { ord(word[slen + 1]) == (unsigned int)c) {
slen += 2; slen += 2;
stype |= 0x80; stype |= STYPE_DBL;
} }
} else if (stype == 0x80 && (c == ord(' ') || c == ord('0'))) { } else if (stype == STYPE_DBL && (c == ord(' ') || c == ord('0'))) {
stype |= ord('0'); /*XXX EBCDIC */ stype |= ord('0');
} else if (ctype(c, C_SUB1)) { } else if (ctype(c, C_SUB1)) {
slen += 2; slen += 2;
stype |= c; stype |= c;
@ -1231,7 +1237,7 @@ varsub(Expand *xp, const char *sp, const char *word,
stype = c; stype = c;
if (word[slen + 0] == CHAR && if (word[slen + 0] == CHAR &&
ord(word[slen + 1]) == (unsigned int)c) { ord(word[slen + 1]) == (unsigned int)c) {
stype |= 0x80; stype |= STYPE_DBL;
slen += 2; slen += 2;
} }
} else if (c == ord('@')) { } else if (c == ord('@')) {
@ -1245,7 +1251,7 @@ varsub(Expand *xp, const char *sp, const char *word,
default: default:
return (-1); return (-1);
} }
stype |= 0x100 | c; stype |= STYPE_AT | c;
slen += 4; slen += 4;
} else if (stype) } else if (stype)
/* : is not ok */ /* : is not ok */
@ -1255,7 +1261,7 @@ varsub(Expand *xp, const char *sp, const char *word,
c = ord(sp[0]); c = ord(sp[0]);
if (c == ord('*') || c == ord('@')) { if (c == ord('*') || c == ord('@')) {
switch (stype & 0x17F) { switch (stype & STYPE_SINGLE) {
/* can't assign to a vector */ /* can't assign to a vector */
case ord('='): case ord('='):
/* can't trim a vector (yet) */ /* can't trim a vector (yet) */
@ -1263,10 +1269,10 @@ varsub(Expand *xp, const char *sp, const char *word,
case ord('#'): case ord('#'):
case ord('?'): case ord('?'):
case ord('0'): case ord('0'):
case 0x100 | ord('/'): case ord('/') | STYPE_AT:
case ord('/'): case ord('/'):
case 0x100 | ord('#'): case ord('#') | STYPE_AT:
case 0x100 | ord('Q'): case ord('Q') | STYPE_AT:
return (-1); return (-1);
} }
if (e->loc->argc == 0) { if (e->loc->argc == 0) {
@ -1286,7 +1292,7 @@ varsub(Expand *xp, const char *sp, const char *word,
ord(p[1]) == ord('@')) && ord(p[2]) == ord(']')) { ord(p[1]) == ord('@')) && ord(p[2]) == ord(']')) {
XPtrV wv; XPtrV wv;
switch (stype & 0x17F) { switch (stype & STYPE_SINGLE) {
/* can't assign to a vector */ /* can't assign to a vector */
case ord('='): case ord('='):
/* can't trim a vector (yet) */ /* can't trim a vector (yet) */
@ -1294,10 +1300,10 @@ varsub(Expand *xp, const char *sp, const char *word,
case ord('#'): case ord('#'):
case ord('?'): case ord('?'):
case ord('0'): case ord('0'):
case 0x100 | ord('/'): case ord('/') | STYPE_AT:
case ord('/'): case ord('/'):
case 0x100 | ord('#'): case ord('#') | STYPE_AT:
case 0x100 | ord('Q'): case ord('Q') | STYPE_AT:
return (-1); return (-1);
} }
c = 0; c = 0;
@ -1327,21 +1333,21 @@ varsub(Expand *xp, const char *sp, const char *word,
xp->var = global(sp); xp->var = global(sp);
xp->str = str_val(xp->var); xp->str = str_val(xp->var);
/* can't assign things like $! or $1 */ /* can't assign things like $! or $1 */
if ((stype & 0x17F) == ord('=') && !*xp->str && if ((stype & STYPE_SINGLE) == ord('=') && !*xp->str &&
ctype(*sp, C_VAR1 | C_DIGIT)) ctype(*sp, C_VAR1 | C_DIGIT))
return (-1); return (-1);
state = XSUB; state = XSUB;
} }
c = stype & 0x7F; c = stype & STYPE_CHAR;
/* test the compiler's code generator */ /* test the compiler's code generator */
if (((stype < 0x100) && (ctype(c, C_SUB2) || if ((!(stype & STYPE_AT) && (ctype(c, C_SUB2) ||
(((stype & 0x80) ? *xp->str == '\0' : xp->str == null) && (((stype & STYPE_DBL) ? *xp->str == '\0' : xp->str == null) &&
(state != XARG || (ifs0 || xp->split ? (state != XARG || (ifs0 || xp->split ?
(xp->u.strv[0] == NULL) : !hasnonempty(xp->u.strv))) ? (xp->u.strv[0] == NULL) : !hasnonempty(xp->u.strv))) ?
ctype(c, C_EQUAL | C_MINUS | C_QUEST) : c == ord('+')))) || ctype(c, C_EQUAL | C_MINUS | C_QUEST) : c == ord('+')))) ||
stype == (0x80 | ord('0')) || stype == (0x100 | ord('#')) || stype == (ord('0') | STYPE_DBL) || stype == (ord('#') | STYPE_AT) ||
stype == (0x100 | ord('Q')) || (stype & 0x7F) == ord('/')) stype == (ord('Q') | STYPE_AT) || (stype & STYPE_CHAR) == ord('/'))
/* expand word instead of variable value */ /* expand word instead of variable value */
state = XBASE; state = XBASE;
if (Flag(FNOUNSET) && xp->str == null && !zero_ok && if (Flag(FNOUNSET) && xp->str == null && !zero_ok &&
@ -1483,8 +1489,8 @@ trimsub(char *str, char *pat, int how)
char *end = strnul(str); char *end = strnul(str);
char *p, c; char *p, c;
switch (how & 0xFF) { switch (how & (STYPE_CHAR | STYPE_DBL)) {
case '#': case ord('#'):
/* shortest match at beginning */ /* shortest match at beginning */
for (p = str; p <= end; p += utf_ptradj(p)) { for (p = str; p <= end; p += utf_ptradj(p)) {
c = *p; *p = '\0'; c = *p; *p = '\0';
@ -1496,7 +1502,7 @@ trimsub(char *str, char *pat, int how)
*p = c; *p = c;
} }
break; break;
case '#'|0x80: case ord('#') | STYPE_DBL:
/* longest match at beginning */ /* longest match at beginning */
for (p = end; p >= str; p--) { for (p = end; p >= str; p--) {
c = *p; *p = '\0'; c = *p; *p = '\0';
@ -1508,7 +1514,7 @@ trimsub(char *str, char *pat, int how)
*p = c; *p = c;
} }
break; break;
case '%': case ord('%'):
/* shortest match at end */ /* shortest match at end */
p = end; p = end;
while (p >= str) { while (p >= str) {
@ -1524,7 +1530,7 @@ trimsub(char *str, char *pat, int how)
--p; --p;
} }
break; break;
case '%'|0x80: case ord('%') | STYPE_DBL:
/* longest match at end */ /* longest match at end */
for (p = str; p <= end; p++) for (p = str; p <= end; p++)
if (gmatchx(p, pat, false)) { if (gmatchx(p, pat, false)) {