summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2006-08-01 21:28:04 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2006-08-01 21:28:04 +0000
commitbb912594b2325334a603893e90e8d9aa7cc534ca (patch)
treebbbd081b8b2191081b260056ce17a4876b74227a
parent7d77bc95b2ba7276cf430a989e9b4000c72ba765 (diff)
downloadzsh-bb912594b2325334a603893e90e8d9aa7cc534ca.tar.gz
zsh-bb912594b2325334a603893e90e8d9aa7cc534ca.zip
22575: multibyte fixes for bslashquote(), getzlequery()
-rw-r--r--Src/Zle/compresult.c2
-rw-r--r--Src/Zle/zle.h4
-rw-r--r--Src/Zle/zle_tricky.c2
-rw-r--r--Src/Zle/zle_utils.c46
-rw-r--r--Src/utils.c250
-rw-r--r--Src/ztype.h7
6 files changed, 163 insertions, 148 deletions
diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c
index 2aa382cb5..887720a2f 100644
--- a/Src/Zle/compresult.c
+++ b/Src/Zle/compresult.c
@@ -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);
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h
index 69c73f4cf..f56960734 100644
--- a/Src/Zle/zle.h
+++ b/Src/Zle/zle.h
@@ -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
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index 28857b03e..fb0ebad2a 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -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);
diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index 2c92c955e..cce162fa0 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -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. */
diff --git a/Src/utils.c b/Src/utils.c
index 0574431d0..a81c4ed04 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -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);
+
+ if (e && !sf && *e <= u) {
+ *e = v;
+ sf = 1;
+ }
+ if (
+#ifdef MULTIBYTE_SUPPORT
+ cc != WEOF &&
+#endif
+ MB_ISPRINT(cc)) {
+ switch (cc) {
+ case ZWC('\\'):
+ case ZWC('\''):
+ *v++ = '\\';
+ break;
- default:
- if(imeta(c)) {
- *v++ = Meta;
- *v++ = c ^ 32;
- }
- else {
- if (isset(BANGHIST) && c == bangchar) {
- *v++ = '\\';
+ default:
+ if (isset(BANGHIST) && cc == (wchar_t)bangchar)
+ *v++ = '\\';
+ break;
}
- *v++ = c;
- }
- break;
- }
- }
- else {
- 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;
+ 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;
- default:
- *v++ = '\\';
- *v++ = '0' + ((c >> 6) & 7);
- *v++ = '0' + ((c >> 3) & 7);
- *v++ = '0' + (c & 7);
- 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++;
+ }
+ 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++ = 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++ = '\\';
+ while (*u && (*u != c || level)) {
+ if (*u == beg)
+ level++;
+ else if (*u == c)
+ level--;
+ *v++ = *u++;
+ }
+ if (*u)
*v++ = *u;
- *v++ = '\'';
- } else if (*u == '\n')
- *v++ = '"', *v++ = '\n', *v++ = '"';
else
- *v++ = '\'', *v++ = '\'';
+ u--;
continue;
- } else
- *v++ = '\\';
+ }
+ 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';
diff --git a/Src/ztype.h b/Src/ztype.h
index 7aa56b073..27402fba4 100644
--- a/Src/ztype.h
+++ b/Src/ztype.h
@@ -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))