From 2eacbef91913fe967335812900d43cf2edfa54d9 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 7 Aug 2017 18:47:43 +0100 Subject: 41499 (with one further tweak): POSIX_STRINGS behaviour. Ignore a terminating delimiter when splitting as separators despite being called separators are terminators. --- Src/utils.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/Src/utils.c b/Src/utils.c index 5055d69fe..d30a7b47e 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -3500,12 +3500,12 @@ skipwsep(char **s) mod_export char ** spacesplit(char *s, int allownull, int heap, int quote) { - char *t, **ret, **ptr; + char *t, **ret, **ptr, **eptr; int l = sizeof(*ret) * (wordcount(s, NULL, -!allownull) + 1); char *(*dup)(const char *) = (heap ? dupstring : ztrdup); /* ### TODO: s/calloc/alloc/ */ - ptr = ret = (char **) (heap ? hcalloc(l) : zshcalloc(l)); + eptr = ptr = ret = (char **) (heap ? hcalloc(l) : zshcalloc(l)); if (quote) { /* @@ -3537,6 +3537,7 @@ spacesplit(char *s, int allownull, int heap, int quote) if (s > t || allownull) { *ptr = (char *) (heap ? zhalloc((s - t) + 1) : zalloc((s - t) + 1)); + eptr = ptr; ztrncpy(*ptr++, t, s - t); } else *ptr++ = dup(nulstring); @@ -3545,6 +3546,21 @@ spacesplit(char *s, int allownull, int heap, int quote) } if (!allownull && t != s) *ptr++ = dup(""); + if (isset(POSIXSTRINGS) && ptr > eptr + 1) { + /* + * Trailing separators do not generate extra fields in POSIX. + * Note this is only the final separator --- if the + * immediately preceding field was null it is still counted. + * So just back up one. + */ + --ptr; + if (!heap) { + char **ret2 = realloc(ret, sizeof(*ret) * (ptr+1-ret)); + ptr -= ret-ret2; + free(ret); + ret = ret2; + } + } *ptr = NULL; return ret; } -- cgit 1.4.1