From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27015 invoked from network); 8 Jan 2007 21:12:02 -0000 X-Spam-Checker-Version: SpamAssassin 3.1.7 (2006-10-05) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=AWL,BAYES_00, FORGED_RCVD_HELO autolearn=ham version=3.1.7 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 8 Jan 2007 21:12:02 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 74564 invoked from network); 8 Jan 2007 21:11:56 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 8 Jan 2007 21:11:56 -0000 Received: (qmail 5272 invoked by alias); 8 Jan 2007 20:51:59 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 23097 Received: (qmail 5260 invoked from network); 8 Jan 2007 20:51:59 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 8 Jan 2007 20:51:59 -0000 Received: (qmail 56028 invoked from network); 8 Jan 2007 20:51:59 -0000 Received: from mtaout01-winn.ispmail.ntl.com (81.103.221.47) by a.mx.sunsite.dk with SMTP; 8 Jan 2007 20:51:54 -0000 Received: from aamtaout03-winn.ispmail.ntl.com ([81.103.221.35]) by mtaout01-winn.ispmail.ntl.com with ESMTP id <20070108205102.WWV9447.mtaout01-winn.ispmail.ntl.com@aamtaout03-winn.ispmail.ntl.com> for ; Mon, 8 Jan 2007 20:51:02 +0000 Received: from pwslaptop.csr.com ([81.107.46.42]) by aamtaout03-winn.ispmail.ntl.com with ESMTP id <20070108205102.BUCF26699.aamtaout03-winn.ispmail.ntl.com@pwslaptop.csr.com> for ; Mon, 8 Jan 2007 20:51:02 +0000 Received: from pwslaptop.csr.com (pwslaptop.csr.com [127.0.0.1]) by pwslaptop.csr.com (8.13.8/8.13.7) with ESMTP id l08KopIf005736 for ; Mon, 8 Jan 2007 20:50:54 GMT Message-Id: <200701082050.l08KopIf005736@pwslaptop.csr.com> From: Peter Stephenson To: zsh-workers@sunsite.dk (Zsh hackers list) Subject: PATCH: more $'...' completion Date: Mon, 08 Jan 2007 20:50:51 +0000 This fixes completion of filenames in cases like: sh -c $'ls "quoted filename" "and another" which was still thoroughly broken after my previous patch. This is still nowhere near the end of the $'-completion saga, but once again I think it's better than it was before. Index: Src/lex.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/lex.c,v retrieving revision 1.35 diff -u -r1.35 lex.c --- Src/lex.c 13 Dec 2006 18:49:07 -0000 1.35 +++ Src/lex.c 8 Jan 2007 20:48:32 -0000 @@ -96,18 +96,18 @@ mod_export int wb, we; /* 1 if aliases should not be expanded */ - + /**/ mod_export int noaliases; /* we are parsing a line sent to use by the editor */ - + /**/ mod_export int zleparse; - + /**/ mod_export int wordbeg; - + /**/ mod_export int parbegin; @@ -115,7 +115,7 @@ mod_export int parend; /* don't recognize comments */ - + /**/ mod_export int nocomments; @@ -1181,10 +1181,20 @@ STOPHIST while ((c = hgetc()) != '\'' && !lexstop) { if (strquote && c == '\\') { - add(c); c = hgetc(); if (lexstop) break; + /* + * Mostly we don't need to do anything special + * with escape backslashes or closing quotes + * inside $'...'; however in completion we + * need to be able to strip multiple backslashes + * neatly. + */ + if (c == '\\' || c == '\'') + add(Bnull); + else + add('\\'); } else if (!sub && isset(CSHJUNKIEQUOTES) && c == '\n') { if (bptr[-1] == '\\') bptr--, len--; Index: Src/utils.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/utils.c,v retrieving revision 1.148 diff -u -r1.148 utils.c --- Src/utils.c 19 Dec 2006 13:01:43 -0000 1.148 +++ Src/utils.c 8 Jan 2007 20:48:33 -0000 @@ -4577,10 +4577,27 @@ /* * Decode a key string, turning it into the literal characters. * The value returned is a newly allocated string from the heap. - * The length is (usually) returned in *len. + * + * The length is returned in *len. This is usually the length of + * the final unmetafied string. The exception is the case of + * a complete GETKEY_DOLLAR_QUOTE conversion where *len is the + * length of the input string which has been used (up to and including + * the terminating single quote); as the final string is metafied and + * NULL-terminated its length is not required. If both GETKEY_DOLLAR_QUOTE + * and GETKEY_UPDATE_OFFSET are present in "how", the string is not + * expected to be terminated (this is used in completion to parse + * a partial $'...'-quoted string) and the length passed back is + * that of the converted string. Note in both cases that this is a length + * in bytes (i.e. the same as given by a raw pointer difference), not + * characters, which may occupy multiple bytes. + * * how is a set of bits from the GETKEY_ values defined in zsh.h; * not all combinations of bits are useful. Callers will typically * use one of the GETKEYS_ values which define sets of bits. + * Note, for example that: + * - GETKEY_SINGLE_CHAR must not be combined with GETKEY_DOLLAR_QUOTE. + * - GETKEY_UPDATE_OFFSET is only allowed if GETKEY_DOLLAR_QUOTE is + * also present. * * The return value is unmetafied unless GETKEY_DOLLAR_QUOTE is * in use. @@ -4946,9 +4963,9 @@ if (how & GETKEY_DOLLAR_QUOTE) *tdest = '\0'; if (how & GETKEY_SINGLE_CHAR) - *misc = 0; + *misc = 0; else - *len = t - buf; + *len = ((how & GETKEY_DOLLAR_QUOTE) ? tdest : t) - buf; return buf; } Index: Src/zsh.h =================================================================== RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v retrieving revision 1.105 diff -u -r1.105 zsh.h --- Src/zsh.h 4 Jan 2007 17:24:03 -0000 1.105 +++ Src/zsh.h 8 Jan 2007 20:48:35 -0000 @@ -1914,8 +1914,12 @@ #define STRINGIFY(x) STRINGIFY_LITERAL(x) #define ERRMSG(x) (__FILE__ ":" STRINGIFY(__LINE__) ": " x) # define DPUTS(X,Y) if (!(X)) {;} else dputs(ERRMSG(Y)) +# define DPUTS1(X,Y,Z1) if (!(X)) {;} else dputs(ERRMSG(Y), Z1) +# define DPUTS2(X,Y,Z1,Z2) if (!(X)) {;} else dputs(ERRMSG(Y), Z1, Z2) #else # define DPUTS(X,Y) +# define DPUTS1(X,Y,Z1) +# define DPUTS2(X,Y,Z1,Z2) #endif /**************************/ Index: Src/Zle/compcore.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/compcore.c,v retrieving revision 1.88 diff -u -r1.88 compcore.c --- Src/Zle/compcore.c 8 Dec 2006 18:52:05 -0000 1.88 +++ Src/Zle/compcore.c 8 Jan 2007 20:48:35 -0000 @@ -1432,10 +1432,8 @@ * set, which isn't necessarily correct if the quotes were typed by * the user). * osq: c.f. odq, taking account of Snull's and embeded "'"'s. - * issq: flag that current quoting is single quotes; I assume that - * civilization would end if we used a consistent way of - * flagging the different types of quotes, or something. - * lsq: when quoting is single quotes (issq), counts the offset + * qttype: type of quotes using standard QT_* definitions. + * lsq: when quoting is single quotes (QT_SINGLE), counts the offset * adjustment needed in the word being examined in the lexer loop. * sqq: the value of lsq for the current completion word. * qa: not, unfortunately, a question and answer session with the @@ -1443,7 +1441,7 @@ * when stripping single quotes: 1 for RCQUOTES, 3 otherwise * (because we leave a "'" in the final string). */ - int dq = 0, odq, sq = 0, osq, issq = 0, sqq = 0, lsq = 0, qa = 0; + int dq = 0, odq, sq = 0, osq, qttype, sqq = 0, lsq = 0, qa = 0; /* dolq: like sq and dq but for dollars quoting. */ int dolq = 0; /* remember some global variable values (except lp is local) */ @@ -1479,26 +1477,25 @@ addedx = 1; noerrs = 1; lexsave(); - tmp = (char *) zhalloc(tl = 3 + strlen(s)); + /* + * tl is the length of the temporary string including + * the space at the start and the x at the cursor position, + * but not the NULL byte. + */ + tl = strlen(s) + 2; + tmp = (char *) zhalloc(tl + 1); tmp[0] = ' '; memcpy(tmp + 1, s, noffs); tmp[(scs = zlemetacs = 1 + noffs)] = 'x'; strcpy(tmp + 2 + noffs, s + noffs); - switch (*compqstack) { - case QT_NONE: -#ifdef DEBUG - dputs("BUG: head of compqstack is NULL"); -#endif - break; - + switch ((qttype = *compqstack)) { case QT_BACKSLASH: remq = 1; tmp = rembslash(tmp); break; case QT_SINGLE: - issq = 1; if (isset(RCQUOTES)) qa = 1; else @@ -1531,22 +1528,32 @@ break; case QT_DOLLARS: - sl = strlen(tmp); j = zlemetacs; - tmp = getkeystring(tmp, &tl, + tmp = getkeystring(tmp, &sl, GETKEY_DOLLAR_QUOTE|GETKEY_UPDATE_OFFSET, &zlemetacs); - /* The number of characters we removed because of $' quoting */ - dolq = sl - tl; + /* The number of bytes we removed because of $' quoting */ + dolq = tl - sl; /* Offset into the word is modified, too... */ css += zlemetacs - j; break; + + case QT_NONE: + default: /* to silence compiler warnings */ +#ifdef DEBUG + dputs("BUG: head of compqstack is NULL"); +#endif + break; + } odq = dq; osq = sq; inpush(dupstrspace(tmp), 0, NULL); zlemetaline = tmp; - zlemetall = tl - 1; + /* + * Length of temporary string, calculated above. + */ + zlemetall = tl; strinbeg(0); noaliases = 1; do { @@ -1582,7 +1589,7 @@ dq--; } } - if (issq) { + if (qttype == QT_SINGLE) { for (p = tokstr, lsq = 0; *p; p++) { if (sq && *p == Snull) sq -= qa; @@ -1606,6 +1613,8 @@ swe = we - 1 - dq - sq - dolq; sqq = lsq; soffs = zlemetacs - swb - css; + DPUTS2(p[soffs] != 'x', "expecting 'x' at offset %d of \"%s\"", + soffs, p); chuck(p + soffs); ns = dupstring(p); } @@ -1736,7 +1745,7 @@ */ sav = s[(i = swb - 1 - sqq + dq)]; s[i] = '\0'; - qp = (issq ? dupstring(s) : rembslash(s)); + qp = (qttype == QT_SINGLE) ? dupstring(s) : rembslash(s); s[i] = sav; if (swe < swb) swe = swb; @@ -1747,11 +1756,11 @@ if ((int)strlen(ns) > swe - swb + 1) ns[swe - swb + 1] = '\0'; } - qs = (issq ? dupstring(s + swe) : rembslash(s + swe)); + qs = (qttype == QT_SINGLE) ? dupstring(s + swe) : rembslash(s + swe); sl = strlen(ns); if (soffs > sl) soffs = sl; - if (issq) { + if (qttype == QT_SINGLE) { remsquote(qp); remsquote(qs); } -- Peter Stephenson Web page now at http://homepage.ntlworld.com/p.w.stephenson/