mirror of
https://github.com/zsh-users/zsh
synced 2024-09-30 05:06:09 +00:00
51485: module for several ksh93 features, mostly enabled only in ksh emulation.
This commit is contained in:
parent
4bc1f6e0d2
commit
ea0bd72dd8
|
@ -1,5 +1,9 @@
|
|||
2023-03-05 Bart Schaefer <schaefer@zsh.org>
|
||||
|
||||
* 51485: Doc/Makefile.in, Doc/Zsh/mod_ksh93.yo, Src/utils.c,
|
||||
Src/Modules/ksh93.c, Src/Modules/ksh93.mdd: module for several
|
||||
ksh93 features, mostly enabled only in ksh emulation.
|
||||
|
||||
* 51484: Src/builtins.yo Src/params.c: Extend named reference
|
||||
handling for special parameters, improve doc.
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ Zsh/mod_compctl.yo Zsh/mod_complete.yo Zsh/mod_complist.yo \
|
|||
Zsh/mod_computil.yo Zsh/mod_curses.yo \
|
||||
Zsh/mod_datetime.yo Zsh/mod_db_gdbm.yo Zsh/mod_deltochar.yo \
|
||||
Zsh/mod_example.yo Zsh/mod_files.yo Zsh/mod_langinfo.yo \
|
||||
Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo \
|
||||
Zsh/mod_ksh93.yo Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo \
|
||||
Zsh/mod_nearcolor.yo Zsh/mod_newuser.yo \
|
||||
Zsh/mod_parameter.yo Zsh/mod_pcre.yo Zsh/mod_private.yo \
|
||||
Zsh/mod_regex.yo Zsh/mod_sched.yo Zsh/mod_socket.yo \
|
||||
|
|
211
Doc/Zsh/mod_ksh93.yo
Normal file
211
Doc/Zsh/mod_ksh93.yo
Normal file
|
@ -0,0 +1,211 @@
|
|||
COMMENT(!MOD!zsh/ksh93
|
||||
Extended ksh93 compatibility for "emulate ksh"
|
||||
!MOD!)
|
||||
cindex(ksh93)
|
||||
The tt(zsh/ksh93) module provides one builtin and several parameters to
|
||||
improve compatibility with ksh93. As of this writing, several ksh93
|
||||
features are still missing.
|
||||
|
||||
subsect(Ksh Builtins)
|
||||
The single builtin provided by this module is:
|
||||
|
||||
startitem()
|
||||
findex(nameref)
|
||||
cindex(named references, creating)
|
||||
item(tt(nameref) [ tt(-r) ] var(pname)[tt(=)var(rname)])(
|
||||
Equivalent to tt(typeset -n )var(pname)tt(=)var(rname)
|
||||
|
||||
However, tt(nameref) is a builtin command rather than a reserved word,
|
||||
so when var(rname) uses subscript syntax it must be quoted against
|
||||
globbing. Subscripts in referenced parameters are not supported in
|
||||
ksh93, so this is not a significant compatibility issue.
|
||||
)
|
||||
enditem()
|
||||
|
||||
subsect(Ksh Parameters)
|
||||
cindex(parameters, ksh)
|
||||
Parameters supplied by this module that are marked with `<K>' below are
|
||||
available only in ksh emulation.
|
||||
|
||||
startitem()
|
||||
vindex(.sh.command)
|
||||
item(tt(.sh.command))(
|
||||
A named reference to `tt(ZSH_DEBUG_CMD)'
|
||||
)
|
||||
vindex(.sh.edchar)
|
||||
item(tt(.sh.edchar) <K>)(
|
||||
In a ZLE widget, equivalent to the `tt(KEYS)' special parameter. In a
|
||||
future release, assignments to this parameter will affect the input
|
||||
stream seen by ZLE.
|
||||
)
|
||||
vindex(.sh.edcol)
|
||||
item(tt(.sh.edcol))(
|
||||
A named reference to the ZLE special parameter `tt(CURSOR)'.
|
||||
)
|
||||
vindex(.sh.edmode)
|
||||
item(tt(.sh.edmode) <K>)(
|
||||
In a ZLE widget, this parameter has the value tt(ESC) (tt($'\e')) if the
|
||||
`tt(main)' keymap is selected, and the empty string otherwise. This is
|
||||
intended for use with vi-mode key bindings (`tt(bindkey -v)'). In a
|
||||
future revision, assigning `tt(.sh.edchar=${.sh.edmode})' is expected
|
||||
to initiate `tt(vicmd)' mode when `tt(viins)' is active, and do
|
||||
nothing when `tt(vicmd)' is already active.
|
||||
)
|
||||
vindex(.sh.edtext)
|
||||
item(tt(.sh.edtext))(
|
||||
A named reference to the `tt(BUFFER)' special ZLE parameter.
|
||||
)
|
||||
vindex(.sh.file)
|
||||
item(tt(.sh.file))(
|
||||
A named reference to the `tt(ZSH_SCRIPT)' parameter.
|
||||
)
|
||||
vindex(.sh.fun)
|
||||
item(tt(.sh.fun) <K>)(
|
||||
In a shell function, the function's name. Usually the same as `tt($0)',
|
||||
but not affected by tt(POSIX_ARGZERO) or tt(FUNCTION_ARGZERO) options.
|
||||
)
|
||||
vindex(.sh.level)
|
||||
item(tt(.sh.level) <K>)(
|
||||
In a shell function, initially set to the depth of the call stack. This
|
||||
may be assigned to change the apparent depth. However, such assignment
|
||||
does not affect the scope of local parameters.
|
||||
)
|
||||
vindex(.sh.lineno)
|
||||
item(tt(.sh.lineno))(
|
||||
A named reference to the `tt(LINENO)' special parameter.
|
||||
)
|
||||
vindex(.sh.match)
|
||||
item(tt(.sh.match))(
|
||||
An array equivalent to the `tt(match)' parameter as assigned by the
|
||||
`tt(LPAR()#b)tt(RPAR())' extended globbing flag. When the
|
||||
tt(KSH_ARRAYS) option is set, `tt(${.sh.match[0]})' gives the value of
|
||||
the `tt(MATCH)' parameter as set by the `tt(LPAR()#m)tt(RPAR())' extended
|
||||
globbing flag. Currently, the tt(EXTENDED_GLOB) option must be enabled
|
||||
and those flags must be explicitly used in a pattern in order for these
|
||||
values of `tt(.sh.match)' to be set.
|
||||
)
|
||||
vindex(.sh.name)
|
||||
item(tt(.sh.name) <K>)(
|
||||
When the `tt(vared)' command is used, this parameter may be used in
|
||||
user-defined ZLE widgets to get the name of the variable being edited.
|
||||
A future release is expected to use this parameter in the implementation
|
||||
of "discipline functions".
|
||||
)
|
||||
vindex(.sh.subscript)
|
||||
item(tt(.sh.subscript) <K>)(
|
||||
When `tt(vared)' has been used on an array element, this parameter holds
|
||||
the array index (either a number, or an associative array key).
|
||||
)
|
||||
vindex(.sh.subshell)
|
||||
item(tt(.sh.subshell))(
|
||||
A named reference to the `tt(ZSH_SUBSHELL)' parameter.
|
||||
)
|
||||
vindex(.sh.value)
|
||||
item(tt(.sh.value) <K>)(
|
||||
In `tt(vared)' this is a named reference to the ZLE special `tt(BUFFER)'.
|
||||
A future release is expected to use this parameter in the implementation
|
||||
of "discipline functions".
|
||||
)
|
||||
vindex(.sh.version)
|
||||
item(tt(.sh.version))(
|
||||
A named reference to `tt(ZSH_PATCHLEVEL)'.
|
||||
)
|
||||
enditem()
|
||||
|
||||
subsect(Future Compatibility)
|
||||
|
||||
The following features of ksh93 are not currently supported but may be
|
||||
available in a future release.
|
||||
|
||||
startitem()
|
||||
item(var(pathdir)tt(/.paths))(
|
||||
Each directory var(pathdir) in the tt(PATH) parameter may contain a
|
||||
text file `tt(.paths)' which may define additional directories to
|
||||
be searched for function definitions (tt(FPATH)), external executables
|
||||
(tt(PATH)), and plugin files (similar to tt(MODULE_PATH)).
|
||||
|
||||
em(THIS FEATURE IS UNLIKELY EVER TO BE IMPLEMENTED.)
|
||||
)
|
||||
item(tt(builtin -f )var(file))(
|
||||
Installs a new shell builtin command dynamically linked from var(file),
|
||||
where var(file) is found by a path search and the base name of the file
|
||||
is the name of the builtin to be added.
|
||||
|
||||
Similar to `tt(zmodload -F zsh/)var(file)tt( +b:)var(file)'.
|
||||
|
||||
em(THIS FEATURE IS UNLIKELY EVER TO BE IMPLEMENTED.)
|
||||
)
|
||||
item(tt(namespace )var(ident)tt( { )var(list)tt( }))(
|
||||
This reserved word executes the current shell compound command
|
||||
tt({ )var(list)tt( }), with the special behavior that all functions
|
||||
and parameters `var(name)' declared within var(list) are implicitly
|
||||
prefixed to become `tt(.)var(ident)tt(.)var(name)', and similarly any
|
||||
reference to a function or parameter `var(name)' is searched for as
|
||||
`tt(.)var(ident)tt(.)var(name)' before falling back to `var(name)'.
|
||||
|
||||
em(THIS FEATURE IS NOT YET IMPLEMENTED.)
|
||||
)
|
||||
item(tt(.sh.math) <K>)(
|
||||
This parameter is more accurately considered a namespace. A function
|
||||
defintion of the form
|
||||
ifzman()
|
||||
indent(tt(function .sh.math.)var(name)tt( )var(ident)tt( ... { )var(list)tt( }))
|
||||
|
||||
is equivalent to the native zsh definition
|
||||
ifzman()
|
||||
example(tt(function )var(name)tt( {)
|
||||
tt( local )var(ident)tt(=$1 ...)
|
||||
tt( )var(list)
|
||||
tt(})
|
||||
tt(functions -M )var(name)tt( 1 3))
|
||||
ifzman()
|
||||
Up to 3 var(ident) arguments, interpreted as floating point numbers,
|
||||
may be provided for a function defined with tt(.sh.math) in this way.
|
||||
The names (but not definitions) of all such functions are available
|
||||
via tt(${.sh.math[@]}).
|
||||
|
||||
em(THIS FEATURE IS NOT YET IMPLEMENTED.)
|
||||
)
|
||||
item(tt(var(name)tt(.get)))(
|
||||
A shell function having this name, if defined, is invoked whenever the
|
||||
parameter tt(${)var(name)tt(}) is referenced, including by commands
|
||||
such as `tt(typeset -p)'. If the special variable `tt(.sh.value)' is
|
||||
assigned by the function, that value is substituted instead of the
|
||||
true value of var(name). This does not change the value of var(name),
|
||||
but there is no way to access the actual value without first removing
|
||||
the function.
|
||||
|
||||
Additionally, an explicit reference to tt(${)var(name)tt(.get})
|
||||
calls the function var(name)tt(.get) even if there is no parameter
|
||||
`var(name)' and substitutes the standard output of the function.
|
||||
|
||||
em(THIS FEATURE IS NOT YET IMPLEMENTED.)
|
||||
)
|
||||
xitem(tt(var(name)tt(.set)))
|
||||
item(tt(var(name)tt(.append)))(
|
||||
Shell functions having these names are invoked when the parameter
|
||||
var(name) is assigned or (for array types) has a new field appended.
|
||||
The function may change the result of the operation by assigning to
|
||||
the `tt(.sh.value)' special parameter, or block the change by
|
||||
unsetting `tt(.sh.value)'.
|
||||
|
||||
Explicit reference to tt(${)var(name)tt(.set}) or tt(${)var(name)tt(.append})
|
||||
substitutes the standard output of the function.
|
||||
|
||||
em(THIS FEATURE IS NOT YET IMPLEMENTED.)
|
||||
)
|
||||
item(tt(var(name)tt(.unset)))(
|
||||
When a function of this name is defined, it is called whenever the
|
||||
parameter var(name) would be unset. The function must explicitly
|
||||
`tt(unset )var(name)', otherwise the variable remains set.
|
||||
|
||||
em(THIS FEATURE IS NOT YET IMPLEMENTED.)
|
||||
)
|
||||
item(tt(${ )var(list)tt(;}))(
|
||||
Note the space after the opening brace (tt({)). This executes var(list)
|
||||
in the current shell and substitutes its standard output in the manner
|
||||
of `tt($LPAR())var(list)tt(RPAR())' but without forking.
|
||||
|
||||
em(THIS FEATURE IS NOT YET IMPLEMENTED.)
|
||||
)
|
||||
enditem()
|
265
Src/Modules/ksh93.c
Normal file
265
Src/Modules/ksh93.c
Normal file
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* ksh93.c - support for more ksh93 features
|
||||
*
|
||||
* This file is part of zsh, the Z shell.
|
||||
*
|
||||
* Copyright (c) 2022 Barton E. Schaefer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and to distribute modified versions of this software for any
|
||||
* purpose, provided that the above copyright notice and the following
|
||||
* two paragraphs appear in all copies of this software.
|
||||
*
|
||||
* In no event shall Barton E. Schaefer or the Zsh Development
|
||||
* Group be liable to any party for direct, indirect, special, incidental, or
|
||||
* consequential damages arising out of the use of this software and its
|
||||
* documentation, even if Barton E. Schaefer and the Zsh
|
||||
* Development Group have been advised of the possibility of such damage.
|
||||
*
|
||||
* Barton E. Schaefer and the Zsh Development Group
|
||||
* specifically disclaim any warranties, including, but not limited to, the
|
||||
* implied warranties of merchantability and fitness for a particular purpose.
|
||||
* The software provided hereunder is on an "as is" basis, and
|
||||
* Barton E. Schaefer and the Zsh Development Group have no
|
||||
* obligation to provide maintenance, support, updates, enhancements, or
|
||||
* modifications.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ksh93.mdh"
|
||||
#include "ksh93.pro"
|
||||
|
||||
/* Implementing "namespace" requires creating a new keword. Hrm. */
|
||||
|
||||
/*
|
||||
* Standard module configuration/linkage
|
||||
*/
|
||||
|
||||
static struct builtin bintab[] = {
|
||||
BUILTIN("nameref", BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "gr", "n")
|
||||
};
|
||||
|
||||
#include "zsh.mdh"
|
||||
|
||||
static void
|
||||
edcharsetfn(Param pm, char *x)
|
||||
{
|
||||
/*
|
||||
* To make this work like ksh, we must intercept $KEYS before the widget
|
||||
* is looked up, so that changing the key sequence causes a different
|
||||
* widget to be substituted. Somewhat similar to "bindkey -s".
|
||||
*
|
||||
* Ksh93 adds SIGKEYBD to the trap list for this purpose.
|
||||
*/
|
||||
;
|
||||
}
|
||||
|
||||
static char **
|
||||
matchgetfn(Param pm)
|
||||
{
|
||||
char **zsh_match = getaparam("match");
|
||||
|
||||
/* For this to work accurately, ksh emulation should always imply
|
||||
* that the (#m) and (#b) extendedglob operators are enabled.
|
||||
*
|
||||
* When we have a 0th element (ksharrays), it is $MATCH. Elements
|
||||
* 1st and larger mirror the $match array.
|
||||
*/
|
||||
|
||||
if (pm->u.arr)
|
||||
freearray(pm->u.arr);
|
||||
if (zsh_match && *zsh_match) {
|
||||
if (isset(KSHARRAYS)) {
|
||||
char **ap =
|
||||
(char **) zalloc(sizeof(char *) * (arrlen(zsh_match)+1));
|
||||
pm->u.arr = ap;
|
||||
*ap++ = ztrdup(getsparam("MATCH"));
|
||||
while (*zsh_match)
|
||||
*ap = ztrdup(*zsh_match++);
|
||||
} else
|
||||
pm->u.arr = zarrdup(zsh_match);
|
||||
} else if (isset(KSHARRAYS)) {
|
||||
pm->u.arr = mkarray(ztrdup(getsparam("MATCH")));
|
||||
} else
|
||||
pm->u.arr = NULL;
|
||||
|
||||
return arrgetfn(pm);
|
||||
}
|
||||
|
||||
static const struct gsu_scalar constant_gsu =
|
||||
{ strgetfn, NULL, nullunsetfn };
|
||||
|
||||
static const struct gsu_scalar sh_edchar_gsu =
|
||||
{ strvargetfn, edcharsetfn, nullunsetfn };
|
||||
static const struct gsu_scalar sh_edmode_gsu =
|
||||
{ strgetfn, nullstrsetfn, nullunsetfn };
|
||||
static const struct gsu_array sh_match_gsu =
|
||||
{ matchgetfn, arrsetfn, stdunsetfn };
|
||||
static const struct gsu_scalar sh_name_gsu =
|
||||
{ strvargetfn, nullstrsetfn, nullunsetfn };
|
||||
static const struct gsu_scalar sh_subscript_gsu =
|
||||
{ strvargetfn, nullstrsetfn, nullunsetfn };
|
||||
|
||||
static char *sh_name;
|
||||
static char *sh_subscript;
|
||||
static char *sh_edchar;
|
||||
static char sh_edmode[2];
|
||||
|
||||
/*
|
||||
* Some parameters listed here do not appear in ksh93.mdd autofeatures
|
||||
* because they are only instantiated by ksh93_wrapper() below. This
|
||||
* obviously includes those commented out here.
|
||||
*/
|
||||
static struct paramdef partab[] = {
|
||||
PARAMDEF(".sh.command", PM_NAMEREF|PM_READONLY, "ZSH_DEBUG_CMD", &constant_gsu),
|
||||
PARAMDEF(".sh.edchar", PM_SCALAR|PM_SPECIAL, &sh_edchar, &sh_edchar_gsu),
|
||||
PARAMDEF(".sh.edcol", PM_NAMEREF|PM_READONLY, "CURSOR", &constant_gsu),
|
||||
PARAMDEF(".sh.edmode", PM_SCALAR|PM_READONLY|PM_SPECIAL, &sh_edmode, &sh_edmode_gsu),
|
||||
PARAMDEF(".sh.edtext", PM_NAMEREF|PM_READONLY, "BUFFER", &constant_gsu),
|
||||
PARAMDEF(".sh.file", PM_NAMEREF|PM_READONLY, "ZSH_SCRIPT", &constant_gsu),
|
||||
/* PARAMDEF(".sh.fun", PM_SCALAR|PM_UNSET, NULL, &constant_gsu), */
|
||||
/* PARAMDEF(".sh.level", PM_INTEGER|PM_UNSET, NULL, &constant_gsu), */
|
||||
PARAMDEF(".sh.lineno", PM_NAMEREF|PM_READONLY, "LINENO", &constant_gsu),
|
||||
PARAMDEF(".sh.match", PM_ARRAY|PM_READONLY, NULL, &sh_match_gsu),
|
||||
PARAMDEF(".sh.name", PM_SCALAR|PM_READONLY|PM_SPECIAL, &sh_name, &sh_name_gsu),
|
||||
PARAMDEF(".sh.subscript", PM_SCALAR|PM_READONLY|PM_SPECIAL, &sh_subscript, &sh_subscript_gsu),
|
||||
PARAMDEF(".sh.subshell", PM_NAMEREF|PM_READONLY, "ZSH_SUBSHELL", &constant_gsu),
|
||||
/* SPECIALPMDEF(".sh.value", 0, NULL, NULL, NULL), */
|
||||
PARAMDEF(".sh.version", PM_NAMEREF|PM_READONLY, "ZSH_PATCHLEVEL", &constant_gsu)
|
||||
};
|
||||
|
||||
static struct features module_features = {
|
||||
bintab, sizeof(bintab)/sizeof(*bintab),
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
partab, sizeof(partab)/sizeof(*partab),
|
||||
0
|
||||
};
|
||||
|
||||
/**/
|
||||
static int
|
||||
ksh93_wrapper(Eprog prog, FuncWrap w, char *name)
|
||||
{
|
||||
Funcstack f;
|
||||
Param pm;
|
||||
zlong num = funcstack->prev ? getiparam(".sh.level") : 0;
|
||||
|
||||
if (!EMULATION(EMULATE_KSH))
|
||||
return 1;
|
||||
|
||||
if (num == 0)
|
||||
for (f = funcstack; f; f = f->prev, num++);
|
||||
else
|
||||
num++;
|
||||
|
||||
queue_signals();
|
||||
++locallevel; /* Make these local */
|
||||
if ((pm = createparam(".sh.level", PM_LOCAL|PM_UNSET))) {
|
||||
pm->level = locallevel; /* Why is this necessary? */
|
||||
setiparam(".sh.level", num);
|
||||
}
|
||||
if ((pm = createparam(".sh.fun", PM_LOCAL|PM_UNSET))) {
|
||||
pm->level = locallevel;
|
||||
setsparam(".sh.fun", ztrdup(name));
|
||||
pm->node.flags |= PM_READONLY;
|
||||
}
|
||||
if (zleactive) {
|
||||
extern mod_import_variable char *curkeymapname; /* XXX */
|
||||
extern mod_import_variable char *varedarg; /* XXX */
|
||||
/* How to distinguish emacs bindings? */
|
||||
if (curkeymapname && strcmp(curkeymapname, "main") == 0)
|
||||
strcpy(sh_edmode, "\e");
|
||||
else
|
||||
strcpy(sh_edmode, "");
|
||||
if (!sh_edchar)
|
||||
sh_edchar = dupstring(getsparam("KEYS"));
|
||||
if (varedarg) {
|
||||
char *ie = itype_end((sh_name = dupstring(varedarg)), INAMESPC, 0);
|
||||
if (ie && *ie) {
|
||||
*ie++ = '\0';
|
||||
/* Assume bin_vared has validated subscript */
|
||||
sh_subscript = dupstring(ie);
|
||||
ie = sh_subscript + strlen(sh_subscript);
|
||||
*--ie = '\0';
|
||||
} else
|
||||
sh_subscript = NULL;
|
||||
if ((pm = createparam(".sh.value", PM_LOCAL|PM_NAMEREF|PM_UNSET))) {
|
||||
pm->level = locallevel;
|
||||
setloopvar(".sh.value", "BUFFER"); /* Hack */
|
||||
}
|
||||
} else
|
||||
sh_name = sh_subscript = NULL;
|
||||
} else {
|
||||
sh_edchar = sh_name = sh_subscript = NULL;
|
||||
strcpy(sh_edmode, "");
|
||||
/* TODO:
|
||||
* - disciplines
|
||||
* - special handling of .sh.value in math
|
||||
*/
|
||||
}
|
||||
--locallevel;
|
||||
unqueue_signals();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct funcwrap wrapper[] = {
|
||||
WRAPDEF(ksh93_wrapper),
|
||||
};
|
||||
|
||||
/**/
|
||||
int
|
||||
setup_(UNUSED(Module m))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
features_(Module m, char ***features)
|
||||
{
|
||||
*features = featuresarray(m, &module_features);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
enables_(Module m, int **enables)
|
||||
{
|
||||
return handlefeatures(m, &module_features, enables);
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
boot_(Module m)
|
||||
{
|
||||
return addwrapper(m, wrapper);
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
cleanup_(Module m)
|
||||
{
|
||||
struct paramdef *p;
|
||||
|
||||
deletewrapper(m, wrapper);
|
||||
|
||||
/* Clean up namerefs, otherwise deleteparamdef() is confused */
|
||||
for (p = partab; p < partab + sizeof(partab)/sizeof(*partab); ++p) {
|
||||
if (p->flags & PM_NAMEREF) {
|
||||
HashNode hn = gethashnode2(paramtab, p->name);
|
||||
if (hn)
|
||||
((Param)hn)->node.flags &= ~PM_NAMEREF;
|
||||
}
|
||||
}
|
||||
return setfeatureenables(m, &module_features, NULL);
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
finish_(UNUSED(Module m))
|
||||
{
|
||||
return 0;
|
||||
}
|
8
Src/Modules/ksh93.mdd
Normal file
8
Src/Modules/ksh93.mdd
Normal file
|
@ -0,0 +1,8 @@
|
|||
name=zsh/ksh93
|
||||
link=either
|
||||
load=yes
|
||||
|
||||
autofeatures="b:nameref"
|
||||
autofeatures_emu="b:nameref p:.sh.command p:.sh.edcol p:.sh.edtext p:.sh.file p:.sh.lineno p:.sh.match p:.sh.subshell p:.sh.version"
|
||||
|
||||
objects="ksh93.o"
|
|
@ -4319,7 +4319,7 @@ itype_end(const char *ptr, int itype, int once)
|
|||
{
|
||||
if (itype == INAMESPC) {
|
||||
itype = IIDENT;
|
||||
if (once == 0 && !isset(POSIXIDENTIFIERS)) {
|
||||
if (once == 0 && (!isset(POSIXIDENTIFIERS) || EMULATION(EMULATE_KSH))) {
|
||||
/* Special case for names containing ".", ksh93 namespaces */
|
||||
char *t = itype_end(ptr + (*ptr == '.'), itype, 0);
|
||||
if (t > ptr+1) {
|
||||
|
|
Loading…
Reference in a new issue