summary refs log tree commit diff
path: root/Src/utils.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2000-07-27 17:48:47 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2000-07-27 17:48:47 +0000
commit0aee5e1bb490617b1d84d5ad8e20571d26fc9986 (patch)
tree54f2adfe54ef20a76b24ae8e25c5bdb203d14a02 /Src/utils.c
parent31862868fa7979e4b58cb71c42ac1c63acb8c7fc (diff)
downloadzsh-0aee5e1bb490617b1d84d5ad8e20571d26fc9986.tar.gz
zsh-0aee5e1bb490617b1d84d5ad8e20571d26fc9986.tar.xz
zsh-0aee5e1bb490617b1d84d5ad8e20571d26fc9986.zip
12414: vared quotes separators when editing arrays
Diffstat (limited to 'Src/utils.c')
-rw-r--r--Src/utils.c43
1 files changed, 34 insertions, 9 deletions
diff --git a/Src/utils.c b/Src/utils.c
index 33fed62dd..48218326b 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1831,7 +1831,7 @@ skipwsep(char **s)
 
 /**/
 mod_export char **
-spacesplit(char *s, int allownull, int heap)
+spacesplit(char *s, int allownull, int heap, int quote)
 {
     char *t, **ret, **ptr;
     int l = sizeof(*ret) * (wordcount(s, NULL, -!allownull) + 1);
@@ -1839,6 +1839,14 @@ spacesplit(char *s, int allownull, int heap)
 
     ptr = ret = (heap ? (char **) hcalloc(l) : (char **) zcalloc(l));
 
+    if (quote) {
+	/*
+	 * we will be stripping quoted separators by hacking string,
+	 * so make sure it's hackable.
+	 */
+	s = dupstring(s);
+    }
+
     t = s;
     skipwsep(&s);
     if (*s && isep(*s == Meta ? s[1] ^ 32 : *s))
@@ -1853,7 +1861,7 @@ spacesplit(char *s, int allownull, int heap)
 	    skipwsep(&s);
 	}
 	t = s;
-	findsep(&s, NULL);
+	findsep(&s, NULL, quote);
 	if (s > t || allownull) {
 	    *ptr = (heap ? (char *) hcalloc((s - t) + 1) :
 		    (char *) zcalloc((s - t) + 1));
@@ -1871,13 +1879,30 @@ spacesplit(char *s, int allownull, int heap)
 
 /**/
 static int
-findsep(char **s, char *sep)
+findsep(char **s, char *sep, int quote)
 {
+    /*
+     * *s is the string we are looking along, which will be updated
+     * to the point we have got to.
+     *
+     * sep is a possibly multicharacter separator to look for.  If NULL,
+     * use normal separator characters.
+     *
+     * quote is a flag that '\<sep>' should not be treated as a separator.
+     * in this case we need to be able to strip the backslash directly
+     * in the string, so the calling function must have sent us something
+     * modifiable.  currently this only works for sep == NULL.
+     */
     int i;
     char *t, *tt;
 
     if (!sep) {
 	for (t = *s; *t; t++) {
+	    if (quote && *t == '\\' &&
+		isep(t[1] == Meta ? (t[2] ^ 32) : t[1])) {
+		chuck(t);
+		continue;
+	    }
 	    if (*t == Meta) {
 		if (isep(t[1] ^ 32))
 		    break;
@@ -1928,7 +1953,7 @@ findword(char **s, char *sep)
     if (sep) {
 	sl = strlen(sep);
 	r = *s;
-	while (! findsep(s, sep)) {
+	while (! findsep(s, sep, 0)) {
 	    r = *s += sl;
 	}
 	return r;
@@ -1942,7 +1967,7 @@ findword(char **s, char *sep)
 	    break;
     }
     *s = t;
-    findsep(s, sep);
+    findsep(s, sep, 0);
     return t;
 }
 
@@ -1955,7 +1980,7 @@ wordcount(char *s, char *sep, int mul)
     if (sep) {
 	r = 1;
 	sl = strlen(sep);
-	for (; (c = findsep(&s, sep)) >= 0; s += sl)
+	for (; (c = findsep(&s, sep, 0)) >= 0; s += sl)
 	    if ((c && *(s + sl)) || mul)
 		r++;
     } else {
@@ -1975,7 +2000,7 @@ wordcount(char *s, char *sep, int mul)
 		if (mul <= 0)
 		    skipwsep(&s);
 	    }
-	    findsep(&s, NULL);
+	    findsep(&s, NULL, 0);
 	    t = s;
 	    if (mul <= 0)
 		skipwsep(&s);
@@ -2023,7 +2048,7 @@ sepsplit(char *s, char *sep, int allownull, int heap)
     char *t, *tt, **r, **p;
 
     if (!sep)
-	return spacesplit(s, allownull, heap);
+	return spacesplit(s, allownull, heap, 0);
 
     sl = strlen(sep);
     n = wordcount(s, sep, 1);
@@ -2032,7 +2057,7 @@ sepsplit(char *s, char *sep, int allownull, int heap)
 
     for (t = s; n--;) {
 	tt = t;
-	findsep(&t, sep);
+	findsep(&t, sep, 0);
 	*p = (heap ? (char *) hcalloc(t - tt + 1) :
 	      (char *) zcalloc(t - tt + 1));
 	strncpy(*p, tt, t - tt);