1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-08-07 01:30:59 +02:00

Merge branch 'mikachu/badarrays' into schaefer/badarrays

This commit is contained in:
Barton E. Schaefer 2017-05-28 12:29:29 -07:00
commit bcdfcb2765
13 changed files with 132 additions and 61 deletions

View file

@ -27,5 +27,5 @@
# This must also serve as a shell script, so do not add spaces around the # This must also serve as a shell script, so do not add spaces around the
# `=' signs. # `=' signs.
VERSION=5.3.1-dev-0 VERSION=5.3.1-dev-0-badarrays
VERSION_DATE='December 22, 2016' VERSION_DATE='May 28, 2017'

View file

@ -42,11 +42,11 @@ savematch(MatchData *m)
char **a; char **a;
queue_signals(); queue_signals();
a = getaparam("match"); a = getaparam("match", NULL);
m->match = a ? zarrdup(a) : NULL; m->match = a ? zarrdup(a) : NULL;
a = getaparam("mbegin"); a = getaparam("mbegin", NULL);
m->mbegin = a ? zarrdup(a) : NULL; m->mbegin = a ? zarrdup(a) : NULL;
a = getaparam("mend"); a = getaparam("mend", NULL);
m->mend = a ? zarrdup(a) : NULL; m->mend = a ? zarrdup(a) : NULL;
unqueue_signals(); unqueue_signals();
} }
@ -402,7 +402,7 @@ evalstyle(Stypat p)
errflag = ef | (errflag & ERRFLAG_INT); errflag = ef | (errflag & ERRFLAG_INT);
queue_signals(); queue_signals();
if ((ret = getaparam("reply"))) if ((ret = getaparam("reply", NULL)))
ret = arrdup(ret); ret = arrdup(ret);
else if ((str = getsparam("reply"))) { else if ((str = getsparam("reply"))) {
ret = (char **) hcalloc(2 * sizeof(char *)); ret = (char **) hcalloc(2 * sizeof(char *));
@ -1343,7 +1343,7 @@ rmatch(RParseResult *sm, char *subj, char *var1, char *var2, int comp)
int len; int len;
queue_signals(); queue_signals();
mend = getaparam("mend"); mend = getaparam("mend", NULL);
len = atoi(mend[0]); len = atoi(mend[0]);
unqueue_signals(); unqueue_signals();

View file

@ -1971,7 +1971,7 @@ get_user_var(char *nam)
char **arr = NULL, *val; char **arr = NULL, *val;
queue_signals(); queue_signals();
if ((arr = getaparam(nam)) || (arr = gethparam(nam))) if ((arr = getaparam(nam, NULL)) || (arr = gethparam(nam)))
arr = (incompfunc ? arrdup(arr) : arr); arr = (incompfunc ? arrdup(arr) : arr);
else if ((val = getsparam(nam))) { else if ((val = getsparam(nam))) {
arr = (char **) zhalloc(2*sizeof(char *)); arr = (char **) zhalloc(2*sizeof(char *));

View file

@ -871,7 +871,7 @@ bin_compdescribe(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
} else { } else {
char **opts; char **opts;
if (!(opts = getaparam(args[4]))) { if (!(opts = getaparam(args[4], NULL))) {
zwarnnam(nam, "unknown parameter: %s", args[4]); zwarnnam(nam, "unknown parameter: %s", args[4]);
return 1; return 1;
} }
@ -4929,17 +4929,16 @@ bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
return 1; return 1;
} }
queue_signals(); queue_signals();
if (!(tmp = getaparam(args[1]))) { if (!(tmp = getaparam(args[1], NULL))) {
unqueue_signals();
zwarnnam(nam, "unknown parameter: %s", args[1]); zwarnnam(nam, "unknown parameter: %s", args[1]);
return 0; return 0;
} }
for (l = newlinklist(); *tmp; tmp++) for (l = newlinklist(); *tmp; tmp++)
addlinknode(l, quotestring(*tmp, QT_BACKSLASH_PATTERN)); addlinknode(l, quotestring(*tmp, QT_BACKSLASH_PATTERN));
set_list_array(args[1], cf_pats((args[0][1] == 'P'), !!args[0][2], set_list_array(args[1], cf_pats((args[0][1] == 'P'), !!args[0][2],
l, getaparam(args[2]), args[3], l, getaparam(args[2], NULL), args[3],
args[4], args[5], args[4], args[5],
getaparam(args[6]), args + 7)); getaparam(args[6], NULL), args + 7));
unqueue_signals(); unqueue_signals();
return 0; return 0;
} }
@ -4960,12 +4959,12 @@ bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
return 1; return 1;
} }
queue_signals(); queue_signals();
tmp = getaparam(args[2]); tmp = getaparam(args[2], NULL);
l = newlinklist(); l = newlinklist();
if (tmp) if (tmp)
for (; *tmp; tmp++) for (; *tmp; tmp++)
addlinknode(l, *tmp); addlinknode(l, *tmp);
if (!(tmp = getaparam(args[1]))) { if (!(tmp = getaparam(args[1], NULL))) {
unqueue_signals(); unqueue_signals();
zwarnnam(nam, "unknown parameter: %s", args[1]); zwarnnam(nam, "unknown parameter: %s", args[1]);
return 0; return 0;
@ -4990,7 +4989,7 @@ bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
return 1; return 1;
} }
queue_signals(); queue_signals();
if (!(tmp = getaparam(args[1]))) { if (!(tmp = getaparam(args[1], NULL))) {
unqueue_signals(); unqueue_signals();
zwarnnam(nam, "unknown parameter: %s", args[1]); zwarnnam(nam, "unknown parameter: %s", args[1]);
return 0; return 0;

View file

@ -1193,6 +1193,7 @@ char *
zleread(char **lp, char **rp, int flags, int context, char *init, char *finish) zleread(char **lp, char **rp, int flags, int context, char *init, char *finish)
{ {
char *s, **bracket; char *s, **bracket;
int bracket_len;
int old_errno = errno; int old_errno = errno;
int tmout = getiparam("TMOUT"); int tmout = getiparam("TMOUT");
@ -1328,7 +1329,8 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish)
if (zleline && *zleline) if (zleline && *zleline)
redrawhook(); redrawhook();
if ((bracket = getaparam("zle_bracketed_paste")) && arrlen(bracket) == 2) if ((bracket = getaparam("zle_bracketed_paste", &bracket_len)) &&
bracket_len == 2)
fputs(*bracket, shout); fputs(*bracket, shout);
zrefresh(); zrefresh();
@ -1340,7 +1342,7 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish)
"ZLE_VARED_ABORTED" : "ZLE_VARED_ABORTED" :
"ZLE_LINE_ABORTED", zlegetline(NULL, NULL)); "ZLE_LINE_ABORTED", zlegetline(NULL, NULL));
if ((bracket = getaparam("zle_bracketed_paste")) && arrlen(bracket) == 2) if ((bracket = getaparam("zle_bracketed_paste", &bracket_len)) && bracket_len == 2)
fputs(bracket[1], shout); fputs(bracket[1], shout);
if (done && !exit_pending && !errflag) if (done && !exit_pending && !errflag)

View file

@ -313,7 +313,7 @@ static const REFRESH_ELEMENT zr_start_ellipsis[] = {
static void static void
zle_set_highlight(void) zle_set_highlight(void)
{ {
char **atrs = getaparam("zle_highlight"); char **atrs = getaparam("zle_highlight", NULL);
int special_atr_on_set = 0; int special_atr_on_set = 0;
int region_atr_on_set = 0; int region_atr_on_set = 0;
int isearch_atr_on_set = 0; int isearch_atr_on_set = 0;

View file

@ -30,6 +30,8 @@
/* this is defined so we get the prototype for open_memstream */ /* this is defined so we get the prototype for open_memstream */
#define _GNU_SOURCE 1 #define _GNU_SOURCE 1
#include <assert.h>
#include "zsh.mdh" #include "zsh.mdh"
#include "builtin.pro" #include "builtin.pro"
@ -53,7 +55,7 @@ static struct builtin builtins[] =
BUILTIN("cd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL), BUILTIN("cd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL),
BUILTIN("chdir", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL), BUILTIN("chdir", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL),
BUILTIN("continue", BINF_PSPECIAL, bin_break, 0, 1, BIN_CONTINUE, NULL, NULL), BUILTIN("continue", BINF_PSPECIAL, bin_break, 0, 1, BIN_CONTINUE, NULL, NULL),
BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klmprtuxz", NULL), BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "ACE:%F:%HL:%R:%TUZ:%acfghi:%klmprtuxz", NULL),
BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL), BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL),
BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmprs", NULL), BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmprs", NULL),
BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL), BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL),
@ -86,7 +88,7 @@ static struct builtin builtins[] =
BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL), BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL),
BUILTIN("kill", BINF_HANDLES_OPTS, bin_kill, 0, -1, 0, NULL, NULL), BUILTIN("kill", BINF_HANDLES_OPTS, bin_kill, 0, -1, 0, NULL, NULL),
BUILTIN("let", 0, bin_let, 1, -1, 0, NULL, NULL), BUILTIN("let", 0, bin_let, 1, -1, 0, NULL, NULL),
BUILTIN("local", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%ahi:%lprtux", NULL), BUILTIN("local", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "ACE:%F:%HL:%R:%TUZ:%achi:%lprtux", NULL),
BUILTIN("log", 0, bin_log, 0, 0, 0, NULL, NULL), BUILTIN("log", 0, bin_log, 0, 0, 0, NULL, NULL),
BUILTIN("logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL), BUILTIN("logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL),
@ -106,7 +108,7 @@ static struct builtin builtins[] =
BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL), BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
BUILTIN("r", 0, bin_fc, 0, -1, BIN_R, "IlLnr", NULL), BUILTIN("r", 0, bin_fc, 0, -1, BIN_R, "IlLnr", NULL),
BUILTIN("read", 0, bin_read, 0, -1, 0, "cd:ek:%lnpqrst:%zu:AE", NULL), BUILTIN("read", 0, bin_read, 0, -1, 0, "cd:ek:%lnpqrst:%zu:AE", NULL),
BUILTIN("readonly", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, BIN_READONLY, "AE:%F:%HL:%R:%TUZ:%afghi:%lptux", "r"), BUILTIN("readonly", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, BIN_READONLY, "ACE:%F:%HL:%R:%TUZ:%acfghi:%lptux", "r"),
BUILTIN("rehash", 0, bin_hash, 0, 0, 0, "df", "r"), BUILTIN("rehash", 0, bin_hash, 0, 0, 0, "df", "r"),
BUILTIN("return", BINF_PSPECIAL, bin_break, 0, 1, BIN_RETURN, NULL, NULL), BUILTIN("return", BINF_PSPECIAL, bin_break, 0, 1, BIN_RETURN, NULL, NULL),
BUILTIN("set", BINF_PSPECIAL | BINF_HANDLES_OPTS, bin_set, 0, -1, 0, NULL, NULL), BUILTIN("set", BINF_PSPECIAL | BINF_HANDLES_OPTS, bin_set, 0, -1, 0, NULL, NULL),
@ -120,7 +122,7 @@ static struct builtin builtins[] =
BUILTIN("trap", BINF_PSPECIAL | BINF_HANDLES_OPTS, bin_trap, 0, -1, 0, NULL, NULL), BUILTIN("trap", BINF_PSPECIAL | BINF_HANDLES_OPTS, bin_trap, 0, -1, 0, NULL, NULL),
BUILTIN("true", 0, bin_true, 0, -1, 0, NULL, NULL), BUILTIN("true", 0, bin_true, 0, -1, 0, NULL, NULL),
BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsSw", "v"), BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsSw", "v"),
BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klprtuxmz", NULL), BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "ACE:%F:%HL:%R:%TUZ:%acfghi:%klprtuxmz", NULL),
BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL), BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL),
BUILTIN("unalias", 0, bin_unhash, 0, -1, BIN_UNALIAS, "ams", NULL), BUILTIN("unalias", 0, bin_unhash, 0, -1, BIN_UNALIAS, "ams", NULL),
BUILTIN("unfunction", 0, bin_unhash, 1, -1, BIN_UNFUNCTION, "m", "f"), BUILTIN("unfunction", 0, bin_unhash, 1, -1, BIN_UNFUNCTION, "m", "f"),
@ -673,11 +675,9 @@ bin_set(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
if (array) { if (array) {
/* create an array with the specified elements */ /* create an array with the specified elements */
char **a = NULL, **y; char **a = NULL, **y;
int len = arrlen(args); int len = arrlen(args), al;
if (array < 0 && (a = getaparam(arrayname))) {
int al = arrlen(a);
if (array < 0 && (a = getaparam(arrayname, &al))) {
if (al > len) if (al > len)
len = al; len = al;
} }
@ -3611,7 +3611,10 @@ bin_unset(char *name, char **argv, Options ops, int func)
} else { } else {
/* start is after the element for reverse index */ /* start is after the element for reverse index */
int start = vbuf.start - !!(vbuf.flags & VALFLAG_INV); int start = vbuf.start - !!(vbuf.flags & VALFLAG_INV);
if (arrlen_gt(vbuf.pm->u.arr, start)) { if (!(vbuf.pm->node.flags & PM_CACHELEN))
vbuf.pm->length = arrlen(vbuf.pm->u.arr);
assert(vbuf.pm->length == arrlen(vbuf.pm->u.arr));
if (start < vbuf.pm->length) {
char *arr[2]; char *arr[2];
arr[0] = ""; arr[0] = "";
arr[1] = 0; arr[1] = 0;
@ -5264,7 +5267,7 @@ bin_shift(char *name, char **argv, Options ops, UNUSED(int func))
/* optional argument can be either numeric or an array */ /* optional argument can be either numeric or an array */
queue_signals(); queue_signals();
if (*argv && !getaparam(*argv)) if (*argv && !getaparam(*argv, NULL))
num = mathevali(*argv++); num = mathevali(*argv++);
if (num < 0) { if (num < 0) {
@ -5274,9 +5277,10 @@ bin_shift(char *name, char **argv, Options ops, UNUSED(int func))
} }
if (*argv) { if (*argv) {
int len = 0;
for (; *argv; argv++) for (; *argv; argv++)
if ((s = getaparam(*argv))) { if ((s = getaparam(*argv, &len))) {
if (arrlen_lt(s, num)) { if (num > len) {
zwarnnam(name, "shift count must be <= $#"); zwarnnam(name, "shift count must be <= $#");
ret++; ret++;
continue; continue;
@ -5284,7 +5288,7 @@ bin_shift(char *name, char **argv, Options ops, UNUSED(int func))
if (OPT_ISSET(ops,'p')) { if (OPT_ISSET(ops,'p')) {
char **s2, **src, **dst; char **s2, **src, **dst;
int count; int count;
l = arrlen(s); l = len;
src = s; src = s;
dst = s2 = (char **)zalloc((l - num + 1) * sizeof(char *)); dst = s2 = (char **)zalloc((l - num + 1) * sizeof(char *));
for (count = l - num; count; count--) for (count = l - num; count; count--)

View file

@ -3860,7 +3860,7 @@ qualsheval(char *name, UNUSED(struct stat *buf), UNUSED(off_t days), char *str)
errflag = ef | (errflag & ERRFLAG_INT); errflag = ef | (errflag & ERRFLAG_INT);
lastval = lv; lastval = lv;
if (!(inserts = getaparam("reply")) && if (!(inserts = getaparam("reply", NULL)) &&
!(inserts = gethparam("reply"))) { !(inserts = gethparam("reply"))) {
char *tmp; char *tmp;

View file

@ -27,6 +27,8 @@
* *
*/ */
#include <assert.h>
#include "zsh.mdh" #include "zsh.mdh"
#include "params.pro" #include "params.pro"
@ -274,7 +276,7 @@ typedef struct iparam {
static initparam special_params[] ={ static initparam special_params[] ={
#define GSU(X) BR((GsuScalar)(void *)(&(X))) #define GSU(X) BR((GsuScalar)(void *)(&(X)))
#define NULL_GSU BR((GsuScalar)(void *)NULL) #define NULL_GSU BR((GsuScalar)(void *)NULL)
#define IPDEF1(A,B,C) {{NULL,A,PM_INTEGER|PM_SPECIAL|C},BR(NULL),GSU(B),10,0,NULL,NULL,NULL,0} #define IPDEF1(A,B,C) {{NULL,A,PM_INTEGER|PM_SPECIAL|C},BR(NULL),GSU(B),10,0,0,NULL,NULL,NULL,0}
IPDEF1("#", pound_gsu, PM_READONLY), IPDEF1("#", pound_gsu, PM_READONLY),
IPDEF1("ERRNO", errno_gsu, PM_UNSET), IPDEF1("ERRNO", errno_gsu, PM_UNSET),
IPDEF1("GID", gid_gsu, PM_DONTIMPORT | PM_RESTRICTED), IPDEF1("GID", gid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
@ -287,7 +289,7 @@ IPDEF1("UID", uid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
IPDEF1("EUID", euid_gsu, PM_DONTIMPORT | PM_RESTRICTED), IPDEF1("EUID", euid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
IPDEF1("TTYIDLE", ttyidle_gsu, PM_READONLY), IPDEF1("TTYIDLE", ttyidle_gsu, PM_READONLY),
#define IPDEF2(A,B,C) {{NULL,A,PM_SCALAR|PM_SPECIAL|C},BR(NULL),GSU(B),0,0,NULL,NULL,NULL,0} #define IPDEF2(A,B,C) {{NULL,A,PM_SCALAR|PM_SPECIAL|C},BR(NULL),GSU(B),0,0,0,NULL,NULL,NULL,0}
IPDEF2("USERNAME", username_gsu, PM_DONTIMPORT|PM_RESTRICTED), IPDEF2("USERNAME", username_gsu, PM_DONTIMPORT|PM_RESTRICTED),
IPDEF2("-", dash_gsu, PM_READONLY), IPDEF2("-", dash_gsu, PM_READONLY),
IPDEF2("histchars", histchars_gsu, PM_DONTIMPORT), IPDEF2("histchars", histchars_gsu, PM_DONTIMPORT),
@ -322,7 +324,7 @@ LCIPDEF("LC_TIME"),
# endif # endif
#endif /* USE_LOCALE */ #endif /* USE_LOCALE */
#define IPDEF4(A,B) {{NULL,A,PM_INTEGER|PM_READONLY|PM_SPECIAL},BR((void *)B),GSU(varint_readonly_gsu),10,0,NULL,NULL,NULL,0} #define IPDEF4(A,B) {{NULL,A,PM_INTEGER|PM_READONLY|PM_SPECIAL},BR((void *)B),GSU(varint_readonly_gsu),10,0,0,NULL,NULL,NULL,0}
IPDEF4("!", &lastpid), IPDEF4("!", &lastpid),
IPDEF4("$", &mypid), IPDEF4("$", &mypid),
IPDEF4("?", &lastval), IPDEF4("?", &lastval),
@ -331,15 +333,15 @@ IPDEF4("LINENO", &lineno),
IPDEF4("PPID", &ppid), IPDEF4("PPID", &ppid),
IPDEF4("ZSH_SUBSHELL", &zsh_subshell), IPDEF4("ZSH_SUBSHELL", &zsh_subshell),
#define IPDEF5(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL},BR((void *)B),GSU(F),10,0,NULL,NULL,NULL,0} #define IPDEF5(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL},BR((void *)B),GSU(F),10,0,0,NULL,NULL,NULL,0}
#define IPDEF5U(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL|PM_UNSET},BR((void *)B),GSU(F),10,0,NULL,NULL,NULL,0} #define IPDEF5U(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL|PM_UNSET},BR((void *)B),GSU(F),10,0,0,NULL,NULL,NULL,0}
IPDEF5("COLUMNS", &zterm_columns, zlevar_gsu), IPDEF5("COLUMNS", &zterm_columns, zlevar_gsu),
IPDEF5("LINES", &zterm_lines, zlevar_gsu), IPDEF5("LINES", &zterm_lines, zlevar_gsu),
IPDEF5U("ZLE_RPROMPT_INDENT", &rprompt_indent, rprompt_indent_gsu), IPDEF5U("ZLE_RPROMPT_INDENT", &rprompt_indent, rprompt_indent_gsu),
IPDEF5("SHLVL", &shlvl, varinteger_gsu), IPDEF5("SHLVL", &shlvl, varinteger_gsu),
/* Don't import internal integer status variables. */ /* Don't import internal integer status variables. */
#define IPDEF6(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL|PM_DONTIMPORT},BR((void *)B),GSU(F),10,0,NULL,NULL,NULL,0} #define IPDEF6(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL|PM_DONTIMPORT},BR((void *)B),GSU(F),10,0,0,NULL,NULL,NULL,0}
IPDEF6("OPTIND", &zoptind, varinteger_gsu), IPDEF6("OPTIND", &zoptind, varinteger_gsu),
IPDEF6("TRY_BLOCK_ERROR", &try_errflag, varinteger_gsu), IPDEF6("TRY_BLOCK_ERROR", &try_errflag, varinteger_gsu),
IPDEF6("TRY_BLOCK_INTERRUPT", &try_interrupt, varinteger_gsu), IPDEF6("TRY_BLOCK_INTERRUPT", &try_interrupt, varinteger_gsu),
@ -420,7 +422,7 @@ IPDEF9F("path", &path, "PATH", PM_RESTRICTED),
IPDEF10("pipestatus", pipestatus_gsu), IPDEF10("pipestatus", pipestatus_gsu),
{{NULL,NULL,0},BR(NULL),NULL_GSU,0,0,NULL,NULL,NULL,0}, {{NULL,NULL,0},BR(NULL),NULL_GSU,0,0,0,NULL,NULL,NULL,0},
}; };
/* /*
@ -991,7 +993,7 @@ createparam(char *name, int flags)
} }
pm = oldpm; pm = oldpm;
pm->base = pm->width = 0; pm->base = pm->width = pm->length = 0;
oldpm = pm->old; oldpm = pm->old;
} else { } else {
pm = (Param) zshcalloc(sizeof *pm); pm = (Param) zshcalloc(sizeof *pm);
@ -1104,6 +1106,7 @@ copyparam(Param tpm, Param pm, int fakecopy)
*/ */
tpm->node.flags = pm->node.flags; tpm->node.flags = pm->node.flags;
tpm->base = pm->base; tpm->base = pm->base;
tpm->length = pm->length;
tpm->width = pm->width; tpm->width = pm->width;
tpm->level = pm->level; tpm->level = pm->level;
if (!fakecopy) if (!fakecopy)
@ -1552,7 +1555,12 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
ta = getarrvalue(v); ta = getarrvalue(v);
if (!ta || !*ta) if (!ta || !*ta)
return !down; return !down;
len = arrlen(ta); if (v->pm->node.flags & PM_CACHELEN) {
len = arrcachelen(v->pm);
if (v->pm->node.flags & PM_CHECKLEN)
assert(len == arrlen(ta));
} else
len = arrlen(ta);
if (beg < 0) if (beg < 0)
beg += len; beg += len;
if (down) { if (down) {
@ -1575,7 +1583,12 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
} }
} else if (word) { } else if (word) {
ta = sepsplit(d = s = getstrvalue(v), sep, 1, 1); ta = sepsplit(d = s = getstrvalue(v), sep, 1, 1);
len = arrlen(ta); if (v->pm->node.flags & PM_CACHELEN) {
len = arrcachelen(v->pm);
if (v->pm->node.flags & PM_CHECKLEN)
assert(len == arrlen(ta));
} else
len = arrlen(ta);
if (beg < 0) if (beg < 0)
beg += len; beg += len;
if (down) { if (down) {
@ -2714,10 +2727,15 @@ setarrvalue(Value v, char **val)
char **const old = v->pm->gsu.a->getfn(v->pm); char **const old = v->pm->gsu.a->getfn(v->pm);
char **new; char **new;
char **p, **q, **r; /* index variables */ char **p, **q, **r; /* index variables */
const int pre_assignment_length = arrlen(old); int pre_assignment_length = arrcachelen(v->pm);
int post_assignment_length; int post_assignment_length;
int i; int i;
if (v->pm->node.flags & PM_CACHELEN) {
if (v->pm->node.flags & PM_CHECKLEN)
assert(v->pm->length == arrlen(old));
} else
pre_assignment_length = arrlen(old);
q = old; q = old;
if ((v->flags & VALFLAG_INV) && unset(KSHARRAYS)) { if ((v->flags & VALFLAG_INV) && unset(KSHARRAYS)) {
@ -2880,14 +2898,25 @@ getsparam_u(char *s)
/**/ /**/
mod_export char ** mod_export char **
getaparam(char *s) getaparam(char *s, int *len)
{ {
struct value vbuf; struct value vbuf;
Value v; Value v;
if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) && if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) &&
PM_TYPE(v->pm->node.flags) == PM_ARRAY) PM_TYPE(v->pm->node.flags) == PM_ARRAY)
{
if (len) {
if (v->pm->node.flags & PM_CACHELEN) {
*len = arrcachelen(v->pm);
if (v->pm->node.flags & PM_CHECKLEN)
assert (*len == arrlen(v->pm->gsu.a->getfn(v->pm)));
} else
*len = arrlen(v->pm->gsu.a->getfn(v->pm));
}
//fprintf(stderr, "%i %i\n", v->pm->length, arrlen(v->pm->gsu.a->getfn(v->pm)));
return v->pm->gsu.a->getfn(v->pm); return v->pm->gsu.a->getfn(v->pm);
}
return NULL; return NULL;
} }
@ -3061,7 +3090,10 @@ assignsparam(char *s, char *val, int flags)
return v->pm; /* avoid later setstrvalue() call */ return v->pm; /* avoid later setstrvalue() call */
case PM_ARRAY: case PM_ARRAY:
if (unset(KSHARRAYS)) { if (unset(KSHARRAYS)) {
v->start = arrlen(v->pm->gsu.a->getfn(v->pm)); if (v->pm->node.flags & PM_CACHELEN)
v->start = arrcachelen(v->pm);
else
v->start = arrlen(v->pm->gsu.a->getfn(v->pm));
v->end = v->start + 1; v->end = v->start + 1;
} else { } else {
/* ksh appends scalar to first element */ /* ksh appends scalar to first element */
@ -3164,6 +3196,8 @@ assignaparam(char *s, char **val, int flags)
char **new; char **new;
int lv = arrlen(val); int lv = arrlen(val);
v->pm->length = lv + 1;
new = (char **) zalloc(sizeof(char *) * (lv + 2)); new = (char **) zalloc(sizeof(char *) * (lv + 2));
*new = ztrdup(getstrvalue(v)); *new = ztrdup(getstrvalue(v));
memcpy(new+1, val, sizeof(char *) * (lv + 1)); memcpy(new+1, val, sizeof(char *) * (lv + 1));
@ -3188,7 +3222,16 @@ assignaparam(char *s, char **val, int flags)
if (flags & ASSPM_AUGMENT) { if (flags & ASSPM_AUGMENT) {
if (v->start == 0 && v->end == -1) { if (v->start == 0 && v->end == -1) {
if (PM_TYPE(v->pm->node.flags) & PM_ARRAY) { if (PM_TYPE(v->pm->node.flags) & PM_ARRAY) {
v->start = arrlen(v->pm->gsu.a->getfn(v->pm)); if (v->pm->node.flags & PM_CACHELEN) {
v->start =
//arrlen(v->pm->gsu.a->getfn(v->pm));
arrcachelen(v->pm);
if (v->pm->node.flags & PM_CHECKLEN)
assert(v->pm->length == arrlen(v->pm->gsu.a->getfn(v->pm)));
} else {
v->start =
arrlen(v->pm->gsu.a->getfn(v->pm));
}
v->end = v->start + 1; v->end = v->start + 1;
} else if (PM_TYPE(v->pm->node.flags) & PM_HASHED) } else if (PM_TYPE(v->pm->node.flags) & PM_HASHED)
v->start = -1, v->end = 0; v->start = -1, v->end = 0;
@ -3196,7 +3239,16 @@ assignaparam(char *s, char **val, int flags)
if (v->end > 0) if (v->end > 0)
v->start = v->end--; v->start = v->end--;
else if (PM_TYPE(v->pm->node.flags) & PM_ARRAY) { else if (PM_TYPE(v->pm->node.flags) & PM_ARRAY) {
v->end = arrlen(v->pm->gsu.a->getfn(v->pm)) + v->end; if (v->pm->node.flags & PM_CACHELEN) {
v->end
//= arrlen(v->pm->gsu.a->getfn(v->pm)) + v->end;
+= arrcachelen(v->pm);
if (v->pm->node.flags & PM_CHECKLEN)
assert(v->pm->length == arrlen(v->pm->gsu.a->getfn(v->pm)));
} else {
v->end
= arrlen(v->pm->gsu.a->getfn(v->pm)) + v->end;
}
v->start = v->end + 1; v->start = v->end + 1;
} }
} }

View file

@ -1889,7 +1889,7 @@ allocate_colour_buffer(void)
if (colseq_buf_allocs++) if (colseq_buf_allocs++)
return; return;
atrs = getaparam("zle_highlight"); atrs = getaparam("zle_highlight", NULL);
if (atrs) { if (atrs) {
for (; *atrs; atrs++) { for (; *atrs; atrs++) {
if (strpfx("fg_start_code:", *atrs)) { if (strpfx("fg_start_code:", *atrs)) {

View file

@ -27,6 +27,8 @@
* *
*/ */
#include <assert.h>
#include "zsh.mdh" #include "zsh.mdh"
#include "subst.pro" #include "subst.pro"
@ -35,6 +37,8 @@
/**/ /**/
char nulstring[] = {Nularg, '\0'}; char nulstring[] = {Nularg, '\0'};
int arrcachelen(Param pm);
/* Do substitutions before fork. These are: /* Do substitutions before fork. These are:
* - Process substitution: <(...), >(...), =(...) * - Process substitution: <(...), >(...), =(...)
* - Parameter substitution * - Parameter substitution
@ -2555,9 +2559,13 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
* necessary joining of arrays until this point * necessary joining of arrays until this point
* to avoid the multsub() horror. * to avoid the multsub() horror.
*/ */
int tmplen;
/* arrlen() is expensive, so only compute it if needed. */ if (v->pm->node.flags & PM_CACHELEN) {
int tmplen = -1; tmplen = arrcachelen(v->pm);
if (v->pm->node.flags & PM_CHECKLEN)
assert(tmplen == arrlen(v->pm->gsu.a->getfn(v->pm)));
} else
tmplen = -1;
if (v->start < 0) { if (v->start < 0) {
tmplen = arrlen(v->pm->gsu.a->getfn(v->pm)); tmplen = arrlen(v->pm->gsu.a->getfn(v->pm));
@ -3068,11 +3076,14 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
val = dupstring(""); val = dupstring("");
} else { } else {
char *sval; char *sval;
zip = getaparam(s); int ziplen;
zip = getaparam(s, &ziplen);
if (!zip) { if (!zip) {
sval = getsparam(s); sval = getsparam(s);
if (sval) if (sval)
zip = hmkarray(sval); zip = hmkarray(sval);
ziplen = 1;
ziplen = !!sval;
} }
if (!isarr) { if (!isarr) {
aval = mkarray(val); aval = mkarray(val);
@ -3080,9 +3091,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
} }
if (zip) { if (zip) {
char **out; char **out;
int alen, ziplen, outlen, i = 0; int alen, outlen, i = 0;
alen = arrlen(aval); alen = arrlen(aval);
ziplen = arrlen(zip);
outlen = shortest ^ (alen > ziplen) ? alen : ziplen; outlen = shortest ^ (alen > ziplen) ? alen : ziplen;
if (!shortest && (alen == 0 || ziplen == 0)) { if (!shortest && (alen == 0 || ziplen == 0)) {
if (ziplen) if (ziplen)
@ -3112,6 +3122,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
} else if (inbrace && (*s == '|' || *s == Bar || } else if (inbrace && (*s == '|' || *s == Bar ||
*s == '*' || *s == Star)) { *s == '*' || *s == Star)) {
int intersect = (*s == '*' || *s == Star); int intersect = (*s == '*' || *s == Star);
int compare_len;
char **compare, **ap, **apsrc; char **compare, **ap, **apsrc;
++s; ++s;
if (*itype_end(s, IIDENT, 0)) { if (*itype_end(s, IIDENT, 0)) {
@ -3119,9 +3130,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
zerr("not an identifier: %s", s); zerr("not an identifier: %s", s);
return NULL; return NULL;
} }
compare = getaparam(s); compare = getaparam(s, &compare_len);
if (compare) { if (compare) {
HashTable ht = newuniqtable(arrlen(compare)+1); HashTable ht = newuniqtable(compare_len+1);
int present; int present;
for (ap = compare; *ap; ap++) for (ap = compare; *ap; ap++)
(void)addhashnode2(ht, *ap, (HashNode) (void)addhashnode2(ht, *ap, (HashNode)

View file

@ -1501,7 +1501,7 @@ callhookfunc(char *name, LinkList lnklst, int arrayp, int *retval)
memcpy(arrnam, name, namlen); memcpy(arrnam, name, namlen);
memcpy(arrnam + namlen, HOOK_SUFFIX, HOOK_SUFFIX_LEN); memcpy(arrnam + namlen, HOOK_SUFFIX, HOOK_SUFFIX_LEN);
if ((arrptr = getaparam(arrnam))) { if ((arrptr = getaparam(arrnam, NULL))) {
arrptr = arrdup(arrptr); arrptr = arrdup(arrptr);
for (; *arrptr; arrptr++) { for (; *arrptr; arrptr++) {
if ((shfunc = getshfunc(*arrptr))) { if ((shfunc = getshfunc(*arrptr))) {
@ -3810,7 +3810,7 @@ subst_string_by_func(Shfunc func, char *arg1, char *orig)
if (doshfunc(func, l, 1)) if (doshfunc(func, l, 1))
ret = NULL; ret = NULL;
else else
ret = getaparam("reply"); ret = getaparam("reply", NULL);
sfcontext = osc; sfcontext = osc;
stopmsg = osm; stopmsg = osm;
@ -3842,7 +3842,7 @@ subst_string_by_hook(char *name, char *arg1, char *orig)
memcpy(arrnam, name, namlen); memcpy(arrnam, name, namlen);
memcpy(arrnam + namlen, HOOK_SUFFIX, HOOK_SUFFIX_LEN); memcpy(arrnam + namlen, HOOK_SUFFIX, HOOK_SUFFIX_LEN);
if ((arrptr = getaparam(arrnam))) { if ((arrptr = getaparam(arrnam, NULL))) {
/* Guard against internal modification of the array */ /* Guard against internal modification of the array */
arrptr = arrdup(arrptr); arrptr = arrdup(arrptr);
for (; *arrptr; arrptr++) { for (; *arrptr; arrptr++) {

View file

@ -1779,6 +1779,7 @@ struct param {
int base; /* output base or floating point prec */ int base; /* output base or floating point prec */
int width; /* field width */ int width; /* field width */
int length; /* length of array */
char *env; /* location in environment, if exported */ char *env; /* location in environment, if exported */
char *ename; /* name of corresponding environment var */ char *ename; /* name of corresponding environment var */
Param old; /* old struct for use with local */ Param old; /* old struct for use with local */
@ -1833,6 +1834,8 @@ struct tieddata {
#define PM_KSHSTORED (1<<17) /* function stored in ksh form */ #define PM_KSHSTORED (1<<17) /* function stored in ksh form */
#define PM_ZSHSTORED (1<<18) /* function stored in zsh form */ #define PM_ZSHSTORED (1<<18) /* function stored in zsh form */
#define PM_CACHELEN (1<<19) /* length is cached */
#define PM_CHECKLEN (1<<20) /* cached length is checked */
/* Remaining flags do not correspond directly to command line arguments */ /* Remaining flags do not correspond directly to command line arguments */
#define PM_DONTIMPORT_SUID (1<<19) /* do not import if running setuid */ #define PM_DONTIMPORT_SUID (1<<19) /* do not import if running setuid */
@ -1854,7 +1857,7 @@ struct tieddata {
#define PM_NAMEDDIR (1<<30) /* has a corresponding nameddirtab entry */ #define PM_NAMEDDIR (1<<30) /* has a corresponding nameddirtab entry */
/* The option string corresponds to the first of the variables above */ /* The option string corresponds to the first of the variables above */
#define TYPESET_OPTSTR "aiEFALRZlurtxUhHTkz" #define TYPESET_OPTSTR "aiEFALRZlurtxUhHTkzcC"
/* These typeset options take an optional numeric argument */ /* These typeset options take an optional numeric argument */
#define TYPESET_OPTNUM "LRZiEF" #define TYPESET_OPTNUM "LRZiEF"