mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Revert "[1.0 release prep] Remove tilde expansion discipline"
This revertsc0334e32, thereby restoring936a1939. After the fixes in0a343244anda2bc49be, 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…
Add table
Add a link
Reference in a new issue