since we have wcwidth anyway, expose it as ${%strvar} to the user, iff
utf8-mode is enabled (otherwise it'll be a synonym for ${#strvar} aka the number of octets in it)
This commit is contained in:
parent
aa31a51e5f
commit
2094e3f25c
63
check.t
63
check.t
@ -1,4 +1,4 @@
|
|||||||
# $MirOS: src/bin/mksh/check.t,v 1.340 2009/11/21 22:32:05 tg Exp $
|
# $MirOS: src/bin/mksh/check.t,v 1.341 2009/11/21 23:23:16 tg Exp $
|
||||||
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
|
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
|
||||||
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
|
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
|
||||||
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
||||||
@ -25,7 +25,7 @@
|
|||||||
# http://www.research.att.com/~gsf/public/ifs.sh
|
# http://www.research.att.com/~gsf/public/ifs.sh
|
||||||
|
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
@(#)MIRBSD KSH R39 2009/11/09
|
@(#)MIRBSD KSH R39 2009/11/21
|
||||||
description:
|
description:
|
||||||
Check version of shell.
|
Check version of shell.
|
||||||
stdin:
|
stdin:
|
||||||
@ -6680,3 +6680,62 @@ expected-stdout:
|
|||||||
done
|
done
|
||||||
expected-stderr-pattern: /.*-x.*option/
|
expected-stderr-pattern: /.*-x.*option/
|
||||||
---
|
---
|
||||||
|
name: wcswidth-1
|
||||||
|
description:
|
||||||
|
Check the new wcswidth feature
|
||||||
|
stdin:
|
||||||
|
s=何
|
||||||
|
set +U
|
||||||
|
print octets: ${#s} ${%s} .
|
||||||
|
set -U
|
||||||
|
print characters: ${#s} .
|
||||||
|
print columns: ${%s} .
|
||||||
|
expected-stdout:
|
||||||
|
octets: 3 3 .
|
||||||
|
characters: 1 .
|
||||||
|
columns: 2 .
|
||||||
|
---
|
||||||
|
name: wcswidth-2
|
||||||
|
description:
|
||||||
|
Check some corner cases
|
||||||
|
stdin:
|
||||||
|
print % $% .
|
||||||
|
expected-stdout:
|
||||||
|
% $% .
|
||||||
|
---
|
||||||
|
name: wcswidth-3
|
||||||
|
description:
|
||||||
|
Check some corner cases
|
||||||
|
stdin:
|
||||||
|
print ${%} .
|
||||||
|
expected-stderr-pattern:
|
||||||
|
/bad substitution/
|
||||||
|
expected-exit: 1
|
||||||
|
---
|
||||||
|
name: wcswidth-4a
|
||||||
|
description:
|
||||||
|
Check some corner cases
|
||||||
|
stdin:
|
||||||
|
print ${%*} .
|
||||||
|
expected-stderr-pattern:
|
||||||
|
/bad substitution/
|
||||||
|
expected-exit: 1
|
||||||
|
---
|
||||||
|
name: wcswidth-4b
|
||||||
|
description:
|
||||||
|
Check some corner cases
|
||||||
|
stdin:
|
||||||
|
print ${%@} .
|
||||||
|
expected-stderr-pattern:
|
||||||
|
/bad substitution/
|
||||||
|
expected-exit: 1
|
||||||
|
---
|
||||||
|
name: wcswidth-4c
|
||||||
|
description:
|
||||||
|
Check some corner cases
|
||||||
|
stdin:
|
||||||
|
:
|
||||||
|
print ${%?} .
|
||||||
|
expected-stdout:
|
||||||
|
1 .
|
||||||
|
---
|
||||||
|
28
eval.c
28
eval.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.72 2009/11/21 22:32:08 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.73 2009/11/21 23:23:17 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* string expansion
|
* string expansion
|
||||||
@ -911,14 +911,20 @@ varsub(Expand *xp, const char *sp, const char *word,
|
|||||||
struct tbl *vp;
|
struct tbl *vp;
|
||||||
bool zero_ok = false;
|
bool zero_ok = false;
|
||||||
|
|
||||||
if (sp[0] == '\0') /* Bad variable name */
|
if ((stype = sp[0]) == '\0') /* Bad variable name */
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
xp->var = NULL;
|
xp->var = NULL;
|
||||||
|
|
||||||
/* ${#var}, string length or array size */
|
/*-
|
||||||
if (sp[0] == '#' && (c = sp[1]) != '\0') {
|
* ${#var}, string length (-U: characters, +U: octets) or array size
|
||||||
/* Can't have any modifiers for ${#...} */
|
* ${%var}, string width (-U: screen columns, +U: octets)
|
||||||
|
*/
|
||||||
|
c = sp[1];
|
||||||
|
if (stype == '%' && c == '\0')
|
||||||
|
return (-1);
|
||||||
|
if ((stype == '#' || stype == '%') && c != '\0') {
|
||||||
|
/* Can't have any modifiers for ${#...} or ${%...} */
|
||||||
if (*word != CSUBST)
|
if (*word != CSUBST)
|
||||||
return (-1);
|
return (-1);
|
||||||
sp++;
|
sp++;
|
||||||
@ -927,6 +933,8 @@ varsub(Expand *xp, const char *sp, const char *word,
|
|||||||
p[2] == ']') {
|
p[2] == ']') {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
|
if (stype != '#')
|
||||||
|
return (-1);
|
||||||
vp = global(arrayname(sp));
|
vp = global(arrayname(sp));
|
||||||
if (vp->flag & (ISSET|ARRAY))
|
if (vp->flag & (ISSET|ARRAY))
|
||||||
zero_ok = true;
|
zero_ok = true;
|
||||||
@ -934,17 +942,19 @@ varsub(Expand *xp, const char *sp, const char *word,
|
|||||||
if (vp->flag & ISSET)
|
if (vp->flag & ISSET)
|
||||||
n++;
|
n++;
|
||||||
c = n;
|
c = n;
|
||||||
} else if (c == '*' || c == '@')
|
} else if (c == '*' || c == '@') {
|
||||||
|
if (stype != '#')
|
||||||
|
return (-1);
|
||||||
c = e->loc->argc;
|
c = e->loc->argc;
|
||||||
else {
|
} else {
|
||||||
p = str_val(global(sp));
|
p = str_val(global(sp));
|
||||||
zero_ok = p != null;
|
zero_ok = p != null;
|
||||||
c = utflen(p);
|
c = stype == '#' ? (int)utflen(p) : utf_mbswidth(p);
|
||||||
}
|
}
|
||||||
if (Flag(FNOUNSET) && c == 0 && !zero_ok)
|
if (Flag(FNOUNSET) && c == 0 && !zero_ok)
|
||||||
errorf("%s: parameter not set", sp);
|
errorf("%s: parameter not set", sp);
|
||||||
*stypep = 0; /* unqualified variable/string substitution */
|
*stypep = 0; /* unqualified variable/string substitution */
|
||||||
xp->str = shf_smprintf("%lu", (unsigned long)c);
|
xp->str = shf_smprintf("%u", (unsigned int)c);
|
||||||
return (XSUB);
|
return (XSUB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
lex.c
4
lex.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.100 2009/10/04 12:45:22 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.101 2009/11/21 23:23:18 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* states while lexing word
|
* states while lexing word
|
||||||
@ -1548,7 +1548,7 @@ get_brace_var(XString *wsp, char *wp)
|
|||||||
/* State machine to figure out where the variable part ends. */
|
/* State machine to figure out where the variable part ends. */
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PS_INITIAL:
|
case PS_INITIAL:
|
||||||
if (c == '#' || c == '!') {
|
if (c == '#' || c == '!' || c == '%') {
|
||||||
state = PS_SAW_HASH;
|
state = PS_SAW_HASH;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
8
mksh.1
8
mksh.1
@ -1,4 +1,4 @@
|
|||||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.197 2009/11/21 23:21:23 tg Exp $
|
.\" $MirOS: src/bin/mksh/mksh.1,v 1.198 2009/11/21 23:23:18 tg Exp $
|
||||||
.\" $OpenBSD: ksh.1,v 1.129 2009/05/28 06:09:06 jmc Exp $
|
.\" $OpenBSD: ksh.1,v 1.129 2009/05/28 06:09:06 jmc Exp $
|
||||||
.\"-
|
.\"-
|
||||||
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||||
@ -1449,6 +1449,12 @@ of the string value of parameter
|
|||||||
The number of elements in the array
|
The number of elements in the array
|
||||||
.Ar name .
|
.Ar name .
|
||||||
.Pp
|
.Pp
|
||||||
|
.It Pf ${% Ns Ar name Ns \&}
|
||||||
|
The width
|
||||||
|
.Pq in screen columns
|
||||||
|
of the string value of parameter
|
||||||
|
.Ar name .
|
||||||
|
.Pp
|
||||||
.It Pf ${! Ns Ar name Ns }
|
.It Pf ${! Ns Ar name Ns }
|
||||||
The name of the variable referred to by
|
The name of the variable referred to by
|
||||||
.Ar name .
|
.Ar name .
|
||||||
|
4
sh.h
4
sh.h
@ -134,9 +134,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#ifdef EXTERN
|
||||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.360 2009/11/09 23:35:11 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.361 2009/11/21 23:23:20 tg Exp $");
|
||||||
#endif
|
#endif
|
||||||
#define MKSH_VERSION "R39 2009/11/09"
|
#define MKSH_VERSION "R39 2009/11/21"
|
||||||
|
|
||||||
#ifndef MKSH_INCLUDES_ONLY
|
#ifndef MKSH_INCLUDES_ONLY
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user