1
0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-09-28 15:01:21 +02:00

assume width 1 for control characters;

don't crash if width of repeated padding string is 0
This commit is contained in:
Peter Stephenson 2006-09-15 13:17:27 +00:00
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

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

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

@ -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);
}
}
}
}

@ -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;