Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: Re: Shell-word splitting (was: Re: Proposed _history completer)



Bart Schaefer wrote:

> On May 3,  9:16am, Sven Wischnowsky wrote:
> } Subject: Re: Shell-word splitting (was: Re: Proposed _history completer)
> }
> } > Bart Schaefer wrote:
> } > 
> } > > Hrm, again; maybe the way to do this is with a modifier rather than a
> } > > flag.  :S is available, and it'd be kinda fun to be able to apply this
> } > > to history as well as to parameters.  Or maybe it wouldn't ...
> } 
> } I should have thought more about this yesterday...
> 
> So should I, apparently.
> 
> } Erm, the history modifier code only ever works on single words
> 
> Right.  Ah, well.  I still think a modifier might be less confusing than
> a flag, particularly if we have to use a character like `=' for the flag,
> but ...

I still agree that :S would be nice, but even in parameter expansions
do the modifiers work only per-element. In the code, too, and that's
what held me back. But enough people start shouting at me, I'll modify
modify() to allow it to return an array and so on...


Anyway, here's the patch, implementing the (z) flag which makes the
parameter value be zplitted uzing zsh zhell zyntax. This works a bit
like the (s) flag (or the `=' before the name) and is done at the very
end, so to access words resulting from the splitting:

  % foo='it says: "hello world"'
  % echo ${${(z)foo}[3]}
  "hello world"

We could probably move the code that does the splitting up somewhere
but it would then behave more differently from (s) and = than it does
now, so that would probably be a bad idea.


Most of the hunks have to do with bufferwords() which now can get the
string to split as an argument.

Bye
 Sven

Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.7
diff -u -r1.7 expn.yo
--- Doc/Zsh/expn.yo	2000/04/17 10:57:48	1.7
+++ Doc/Zsh/expn.yo	2000/05/03 12:18:48
@@ -676,6 +676,10 @@
 Split the result of the expansion to lines. This is a shorthand
 for `tt(ps:\n:)'.
 )
+item(tt(z))(
+Split the result of the expansion into words using shell parsing to
+find the words, i.e. taking into account any quoting in the value.
+)
 item(tt(t))(
 Use a string describing the type of the parameter where the value
 of the parameter would usually appear. This string consists of keywords
Index: Src/hist.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/hist.c,v
retrieving revision 1.2
diff -u -r1.2 hist.c
--- Src/hist.c	2000/04/12 08:24:16	1.2
+++ Src/hist.c	2000/05/03 12:18:48
@@ -2037,17 +2037,28 @@
 
 /**/
 mod_export LinkList
-bufferwords(int *index)
+bufferwords(LinkList list, char *buf, int *index)
 {
-    LinkList list = newlinklist();
     int num = 0, cur = -1, got = 0, ne = noerrs, ocs = cs;
     char *p;
 
+    if (!list)
+	list = newlinklist();
+
     zleparse = 1;
     addedx = 0;
     noerrs = 1;
     lexsave();
-    if (!isfirstln && chline) {
+    if (buf) {
+	int l = strlen(buf);
+
+	p = (char *) zhalloc(l + 2);
+	memcpy(p, buf, l);
+	p[l] = ' ';
+	p[l + 1] = '\0';
+	inpush(p, 0, NULL);
+	cs = 0;
+    } else if (!isfirstln && chline) {
 	p = (char *) zhalloc(hptr - chline + ll + 2);
 	memcpy(p, chline, hptr - chline);
 	memcpy(p + (hptr - chline), line, ll);
@@ -2074,6 +2085,17 @@
 	    untokenize((p = dupstring(tokstr)));
 	    addlinknode(list, p);
 	    num++;
+	} else if (buf) {
+	    if (IS_REDIROP(tok) && tokfd >= 0) {
+		char b[20];
+
+		sprintf(b, "%d%s", tokfd, tokstrings[tok]);
+		addlinknode(list, dupstring(b));
+		num++;
+	    } else if (tok != NEWLIN) {
+		addlinknode(list, dupstring(tokstrings[tok]));
+		num++;
+	    }
 	}
 	if (!got && !zleparse) {
 	    got = 1;
Index: Src/subst.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.2
diff -u -r1.2 subst.c
--- Src/subst.c	2000/04/06 18:44:01	1.2
+++ Src/subst.c	2000/05/03 12:18:49
@@ -750,6 +750,7 @@
     int casmod = 0;
     int quotemod = 0, quotetype = 0, quoteerr = 0;
     int visiblemod = 0;
+    int shsplit = 0;
     char *sep = NULL, *spsep = NULL;
     char *premul = NULL, *postmul = NULL, *preone = NULL, *postone = NULL;
     char *replstr = NULL;	/* replacement string for /orig/repl */
@@ -971,6 +972,10 @@
 		    presc++;
 		    break;
 
+		case 'z':
+		    shsplit = 1;
+		    break;
+
 		default:
 		  flagerr:
 		    zerr("error in flags", NULL, 0);
@@ -1747,6 +1752,34 @@
 		val = dupstring(val), copied = 1;
 	    val = nicedupstring(val);
 	}
+    }
+    if (shsplit) {
+	LinkList list = NULL;
+
+	if (isarr) {
+	    char **ap;
+	    for (ap = aval; *ap; ap++)
+		list = bufferwords(list, *ap, NULL);
+	    isarr = 0;
+	} else
+	    list = bufferwords(NULL, val, NULL);
+
+	if (!firstnode(list))
+	    val = dupstring("");
+	else if (!nextnode(firstnode(list)))
+	    val = getdata(firstnode(list));
+	else {
+	    char **ap;
+	    LinkNode node;
+
+	    aval = ap = (char **) zhalloc((countlinknodes(list) + 1) *
+					  sizeof(char *));
+	    for (node = firstnode(list); node; incnode(node))
+		*ap++ = (char *) getdata(node);
+	    *ap = NULL;
+	    mult_isarr = isarr = 2;
+	}
+	copied = 1;
     }
     if (isarr) {
 	char *x;
Index: Src/Modules/parameter.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/parameter.c,v
retrieving revision 1.4
diff -u -r1.4 parameter.c
--- Src/Modules/parameter.c	2000/04/12 08:24:16	1.4
+++ Src/Modules/parameter.c	2000/05/03 12:18:49
@@ -1098,7 +1098,7 @@
     int i = addhistnum(curhist, -1, HIST_FOREIGN), iw;
     Histent he = quietgethistent(i, GETHIST_UPWARD);
 
-    ll = bufferwords(NULL);
+    ll = bufferwords(NULL, NULL, NULL);
     for (n = firstnode(ll); n; incnode(n))
 	pushnode(l, getdata(n));
 
Index: Src/Zle/zle_misc.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_misc.c,v
retrieving revision 1.2
diff -u -r1.2 zle_misc.c
--- Src/Zle/zle_misc.c	2000/04/12 08:24:16	1.2
+++ Src/Zle/zle_misc.c	2000/05/03 12:18:50
@@ -549,7 +549,7 @@
     int i;
     char *p = NULL;
 
-    l = bufferwords(&i);
+    l = bufferwords(NULL, NULL, &i);
 
     for (n = firstnode(l); n; incnode(n))
 	if (!i--) {

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author