From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19877 invoked from network); 3 May 2000 12:20:52 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 3 May 2000 12:20:52 -0000 Received: (qmail 4865 invoked by alias); 3 May 2000 12:20:45 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 11113 Received: (qmail 4721 invoked from network); 3 May 2000 12:20:35 -0000 Date: Wed, 3 May 2000 14:20:33 +0200 (MET DST) Message-Id: <200005031220.OAA00376@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk In-reply-to: "Bart Schaefer"'s message of Wed, 3 May 2000 10:55:24 +0000 Subject: 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@informatik.hu-berlin.de