mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-13 11:42:21 +00:00
Revert "[1.0 release prep] Remove tilde expansion discipline"
This revertsc0334e32
, thereby restoring936a1939
. After the fixes in0a343244
anda2bc49be
, the tilde expansion disciplines work nicely, so they can come back to the 1.0 branch.
This commit is contained in:
parent
a2bc49bed1
commit
350e52877b
9 changed files with 134 additions and 1 deletions
6
ANNOUNCE
6
ANNOUNCE
|
@ -82,6 +82,12 @@ New shell language features:
|
||||||
useful; it now matches all hidden files (dotfiles) in the current
|
useful; it now matches all hidden files (dotfiles) in the current
|
||||||
directory, without the harmful inclusion of '.' and '..'.
|
directory, without the harmful inclusion of '.' and '..'.
|
||||||
|
|
||||||
|
- Tilde expansion can now be extended or modified by defining a
|
||||||
|
.sh.tilde.get or .sh.tilde.set discipline function. This replaces a
|
||||||
|
2004 undocumented attempt to add this functionality via a .sh.tilde
|
||||||
|
command, which never worked and crashed the shell. See the manual for
|
||||||
|
details on the new method.
|
||||||
|
|
||||||
New features in built-in commands:
|
New features in built-in commands:
|
||||||
|
|
||||||
- Usage error messages now show the --help/--man self-documentation options.
|
- Usage error messages now show the --help/--man self-documentation options.
|
||||||
|
|
5
NEWS
5
NEWS
|
@ -422,6 +422,11 @@ Any uppercase BUG_* names are modernish shell bug IDs.
|
||||||
|
|
||||||
2021-03-16:
|
2021-03-16:
|
||||||
|
|
||||||
|
- Tilde expansion can now be extended or modified by defining a .sh.tilde.get
|
||||||
|
or .sh.tilde.set discipline function. This replaces a 2004 undocumented
|
||||||
|
attempt to add this functionality via a .sh.tilde built-in, which never
|
||||||
|
worked and crashed the shell. See the manual for details on the new method.
|
||||||
|
|
||||||
- Fixed a bug in interactive shells: if a variable used by the shell called
|
- Fixed a bug in interactive shells: if a variable used by the shell called
|
||||||
a discipline function (such as PS1.get() or COLUMNS.set()), the value of $?
|
a discipline function (such as PS1.get() or COLUMNS.set()), the value of $?
|
||||||
was set to the exit status of the discipline function instead of the last
|
was set to the exit status of the discipline function instead of the last
|
||||||
|
|
|
@ -104,6 +104,7 @@ const struct shtable2 shtab_variables[] =
|
||||||
".sh.math", 0, (char*)0,
|
".sh.math", 0, (char*)0,
|
||||||
".sh.pool", 0, (char*)0,
|
".sh.pool", 0, (char*)0,
|
||||||
".sh.pid", NV_INTEGER|NV_NOFREE, (char*)0,
|
".sh.pid", NV_INTEGER|NV_NOFREE, (char*)0,
|
||||||
|
".sh.tilde", 0, (char*)0,
|
||||||
"SHLVL", NV_INTEGER|NV_NOFREE|NV_EXPORT, (char*)0,
|
"SHLVL", NV_INTEGER|NV_NOFREE|NV_EXPORT, (char*)0,
|
||||||
#if SHOPT_MULTIBYTE
|
#if SHOPT_MULTIBYTE
|
||||||
"CSWIDTH", 0, (char*)0,
|
"CSWIDTH", 0, (char*)0,
|
||||||
|
|
|
@ -104,6 +104,7 @@ extern void sh_save_rand_seed(struct rand *, int);
|
||||||
#define SH_MATHNOD (shgd->bltin_nodes+62)
|
#define SH_MATHNOD (shgd->bltin_nodes+62)
|
||||||
#define SH_JOBPOOL (shgd->bltin_nodes+63)
|
#define SH_JOBPOOL (shgd->bltin_nodes+63)
|
||||||
#define SH_PIDNOD (shgd->bltin_nodes+64)
|
#define SH_PIDNOD (shgd->bltin_nodes+64)
|
||||||
#define SHLVL (shgd->bltin_nodes+65)
|
#define SH_TILDENOD (shgd->bltin_nodes+65)
|
||||||
|
#define SHLVL (shgd->bltin_nodes+66)
|
||||||
|
|
||||||
#endif /* SH_VALNOD */
|
#endif /* SH_VALNOD */
|
||||||
|
|
|
@ -849,6 +849,37 @@ A
|
||||||
.B :
|
.B :
|
||||||
also terminates a user name following a
|
also terminates a user name following a
|
||||||
.BR \(ap .
|
.BR \(ap .
|
||||||
|
.PP
|
||||||
|
The tilde expansion mechanism may be extended or modified
|
||||||
|
by defining one of the discipline functions
|
||||||
|
.B .sh.tilde.set
|
||||||
|
or
|
||||||
|
.B .sh.tilde.get
|
||||||
|
(see
|
||||||
|
.I Functions
|
||||||
|
and
|
||||||
|
.I Discipline Functions
|
||||||
|
below).
|
||||||
|
If either exists,
|
||||||
|
then upon encountering a tilde word to expand,
|
||||||
|
that function is called with the tilde word assigned to either
|
||||||
|
.B .sh.value
|
||||||
|
(for the
|
||||||
|
.B .sh.tilde.set
|
||||||
|
function) or
|
||||||
|
.B .sh.tilde
|
||||||
|
(for the
|
||||||
|
.B .sh.tilde.get
|
||||||
|
function).
|
||||||
|
Performing tilde expansion within a discipline function will not recursively
|
||||||
|
call that function, but default tilde expansion remains active,
|
||||||
|
so literal tildes should still be quoted where required.
|
||||||
|
Either function may assign a replacement string to
|
||||||
|
.BR .sh.value .
|
||||||
|
If this value is non-empty and does not start with a
|
||||||
|
.BR \(ap ,
|
||||||
|
it replaces the default tilde expansion when the function terminates.
|
||||||
|
Otherwise, the tilde expansion is left unchanged.
|
||||||
.SS Command Substitution.
|
.SS Command Substitution.
|
||||||
The standard output from a command list enclosed in
|
The standard output from a command list enclosed in
|
||||||
parentheses preceded by a dollar sign (
|
parentheses preceded by a dollar sign (
|
||||||
|
|
|
@ -2631,7 +2631,23 @@ static void tilde_expand2(Shell_t *shp, register int offset)
|
||||||
char *cp = NIL(char*); /* character pointer for tilde expansion result */
|
char *cp = NIL(char*); /* character pointer for tilde expansion result */
|
||||||
char *stakp = stakptr(0); /* current stack object (&stakp[offset] is tilde string) */
|
char *stakp = stakptr(0); /* current stack object (&stakp[offset] is tilde string) */
|
||||||
int curoff = staktell(); /* current offset of current stack object */
|
int curoff = staktell(); /* current offset of current stack object */
|
||||||
|
static char block; /* for disallowing tilde expansion in .get/.set to change ${.sh.tilde} */
|
||||||
/*
|
/*
|
||||||
|
* Allow overriding tilde expansion with a .sh.tilde.set or .get discipline function.
|
||||||
|
*/
|
||||||
|
if(!block && SH_TILDENOD->nvfun && SH_TILDENOD->nvfun->disc)
|
||||||
|
{
|
||||||
|
stakfreeze(1); /* terminate current stack object to avoid data corruption */
|
||||||
|
block++;
|
||||||
|
nv_putval(SH_TILDENOD, &stakp[offset], 0);
|
||||||
|
cp = nv_getval(SH_TILDENOD);
|
||||||
|
block--;
|
||||||
|
if(cp[0]=='\0' || cp[0]=='~')
|
||||||
|
cp = NIL(char*); /* do not use empty or unexpanded result */
|
||||||
|
stakset(stakp,curoff); /* restore stack to state on function entry */
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Perform default tilde expansion unless overridden.
|
||||||
* Write the result to the stack, if any.
|
* Write the result to the stack, if any.
|
||||||
*/
|
*/
|
||||||
stakputc(0);
|
stakputc(0);
|
||||||
|
|
|
@ -751,6 +751,24 @@ r ^:test-2: echo Success\r\n$
|
||||||
r ^Success\r\n$
|
r ^Success\r\n$
|
||||||
!
|
!
|
||||||
|
|
||||||
|
# err_exit #
|
||||||
|
((SHOPT_VSH || SHOPT_ESH)) && tst $LINENO <<"!"
|
||||||
|
L value of $? after tilde expansion in tab completion
|
||||||
|
|
||||||
|
# Make sure that a .sh.tilde.set discipline function
|
||||||
|
# cannot influence the exit status.
|
||||||
|
|
||||||
|
w .sh.tilde.set() { true; }
|
||||||
|
w HOME=/tmp
|
||||||
|
w false ~\t
|
||||||
|
u false /tmp
|
||||||
|
w echo "Exit status is: $?"
|
||||||
|
u Exit status is: 1
|
||||||
|
w (exit 42)
|
||||||
|
w echo $? ~\t
|
||||||
|
u 42 /tmp
|
||||||
|
!
|
||||||
|
|
||||||
# err_exit #
|
# err_exit #
|
||||||
((SHOPT_MULTIBYTE && (SHOPT_VSH || SHOPT_ESH))) &&
|
((SHOPT_MULTIBYTE && (SHOPT_VSH || SHOPT_ESH))) &&
|
||||||
[[ ${LC_ALL:-${LC_CTYPE:-${LANG:-}}} =~ [Uu][Tt][Ff]-?8 ]] &&
|
[[ ${LC_ALL:-${LC_CTYPE:-${LANG:-}}} =~ [Uu][Tt][Ff]-?8 ]] &&
|
||||||
|
|
|
@ -107,6 +107,8 @@ got=~
|
||||||
HOME=$saveHOME
|
HOME=$saveHOME
|
||||||
|
|
||||||
# ======
|
# ======
|
||||||
|
# Tilde expansion discipline function tests
|
||||||
|
|
||||||
# This nonfunctional mess was removed in ksh 93u+m ...
|
# This nonfunctional mess was removed in ksh 93u+m ...
|
||||||
if builtin .sh.tilde 2>/dev/null
|
if builtin .sh.tilde 2>/dev/null
|
||||||
then got=$(.sh.tilde & wait "$!" 2>&1)
|
then got=$(.sh.tilde & wait "$!" 2>&1)
|
||||||
|
@ -114,5 +116,57 @@ then got=$(.sh.tilde & wait "$!" 2>&1)
|
||||||
"(got status $e$( ((e>128)) && print -n / && kill -l "$e"), $(printf %q "$got"))"
|
"(got status $e$( ((e>128)) && print -n / && kill -l "$e"), $(printf %q "$got"))"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ... and replaced by a proper use of discipline functions that allows customising tilde expansion.
|
||||||
|
((.sh.version >= 20210316)) &&
|
||||||
|
for disc in get set
|
||||||
|
do (
|
||||||
|
ulimit -t unlimited 2>/dev/null # fork subshell to cope with a possible crash
|
||||||
|
|
||||||
|
eval ".sh.tilde.$disc()
|
||||||
|
{
|
||||||
|
case \${.sh.${ [[ $disc == get ]] && print tilde || print value; }} in
|
||||||
|
'~tmp') .sh.value=\$tmp ;;
|
||||||
|
'~INC') .sh.value=\$((++i)) ;;
|
||||||
|
'~spc') .sh.value=$'one\ttwo three\n\tfour' ;;
|
||||||
|
'~') .sh.value=~/addition ;; # this should not recurse
|
||||||
|
esac
|
||||||
|
}"
|
||||||
|
|
||||||
|
got=~/foo
|
||||||
|
exp=$HOME/addition/foo
|
||||||
|
[[ $got == "$exp" ]] || err_exit "$disc discipline: bare tilde expansion:" \
|
||||||
|
"expected $(printf %q "$exp"), got $(printf %q "$got")"
|
||||||
|
|
||||||
|
.sh.tilde=oldvalue
|
||||||
|
got=$(print ~tmp/foo.$$; print "${.sh.tilde}")
|
||||||
|
exp=$tmp/foo.$$$'\n'$tmp
|
||||||
|
[[ $got == "$exp" ]] || err_exit "$disc discipline: result left in \${.sh.tilde}:" \
|
||||||
|
"expected $(printf %q "$tmp"), got $(printf %q "${.sh.tilde}")"
|
||||||
|
[[ ${.sh.tilde} == oldvalue ]] || err_exit "$disc discipline: \${.sh.tilde} subshell leak"
|
||||||
|
|
||||||
|
i=0
|
||||||
|
set -- ~INC ~INC ~INC ~INC ~INC
|
||||||
|
got=$#,$1,$2,$3,$4,$5
|
||||||
|
exp=5,1,2,3,4,5
|
||||||
|
[[ $got == "$exp" ]] || err_exit "$disc discipline: counter:" \
|
||||||
|
"expected $(printf %q "$exp"), got $(printf %q "$got")"
|
||||||
|
((i==5)) || err_exit "$disc discipline: counter: $i != 5"
|
||||||
|
|
||||||
|
set -- ~spc ~spc ~spc
|
||||||
|
got=$#,$1,$2,$3
|
||||||
|
exp=$'3,one\ttwo three\n\tfour,one\ttwo three\n\tfour,one\ttwo three\n\tfour'
|
||||||
|
[[ $got == "$exp" ]] || err_exit "$disc discipline: quoting of whitespace:" \
|
||||||
|
"expected $(printf %q "$exp"), got $(printf %q "$got")"
|
||||||
|
|
||||||
|
print "$Errors" >$tmp/Errors
|
||||||
|
) &
|
||||||
|
wait "$!" 2>crashmsg
|
||||||
|
if ((!(e = $?)))
|
||||||
|
then read Errors <$tmp/Errors
|
||||||
|
else err_exit ".sh.tilde.$disc discipline function crashes the shell" \
|
||||||
|
"(got status $e$( ((e>128)) && print -n / && kill -l "$e"), $(printf %q "$(<crashmsg)"))"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# ======
|
# ======
|
||||||
exit $((Errors<125?Errors:125))
|
exit $((Errors<125?Errors:125))
|
||||||
|
|
|
@ -1029,6 +1029,7 @@ set -- \
|
||||||
".sh.math" \
|
".sh.math" \
|
||||||
".sh.pool" \
|
".sh.pool" \
|
||||||
".sh.pid" \
|
".sh.pid" \
|
||||||
|
".sh.tilde" \
|
||||||
"SHLVL" \
|
"SHLVL" \
|
||||||
"CSWIDTH"
|
"CSWIDTH"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue