sprinkle a few ord() and add an indicator of why some code fails on EBCDIC

This commit is contained in:
tg
2017-05-03 14:51:25 +00:00
parent 0ee37a982d
commit 4c5d033f75

121
eval.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.209 2017/04/29 22:04:27 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.210 2017/05/03 14:51:25 tg Exp $");
/* /*
* string expansion * string expansion
@ -1115,7 +1115,7 @@ varsub(Expand *xp, const char *sp, const char *word,
struct tbl *vp; struct tbl *vp;
bool zero_ok = false; bool zero_ok = false;
if ((stype = sp[0]) == '\0') if ((stype = ord(sp[0])) == '\0')
/* Bad variable name */ /* Bad variable name */
return (-1); return (-1);
@ -1125,8 +1125,8 @@ varsub(Expand *xp, const char *sp, const char *word,
* ${#var}, string length (-U: characters, +U: octets) or array size * ${#var}, string length (-U: characters, +U: octets) or array size
* ${%var}, string width (-U: screen columns, +U: octets) * ${%var}, string width (-U: screen columns, +U: octets)
*/ */
c = sp[1]; c = ord(sp[1]);
if (stype == '%' && c == '\0') if (stype == ord('%') && c == '\0')
return (-1); return (-1);
if (ctype(stype, C_SUB2) && c != '\0') { if (ctype(stype, C_SUB2) && c != '\0') {
/* Can't have any modifiers for ${#...} or ${%...} */ /* Can't have any modifiers for ${#...} or ${%...} */
@ -1134,11 +1134,11 @@ varsub(Expand *xp, const char *sp, const char *word,
return (-1); return (-1);
sp++; sp++;
/* Check for size of array */ /* Check for size of array */
if ((p = cstrchr(sp, '[')) && (p[1] == '*' || p[1] == '@') && if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ord('*') ||
p[2] == ']') { ord(p[1]) == ord('@')) && ord(p[2]) == ord(']')) {
int n = 0; int n = 0;
if (stype != '#') if (stype != ord('#'))
return (-1); return (-1);
vp = global(arrayname(sp)); vp = global(arrayname(sp));
if (vp->flag & (ISSET|ARRAY)) if (vp->flag & (ISSET|ARRAY))
@ -1147,14 +1147,14 @@ varsub(Expand *xp, const char *sp, const char *word,
if (vp->flag & ISSET) if (vp->flag & ISSET)
n++; n++;
c = n; c = n;
} else if (c == '*' || c == '@') { } else if (c == ord('*') || c == ord('@')) {
if (stype != '#') if (stype != ord('#'))
return (-1); return (-1);
c = e->loc->argc; c = e->loc->argc;
} else { } else {
p = str_val(global(sp)); p = str_val(global(sp));
zero_ok = p != null; zero_ok = p != null;
if (stype == '#') if (stype == ord('#'))
c = utflen(p); c = utflen(p);
else { else {
/* partial utf_mbswidth reimplementation */ /* partial utf_mbswidth reimplementation */
@ -1189,11 +1189,11 @@ varsub(Expand *xp, const char *sp, const char *word,
xp->str = shf_smprintf(Tf_d, c); xp->str = shf_smprintf(Tf_d, c);
return (XSUB); return (XSUB);
} }
if (stype == '!' && c != '\0' && *word == CSUBST) { if (stype == ord('!') && c != '\0' && *word == CSUBST) {
sp++; sp++;
if ((p = cstrchr(sp, '[')) && (p[1] == '*' || p[1] == '@') && if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ord('*') ||
p[2] == ']') { ord(p[1]) == ord('@')) && ord(p[2]) == ord(']')) {
c = '!'; c = ord('!');
stype = 0; stype = 0;
goto arraynames; goto arraynames;
} }
@ -1206,21 +1206,22 @@ varsub(Expand *xp, const char *sp, const char *word,
/* Check for qualifiers in word part */ /* Check for qualifiers in word part */
stype = 0; stype = 0;
c = word[slen + 0] == CHAR ? word[slen + 1] : 0; c = word[slen + 0] == CHAR ? ord(word[slen + 1]) : 0;
if (c == ':') { if (c == ord(':')) {
slen += 2; slen += 2;
stype = 0x80; stype = 0x80;
c = word[slen + 0] == CHAR ? word[slen + 1] : 0; c = word[slen + 0] == CHAR ? ord(word[slen + 1]) : 0;
} }
if (!stype && c == '/') { if (!stype && c == ord('/')) {
slen += 2; slen += 2;
stype = c; stype = c;
if (word[slen] == ADELIM && word[slen + 1] == c) { if (word[slen] == ADELIM &&
ord(word[slen + 1]) == (unsigned int)c) {
slen += 2; slen += 2;
stype |= 0x80; stype |= 0x80;
} }
} else if (stype == 0x80 && (c == ' ' || c == '0')) { } else if (stype == 0x80 && (c == ord(' ') || c == ord('0'))) {
stype |= '0'; stype |= ord('0'); /*XXX EBCDIC */
} else if (ctype(c, C_SUB1)) { } else if (ctype(c, C_SUB1)) {
slen += 2; slen += 2;
stype |= c; stype |= c;
@ -1228,16 +1229,18 @@ varsub(Expand *xp, const char *sp, const char *word,
/* Note: ksh88 allows :%, :%%, etc */ /* Note: ksh88 allows :%, :%%, etc */
slen += 2; slen += 2;
stype = c; stype = c;
if (word[slen + 0] == CHAR && c == word[slen + 1]) { if (word[slen + 0] == CHAR &&
ord(word[slen + 1]) == (unsigned int)c) {
stype |= 0x80; stype |= 0x80;
slen += 2; slen += 2;
} }
} else if (c == '@') { } else if (c == ord('@')) {
/* @x where x is command char */ /* @x where x is command char */
switch (c = word[slen + 2] == CHAR ? word[slen + 3] : 0) { switch (c = ord(word[slen + 2]) == CHAR ?
case '#': ord(word[slen + 3]) : 0) {
case '/': case ord('#'):
case 'Q': case ord('/'):
case ord('Q'):
break; break;
default: default:
return (-1); return (-1);
@ -1250,51 +1253,51 @@ varsub(Expand *xp, const char *sp, const char *word,
if (!stype && *word != CSUBST) if (!stype && *word != CSUBST)
return (-1); return (-1);
c = sp[0]; c = ord(sp[0]);
if (c == '*' || c == '@') { if (c == ord('*') || c == ord('@')) {
switch (stype & 0x17F) { switch (stype & 0x17F) {
/* can't assign to a vector */ /* can't assign to a vector */
case '=': case ord('='):
/* can't trim a vector (yet) */ /* can't trim a vector (yet) */
case '%': case ord('%'):
case '#': case ord('#'):
case '?': case ord('?'):
case '0': case ord('0'):
case 0x100 | '/': case 0x100 | ord('/'):
case '/': case ord('/'):
case 0x100 | '#': case 0x100 | ord('#'):
case 0x100 | 'Q': case 0x100 | ord('Q'):
return (-1); return (-1);
} }
if (e->loc->argc == 0) { if (e->loc->argc == 0) {
xp->str = null; xp->str = null;
xp->var = global(sp); xp->var = global(sp);
state = c == '@' ? XNULLSUB : XSUB; state = c == ord('@') ? XNULLSUB : XSUB;
} else { } else {
xp->u.strv = (const char **)e->loc->argv + 1; xp->u.strv = (const char **)e->loc->argv + 1;
xp->str = *xp->u.strv++; xp->str = *xp->u.strv++;
/* $@ */ /* $@ */
xp->split = tobool(c == '@'); xp->split = tobool(c == ord('@'));
state = XARG; state = XARG;
} }
/* POSIX 2009? */ /* POSIX 2009? */
zero_ok = true; zero_ok = true;
} else if ((p = cstrchr(sp, '[')) && (p[1] == '*' || p[1] == '@') && } else if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ord('*') ||
p[2] == ']') { ord(p[1]) == ord('@')) && ord(p[2]) == ord(']')) {
XPtrV wv; XPtrV wv;
switch (stype & 0x17F) { switch (stype & 0x17F) {
/* can't assign to a vector */ /* can't assign to a vector */
case '=': case ord('='):
/* can't trim a vector (yet) */ /* can't trim a vector (yet) */
case '%': case ord('%'):
case '#': case ord('#'):
case '?': case ord('?'):
case '0': case ord('0'):
case 0x100 | '/': case 0x100 | ord('/'):
case '/': case ord('/'):
case 0x100 | '#': case 0x100 | ord('#'):
case 0x100 | 'Q': case 0x100 | ord('Q'):
return (-1); return (-1);
} }
c = 0; c = 0;
@ -1304,27 +1307,27 @@ varsub(Expand *xp, const char *sp, const char *word,
for (; vp; vp = vp->u.array) { for (; vp; vp = vp->u.array) {
if (!(vp->flag&ISSET)) if (!(vp->flag&ISSET))
continue; continue;
XPput(wv, c == '!' ? shf_smprintf(Tf_lu, XPput(wv, c == ord('!') ? shf_smprintf(Tf_lu,
arrayindex(vp)) : arrayindex(vp)) :
str_val(vp)); str_val(vp));
} }
if (XPsize(wv) == 0) { if (XPsize(wv) == 0) {
xp->str = null; xp->str = null;
state = p[1] == '@' ? XNULLSUB : XSUB; state = ord(p[1]) == ord('@') ? XNULLSUB : XSUB;
XPfree(wv); XPfree(wv);
} else { } else {
XPput(wv, 0); XPput(wv, 0);
xp->u.strv = (const char **)XPptrv(wv); xp->u.strv = (const char **)XPptrv(wv);
xp->str = *xp->u.strv++; xp->str = *xp->u.strv++;
/* ${foo[@]} */ /* ${foo[@]} */
xp->split = tobool(p[1] == '@'); xp->split = tobool(ord(p[1]) == ord('@'));
state = XARG; state = XARG;
} }
} else { } else {
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) == '=' && !*xp->str && if ((stype & 0x17F) == ord('=') && !*xp->str &&
ctype(*sp, C_VAR1 | C_DIGIT)) ctype(*sp, C_VAR1 | C_DIGIT))
return (-1); return (-1);
state = XSUB; state = XSUB;
@ -1336,13 +1339,13 @@ varsub(Expand *xp, const char *sp, const char *word,
(((stype & 0x80) ? *xp->str == '\0' : xp->str == null) && (((stype & 0x80) ? *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 == '+'))) || ctype(c, C_EQUAL | C_MINUS | C_QUEST) : c == ord('+')))) ||
stype == (0x80 | '0') || stype == (0x100 | '#') || stype == (0x80 | ord('0')) || stype == (0x100 | ord('#')) ||
stype == (0x100 | 'Q') || (stype & 0x7F) == '/') stype == (0x100 | ord('Q')) || (stype & 0x7F) == 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 &&
(ctype(c, C_SUB2) || (state != XBASE && c != '+'))) (ctype(c, C_SUB2) || (state != XBASE && c != ord('+'))))
errorf(Tf_parm, sp); errorf(Tf_parm, sp);
*stypep = stype; *stypep = stype;
*slenp = slen; *slenp = slen;