1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-11 13:01:28 +02:00

22575: multibyte fixes for bslashquote(), getzlequery()

This commit is contained in:
Peter Stephenson 2006-08-01 21:28:04 +00:00
parent 7d77bc95b2
commit bb912594b2
6 changed files with 170 additions and 155 deletions

View file

@ -1861,7 +1861,7 @@ asklist(void)
listdat.nlines)); listdat.nlines));
qup = ((l + columns - 1) / columns) - 1; qup = ((l + columns - 1) / columns) - 1;
fflush(shout); fflush(shout);
if (getzlequery(1) != 'y') { if (!getzlequery()) {
if (clearflag) { if (clearflag) {
putc('\r', shout); putc('\r', shout);
tcmultout(TCUP, TCMULTUP, qup); tcmultout(TCUP, TCMULTUP, qup);

View file

@ -125,9 +125,9 @@ static inline int ZS_strncmp(ZLE_STRING_T s1, ZLE_STRING_T s2, size_t l)
#define ZC_icntrl icntrl #define ZC_icntrl icntrl
#define ZC_idigit idigit #define ZC_idigit idigit
#define ZC_iident iident #define ZC_iident iident
#define ZC_ilower ilower #define ZC_ilower islower
#define ZC_inblank inblank #define ZC_inblank inblank
#define ZC_iupper iupper #define ZC_iupper isupper
#define ZC_iword iword #define ZC_iword iword
#define ZC_tolower tulower #define ZC_tolower tulower

View file

@ -2298,7 +2298,7 @@ listlist(LinkList l)
fprintf(shout, "zsh: do you wish to see all %d lines? ", nlines)); fprintf(shout, "zsh: do you wish to see all %d lines? ", nlines));
qup = ((l + columns - 1) / columns) - 1; qup = ((l + columns - 1) / columns) - 1;
fflush(shout); fflush(shout);
if (getzlequery(1) != 'y') { if (!getzlequery()) {
if (clearflag) { if (clearflag) {
putc('\r', shout); putc('\r', shout);
tcmultout(TCUP, TCMULTUP, qup); tcmultout(TCUP, TCMULTUP, qup);

View file

@ -653,50 +653,42 @@ zlinefind(ZLE_STRING_T haystack, int haylen, int pos,
} }
/* /*
* Query the user, and return a single character response. The question * Query the user, and return 1 for yes, 0 for no. The question is assumed to
* is assumed to have been printed already, and the cursor is left * have been printed already, and the cursor is left immediately after the
* immediately after the response echoed. (Might cause a problem if * response echoed. (Might cause a problem if this takes it onto the next
* this takes it onto the next line.) If yesno is non-zero: <Tab> is * line.) <Tab> is interpreted as 'y'; any other control character is
* interpreted as 'y'; any other control character is interpreted as * interpreted as 'n'. If there are any characters in the buffer, this is
* 'n'. If there are any characters in the buffer, this is taken as a * taken as a negative response, and no characters are read. Case is folded.
* negative response, and no characters are read. Case is folded.
*
* TBD: this may need extending to return a wchar_t or possibly
* a wint_t.
*/ */
/**/ /**/
mod_export int mod_export int
getzlequery(int yesno) getzlequery(void)
{ {
ZLE_INT_T c; ZLE_INT_T c;
#ifdef FIONREAD #ifdef FIONREAD
int val; int val;
if (yesno) {
/* check for typeahead, which is treated as a negative response */ /* check for typeahead, which is treated as a negative response */
ioctl(SHTTY, FIONREAD, (char *)&val); ioctl(SHTTY, FIONREAD, (char *)&val);
if (val) { if (val) {
putc('n', shout); putc('n', shout);
return 'n'; return 0;
}
} }
#endif #endif
/* get a character from the tty and interpret it */ /* get a character from the tty and interpret it */
c = getfullchar(0); c = getfullchar(0);
if (yesno) {
if (c == ZWC('\t')) if (c == ZWC('\t'))
c = ZWC('y'); c = ZWC('y');
else if (ZC_icntrl(c) || c == ZLEEOF) else if (ZC_icntrl(c) || c == ZLEEOF)
c = ZWC('n'); c = ZWC('n');
else else
c = ZC_tolower(c); c = ZC_tolower(c);
}
/* echo response and return */ /* echo response and return */
if (c != ZWC('\n')) if (c != ZWC('\n'))
zwcputc(c); zwcputc(c);
return c; return c == ZWC('y');
} }
/* Format a string, keybinding style. */ /* Format a string, keybinding style. */

View file

@ -2835,7 +2835,7 @@ wcsitype(wchar_t c, int itype)
if (len == 0) { if (len == 0) {
/* NULL is special */ /* NULL is special */
return zistype(0, itype); return zistype(0, itype);
} else if (len == 1 && iascii(*outstr)) { } else if (len == 1 && isascii(*outstr)) {
return zistype(*outstr, itype); return zistype(*outstr, itype);
} else { } else {
switch (itype) { switch (itype) {
@ -2897,7 +2897,7 @@ itype_end(const char *ptr, int itype, int once)
/* in this case non-ASCII characters can't match */ /* in this case non-ASCII characters can't match */
if (chr > 127 || !zistype(chr,itype)) if (chr > 127 || !zistype(chr,itype))
break; break;
} else if (len == 1 && iascii(*ptr)) { } else if (len == 1 && isascii(*ptr)) {
/* ASCII: can't be metafied, use standard test */ /* ASCII: can't be metafied, use standard test */
if (!zistype(*ptr,itype)) if (!zistype(*ptr,itype))
break; break;
@ -4017,7 +4017,7 @@ hasspecial(char const *s)
* The last argument should be zero if this is to be used outside a string, * * The last argument should be zero if this is to be used outside a string, *
* one if it is to be quoted for the inside of a single quoted string, * * one if it is to be quoted for the inside of a single quoted string, *
* two if it is for the inside of a double quoted string, and * * two if it is for the inside of a double quoted string, and *
* three if it is for the inside of a posix quoted string. * * three if it is for the inside of a $'...' quoted string. *
* The string may be metafied and contain tokens. */ * The string may be metafied and contain tokens. */
/**/ /**/
@ -4031,38 +4031,51 @@ bslashquote(const char *s, char **e, int instring)
tt = v = buf; tt = v = buf;
u = s; u = s;
for (; *u; u++) {
if (e && *e == u)
*e = v, sf = 1;
if (instring == 3) { if (instring == 3) {
int c = *u; /*
if (c == Meta) { * As we test for printability here we need to be able
c = *++u ^ 32; * to look for multibyte characters.
*/
convchar_t cc;
MB_METACHARINIT();
while (*u) {
const char *uend = u + MB_METACHARLENCONV(u, &cc);
if (e && !sf && *e <= u) {
*e = v;
sf = 1;
} }
c &= 0xff; if (
if(isprint(c)) { #ifdef MULTIBYTE_SUPPORT
switch (c) { cc != WEOF &&
case '\\': #endif
case '\'': MB_ISPRINT(cc)) {
switch (cc) {
case ZWC('\\'):
case ZWC('\''):
*v++ = '\\'; *v++ = '\\';
*v++ = c;
break; break;
default: default:
if(imeta(c)) { if (isset(BANGHIST) && cc == (wchar_t)bangchar)
*v++ = Meta;
*v++ = c ^ 32;
}
else {
if (isset(BANGHIST) && c == bangchar) {
*v++ = '\\'; *v++ = '\\';
}
*v++ = c;
}
break; break;
} }
} while (u < uend)
else { *v++ = *u++;
} else {
/* Not printable */
for (; u < uend; u++) {
/*
* Just do this byte by byte; there's no great
* advantage in being clever with multibyte
* characters if we don't think they're printable.
*/
int c;
if (*u == Meta)
c = STOUC(*++u ^ 32);
else
c = STOUC(*u);
switch (c) { switch (c) {
case '\0': case '\0':
*v++ = '\\'; *v++ = '\\';
@ -4089,9 +4102,19 @@ bslashquote(const char *s, char **e, int instring)
break; break;
} }
} }
continue;
} }
else if (*u == Tick || *u == Qtick) { }
}
else
{
/*
* Here the only special characters are syntactic, so
* we can go through bytewise.
*/
for (; *u; u++) {
if (e && *e == u)
*e = v, sf = 1;
if (*u == Tick || *u == Qtick) {
char c = *u++; char c = *u++;
*v++ = c; *v++ = c;
@ -4127,10 +4150,12 @@ bslashquote(const char *s, char **e, int instring)
else if (ispecial(*u) && else if (ispecial(*u) &&
((*u != '=' && *u != '~') || ((*u != '=' && *u != '~') ||
u == s || u == s ||
(isset(MAGICEQUALSUBST) && (u[-1] == '=' || u[-1] == ':')) || (isset(MAGICEQUALSUBST) &&
(u[-1] == '=' || u[-1] == ':')) ||
(*u == '~' && isset(EXTENDEDGLOB))) && (*u == '~' && isset(EXTENDEDGLOB))) &&
(!instring || (!instring ||
(isset(BANGHIST) && *u == (char)bangchar && instring != 1) || (isset(BANGHIST) && *u == (char)bangchar &&
instring != 1) ||
(instring == 2 && (instring == 2 &&
(*u == '$' || *u == '`' || *u == '\"' || *u == '\\')) || (*u == '$' || *u == '`' || *u == '\"' || *u == '\\')) ||
(instring == 1 && *u == '\''))) { (instring == 1 && *u == '\''))) {
@ -4153,6 +4178,7 @@ bslashquote(const char *s, char **e, int instring)
*v++ = *u++; *v++ = *u++;
*v++ = *u; *v++ = *u;
} }
}
*v = '\0'; *v = '\0';
if (e && *e == u) if (e && *e == u)

View file

@ -61,11 +61,8 @@
#ifdef MULTIBYTE_SUPPORT #ifdef MULTIBYTE_SUPPORT
#define MB_ZISTYPE(X,Y) wcsitype((X),(Y)) #define MB_ZISTYPE(X,Y) wcsitype((X),(Y))
#define MB_ISPRINT(X) iswprint(X)
#else #else
#define MB_ZISTYPE(X,Y) zistype((X),(Y)) #define MB_ZISTYPE(X,Y) zistype((X),(Y))
#define MB_ISPRINT(X) isprint(X)
#endif #endif
#define iascii(X) isascii(STOUC(X))
#define ilower(X) islower(STOUC(X))
#define iprint(X) isprint(STOUC(X))
#define iupper(X) isupper(STOUC(X))