From a5cff664765fa9abaccd15e42e39438ccce18404 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sun, 13 Dec 2015 17:30:02 +0100 Subject: Change version on this branch --- Config/version.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/version.mk b/Config/version.mk index 5577f4a0b..b182ffa79 100644 --- a/Config/version.mk +++ b/Config/version.mk @@ -27,5 +27,5 @@ # This must also serve as a shell script, so do not add spaces around the # `=' signs. -VERSION=5.2-dev-1 +VERSION=5.2-dev-1-badarrays VERSION_DATE='January 20, 2015' -- cgit 1.4.1 From 0a88c244ed49aa67543e3fc9b9a5b213e229472d Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Sun, 13 Dec 2015 14:45:22 +0000 Subject: Uncontroversial Changes from Mikael's bcf975a2ea3ebc6ba1ed8150b376bef45e527cda: - paramsubst: Change setting of 'ziplen' --- Src/Modules/zutil.c | 10 +++++----- Src/Zle/compcore.c | 2 +- Src/Zle/computil.c | 14 +++++++------- Src/Zle/zle_main.c | 5 +++-- Src/Zle/zle_refresh.c | 2 +- Src/builtin.c | 15 +++++++-------- Src/glob.c | 2 +- Src/params.c | 8 +++++++- Src/prompt.c | 2 +- Src/subst.c | 13 ++++++++----- Src/utils.c | 6 +++--- Src/zsh.h | 1 + 12 files changed, 45 insertions(+), 35 deletions(-) diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index 477575ccd..90d8faf2e 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -42,11 +42,11 @@ savematch(MatchData *m) char **a; queue_signals(); - a = getaparam("match"); + a = getaparam("match", NULL); m->match = a ? zarrdup(a) : NULL; - a = getaparam("mbegin"); + a = getaparam("mbegin", NULL); m->mbegin = a ? zarrdup(a) : NULL; - a = getaparam("mend"); + a = getaparam("mend", NULL); m->mend = a ? zarrdup(a) : NULL; unqueue_signals(); } @@ -402,7 +402,7 @@ evalstyle(Stypat p) errflag = ef | (errflag & ERRFLAG_INT); queue_signals(); - if ((ret = getaparam("reply"))) + if ((ret = getaparam("reply", NULL))) ret = arrdup(ret); else if ((str = getsparam("reply"))) { ret = (char **) hcalloc(2 * sizeof(char *)); @@ -1329,7 +1329,7 @@ rmatch(RParseResult *sm, char *subj, char *var1, char *var2, int comp) int len; queue_signals(); - mend = getaparam("mend"); + mend = getaparam("mend", NULL); len = atoi(mend[0]); unqueue_signals(); diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index ae7068fc9..0c32be14b 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -1952,7 +1952,7 @@ get_user_var(char *nam) char **arr = NULL, *val; queue_signals(); - if ((arr = getaparam(nam)) || (arr = gethparam(nam))) + if ((arr = getaparam(nam, NULL)) || (arr = gethparam(nam))) arr = (incompfunc ? arrdup(arr) : arr); else if ((val = getsparam(nam))) { arr = (char **) zhalloc(2*sizeof(char *)); diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index e8f0a6fe7..184b263ee 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -870,7 +870,7 @@ bin_compdescribe(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) } else { char **opts; - if (!(opts = getaparam(args[4]))) { + if (!(opts = getaparam(args[4], NULL))) { zwarnnam(nam, "unknown parameter: %s", args[4]); return 1; } @@ -4838,16 +4838,16 @@ bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) return 1; } queue_signals(); - if (!(tmp = getaparam(args[1]))) { + if (!(tmp = getaparam(args[1], NULL))) { zwarnnam(nam, "unknown parameter: %s", args[1]); return 0; } for (l = newlinklist(); *tmp; tmp++) addlinknode(l, *tmp); 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], - getaparam(args[6]), args + 7)); + getaparam(args[6], NULL), args + 7)); unqueue_signals(); return 0; } @@ -4868,12 +4868,12 @@ bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) return 1; } queue_signals(); - tmp = getaparam(args[2]); + tmp = getaparam(args[2], NULL); l = newlinklist(); if (tmp) for (; *tmp; tmp++) addlinknode(l, *tmp); - if (!(tmp = getaparam(args[1]))) { + if (!(tmp = getaparam(args[1], NULL))) { unqueue_signals(); zwarnnam(nam, "unknown parameter: %s", args[1]); return 0; @@ -4898,7 +4898,7 @@ bin_compfiles(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) return 1; } queue_signals(); - if (!(tmp = getaparam(args[1]))) { + if (!(tmp = getaparam(args[1], NULL))) { unqueue_signals(); zwarnnam(nam, "unknown parameter: %s", args[1]); return 0; diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 472e326d1..9bea76e9b 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -1170,6 +1170,7 @@ char * zleread(char **lp, char **rp, int flags, int context, char *init, char *finish) { char *s, **bracket; + int bracket_len; int old_errno = errno; int tmout = getiparam("TMOUT"); @@ -1299,7 +1300,7 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish) zlecallhook(init, NULL); - if ((bracket = getaparam("zle_bracketed_paste")) && arrlen(bracket) == 2) + if ((bracket = getaparam("zle_bracketed_paste", &bracket_len)) && bracket_len == 2) fputs(*bracket, shout); zrefresh(); @@ -1311,7 +1312,7 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish) "ZLE_VARED_ABORTED" : "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); if (done && !exit_pending && !errflag) diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index aca676a1c..13ab144ed 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -313,7 +313,7 @@ static const REFRESH_ELEMENT zr_start_ellipsis[] = { static void zle_set_highlight(void) { - char **atrs = getaparam("zle_highlight"); + char **atrs = getaparam("zle_highlight", NULL); int special_atr_on_set = 0; int region_atr_on_set = 0; int isearch_atr_on_set = 0; diff --git a/Src/builtin.c b/Src/builtin.c index 6f07fc678..6bd9c2729 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -672,11 +672,9 @@ bin_set(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) if (array) { /* create an array with the specified elements */ char **a = NULL, **y; - int len = arrlen(args); - - if (array < 0 && (a = getaparam(arrayname))) { - int al = arrlen(a); + int len = arrlen(args), al; + if (array < 0 && (a = getaparam(arrayname, &al))) { if (al > len) len = al; } @@ -5012,7 +5010,7 @@ bin_shift(char *name, char **argv, Options ops, UNUSED(int func)) /* optional argument can be either numeric or an array */ queue_signals(); - if (*argv && !getaparam(*argv)) + if (*argv && !getaparam(*argv, NULL)) num = mathevali(*argv++); if (num < 0) { @@ -5022,9 +5020,10 @@ bin_shift(char *name, char **argv, Options ops, UNUSED(int func)) } if (*argv) { + int len = 0; for (; *argv; argv++) - if ((s = getaparam(*argv))) { - if (num > arrlen(s)) { + if ((s = getaparam(*argv, &len))) { + if (num > len) { zwarnnam(name, "shift count must be <= $#"); ret++; continue; @@ -5032,7 +5031,7 @@ bin_shift(char *name, char **argv, Options ops, UNUSED(int func)) if (OPT_ISSET(ops,'p')) { char **s2, **src, **dst; int count; - l = arrlen(s); + l = len; src = s; dst = s2 = (char **)zalloc((l - num + 1) * sizeof(char *)); for (count = l - num; count; count--) diff --git a/Src/glob.c b/Src/glob.c index 2051016ec..c15bcd195 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -3824,7 +3824,7 @@ qualsheval(char *name, UNUSED(struct stat *buf), UNUSED(off_t days), char *str) errflag = ef | (errflag & ERRFLAG_INT); lastval = lv; - if (!(inserts = getaparam("reply")) && + if (!(inserts = getaparam("reply", NULL)) && !(inserts = gethparam("reply"))) { char *tmp; diff --git a/Src/params.c b/Src/params.c index c6172e018..fef95fe7f 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2658,14 +2658,20 @@ getsparam_u(char *s) /**/ mod_export char ** -getaparam(char *s) +getaparam(char *s, int *len) { struct value vbuf; Value v; if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) && PM_TYPE(v->pm->node.flags) == PM_ARRAY) + { + if (len) + *len = v->pm->length; + //*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 NULL; } diff --git a/Src/prompt.c b/Src/prompt.c index 831c4f948..e811f8e42 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -1882,7 +1882,7 @@ allocate_colour_buffer(void) if (colseq_buf_allocs++) return; - atrs = getaparam("zle_highlight"); + atrs = getaparam("zle_highlight", NULL); if (atrs) { for (; *atrs; atrs++) { if (strpfx("fg_start_code:", *atrs)) { diff --git a/Src/subst.c b/Src/subst.c index f2d0f6553..8644ea0d6 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -3041,18 +3041,20 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, val = dupstring(""); } else { char *sval; - zip = getaparam(s); + int ziplen; + zip = getaparam(s, &ziplen); if (!zip) { sval = getsparam(s); if (sval) zip = hmkarray(sval); + ziplen = 1; + ziplen = !!sval; } if (!isarr) aval = mkarray(val); if (zip) { char **out; - int alen, ziplen, outlen, i = 0; + int alen, outlen, i = 0; alen = arrlen(aval); - ziplen = arrlen(zip); outlen = shortest ^ (alen > ziplen) ? alen : ziplen; if (!shortest && (alen == 0 || ziplen == 0)) { if (ziplen) @@ -3083,6 +3085,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, } else if (inbrace && (*s == '|' || *s == Bar || *s == '*' || *s == Star)) { int intersect = (*s == '*' || *s == Star); + int compare_len; char **compare, **ap, **apsrc; ++s; if (*itype_end(s, IIDENT, 0)) { @@ -3090,9 +3093,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, zerr("not an identifier: %s", s); return NULL; } - compare = getaparam(s); + compare = getaparam(s, &compare_len); if (compare) { - HashTable ht = newuniqtable(arrlen(compare)+1); + HashTable ht = newuniqtable(compare_len+1); int present; for (ap = compare; *ap; ap++) (void)addhashnode2(ht, *ap, (HashNode) diff --git a/Src/utils.c b/Src/utils.c index 12911d3f4..28e78c149 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1483,7 +1483,7 @@ callhookfunc(char *name, LinkList lnklst, int arrayp, int *retval) memcpy(arrnam, name, namlen); memcpy(arrnam + namlen, HOOK_SUFFIX, HOOK_SUFFIX_LEN); - if ((arrptr = getaparam(arrnam))) { + if ((arrptr = getaparam(arrnam, NULL))) { arrptr = arrdup(arrptr); for (; *arrptr; arrptr++) { if ((shfunc = getshfunc(*arrptr))) { @@ -3748,7 +3748,7 @@ subst_string_by_func(Shfunc func, char *arg1, char *orig) if (doshfunc(func, l, 1)) ret = NULL; else - ret = getaparam("reply"); + ret = getaparam("reply", NULL); sfcontext = osc; stopmsg = osm; @@ -3780,7 +3780,7 @@ subst_string_by_hook(char *name, char *arg1, char *orig) memcpy(arrnam, name, namlen); memcpy(arrnam + namlen, HOOK_SUFFIX, HOOK_SUFFIX_LEN); - if ((arrptr = getaparam(arrnam))) { + if ((arrptr = getaparam(arrnam, NULL))) { /* Guard against internal modification of the array */ arrptr = arrdup(arrptr); for (; *arrptr; arrptr++) { diff --git a/Src/zsh.h b/Src/zsh.h index eee31dad1..0e7b75e25 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1739,6 +1739,7 @@ struct param { int base; /* output base or floating point prec */ int width; /* field width */ + int length; /* length of array */ char *env; /* location in environment, if exported */ char *ename; /* name of corresponding environment var */ Param old; /* old struct for use with local */ -- cgit 1.4.1 From 3062f6aef115bd60fa3a0cae691bd9338f2d3ce7 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Sun, 13 Dec 2015 14:53:17 +0000 Subject: CPU SPINNER AND OUT-OF-MEMORY BUGS - DO NOT USE % make -s check ./B08shift.ztst: starting. *** /tmp/zsh.ztst.out.20779 Sun Dec 13 16:15:26 2015 --- /tmp/zsh.ztst.tout.20779 Sun Dec 13 16:15:26 2015 *************** *** 1,4 **** ! tether mether pip azer sezar akker conter dick ! mether pip azer sezar akker conter dick ! mether pip azer sezar ! mether pip azer --- 1,4 ---- ! yan tan tether mether pip azer sezar akker conter dick ! yan tan tether mether pip azer sezar akker conter dick ! yan tan tether mether pip azer sezar akker conter dick ! yan tan tether mether pip azer sezar akker conter dick Test ./B08shift.ztst failed: output differs from expected as shown above for: array=(yan tan tether mether pip azer sezar akker conter dick) shift 2 array print $array shift array print $array shift -p 3 array print $array shift -p array print $array Error output: (eval):shift:2: shift count must be <= $# (eval):shift:4: shift count must be <= $# (eval):shift:6: shift count must be <= $# (eval):shift:8: shift count must be <= $# Was testing: shifting array ./B08shift.ztst: test failed. ./D04parameter.ztst: starting. *** /tmp/zsh.ztst.out.22016 Sun Dec 13 16:15:49 2015 --- /tmp/zsh.ztst.tout.22016 Sun Dec 13 16:15:49 2015 *************** *** 1,10 **** ! a 1 b 2 c 3 ! a 1 b 2 c 3 ! a 1 b 2 ! a 1 b 2 c 1 d 2 ! a a b ! 1 ! a a ! 1 ! b ! 2 2 --- 1,6 ---- ! ! a b c ! ! a b c d ! ! Test ./D04parameter.ztst failed: output differs from expected as shown above for: foo=(a b c) bar=(1 2 3) print ${foo:^bar} print ${foo:^^bar} foo=(a b c d) bar=(1 2) print ${foo:^bar} print ${foo:^^bar} foo=('a a' b) bar=(1 '2 2') print -l "${foo:^bar}" print -l "${(@)foo:^bar}" Was testing: Zipping arrays, correct output ./D04parameter.ztst: test failed. ./X02zlevi.ztst: starting. comptesteval:6: fatal error: out of heap memory ./X03zlebindkey.ztst: starting. comptesteval:6: fatal error: out of heap memory ./Y01completion.ztst: starting. comptesteval:6: fatal error: out of heap memory ./Y02compmatch.ztst: starting. comptesteval:6: fatal error: out of heap memory ./Y03arguments.ztst: starting. comptesteval:6: fatal error: out of heap memory ************************************** 41 successful test scripts, 7 failures, 0 skipped ************************************** --- Src/params.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/Src/params.c b/Src/params.c index fef95fe7f..abb178042 100644 --- a/Src/params.c +++ b/Src/params.c @@ -263,7 +263,7 @@ typedef struct iparam { static initparam special_params[] ={ #define GSU(X) BR((GsuScalar)(void *)(&(X))) #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("ERRNO", errno_gsu, PM_UNSET), IPDEF1("GID", gid_gsu, PM_DONTIMPORT | PM_RESTRICTED), @@ -276,7 +276,7 @@ IPDEF1("UID", uid_gsu, PM_DONTIMPORT | PM_RESTRICTED), IPDEF1("EUID", euid_gsu, PM_DONTIMPORT | PM_RESTRICTED), 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("-", dash_gsu, PM_READONLY), IPDEF2("histchars", histchars_gsu, PM_DONTIMPORT), @@ -310,7 +310,7 @@ LCIPDEF("LC_TIME"), # endif #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("$", &mypid), IPDEF4("?", &lastval), @@ -319,21 +319,21 @@ IPDEF4("LINENO", &lineno), IPDEF4("PPID", &ppid), 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 IPDEF5U(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL|PM_UNSET},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,0,NULL,NULL,NULL,0} IPDEF5("COLUMNS", &zterm_columns, zlevar_gsu), IPDEF5("LINES", &zterm_lines, zlevar_gsu), IPDEF5U("ZLE_RPROMPT_INDENT", &rprompt_indent, zlevar_gsu), IPDEF5("SHLVL", &shlvl, varinteger_gsu), /* 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("TRY_BLOCK_ERROR", &try_errflag, varinteger_gsu), IPDEF6("TRY_BLOCK_INTERRUPT", &try_interrupt, varinteger_gsu), -#define IPDEF7(A,B) {{NULL,A,PM_SCALAR|PM_SPECIAL},BR((void *)B),GSU(varscalar_gsu),0,0,NULL,NULL,NULL,0} -#define IPDEF7U(A,B) {{NULL,A,PM_SCALAR|PM_SPECIAL|PM_UNSET},BR((void *)B),GSU(varscalar_gsu),0,0,NULL,NULL,NULL,0} +#define IPDEF7(A,B) {{NULL,A,PM_SCALAR|PM_SPECIAL},BR((void *)B),GSU(varscalar_gsu),0,0,0,NULL,NULL,NULL,0} +#define IPDEF7U(A,B) {{NULL,A,PM_SCALAR|PM_SPECIAL|PM_UNSET},BR((void *)B),GSU(varscalar_gsu),0,0,0,NULL,NULL,NULL,0} IPDEF7("OPTARG", &zoptarg), IPDEF7("NULLCMD", &nullcmd), IPDEF7U("POSTEDIT", &postedit), @@ -348,7 +348,7 @@ IPDEF7("PS3", &prompt3), IPDEF7("PS4", &prompt4), IPDEF7("SPROMPT", &sprompt), -#define IPDEF8(A,B,C,D) {{NULL,A,D|PM_SCALAR|PM_SPECIAL},BR((void *)B),GSU(colonarr_gsu),0,0,NULL,C,NULL,0} +#define IPDEF8(A,B,C,D) {{NULL,A,D|PM_SCALAR|PM_SPECIAL},BR((void *)B),GSU(colonarr_gsu),0,0,0,NULL,C,NULL,0} IPDEF8("CDPATH", &cdpath, "cdpath", 0), IPDEF8("FIGNORE", &fignore, "fignore", 0), IPDEF8("FPATH", &fpath, "fpath", 0), @@ -361,7 +361,7 @@ IPDEF8("ZSH_EVAL_CONTEXT", &zsh_eval_context, "zsh_eval_context", PM_READONLY), /* MODULE_PATH is not imported for security reasons */ IPDEF8("MODULE_PATH", &module_path, "module_path", PM_DONTIMPORT|PM_RESTRICTED), -#define IPDEF9F(A,B,C,D) {{NULL,A,D|PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT},BR((void *)B),GSU(vararray_gsu),0,0,NULL,C,NULL,0} +#define IPDEF9F(A,B,C,D) {{NULL,A,D|PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT},BR((void *)B),GSU(vararray_gsu),0,0,0,NULL,C,NULL,0} #define IPDEF9(A,B,C) IPDEF9F(A,B,C,0) IPDEF9F("*", &pparams, NULL, PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT|PM_READONLY), IPDEF9F("@", &pparams, NULL, PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT|PM_READONLY), @@ -370,9 +370,9 @@ IPDEF9F("@", &pparams, NULL, PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT|PM_READONLY), * This empty row indicates the end of parameters available in * all emulations. */ -{{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}, -#define IPDEF10(A,B) {{NULL,A,PM_ARRAY|PM_SPECIAL},BR(NULL),GSU(B),10,0,NULL,NULL,NULL,0} +#define IPDEF10(A,B) {{NULL,A,PM_ARRAY|PM_SPECIAL},BR(NULL),GSU(B),10,0,0,NULL,NULL,NULL,0} /* * The following parameters are not available in sh/ksh compatibility * @@ -407,7 +407,7 @@ IPDEF9F("path", &path, "PATH", PM_RESTRICTED), 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}, }; /* @@ -895,7 +895,7 @@ createparam(char *name, int flags) } pm = oldpm; - pm->base = pm->width = 0; + pm->base = pm->width = pm->length = 0; oldpm = pm->old; } else { pm = (Param) zshcalloc(sizeof *pm); @@ -1008,6 +1008,7 @@ copyparam(Param tpm, Param pm, int fakecopy) */ tpm->node.flags = pm->node.flags; tpm->base = pm->base; + tpm->length = pm->length; tpm->width = pm->width; tpm->level = pm->level; if (!fakecopy) @@ -2595,6 +2596,7 @@ setarrvalue(Value v, char **val) *p = NULL; v->pm->gsu.a->setfn(v->pm, new); + v->pm->length = post_assignment_length; freearray(val); } } @@ -2908,6 +2910,8 @@ assignaparam(char *s, char **val, int flags) char **new; int lv = arrlen(val); + v->pm->length = lv + 1; + new = (char **) zalloc(sizeof(char *) * (lv + 2)); *new = ztrdup(getstrvalue(v)); memcpy(new+1, val, sizeof(char *) * (lv + 1)); -- cgit 1.4.1 From 7db77ff1bb173a3db5501b195da9effc3b4fbe53 Mon Sep 17 00:00:00 2001 From: Daniel Shahaf Date: Sun, 13 Dec 2015 14:56:43 +0000 Subject: UNREVIEWED: Further optimizations --- Src/builtin.c | 2 +- Src/params.c | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/Src/builtin.c b/Src/builtin.c index 6bd9c2729..27355feff 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3404,7 +3404,7 @@ bin_unset(char *name, char **argv, Options ops, int func) } else { /* start is after the element for reverse index */ int start = vbuf.start - !!(vbuf.flags & VALFLAG_INV); - if (start < arrlen(vbuf.pm->u.arr)) { + if (start < vbuf.pm->length) { char *arr[2]; arr[0] = ""; arr[1] = 0; diff --git a/Src/params.c b/Src/params.c index abb178042..cda9252ec 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1452,7 +1452,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, ta = getarrvalue(v); if (!ta || !*ta) return !down; - len = arrlen(ta); + len = v->pm->length; if (beg < 0) beg += len; if (down) { @@ -1475,7 +1475,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, } } else if (word) { ta = sepsplit(d = s = getstrvalue(v), sep, 1, 1); - len = arrlen(ta); + len = v->pm->length; if (beg < 0) beg += len; if (down) { @@ -2026,8 +2026,8 @@ getstrvalue(Value v) s = sepjoin(ss, NULL, 1); else { if (v->start < 0) - v->start += arrlen(ss); - s = (v->start >= arrlen(ss) || v->start < 0) ? + v->start += v->pm->length; + s = (v->start >= v->pm->length || v->start < 0) ? (char *) hcalloc(1) : ss[v->start]; } return s; @@ -2223,16 +2223,16 @@ getarrvalue(Value v) if (v->start == 0 && v->end == -1) return s; if (v->start < 0) - v->start += arrlen(s); + v->start += v->pm->length; if (v->end < 0) - v->end += arrlen(s) + 1; - if (v->start > arrlen(s) || v->start < 0) + v->end += v->pm->length + 1; + if (v->start > v->pm->length || v->start < 0) s = arrdup(nular); else s = arrdup(s + v->start); if (v->end <= v->start) s[0] = NULL; - else if (v->end - v->start <= arrlen(s)) + else if (v->end - v->start <= v->pm->length) s[v->end - v->start] = NULL; return s; } @@ -2555,7 +2555,7 @@ setarrvalue(Value v, char **val) char **const old = v->pm->gsu.a->getfn(v->pm); char **new; char **p, **q, **r; /* index variables */ - const int pre_assignment_length = arrlen(old); + const int pre_assignment_length = v->pm->length; int post_assignment_length; int i; @@ -2810,7 +2810,7 @@ assignsparam(char *s, char *val, int flags) return v->pm; /* avoid later setstrvalue() call */ case PM_ARRAY: if (unset(KSHARRAYS)) { - v->start = arrlen(v->pm->gsu.a->getfn(v->pm)); + v->start = v->pm->length; v->end = v->start + 1; } else { /* ksh appends scalar to first element */ @@ -2938,7 +2938,9 @@ assignaparam(char *s, char **val, int flags) if (flags & ASSPM_AUGMENT) { if (v->start == 0 && v->end == -1) { if (PM_TYPE(v->pm->node.flags) & PM_ARRAY) { - v->start = arrlen(v->pm->gsu.a->getfn(v->pm)); + v->start = + //arrlen(v->pm->gsu.a->getfn(v->pm)); + v->pm->length; v->end = v->start + 1; } else if (PM_TYPE(v->pm->node.flags) & PM_HASHED) v->start = -1, v->end = 0; @@ -2946,7 +2948,9 @@ assignaparam(char *s, char **val, int flags) if (v->end > 0) v->start = v->end--; else if (PM_TYPE(v->pm->node.flags) & PM_ARRAY) { - v->end = arrlen(v->pm->gsu.a->getfn(v->pm)) + v->end; + v->end + //= arrlen(v->pm->gsu.a->getfn(v->pm)) + v->end; + += v->pm->length; v->start = v->end + 1; } } -- cgit 1.4.1 From 546a6b42b3a2b1172fbd099a0fee2864af16461c Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sun, 13 Dec 2015 17:35:12 +0100 Subject: Assert on problems --- Src/builtin.c | 3 +++ Src/params.c | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Src/builtin.c b/Src/builtin.c index 27355feff..534f49b57 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -30,6 +30,8 @@ /* this is defined so we get the prototype for open_memstream */ #define _GNU_SOURCE 1 +#include + #include "zsh.mdh" #include "builtin.pro" @@ -3404,6 +3406,7 @@ bin_unset(char *name, char **argv, Options ops, int func) } else { /* start is after the element for reverse index */ int start = vbuf.start - !!(vbuf.flags & VALFLAG_INV); + assert(vbuf.pm->length == arrlen(vbuf.pm->u.arr)); if (start < vbuf.pm->length) { char *arr[2]; arr[0] = ""; diff --git a/Src/params.c b/Src/params.c index cda9252ec..cdaa59a92 100644 --- a/Src/params.c +++ b/Src/params.c @@ -27,6 +27,8 @@ * */ +#include + #include "zsh.mdh" #include "params.pro" @@ -1453,6 +1455,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, if (!ta || !*ta) return !down; len = v->pm->length; + assert(len == arrlen(ta)); if (beg < 0) beg += len; if (down) { @@ -1476,6 +1479,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, } else if (word) { ta = sepsplit(d = s = getstrvalue(v), sep, 1, 1); len = v->pm->length; + assert(len == arrlen(ta)); if (beg < 0) beg += len; if (down) { @@ -2025,6 +2029,7 @@ getstrvalue(Value v) if (v->isarr) s = sepjoin(ss, NULL, 1); else { + assert(v->pm->length == arrlen(ss)); if (v->start < 0) v->start += v->pm->length; s = (v->start >= v->pm->length || v->start < 0) ? @@ -2222,6 +2227,7 @@ getarrvalue(Value v) s = getvaluearr(v); if (v->start == 0 && v->end == -1) return s; + assert(v->pm->length == arrlen(s)); if (v->start < 0) v->start += v->pm->length; if (v->end < 0) @@ -2559,6 +2565,7 @@ setarrvalue(Value v, char **val) int post_assignment_length; int i; + assert(v->pm->length == arrlen(old)); q = old; if ((v->flags & VALFLAG_INV) && unset(KSHARRAYS)) { @@ -2668,9 +2675,10 @@ getaparam(char *s, int *len) if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) && PM_TYPE(v->pm->node.flags) == PM_ARRAY) { - if (len) + if (len) { *len = v->pm->length; - //*len = arrlen(v->pm->gsu.a->getfn(v->pm)); + assert (*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); } @@ -2938,6 +2946,7 @@ assignaparam(char *s, char **val, int flags) if (flags & ASSPM_AUGMENT) { if (v->start == 0 && v->end == -1) { if (PM_TYPE(v->pm->node.flags) & PM_ARRAY) { + assert(v->pm->length == arrlen(v->pm->gsu.a->getfn(v->pm))); v->start = //arrlen(v->pm->gsu.a->getfn(v->pm)); v->pm->length; @@ -2948,6 +2957,7 @@ assignaparam(char *s, char **val, int flags) if (v->end > 0) v->start = v->end--; else if (PM_TYPE(v->pm->node.flags) & PM_ARRAY) { + assert(v->pm->length == arrlen(v->pm->gsu.a->getfn(v->pm))); v->end //= arrlen(v->pm->gsu.a->getfn(v->pm)) + v->end; += v->pm->length; -- cgit 1.4.1 From b7c2ddf65c9175b77bb9efc4ec7de7ef472d7a65 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sun, 8 May 2016 21:33:24 +0200 Subject: Add typeset -c to control when cached length is used --- Src/builtin.c | 10 +++-- Src/params.c | 136 +++++++++++++++++++++++++++++++++++++++++++--------------- Src/subst.c | 8 +++- Src/zsh.h | 3 +- 4 files changed, 116 insertions(+), 41 deletions(-) diff --git a/Src/builtin.c b/Src/builtin.c index 534f49b57..6ce313d88 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -55,7 +55,7 @@ static struct builtin builtins[] = 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("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, "AE:%F:%HL:%R:%TUZ:%acfghi:%klmprtuxz", NULL), BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL), BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmprs", NULL), BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL), @@ -88,7 +88,7 @@ static struct builtin builtins[] = BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL), BUILTIN("kill", BINF_HANDLES_OPTS, bin_kill, 0, -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, "AE:%F:%HL:%R:%TUZ:%achi:%lprtux", NULL), BUILTIN("log", 0, bin_log, 0, 0, 0, NULL, NULL), BUILTIN("logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL), @@ -108,7 +108,7 @@ static struct builtin builtins[] = BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", 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("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, "AE:%F:%HL:%R:%TUZ:%acfghi:%lptux", "r"), BUILTIN("rehash", 0, bin_hash, 0, 0, 0, "df", "r"), 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), @@ -122,7 +122,7 @@ static struct builtin builtins[] = 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("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, "AE:%F:%HL:%R:%TUZ:%acfghi:%klprtuxmz", NULL), BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL), BUILTIN("unalias", 0, bin_unhash, 0, -1, BIN_UNALIAS, "ams", NULL), BUILTIN("unfunction", 0, bin_unhash, 1, -1, BIN_UNFUNCTION, "m", "f"), @@ -3406,6 +3406,8 @@ bin_unset(char *name, char **argv, Options ops, int func) } else { /* start is after the element for reverse index */ int start = vbuf.start - !!(vbuf.flags & VALFLAG_INV); + 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]; diff --git a/Src/params.c b/Src/params.c index cdaa59a92..4a5db3c1d 100644 --- a/Src/params.c +++ b/Src/params.c @@ -28,6 +28,7 @@ */ #include +//#define assert(x) #include "zsh.mdh" #include "params.pro" @@ -661,6 +662,19 @@ split_env_string(char *env, char **name, char **value) } else return 0; } + +int +arrcachelen(Param pm) +{ + int len; + + len = pm->length; + if (len == 0 && pm->u.arr) { + len = arrlen(pm->u.arr); + pm->length = len; + } + return len; +} /* Set up parameter hash table. This will add predefined * * parameter entries as well as setting up parameter table * @@ -1454,8 +1468,11 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, ta = getarrvalue(v); if (!ta || !*ta) return !down; - len = v->pm->length; - assert(len == arrlen(ta)); + if (v->pm->node.flags & PM_CACHELEN) { + len = arrcachelen(v->pm); + assert(len == arrlen(ta)); + } else + len = arrlen(ta); if (beg < 0) beg += len; if (down) { @@ -1478,8 +1495,11 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, } } else if (word) { ta = sepsplit(d = s = getstrvalue(v), sep, 1, 1); - len = v->pm->length; - assert(len == arrlen(ta)); + if (v->pm->node.flags & PM_CACHELEN) { + len = arrcachelen(v->pm); + assert(len == arrlen(ta)); + } else + len = arrlen(ta); if (beg < 0) beg += len; if (down) { @@ -2029,11 +2049,20 @@ getstrvalue(Value v) if (v->isarr) s = sepjoin(ss, NULL, 1); else { - assert(v->pm->length == arrlen(ss)); - if (v->start < 0) - v->start += v->pm->length; - s = (v->start >= v->pm->length || v->start < 0) ? - (char *) hcalloc(1) : ss[v->start]; + if (v->pm->node.flags & PM_CACHELEN) { + int len = arrcachelen(v->pm); + assert(v->pm->length == arrlen(ss)); + if (v->start < 0) + v->start += len; + s = (v->start >= len || v->start < 0) ? + (char *) hcalloc(1) : ss[v->start]; + } else { + int len = arrlen(ss); + if (v->start < 0) + v->start += len; + s = (v->start >= len || v->start < 0) ? + (char *) hcalloc(1) : ss[v->start]; + } } return s; case PM_INTEGER: @@ -2227,19 +2256,37 @@ getarrvalue(Value v) s = getvaluearr(v); if (v->start == 0 && v->end == -1) return s; - assert(v->pm->length == arrlen(s)); - if (v->start < 0) - v->start += v->pm->length; - if (v->end < 0) - v->end += v->pm->length + 1; - if (v->start > v->pm->length || v->start < 0) - s = arrdup(nular); - else - s = arrdup(s + v->start); - if (v->end <= v->start) - s[0] = NULL; - else if (v->end - v->start <= v->pm->length) - s[v->end - v->start] = NULL; + if (v->pm->node.flags & PM_CACHELEN) { + int len = arrcachelen(v->pm); + assert(v->pm->length == arrlen(s)); + if (v->start < 0) + v->start += v->pm->length; + if (v->end < 0) + v->end += v->pm->length + 1; + if (v->start > v->pm->length || v->start < 0) + s = arrdup(nular); + else + s = arrdup(s + v->start); + if (v->end <= v->start) + s[0] = NULL; + //XXX[badarrays] s just changed above but here we use the same + // cached length possible cause of problems + else if (v->end - v->start <= v->pm->length) + s[v->end - v->start] = NULL; + } else { + if (v->start < 0) + v->start += arrlen(s); + if (v->end < 0) + v->end += arrlen(s) + 1; + if (v->start > arrlen(s) || v->start < 0) + s = arrdup(nular); + else + s = arrdup(s + v->start); + if (v->end <= v->start) + s[0] = NULL; + else if (v->end - v->start <= arrlen(s)) + s[v->end - v->start] = NULL; + } return s; } @@ -2561,11 +2608,14 @@ setarrvalue(Value v, char **val) char **const old = v->pm->gsu.a->getfn(v->pm); char **new; char **p, **q, **r; /* index variables */ - const int pre_assignment_length = v->pm->length; + int pre_assignment_length = arrcachelen(v->pm); int post_assignment_length; int i; - assert(v->pm->length == arrlen(old)); + if (v->pm->node.flags & PM_CACHELEN) + assert(v->pm->length == arrlen(old)); + else + pre_assignment_length = arrlen(old); q = old; if ((v->flags & VALFLAG_INV) && unset(KSHARRAYS)) { @@ -2676,8 +2726,11 @@ getaparam(char *s, int *len) PM_TYPE(v->pm->node.flags) == PM_ARRAY) { if (len) { - *len = v->pm->length; - assert (*len == arrlen(v->pm->gsu.a->getfn(v->pm))); + if (v->pm->node.flags & PM_CACHELEN) { + *len = arrcachelen(v->pm); + 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); @@ -2818,7 +2871,10 @@ assignsparam(char *s, char *val, int flags) return v->pm; /* avoid later setstrvalue() call */ case PM_ARRAY: if (unset(KSHARRAYS)) { - v->start = v->pm->length; + 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; } else { /* ksh appends scalar to first element */ @@ -2946,10 +3002,15 @@ assignaparam(char *s, char **val, int flags) if (flags & ASSPM_AUGMENT) { if (v->start == 0 && v->end == -1) { if (PM_TYPE(v->pm->node.flags) & PM_ARRAY) { - assert(v->pm->length == arrlen(v->pm->gsu.a->getfn(v->pm))); - v->start = - //arrlen(v->pm->gsu.a->getfn(v->pm)); - v->pm->length; + if (v->pm->node.flags & PM_CACHELEN) { + v->start = + //arrlen(v->pm->gsu.a->getfn(v->pm)); + arrcachelen(v->pm); + 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; } else if (PM_TYPE(v->pm->node.flags) & PM_HASHED) v->start = -1, v->end = 0; @@ -2957,10 +3018,15 @@ assignaparam(char *s, char **val, int flags) if (v->end > 0) v->start = v->end--; else if (PM_TYPE(v->pm->node.flags) & PM_ARRAY) { - assert(v->pm->length == arrlen(v->pm->gsu.a->getfn(v->pm))); - v->end - //= arrlen(v->pm->gsu.a->getfn(v->pm)) + v->end; - += v->pm->length; + if (v->pm->node.flags & PM_CACHELEN) { + v->end + //= arrlen(v->pm->gsu.a->getfn(v->pm)) + v->end; + += arrcachelen(v->pm); + 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; } } diff --git a/Src/subst.c b/Src/subst.c index 8644ea0d6..cc59c74d4 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -35,6 +35,8 @@ /**/ char nulstring[] = {Nularg, '\0'}; +int arrcachelen(Param pm); + /* Do substitutions before fork. These are: * - Process substitution: <(...), >(...), =(...) * - Parameter substitution @@ -2548,7 +2550,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * necessary joining of arrays until this point * to avoid the multsub() horror. */ - int tmplen = arrlen(v->pm->gsu.a->getfn(v->pm)); + int tmplen; + if (v->pm->node.flags & PM_CACHELEN) + tmplen = arrcachelen(v->pm); + else + tmplen = arrlen(v->pm->gsu.a->getfn(v->pm)); if (v->start < 0) v->start += tmplen + ((v->flags & VALFLAG_INV) ? 1 : 0); diff --git a/Src/zsh.h b/Src/zsh.h index 0e7b75e25..bf89272f2 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1791,6 +1791,7 @@ struct tieddata { #define PM_KSHSTORED (1<<17) /* function stored in ksh form */ #define PM_ZSHSTORED (1<<18) /* function stored in zsh form */ +#define PM_CACHELEN (1<<19) /* length is cached */ /* Remaining flags do not correspond directly to command line arguments */ #define PM_LOCAL (1<<21) /* this parameter will be made local */ @@ -1809,7 +1810,7 @@ struct tieddata { #define PM_NAMEDDIR (1<<30) /* has a corresponding nameddirtab entry */ /* The option string corresponds to the first of the variables above */ -#define TYPESET_OPTSTR "aiEFALRZlurtxUhHTkz" +#define TYPESET_OPTSTR "aiEFALRZlurtxUhHTkzc" /* These typeset options take an optional numeric argument */ #define TYPESET_OPTNUM "LRZiEF" -- cgit 1.4.1 From f4ab07b48c747e8dade9ee85369445de3a10d669 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sun, 8 May 2016 22:07:09 +0200 Subject: Add typeset -C to control whether to assert the cached length --- Src/builtin.c | 8 ++++---- Src/params.c | 29 ++++++++++++++++++----------- Src/subst.c | 8 ++++++-- Src/zsh.h | 3 ++- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/Src/builtin.c b/Src/builtin.c index 6ce313d88..ba7136eb4 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -55,7 +55,7 @@ static struct builtin builtins[] = 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("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:%acfghi:%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("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmprs", NULL), BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL), @@ -88,7 +88,7 @@ static struct builtin builtins[] = BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL), BUILTIN("kill", BINF_HANDLES_OPTS, bin_kill, 0, -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:%achi:%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("logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL), @@ -108,7 +108,7 @@ static struct builtin builtins[] = BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", 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("readonly", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, BIN_READONLY, "AE:%F:%HL:%R:%TUZ:%acfghi:%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("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), @@ -122,7 +122,7 @@ static struct builtin builtins[] = 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("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:%acfghi:%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("unalias", 0, bin_unhash, 0, -1, BIN_UNALIAS, "ams", NULL), BUILTIN("unfunction", 0, bin_unhash, 1, -1, BIN_UNFUNCTION, "m", "f"), diff --git a/Src/params.c b/Src/params.c index 4a5db3c1d..2e4dd4ee6 100644 --- a/Src/params.c +++ b/Src/params.c @@ -28,7 +28,6 @@ */ #include -//#define assert(x) #include "zsh.mdh" #include "params.pro" @@ -1470,7 +1469,8 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, return !down; if (v->pm->node.flags & PM_CACHELEN) { len = arrcachelen(v->pm); - assert(len == arrlen(ta)); + if (v->pm->node.flags & PM_CHECKLEN) + assert(len == arrlen(ta)); } else len = arrlen(ta); if (beg < 0) @@ -1497,7 +1497,8 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, ta = sepsplit(d = s = getstrvalue(v), sep, 1, 1); if (v->pm->node.flags & PM_CACHELEN) { len = arrcachelen(v->pm); - assert(len == arrlen(ta)); + if (v->pm->node.flags & PM_CHECKLEN) + assert(len == arrlen(ta)); } else len = arrlen(ta); if (beg < 0) @@ -2051,7 +2052,8 @@ getstrvalue(Value v) else { if (v->pm->node.flags & PM_CACHELEN) { int len = arrcachelen(v->pm); - assert(v->pm->length == arrlen(ss)); + if (v->pm->node.flags & PM_CHECKLEN) + assert(v->pm->length == arrlen(ss)); if (v->start < 0) v->start += len; s = (v->start >= len || v->start < 0) ? @@ -2258,7 +2260,8 @@ getarrvalue(Value v) return s; if (v->pm->node.flags & PM_CACHELEN) { int len = arrcachelen(v->pm); - assert(v->pm->length == arrlen(s)); + if (v->pm->node.flags & PM_CHECKLEN) + assert(v->pm->length == arrlen(s)); if (v->start < 0) v->start += v->pm->length; if (v->end < 0) @@ -2612,9 +2615,10 @@ setarrvalue(Value v, char **val) int post_assignment_length; int i; - if (v->pm->node.flags & PM_CACHELEN) - assert(v->pm->length == arrlen(old)); - else + 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; @@ -2728,7 +2732,8 @@ getaparam(char *s, int *len) if (len) { if (v->pm->node.flags & PM_CACHELEN) { *len = arrcachelen(v->pm); - assert (*len == arrlen(v->pm->gsu.a->getfn(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)); } @@ -3006,7 +3011,8 @@ assignaparam(char *s, char **val, int flags) v->start = //arrlen(v->pm->gsu.a->getfn(v->pm)); arrcachelen(v->pm); - assert(v->pm->length == arrlen(v->pm->gsu.a->getfn(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)); @@ -3022,7 +3028,8 @@ assignaparam(char *s, char **val, int flags) v->end //= arrlen(v->pm->gsu.a->getfn(v->pm)) + v->end; += arrcachelen(v->pm); - assert(v->pm->length == arrlen(v->pm->gsu.a->getfn(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; diff --git a/Src/subst.c b/Src/subst.c index cc59c74d4..7081d467d 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -27,6 +27,8 @@ * */ +#include + #include "zsh.mdh" #include "subst.pro" @@ -2551,9 +2553,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * to avoid the multsub() horror. */ int tmplen; - if (v->pm->node.flags & PM_CACHELEN) + if (v->pm->node.flags & PM_CACHELEN) { tmplen = arrcachelen(v->pm); - else + if (v->pm->node.flags & PM_CHECKLEN) + assert(tmplen == arrlen(v->pm->gsu.a->getfn(v->pm))); + } else tmplen = arrlen(v->pm->gsu.a->getfn(v->pm)); if (v->start < 0) diff --git a/Src/zsh.h b/Src/zsh.h index bf89272f2..fe88efe69 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1792,6 +1792,7 @@ struct tieddata { #define PM_KSHSTORED (1<<17) /* function stored in ksh 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 */ #define PM_LOCAL (1<<21) /* this parameter will be made local */ @@ -1810,7 +1811,7 @@ struct tieddata { #define PM_NAMEDDIR (1<<30) /* has a corresponding nameddirtab entry */ /* The option string corresponds to the first of the variables above */ -#define TYPESET_OPTSTR "aiEFALRZlurtxUhHTkzc" +#define TYPESET_OPTSTR "aiEFALRZlurtxUhHTkzcC" /* These typeset options take an optional numeric argument */ #define TYPESET_OPTNUM "LRZiEF" -- cgit 1.4.1