mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-16 22:10:54 +01:00
assume width 1 for control characters;
don't crash if width of repeated padding string is 0
This commit is contained in:
parent
a82ac460c2
commit
bb3628e898
6 changed files with 134 additions and 98 deletions
|
@ -1,3 +1,9 @@
|
|||
2006-09-15 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 22710: README, Doc/Zsh/expn.yo, Src/prompt.c, Src/subst.c,
|
||||
Src/utils.c: assume width 1 for control characters; don't
|
||||
crash if width of repeated padding string is 0.
|
||||
|
||||
2006-09-14 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 22692: Doc/Zsh/expn.yo: additional notes on a couple of
|
||||
|
|
|
@ -871,7 +871,9 @@ var(string1) is used to produce any remaining padding.
|
|||
|
||||
If the tt(MULTIBYTE) option is in effect, screen character widths will
|
||||
be used for the calculation of padding; otherwise individual bytes are
|
||||
treat as occupying one unit of width.
|
||||
treat as occupying one unit of width. Control characters are always
|
||||
assumed to be one unit wide; this allows the mechanism to be used
|
||||
for generating repetitions of control characters.
|
||||
)
|
||||
item(tt(r:)var(expr)tt(::)var(string1)tt(::)var(string2)tt(:))(
|
||||
As tt(l), but pad the words on the right and insert var(string2)
|
||||
|
|
7
README
7
README
|
@ -49,6 +49,13 @@ The variable HOME is no longer set by the shell if zsh is emulating any
|
|||
other shell at startup; it must be present in the environment or set
|
||||
subsequently by the user. It is valid for the variable to be unset.
|
||||
|
||||
The MULTIBYTE option is on by default where it is available; this
|
||||
causes many operations to recognise characters as in the current locale.
|
||||
Older versions of the shell always assumed a character was one byte.
|
||||
In some places the width of the character will be used; this is transparent
|
||||
when used for calculations of screen position, but also occurs, for
|
||||
example, in calculations of padding width.
|
||||
|
||||
Zsh has previously been lax about whether it allows octets with the
|
||||
top bit set to be part of a shell identifier. Older versions of the shell
|
||||
assumed all such octets were allowed in identifiers, however the POSIX
|
||||
|
|
17
Src/prompt.c
17
Src/prompt.c
|
@ -944,10 +944,15 @@ countprompt(char *str, int *wp, int *hp, int overf)
|
|||
multi = 0;
|
||||
break;
|
||||
default:
|
||||
/* If the character isn't printable, wcwidth() returns -1. */
|
||||
/*
|
||||
* If the character isn't printable, wcwidth() returns
|
||||
* -1. We assume width 1.
|
||||
*/
|
||||
wcw = wcwidth(wc);
|
||||
if (wcw > 0)
|
||||
if (wcw >= 0)
|
||||
w += wcw;
|
||||
else
|
||||
w++;
|
||||
multi = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -1152,8 +1157,10 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar)
|
|||
break;
|
||||
default:
|
||||
wcw = wcwidth(cc);
|
||||
if (wcw > 0)
|
||||
if (wcw >= 0)
|
||||
remw -= wcw;
|
||||
else
|
||||
remw--;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
|
@ -1215,8 +1222,10 @@ prompttrunc(int arg, int truncchar, int doprint, int endchar)
|
|||
break;
|
||||
default:
|
||||
wcw = wcwidth(cc);
|
||||
if (wcw > 0)
|
||||
if (wcw >= 0)
|
||||
maxwidth -= wcw;
|
||||
else
|
||||
maxwidth--;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
|
|
178
Src/subst.c
178
Src/subst.c
|
@ -837,29 +837,31 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone,
|
|||
}
|
||||
} else {
|
||||
f -= lpreone;
|
||||
if ((m = f % lpremul)) {
|
||||
/*
|
||||
* Left over fraction of repeated string.
|
||||
*/
|
||||
MB_METACHARINIT();
|
||||
/* Skip this much. */
|
||||
m = lpremul - m;
|
||||
for (t = premul; m > 0; ) {
|
||||
t += MB_METACHARLENCONV(t, &cchar);
|
||||
m -= WCWIDTH(cchar);
|
||||
}
|
||||
/* Output the rest. */
|
||||
while (*t)
|
||||
*r++ = *t++;
|
||||
}
|
||||
for (cc = f / lpremul; cc--;) {
|
||||
/* Repeat the repeated string */
|
||||
MB_METACHARINIT();
|
||||
for (c = lpremul, t = premul; c > 0; ) {
|
||||
cl = MB_METACHARLENCONV(t, &cchar);
|
||||
while (cl--)
|
||||
if (lpremul) {
|
||||
if ((m = f % lpremul)) {
|
||||
/*
|
||||
* Left over fraction of repeated string.
|
||||
*/
|
||||
MB_METACHARINIT();
|
||||
/* Skip this much. */
|
||||
m = lpremul - m;
|
||||
for (t = premul; m > 0; ) {
|
||||
t += MB_METACHARLENCONV(t, &cchar);
|
||||
m -= WCWIDTH(cchar);
|
||||
}
|
||||
/* Output the rest. */
|
||||
while (*t)
|
||||
*r++ = *t++;
|
||||
c -= WCWIDTH(cchar);
|
||||
}
|
||||
for (cc = f / lpremul; cc--;) {
|
||||
/* Repeat the repeated string */
|
||||
MB_METACHARINIT();
|
||||
for (c = lpremul, t = premul; c > 0; ) {
|
||||
cl = MB_METACHARLENCONV(t, &cchar);
|
||||
while (cl--)
|
||||
*r++ = *t++;
|
||||
c -= WCWIDTH(cchar);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (preone) {
|
||||
|
@ -910,19 +912,21 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone,
|
|||
while (*postone)
|
||||
*r++ = *postone++;
|
||||
}
|
||||
for (cc = f / lpostmul; cc--;) {
|
||||
/* Begin the beguine */
|
||||
for (t = postmul; *t; )
|
||||
*r++ = *t++;
|
||||
}
|
||||
if ((m = f % lpostmul)) {
|
||||
/* Fill leftovers with chunk of repeated string */
|
||||
MB_METACHARINIT();
|
||||
while (m > 0) {
|
||||
cl = MB_METACHARLENCONV(postmul, &cchar);
|
||||
m -= WCWIDTH(cchar);
|
||||
while (cl--)
|
||||
*r++ = *postmul++;
|
||||
if (lpostmul) {
|
||||
for (cc = f / lpostmul; cc--;) {
|
||||
/* Begin the beguine */
|
||||
for (t = postmul; *t; )
|
||||
*r++ = *t++;
|
||||
}
|
||||
if ((m = f % lpostmul)) {
|
||||
/* Fill leftovers with chunk of repeated string */
|
||||
MB_METACHARINIT();
|
||||
while (m > 0) {
|
||||
cl = MB_METACHARLENCONV(postmul, &cchar);
|
||||
m -= WCWIDTH(cchar);
|
||||
while (cl--)
|
||||
*r++ = *postmul++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -983,37 +987,39 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone,
|
|||
* first
|
||||
*/
|
||||
f -= lpreone;
|
||||
if ((m = f % lpremul)) {
|
||||
/*
|
||||
* Some fraction of the repeated string needed.
|
||||
*/
|
||||
/* Need this much... */
|
||||
c = m;
|
||||
/* ...skipping this much first. */
|
||||
m = lpremul - m;
|
||||
MB_METACHARINIT();
|
||||
for (t = premul; m > 0; ) {
|
||||
t += MB_METACHARLENCONV(t, &cchar);
|
||||
m -= WCWIDTH(cchar);
|
||||
if (lpremul) {
|
||||
if ((m = f % lpremul)) {
|
||||
/*
|
||||
* Some fraction of the repeated string needed.
|
||||
*/
|
||||
/* Need this much... */
|
||||
c = m;
|
||||
/* ...skipping this much first. */
|
||||
m = lpremul - m;
|
||||
MB_METACHARINIT();
|
||||
for (t = premul; m > 0; ) {
|
||||
t += MB_METACHARLENCONV(t, &cchar);
|
||||
m -= WCWIDTH(cchar);
|
||||
}
|
||||
/* Now the rest of the repeated string. */
|
||||
while (c > 0) {
|
||||
cl = MB_METACHARLENCONV(t, &cchar);
|
||||
while (cl--)
|
||||
*r++ = *t++;
|
||||
c -= WCWIDTH(cchar);
|
||||
}
|
||||
}
|
||||
/* Now the rest of the repeated string. */
|
||||
while (c > 0) {
|
||||
cl = MB_METACHARLENCONV(t, &cchar);
|
||||
while (cl--)
|
||||
*r++ = *t++;
|
||||
c -= WCWIDTH(cchar);
|
||||
}
|
||||
}
|
||||
for (cc = f / lpremul; cc--;) {
|
||||
/*
|
||||
* Repeat the repeated string.
|
||||
*/
|
||||
MB_METACHARINIT();
|
||||
for (c = lpremul, t = premul; c > 0; ) {
|
||||
cl = MB_METACHARLENCONV(t, &cchar);
|
||||
while (cl--)
|
||||
*r++ = *t++;
|
||||
c -= WCWIDTH(cchar);
|
||||
for (cc = f / lpremul; cc--;) {
|
||||
/*
|
||||
* Repeat the repeated string.
|
||||
*/
|
||||
MB_METACHARINIT();
|
||||
for (c = lpremul, t = premul; c > 0; ) {
|
||||
cl = MB_METACHARLENCONV(t, &cchar);
|
||||
while (cl--)
|
||||
*r++ = *t++;
|
||||
c -= WCWIDTH(cchar);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (preone) {
|
||||
|
@ -1089,27 +1095,29 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone,
|
|||
c -= WCWIDTH(cchar);
|
||||
}
|
||||
}
|
||||
/* Repeat the repeated string */
|
||||
for (cc = f / lpostmul; cc--;) {
|
||||
MB_METACHARINIT();
|
||||
for (c = lpostmul, t = postmul; *t; ) {
|
||||
cl = MB_METACHARLENCONV(t, &cchar);
|
||||
while (cl--)
|
||||
*r++ = *t++;
|
||||
c -= WCWIDTH(cchar);
|
||||
if (lpostmul) {
|
||||
/* Repeat the repeated string */
|
||||
for (cc = f / lpostmul; cc--;) {
|
||||
MB_METACHARINIT();
|
||||
for (c = lpostmul, t = postmul; *t; ) {
|
||||
cl = MB_METACHARLENCONV(t, &cchar);
|
||||
while (cl--)
|
||||
*r++ = *t++;
|
||||
c -= WCWIDTH(cchar);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* See if there's any fraction of the repeated
|
||||
* string needed to fill up the remaining space.
|
||||
*/
|
||||
if ((m = f % lpostmul)) {
|
||||
MB_METACHARINIT();
|
||||
while (m > 0) {
|
||||
cl = MB_METACHARLENCONV(postmul, &cchar);
|
||||
while (cl--)
|
||||
*r++ = *postmul++;
|
||||
m -= WCWIDTH(cchar);
|
||||
/*
|
||||
* See if there's any fraction of the repeated
|
||||
* string needed to fill up the remaining space.
|
||||
*/
|
||||
if ((m = f % lpostmul)) {
|
||||
MB_METACHARINIT();
|
||||
while (m > 0) {
|
||||
cl = MB_METACHARLENCONV(postmul, &cchar);
|
||||
while (cl--)
|
||||
*r++ = *postmul++;
|
||||
m -= WCWIDTH(cchar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
20
Src/utils.c
20
Src/utils.c
|
@ -527,8 +527,10 @@ wcs_nicechar(wchar_t c, size_t *widthp, char **swidep)
|
|||
if (widthp) {
|
||||
int wcw = wcwidth(c);
|
||||
*widthp = (s - buf);
|
||||
if (wcw > 0)
|
||||
if (wcw >= 0)
|
||||
*widthp += wcw;
|
||||
else
|
||||
(*widthp)++;
|
||||
}
|
||||
if (swidep)
|
||||
*swidep = s;
|
||||
|
@ -550,12 +552,12 @@ zwcwidth(wint_t wc)
|
|||
{
|
||||
int wcw;
|
||||
/* assume a single-byte character if not valid */
|
||||
if (wc == WEOF)
|
||||
if (wc == WEOF || unset(MULTIBYTE))
|
||||
return 1;
|
||||
wcw = wcwidth(wc);
|
||||
/* if not printable, assume zero width */
|
||||
if (wcw <= 0)
|
||||
return 0;
|
||||
/* if not printable, assume width 1 */
|
||||
if (wcw < 0)
|
||||
return 1;
|
||||
return wcw;
|
||||
}
|
||||
|
||||
|
@ -4077,12 +4079,14 @@ mb_metastrlen(char *ptr, int width)
|
|||
num++;
|
||||
} else if (width) {
|
||||
/*
|
||||
* Returns -1 if not a printable character; best
|
||||
* just to ignore these.
|
||||
* Returns -1 if not a printable character. We
|
||||
* turn this into 1 for backward compatibility.
|
||||
*/
|
||||
int wcw = wcwidth(wc);
|
||||
if (wcw > 0)
|
||||
if (wcw >= 0)
|
||||
num += wcw;
|
||||
else
|
||||
num++;
|
||||
} else
|
||||
num++;
|
||||
laststart = ptr;
|
||||
|
|
Loading…
Reference in a new issue