From 3d130b606a05e5478a43d28b522e15adda0c2741 Mon Sep 17 00:00:00 2001 From: tg Date: Thu, 5 May 2016 22:45:58 +0000 Subject: [PATCH] give C_VAR1 precedence over display variable name; izabera pointed out, rightfully, that, in POSIX shell, ${!#} is defined, and ${!#123} should work --- eval.c | 4 ++-- lex.c | 25 ++++++++++++++++++++----- mksh.1 | 8 +++++--- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/eval.c b/eval.c index 7490db7..4dc48a7 100644 --- a/eval.c +++ b/eval.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.186 2016/05/05 22:19:04 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.187 2016/05/05 22:45:57 tg Exp $"); /* * string expansion @@ -1258,7 +1258,7 @@ varsub(Expand *xp, const char *sp, const char *word, if ((stype & 0x17F) == '=' && ctype(*sp, C_VAR1 | C_DIGIT)) return (-1); - if (*sp == '!' && sp[1]) { + if (*sp == '!' && sp[1] && !ctype(sp[1], C_VAR1)) { ++sp; xp->var = global(sp); if (vstrchr(sp, '[')) diff --git a/lex.c b/lex.c index e5d3556..82f144e 100644 --- a/lex.c +++ b/lex.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.223 2016/04/09 13:55:11 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.224 2016/05/05 22:45:58 tg Exp $"); /* * states while lexing word @@ -1566,20 +1566,34 @@ get_brace_var(XString *wsp, char *wp) { char c; enum parse_state { - PS_INITIAL, PS_SAW_HASH, PS_IDENT, - PS_NUMBER, PS_VAR1 + PS_INITIAL, PS_SAW_PERCENT, PS_SAW_HASH, PS_SAW_BANG, + PS_IDENT, PS_NUMBER, PS_VAR1 } state = PS_INITIAL; while (/* CONSTCOND */ 1) { c = getsc(); /* State machine to figure out where the variable part ends. */ switch (state) { + case PS_SAW_BANG: + if (ctype(c, C_VAR1)) + goto out; + + if (0) + /* FALLTHROUGH */ case PS_INITIAL: - if (c == '#' || c == '!' || c == '%') { + switch (c) { + case '%': + state = PS_SAW_PERCENT; + goto next; + case '#': state = PS_SAW_HASH; - break; + goto next; + case '!': + state = PS_SAW_BANG; + goto next; } /* FALLTHROUGH */ + case PS_SAW_PERCENT: case PS_SAW_HASH: if (ksh_isalphx(c)) state = PS_IDENT; @@ -1620,6 +1634,7 @@ get_brace_var(XString *wsp, char *wp) } goto out; } + next: break; case PS_NUMBER: if (!ksh_isdigit(c)) diff --git a/mksh.1 b/mksh.1 index 1d9e295..04b880b 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.394 2016/03/12 20:45:38 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.395 2016/05/05 22:45:58 tg Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -76,7 +76,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: March 12 2016 $ +.Dd $Mdocdate: May 5 2016 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" @@ -1593,6 +1593,8 @@ is a name reference (bound variable), created by the .Ic nameref command (which is an alias for .Ic typeset Fl n ) . +.Ar name +cannot be one of most special parameters (see below). .Pp .It Pf ${! Ns Ar name Ns \&[*]} .It Pf ${! Ns Ar name Ns \&[@]} @@ -6587,7 +6589,7 @@ for the in-memory portion of the history is slow, should use .Xr memmove 3 . .Pp This document attempts to describe -.Nm mksh\ R52c +.Nm mksh\ R52c+CVS and up, .\" with vendor patches from insert-your-name-here, compiled without any options impacting functionality, such as