plug a few display problems with special parameter name expansions

reported by Stéphane Chazelas
This commit is contained in:
tg 2016-02-26 18:48:14 +00:00
parent c8da180d60
commit a3c28ebd67
5 changed files with 40 additions and 29 deletions

6
eval.c
View File

@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.183 2016/02/26 18:05:10 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.184 2016/02/26 18:48:12 tg Exp $");
/*
* string expansion
@ -404,8 +404,8 @@ expand(
st->stype = stype;
st->base = Xsavepos(ds, dp);
st->f = f;
if (x.var == &vtemp) {
st->var = tempvar();
if (x.var == vtemp) {
st->var = tempvar(vtemp->name);
st->var->flag &= ~INTEGER;
/* can't fail here */
setstr(st->var,

18
expr.c
View File

@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.81 2016/01/14 21:17:50 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.82 2016/02/26 18:48:12 tg Exp $");
/* the order of these enums is constrained by the order of opinfo[] */
enum token {
@ -227,7 +227,7 @@ v_evaluate(struct tbl *vp, const char *expr, volatile int error_ok,
exprtoken(es);
if (es->tok == END) {
es->tok = LIT;
es->val = tempvar();
es->val = tempvar("");
}
v = intvar(es, evalexpr(es, MAX_PREC));
@ -649,7 +649,7 @@ exprtoken(Expr_state *es)
cp += len;
}
if (es->noassign) {
es->val = tempvar();
es->val = tempvar("");
es->val->flag |= EXPRLVALUE;
} else {
strndupx(tvar, es->tokp, cp - es->tokp, ATEMP);
@ -684,7 +684,7 @@ exprtoken(Expr_state *es)
c = *cp++;
strndupx(tvar, es->tokp, --cp - es->tokp, ATEMP);
process_tvar:
es->val = tempvar();
es->val = tempvar("");
es->val->flag &= ~INTEGER;
es->val->type = 0;
es->val->val.s = tvar;
@ -719,17 +719,19 @@ assign_check(Expr_state *es, enum token op, struct tbl *vasn)
}
struct tbl *
tempvar(void)
tempvar(const char *vname)
{
struct tbl *vp;
size_t vsize;
vp = alloc(sizeof(struct tbl), ATEMP);
vsize = strlen(vname) + 1;
vp = alloc(offsetof(struct tbl, name[0]) + vsize, ATEMP);
memcpy(vp->name, vname, vsize);
vp->flag = ISSET|INTEGER;
vp->type = 0;
vp->areap = ATEMP;
vp->ua.hval = 0;
vp->val.i = 0;
vp->name[0] = '\0';
return (vp);
}
@ -744,7 +746,7 @@ intvar(Expr_state *es, struct tbl *vp)
(vp->flag & (ISSET|INTEGER|EXPRLVALUE)) == (ISSET|INTEGER))
return (vp);
vq = tempvar();
vq = tempvar("");
if (setint_v(vq, vp, es->arith) == NULL) {
if (vp->flag & EXPRINEVAL)
evalerr(es, ET_RECURSIVE, vp->name);

4
main.c
View File

@ -34,7 +34,7 @@
#include <locale.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.308 2016/02/24 01:44:46 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.309 2016/02/26 18:48:12 tg Exp $");
extern char **environ;
@ -208,6 +208,8 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
/* initialise permanent Area */
ainit(&aperm);
/* max. name length: -2147483648 = 11 (+ NUL) */
vtemp = alloc(offsetof(struct tbl, name[0]) + 12, APERM);
/* set up base environment */
env.type = E_NONE;

8
sh.h
View File

@ -175,9 +175,9 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.762 2016/02/24 02:08:39 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.763 2016/02/26 18:48:13 tg Exp $");
#endif
#define MKSH_VERSION "R52 2016/02/23"
#define MKSH_VERSION "R52 2016/02/26"
/* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES
@ -1216,7 +1216,7 @@ struct tbl {
char name[4];
};
EXTERN struct tbl vtemp;
EXTERN struct tbl *vtemp;
/* set by global() and local() */
EXTERN bool last_lookup_was_array;
@ -1768,7 +1768,7 @@ size_t utf_ptradj(const char *) MKSH_A_PURE;
int utf_wcwidth(unsigned int) MKSH_A_PURE;
#endif
int ksh_access(const char *, int);
struct tbl *tempvar(void);
struct tbl *tempvar(const char *);
/* funcs.c */
int c_hash(const char **);
int c_pwd(const char **);

33
var.c
View File

@ -28,7 +28,7 @@
#include <sys/sysctl.h>
#endif
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.198 2016/01/21 18:24:45 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.199 2016/02/26 18:48:14 tg Exp $");
/*-
* Variables
@ -242,18 +242,26 @@ global(const char *n)
if (!ksh_isalphx(c)) {
if (array)
errorf(Tbadsubst);
vp = &vtemp;
vp = vtemp;
vp->flag = DEFINED;
vp->type = 0;
vp->areap = ATEMP;
*vp->name = c;
if (ksh_isdigit(c)) {
if (getn(vn, &c) && (c <= l->argc))
/* setstr can't fail here */
setstr(vp, l->argv[c], KSH_RETURN_ERROR);
if (getn(vn, &c)) {
/* main.c:main_init() says 12 */
shf_snprintf(vp->name, 12, "%d", c);
if (c <= l->argc) {
/* setstr can't fail here */
setstr(vp, l->argv[c],
KSH_RETURN_ERROR);
}
} else
vp->name[0] = '\0';
vp->flag |= RDONLY;
goto out;
}
vp->name[0] = c;
vp->name[1] = '\0';
vp->flag |= RDONLY;
if (vn[1] != '\0')
goto out;
@ -320,7 +328,7 @@ local(const char *n, bool copy)
vn = array_index_calc(n, &array, &val);
h = hash(vn);
if (!ksh_isalphx(*vn)) {
vp = &vtemp;
vp = vtemp;
vp->flag = DEFINED|RDONLY;
vp->type = 0;
vp->areap = ATEMP;
@ -479,13 +487,12 @@ void
setint(struct tbl *vq, mksh_ari_t n)
{
if (!(vq->flag&INTEGER)) {
struct tbl *vp = &vtemp;
vp->flag = (ISSET|INTEGER);
vp->type = 0;
vp->areap = ATEMP;
vp->val.i = n;
vtemp->flag = (ISSET|INTEGER);
vtemp->type = 0;
vtemp->areap = ATEMP;
vtemp->val.i = n;
/* setstr can't fail here */
setstr(vq, str_val(vp), KSH_RETURN_ERROR);
setstr(vq, str_val(vtemp), KSH_RETURN_ERROR);
} else
vq->val.i = n;
vq->flag |= ISSET;