From 2bfad02a94ca607d918ea871147680dbeff0999c Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 20 Sep 2006 09:22:34 +0000 Subject: 22742: parameter padding uses string lengths unless (m) flag set 22743: restrict sh "- [args]" -> "-xv [-- args]" hack to sh mode --- ChangeLog | 14 +++++++ Doc/Zsh/builtins.yo | 4 ++ Doc/Zsh/expn.yo | 22 ++++++++--- Src/builtin.c | 2 +- Src/subst.c | 105 +++++++++++++++++++++++++++++++++++----------------- Src/zsh.h | 2 + 6 files changed, 110 insertions(+), 39 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84a0d322a..6ef2782c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2006-09-20 Peter Stephenson + + * 22743: Doc/Zsh/builtis.yo, Src/builtin.c: document the sh + "set - [args]" -> "set -xv [-- args]" hack and limit it to + non-native emulation. + + * 22742: Doc/Zsh/expn.yo, Src/subst.c, Src/zsh.h: padding once + again defaults to character lengths, but (m) flag turns on + character widths for multibyte characters. + 2006-09-17 Clint Adams * 22728, 22734: Doc/Zsh/mod_parameter.yo, Src/Modules/parameter.c, @@ -26,6 +36,10 @@ 2006-09-15 Peter Stephenson + * zsh-users/10720: arno + pws: Functions/Misc/checkmail: + bad recursive argument handling and need to be safer about + options. + * 22715: Src/exec.c: AUTOCONTINUE option never worked. * 22713: Src/Zle/zle_tricky.c: word end in math completion context diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index d8892cd5c..820888ac3 100644 --- a/Doc/Zsh/builtins.yo +++ b/Doc/Zsh/builtins.yo @@ -1160,6 +1160,10 @@ positional parameters will be unset. If no arguments and no `tt(-)tt(-)' are given, then the names and values of all parameters are printed on the standard output. If the only argument is `tt(PLUS())', the names of all parameters are printed. + +For historical reasons, `tt(set -)' is treated as `tt(set +xv)' +and `tt(set -) var(args)' as `tt(set +xv --) var(args)' when in +any other emulation mode than zsh's native mode. ) module(setcap)(zsh/cap) findex(setopt) diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 34d61ed4d..b840f62f0 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -869,11 +869,23 @@ var(string1) and var(string2) are given, tt(string2) is inserted once directly to the left of each word, truncated if necessary, before 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. Control characters are always -assumed to be one unit wide; this allows the mechanism to be used -for generating repetitions of control characters. +If the tt(MULTIBYTE) option is in effect, the flag tt(m) may also +be given, in which case widths will be used for the calculation of +padding; otherwise individual multibyte characters are treated as occupying +one unit of width. + +IF the tt(MULTIBYTE) option is not in effect, each byte in the string is +treated 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(m))( +Only useful together with tt(l) and tt(r) when the tt(MULTIBYTE) option +is in effect. Use the character width reported by the system in +calculating the how much of the string it occupies. Most printable +characters have a width of one unit, however certain Asian character sets +and certain special effects use wider 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) diff --git a/Src/builtin.c b/Src/builtin.c index dbe50d13c..713e41a98 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -535,7 +535,7 @@ bin_set(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) /* Obsolescent sh compatibility: set - is the same as set +xv * * and set - args is the same as set +xv -- args */ - if (*args && **args == '-' && !args[0][1]) { + if (emulation != EMULATE_ZSH && *args && **args == '-' && !args[0][1]) { dosetopt(VERBOSE, 0, 0); dosetopt(XTRACE, 0, 0); if (!args[1]) diff --git a/Src/subst.c b/Src/subst.c index 1a71a155c..28ef9c011 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -738,11 +738,20 @@ invinstrpcmp(const void *a, const void *b) * will be used. */ -/**/ static char * dopadding(char *str, int prenum, int postnum, char *preone, char *postone, - char *premul, char *postmul) + char *premul, char *postmul +#ifdef MULTIBYTE_SUPPORT + , int multi_width +#endif + ) { +#ifdef MULTIBYTE_SUPPORT +#define WCPADWIDTH(cchar) (multi_width ? WCWIDTH(cchar) : 1) +#else +#define WCPADWIDTH(cchar) (1) +#endif + char *def, *ret, *t, *r; int ls, ls2, lpreone, lpostone, lpremul, lpostmul, lr, f, m, c, cc, cl; convchar_t cchar; @@ -761,11 +770,11 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, if (!postmul || !*postmul) postmul = def; - ls = MB_METASTRWIDTH(str); - lpreone = preone ? MB_METASTRWIDTH(preone) : 0; - lpostone = postone ? MB_METASTRWIDTH(postone) : 0; - lpremul = MB_METASTRWIDTH(premul); - lpostmul = MB_METASTRWIDTH(postmul); + ls = MB_METASTRLEN2(str, multi_width); + lpreone = preone ? MB_METASTRLEN2(preone, multi_width) : 0; + lpostone = postone ? MB_METASTRLEN2(postone, multi_width) : 0; + lpremul = MB_METASTRLEN2(premul, multi_width); + lpostmul = MB_METASTRLEN2(postmul, multi_width); if (prenum + postnum == ls) return str; @@ -808,14 +817,14 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, MB_METACHARINIT(); while (f > 0) { str += MB_METACHARLENCONV(str, &cchar); - f -= WCWIDTH(cchar); + f -= WCPADWIDTH(cchar); } /* Now finish the first half. */ for (c = prenum; c > 0; ) { cl = MB_METACHARLENCONV(str, &cchar); while (cl--) *r++ = *str++; - c -= WCWIDTH(cchar); + c -= WCPADWIDTH(cchar); } } else { if (f <= lpreone) { @@ -829,7 +838,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, /* So skip. */ for (t = preone; f > 0; ) { t += MB_METACHARLENCONV(t, &cchar); - f -= WCWIDTH(cchar); + f -= WCPADWIDTH(cchar); } /* Then copy the entire remainder. */ while (*t) @@ -847,7 +856,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, m = lpremul - m; for (t = premul; m > 0; ) { t += MB_METACHARLENCONV(t, &cchar); - m -= WCWIDTH(cchar); + m -= WCPADWIDTH(cchar); } /* Output the rest. */ while (*t) @@ -860,7 +869,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, cl = MB_METACHARLENCONV(t, &cchar); while (cl--) *r++ = *t++; - c -= WCWIDTH(cchar); + c -= WCPADWIDTH(cchar); } } } @@ -873,7 +882,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, /* Output the first half width of the original string. */ for (c = ls2; c > 0; ) { cl = MB_METACHARLENCONV(str, &cchar); - c -= WCWIDTH(cchar); + c -= WCPADWIDTH(cchar); while (cl--) *r++ = *str++; } @@ -887,7 +896,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, MB_METACHARINIT(); for (c = postnum; c > 0; ) { cl = MB_METACHARLENCONV(str, &cchar); - c -= WCWIDTH(cchar); + c -= WCPADWIDTH(cchar); while (cl--) *r++ = *str++; } @@ -900,7 +909,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, /* Can't fit unrepeated string, truncate it */ for (c = f; c > 0; ) { cl = MB_METACHARLENCONV(postone, &cchar); - c -= WCWIDTH(cchar); + c -= WCPADWIDTH(cchar); while (cl--) *r++ = *postone++; } @@ -923,7 +932,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, MB_METACHARINIT(); while (m > 0) { cl = MB_METACHARLENCONV(postmul, &cchar); - m -= WCWIDTH(cchar); + m -= WCPADWIDTH(cchar); while (cl--) *r++ = *postmul++; } @@ -947,14 +956,14 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, MB_METACHARINIT(); while (f > 0) { str += MB_METACHARLENCONV(str, &cchar); - f -= WCWIDTH(cchar); + f -= WCPADWIDTH(cchar); } /* Copy the rest of the original string */ for (c = prenum; c > 0; ) { cl = MB_METACHARLENCONV(str, &cchar); while (cl--) *r++ = *str++; - c -= WCWIDTH(cchar); + c -= WCPADWIDTH(cchar); } } else { /* @@ -975,7 +984,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, MB_METACHARINIT(); for (t = preone; f > 0; ) { t += MB_METACHARLENCONV(t, &cchar); - f -= WCWIDTH(cchar); + f -= WCPADWIDTH(cchar); } /* Copy the rest of preone */ while (*t) @@ -999,14 +1008,14 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, MB_METACHARINIT(); for (t = premul; m > 0; ) { t += MB_METACHARLENCONV(t, &cchar); - m -= WCWIDTH(cchar); + m -= WCPADWIDTH(cchar); } /* Now the rest of the repeated string. */ while (c > 0) { cl = MB_METACHARLENCONV(t, &cchar); while (cl--) *r++ = *t++; - c -= WCWIDTH(cchar); + c -= WCPADWIDTH(cchar); } } for (cc = f / lpremul; cc--;) { @@ -1018,7 +1027,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, cl = MB_METACHARLENCONV(t, &cchar); while (cl--) *r++ = *t++; - c -= WCWIDTH(cchar); + c -= WCPADWIDTH(cchar); } } } @@ -1056,7 +1065,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, cl = MB_METACHARLENCONV(str, &cchar); while (cl--) *r++ = *str++; - c -= WCWIDTH(cchar); + c -= WCPADWIDTH(cchar); } } else { /* @@ -1068,7 +1077,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, cl = MB_METACHARLENCONV(str, &cchar); while (cl--) *r++ = *str++; - c -= WCWIDTH(cchar); + c -= WCPADWIDTH(cchar); } MB_METACHARINIT(); if (f <= lpostone) { @@ -1081,7 +1090,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, cl = MB_METACHARLENCONV(postone, &cchar); while (cl--) *r++ = *postone++; - c -= WCWIDTH(cchar); + c -= WCPADWIDTH(cchar); } } } else { @@ -1092,7 +1101,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, cl = MB_METACHARLENCONV(postone, &cchar); while (cl--) *r++ = *postone++; - c -= WCWIDTH(cchar); + c -= WCPADWIDTH(cchar); } } if (lpostmul) { @@ -1103,7 +1112,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, cl = MB_METACHARLENCONV(t, &cchar); while (cl--) *r++ = *t++; - c -= WCWIDTH(cchar); + c -= WCPADWIDTH(cchar); } } /* @@ -1116,7 +1125,7 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone, cl = MB_METACHARLENCONV(postmul, &cchar); while (cl--) *r++ = *postmul++; - m -= WCWIDTH(cchar); + m -= WCPADWIDTH(cchar); } } } @@ -1414,6 +1423,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) char *replstr = NULL; /* The numbers for (l) and (r) */ zlong prenum = 0, postnum = 0; +#ifdef MULTIBYTE_SUPPORT + /* The (m) flag: use width of multibyte characters */ + int multi_width = 0; +#endif /* * Whether the value has been copied. Optimisation: if we * are modifying an expression, we only need to copy it the @@ -1702,6 +1715,12 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) s = t; break; + case 'm': +#ifdef MULTIBYTE_SUPPORT + multi_width = 1; +#endif + break; + case 'p': escapes = 1; break; @@ -3048,7 +3067,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) while ((x = *aval++)) { if (prenum || postnum) x = dopadding(x, prenum, postnum, preone, postone, - premul, postmul); + premul, postmul +#ifdef MULTIBYTE_SUPPORT + , multi_width +#endif + ); if (eval && subst_parse_str(&x, (qt && !nojoin), quoteerr)) return NULL; xlen = strlen(x); @@ -3092,7 +3115,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) x = aval[0]; if (prenum || postnum) x = dopadding(x, prenum, postnum, preone, postone, - premul, postmul); + premul, postmul +#ifdef MULTIBYTE_SUPPORT + , multi_width +#endif + ); if (eval && subst_parse_str(&x, (qt && !nojoin), quoteerr)) return NULL; xlen = strlen(x); @@ -3107,7 +3134,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) x = aval[i++]; if (prenum || postnum) x = dopadding(x, prenum, postnum, preone, postone, - premul, postmul); + premul, postmul +#ifdef MULTIBYTE_SUPPORT + , multi_width +#endif + ); if (eval && subst_parse_str(&x, (qt && !nojoin), quoteerr)) return NULL; if (qt && !*x && isarr != 2) @@ -3123,7 +3154,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) x = aval[i]; if (prenum || postnum) x = dopadding(x, prenum, postnum, preone, postone, - premul, postmul); + premul, postmul +#ifdef MULTIBYTE_SUPPORT + , multi_width +#endif + ); if (eval && subst_parse_str(&x, (qt && !nojoin), quoteerr)) return NULL; xlen = strlen(x); @@ -3147,7 +3182,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) x = val; if (prenum || postnum) x = dopadding(x, prenum, postnum, preone, postone, - premul, postmul); + premul, postmul +#ifdef MULTIBYTE_SUPPORT + , multi_width +#endif + ); if (eval && subst_parse_str(&x, (qt && !nojoin), quoteerr)) return NULL; xlen = strlen(x); diff --git a/Src/zsh.h b/Src/zsh.h index ce6cf989a..9a76bf9a5 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2008,6 +2008,7 @@ typedef wint_t convchar_t; #define MB_METACHARLEN(str) mb_metacharlenconv(str, NULL) #define MB_METASTRLEN(str) mb_metastrlen(str, 0) #define MB_METASTRWIDTH(str) mb_metastrlen(str, 1) +#define MB_METASTRLEN2(str, widthp) mb_metastrlen(str, widthp) /* * Note WCWIDTH() takes wint_t, typically as a convchar_t. @@ -2041,6 +2042,7 @@ typedef int convchar_t; #define MB_METACHARLEN(str) (*(str) == Meta ? 2 : 1) #define MB_METASTRLEN(str) ztrlen(str) #define MB_METASTRWIDTH(str) ztrlen(str) +#define MB_METASTRLEN2(str, widthp) ztrlen(str) #define WCWIDTH(c) (1) -- cgit 1.4.1