1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-02 10:01:11 +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));
qup = ((l + columns - 1) / columns) - 1;
fflush(shout);
if (getzlequery(1) != 'y') {
if (!getzlequery()) {
if (clearflag) {
putc('\r', shout);
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_idigit idigit
#define ZC_iident iident
#define ZC_ilower ilower
#define ZC_ilower islower
#define ZC_inblank inblank
#define ZC_iupper iupper
#define ZC_iupper isupper
#define ZC_iword iword
#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));
qup = ((l + columns - 1) / columns) - 1;
fflush(shout);
if (getzlequery(1) != 'y') {
if (!getzlequery()) {
if (clearflag) {
putc('\r', shout);
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
* is assumed to have been printed already, and the cursor is left
* immediately after the response echoed. (Might cause a problem if
* this takes it onto the next line.) If yesno is non-zero: <Tab> is
* interpreted as 'y'; any other control character is interpreted as
* 'n'. If there are any characters in the buffer, this is taken as a
* 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.
* Query the user, and return 1 for yes, 0 for no. The question is assumed to
* have been printed already, and the cursor is left immediately after the
* response echoed. (Might cause a problem if this takes it onto the next
* line.) <Tab> is interpreted as 'y'; any other control character is
* interpreted as 'n'. If there are any characters in the buffer, this is
* taken as a negative response, and no characters are read. Case is folded.
*/
/**/
mod_export int
getzlequery(int yesno)
getzlequery(void)
{
ZLE_INT_T c;
#ifdef FIONREAD
int val;
if (yesno) {
/* check for typeahead, which is treated as a negative response */
ioctl(SHTTY, FIONREAD, (char *)&val);
if (val) {
putc('n', shout);
return 'n';
}
/* check for typeahead, which is treated as a negative response */
ioctl(SHTTY, FIONREAD, (char *)&val);
if (val) {
putc('n', shout);
return 0;
}
#endif
/* get a character from the tty and interpret it */
c = getfullchar(0);
if (yesno) {
if (c == ZWC('\t'))
c = ZWC('y');
else if (ZC_icntrl(c) || c == ZLEEOF)
c = ZWC('n');
else
c = ZC_tolower(c);
}
if (c == ZWC('\t'))
c = ZWC('y');
else if (ZC_icntrl(c) || c == ZLEEOF)
c = ZWC('n');
else
c = ZC_tolower(c);
/* echo response and return */
if (c != ZWC('\n'))
zwcputc(c);
return c;
return c == ZWC('y');
}
/* Format a string, keybinding style. */

View file

@ -2835,7 +2835,7 @@ wcsitype(wchar_t c, int itype)
if (len == 0) {
/* NULL is special */
return zistype(0, itype);
} else if (len == 1 && iascii(*outstr)) {
} else if (len == 1 && isascii(*outstr)) {
return zistype(*outstr, itype);
} else {
switch (itype) {
@ -2897,7 +2897,7 @@ itype_end(const char *ptr, int itype, int once)
/* in this case non-ASCII characters can't match */
if (chr > 127 || !zistype(chr,itype))
break;
} else if (len == 1 && iascii(*ptr)) {
} else if (len == 1 && isascii(*ptr)) {
/* ASCII: can't be metafied, use standard test */
if (!zistype(*ptr,itype))
break;
@ -4017,7 +4017,7 @@ hasspecial(char const *s)
* 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, *
* 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. */
/**/
@ -4031,127 +4031,153 @@ bslashquote(const char *s, char **e, int instring)
tt = v = buf;
u = s;
for (; *u; u++) {
if (e && *e == u)
*e = v, sf = 1;
if (instring == 3) {
int c = *u;
if (c == Meta) {
c = *++u ^ 32;
}
c &= 0xff;
if(isprint(c)) {
switch (c) {
case '\\':
case '\'':
*v++ = '\\';
*v++ = c;
break;
if (instring == 3) {
/*
* As we test for printability here we need to be able
* to look for multibyte characters.
*/
convchar_t cc;
MB_METACHARINIT();
while (*u) {
const char *uend = u + MB_METACHARLENCONV(u, &cc);
default:
if(imeta(c)) {
*v++ = Meta;
*v++ = c ^ 32;
}
else {
if (isset(BANGHIST) && c == bangchar) {
*v++ = '\\';
}
*v++ = c;
}
break;
if (e && !sf && *e <= u) {
*e = v;
sf = 1;
}
}
else {
switch (c) {
case '\0':
*v++ = '\\';
*v++ = '0';
if ('0' <= u[1] && u[1] <= '7') {
*v++ = '0';
*v++ = '0';
}
break;
if (
#ifdef MULTIBYTE_SUPPORT
cc != WEOF &&
#endif
MB_ISPRINT(cc)) {
switch (cc) {
case ZWC('\\'):
case ZWC('\''):
*v++ = '\\';
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;
}
}
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 == '\'')
default:
if (isset(BANGHIST) && cc == (wchar_t)bangchar)
*v++ = '\\';
*v++ = *u;
*v++ = '\'';
} else if (*u == '\n')
*v++ = '"', *v++ = '\n', *v++ = '"';
else
*v++ = '\'', *v++ = '\'';
continue;
} else
*v++ = '\\';
break;
}
while (u < uend)
*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) {
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';

View file

@ -61,11 +61,8 @@
#ifdef MULTIBYTE_SUPPORT
#define MB_ZISTYPE(X,Y) wcsitype((X),(Y))
#define MB_ISPRINT(X) iswprint(X)
#else
#define MB_ZISTYPE(X,Y) zistype((X),(Y))
#define MB_ISPRINT(X) isprint(X)
#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))