sprinkle a few ord() and add an indicator of why some code fails on EBCDIC
This commit is contained in:
121
eval.c
121
eval.c
@ -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;
|
||||||
|
Reference in New Issue
Block a user