mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-18 00:51:07 +02:00
23097: splitting of $'...' strings in completion
This commit is contained in:
parent
aab842a0c6
commit
94bdf92a06
5 changed files with 77 additions and 33 deletions
|
@ -1,3 +1,8 @@
|
|||
2007-01-08 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* 23097: Src/lex.c, Src/utils.c, Src/zsh.h, Src/Zle/compcore.c:
|
||||
splitting of $'...' strings in completion.
|
||||
|
||||
2007-01-05 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* 23091: Doc/Zsh/compctl.yo, Doc/Zsh/contrib.yo: fixes
|
||||
|
|
|
@ -1432,10 +1432,8 @@ set_comp_sep(void)
|
|||
* 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 @@ set_comp_sep(void)
|
|||
* 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 @@ set_comp_sep(void)
|
|||
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 @@ set_comp_sep(void)
|
|||
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 @@ set_comp_sep(void)
|
|||
dq--;
|
||||
}
|
||||
}
|
||||
if (issq) {
|
||||
if (qttype == QT_SINGLE) {
|
||||
for (p = tokstr, lsq = 0; *p; p++) {
|
||||
if (sq && *p == Snull)
|
||||
sq -= qa;
|
||||
|
@ -1606,6 +1613,8 @@ set_comp_sep(void)
|
|||
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 @@ set_comp_sep(void)
|
|||
*/
|
||||
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 @@ set_comp_sep(void)
|
|||
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);
|
||||
}
|
||||
|
|
22
Src/lex.c
22
Src/lex.c
|
@ -96,18 +96,18 @@ mod_export int addedx;
|
|||
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 parbegin;
|
|||
mod_export int parend;
|
||||
|
||||
/* don't recognize comments */
|
||||
|
||||
|
||||
/**/
|
||||
mod_export int nocomments;
|
||||
|
||||
|
@ -1181,10 +1181,20 @@ gettokstr(int c, int sub)
|
|||
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--;
|
||||
|
|
24
Src/utils.c
24
Src/utils.c
|
@ -3925,7 +3925,6 @@ mb_niceformat(const char *s, FILE *stream, char **outstrp, int heap)
|
|||
ptr = unmetafy(ums, ¨en);
|
||||
|
||||
memset(&mbs, 0, sizeof mbs);
|
||||
mb_metacharinit();
|
||||
while (umlen > 0) {
|
||||
size_t cnt = eol ? MB_INVALID : mbrtowc(&c, ptr, umlen, &mbs);
|
||||
|
||||
|
@ -4577,10 +4576,27 @@ ucs4toutf8(char *dest, unsigned int wval)
|
|||
/*
|
||||
* 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 +4962,9 @@ getkeystring(char *s, int *len, int how, int *misc)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1914,8 +1914,12 @@ struct heap {
|
|||
#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
|
||||
|
||||
/**************************/
|
||||
|
|
Loading…
Reference in a new issue