diff options
author | Sebastian Gniazdowski <psprint@fastmail.com> | 2016-12-28 05:29:50 +0000 |
---|---|---|
committer | Daniel Shahaf <d.s@daniel.shahaf.name> | 2016-12-28 05:29:59 +0000 |
commit | 4fb4ce190ccb45991979deed503ff3bdfc56ccf2 (patch) | |
tree | 0e5a5059e70c98cbbc2697440d036cb03331fde2 /Src | |
parent | d287f8134035d2e4a8bfc8efc0e6323297e634ec (diff) | |
download | zsh-4fb4ce190ccb45991979deed503ff3bdfc56ccf2.tar.gz zsh-4fb4ce190ccb45991979deed503ff3bdfc56ccf2.tar.xz zsh-4fb4ce190ccb45991979deed503ff3bdfc56ccf2.zip |
40231: Optimise setarrvalue().
Diffstat (limited to 'Src')
-rw-r--r-- | Src/params.c | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/Src/params.c b/Src/params.c index c64d7486b..5b93cafe2 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2708,24 +2708,40 @@ setarrvalue(Value v, char **val) post_assignment_length += pre_assignment_length - v->end; } - p = new = (char **) zalloc(sizeof(char *) - * (post_assignment_length + 1)); - - for (i = 0; i < v->start; i++) - *p++ = i < pre_assignment_length ? ztrdup(*q++) : ztrdup(""); - for (r = val; *r;) { - /* Give away ownership of the string */ - *p++ = *r++; - } - if (v->end < pre_assignment_length) - for (q = old + v->end; *q;) - *p++ = ztrdup(*q++); - *p = NULL; + if (pre_assignment_length == post_assignment_length + && v->pm->gsu.a->setfn == arrsetfn + /* ... and isn't something that arrsetfn() treats specially */ + && 0 == (v->pm->node.flags & (PM_SPECIAL|PM_UNIQUE)) + && NULL == v->pm->ename) + { + /* v->start is 0-based */ + p = old + v->start; + for (r = val; *r;) { + /* Free previous string */ + zsfree(*p); + /* Give away ownership of the string */ + *p++ = *r++; + } + } else { + p = new = (char **) zalloc(sizeof(char *) + * (post_assignment_length + 1)); + + for (i = 0; i < v->start; i++) + *p++ = i < pre_assignment_length ? ztrdup(*q++) : ztrdup(""); + for (r = val; *r;) { + /* Give away ownership of the string */ + *p++ = *r++; + } + if (v->end < pre_assignment_length) + for (q = old + v->end; *q;) + *p++ = ztrdup(*q++); + *p = NULL; - DPUTS2(p - new != post_assignment_length, "setarrvalue: wrong allocation: %d 1= %lu", - post_assignment_length, (unsigned long)(p - new)); + DPUTS2(p - new != post_assignment_length, "setarrvalue: wrong allocation: %d 1= %lu", + post_assignment_length, (unsigned long)(p - new)); - v->pm->gsu.a->setfn(v->pm, new); + v->pm->gsu.a->setfn(v->pm, new); + } /* Ownership of all strings has been * given away, can plainly free */ @@ -3485,6 +3501,8 @@ arrsetfn(Param pm, char **x) /* Arrays tied to colon-arrays may need to fix the environment */ if (pm->ename && x) arrfixenv(pm->ename, x); + /* If you extend this function, update the list of conditions in + * setarrvalue(). */ } /* Function to get value of an association parameter */ |