summaryrefslogtreecommitdiff
path: root/Src/params.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/params.c')
-rw-r--r--Src/params.c50
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 */