1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-02 22:11:54 +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 0;
return 'n';
}
} }
#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,127 +4031,153 @@ bslashquote(const char *s, char **e, int instring)
tt = v = buf; tt = v = buf;
u = s; u = s;
for (; *u; u++) { if (instring == 3) {
if (e && *e == u) /*
*e = v, sf = 1; * As we test for printability here we need to be able
if (instring == 3) { * to look for multibyte characters.
int c = *u; */
if (c == Meta) { convchar_t cc;
c = *++u ^ 32; MB_METACHARINIT();
} while (*u) {
c &= 0xff; const char *uend = u + MB_METACHARLENCONV(u, &cc);
if(isprint(c)) {
switch (c) {
case '\\':
case '\'':
*v++ = '\\';
*v++ = c;
break;
default: if (e && !sf && *e <= u) {
if(imeta(c)) { *e = v;
*v++ = Meta; sf = 1;
*v++ = c ^ 32;
}
else {
if (isset(BANGHIST) && c == bangchar) {
*v++ = '\\';
}
*v++ = c;
}
break;
} }
} if (
else { #ifdef MULTIBYTE_SUPPORT
switch (c) { cc != WEOF &&
case '\0': #endif
*v++ = '\\'; MB_ISPRINT(cc)) {
*v++ = '0'; switch (cc) {
if ('0' <= u[1] && u[1] <= '7') { case ZWC('\\'):
*v++ = '0'; case ZWC('\''):
*v++ = '0'; *v++ = '\\';
} break;
break;
case '\007': *v++ = '\\'; *v++ = 'a'; break; default:
case '\b': *v++ = '\\'; *v++ = 'b'; break; if (isset(BANGHIST) && cc == (wchar_t)bangchar)
case '\f': *v++ = '\\'; *v++ = 'f'; break;
case '\n': *v++ = '\\'; *v++ = 'n'; break;
case '\r': *v++ = '\\'; *v++ = 'r'; break;
case '\t': *v++ = '\\'; *v++ = 't'; break;
case '\v': *v++ = '\\'; *v++ = 'v'; break;
default:
*v++ = '\\';
*v++ = '0' + ((c >> 6) & 7);
*v++ = '0' + ((c >> 3) & 7);
*v++ = '0' + (c & 7);
break;
}
}
continue;
}
else if (*u == Tick || *u == Qtick) {
char c = *u++;
*v++ = c;
while (*u && *u != c)
*v++ = *u++;
*v++ = c;
if (!*u)
u--;
continue;
}
else if ((*u == String || *u == Qstring) &&
(u[1] == Inpar || u[1] == Inbrack || u[1] == Inbrace)) {
char c = (u[1] == Inpar ? Outpar : (u[1] == Inbrace ?
Outbrace : Outbrack));
char beg = *u;
int level = 0;
*v++ = *u++;
*v++ = *u++;
while (*u && (*u != c || level)) {
if (*u == beg)
level++;
else if (*u == c)
level--;
*v++ = *u++;
}
if (*u)
*v++ = *u;
else
u--;
continue;
}
else if (ispecial(*u) &&
((*u != '=' && *u != '~') ||
u == s ||
(isset(MAGICEQUALSUBST) && (u[-1] == '=' || u[-1] == ':')) ||
(*u == '~' && isset(EXTENDEDGLOB))) &&
(!instring ||
(isset(BANGHIST) && *u == (char)bangchar && instring != 1) ||
(instring == 2 &&
(*u == '$' || *u == '`' || *u == '\"' || *u == '\\')) ||
(instring == 1 && *u == '\''))) {
if (*u == '\n' || (instring == 1 && *u == '\'')) {
if (unset(RCQUOTES)) {
*v++ = '\'';
if (*u == '\'')
*v++ = '\\'; *v++ = '\\';
*v++ = *u; break;
*v++ = '\''; }
} else if (*u == '\n') while (u < uend)
*v++ = '"', *v++ = '\n', *v++ = '"'; *v++ = *u++;
else } else {
*v++ = '\'', *v++ = '\''; /* Not printable */
continue; for (; u < uend; u++) {
} else /*
*v++ = '\\'; * 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) {
case '\0':
*v++ = '\\';
*v++ = '0';
if ('0' <= u[1] && u[1] <= '7') {
*v++ = '0';
*v++ = '0';
}
break;
case '\007': *v++ = '\\'; *v++ = 'a'; break;
case '\b': *v++ = '\\'; *v++ = 'b'; break;
case '\f': *v++ = '\\'; *v++ = 'f'; break;
case '\n': *v++ = '\\'; *v++ = 'n'; break;
case '\r': *v++ = '\\'; *v++ = 'r'; break;
case '\t': *v++ = '\\'; *v++ = 't'; break;
case '\v': *v++ = '\\'; *v++ = 'v'; break;
default:
*v++ = '\\';
*v++ = '0' + ((c >> 6) & 7);
*v++ = '0' + ((c >> 3) & 7);
*v++ = '0' + (c & 7);
break;
}
}
}
}
}
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++;
*v++ = c;
while (*u && *u != c)
*v++ = *u++;
*v++ = c;
if (!*u)
u--;
continue;
}
else if ((*u == String || *u == Qstring) &&
(u[1] == Inpar || u[1] == Inbrack || u[1] == Inbrace)) {
char c = (u[1] == Inpar ? Outpar : (u[1] == Inbrace ?
Outbrace : Outbrack));
char beg = *u;
int level = 0;
*v++ = *u++;
*v++ = *u++;
while (*u && (*u != c || level)) {
if (*u == beg)
level++;
else if (*u == c)
level--;
*v++ = *u++;
}
if (*u)
*v++ = *u;
else
u--;
continue;
}
else if (ispecial(*u) &&
((*u != '=' && *u != '~') ||
u == s ||
(isset(MAGICEQUALSUBST) &&
(u[-1] == '=' || u[-1] == ':')) ||
(*u == '~' && isset(EXTENDEDGLOB))) &&
(!instring ||
(isset(BANGHIST) && *u == (char)bangchar &&
instring != 1) ||
(instring == 2 &&
(*u == '$' || *u == '`' || *u == '\"' || *u == '\\')) ||
(instring == 1 && *u == '\''))) {
if (*u == '\n' || (instring == 1 && *u == '\'')) {
if (unset(RCQUOTES)) {
*v++ = '\'';
if (*u == '\'')
*v++ = '\\';
*v++ = *u;
*v++ = '\'';
} else if (*u == '\n')
*v++ = '"', *v++ = '\n', *v++ = '"';
else
*v++ = '\'', *v++ = '\'';
continue;
} else
*v++ = '\\';
}
if(*u == Meta)
*v++ = *u++;
*v++ = *u;
} }
if(*u == Meta)
*v++ = *u++;
*v++ = *u;
} }
*v = '\0'; *v = '\0';

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))