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:
		
							
								
								
									
										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: 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 $ | ||||
| @@ -25,7 +25,7 @@ | ||||
| # http://www.research.att.com/~gsf/public/ifs.sh | ||||
|  | ||||
| expected-stdout: | ||||
| 	@(#)MIRBSD KSH R39 2009/11/09 | ||||
| 	@(#)MIRBSD KSH R39 2009/11/21 | ||||
| description: | ||||
| 	Check version of shell. | ||||
| stdin: | ||||
| @@ -6680,3 +6680,62 @@ expected-stdout: | ||||
| 	done | ||||
| 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" | ||||
|  | ||||
| __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 | ||||
| @@ -911,14 +911,20 @@ varsub(Expand *xp, const char *sp, const char *word, | ||||
| 	struct tbl *vp; | ||||
| 	bool zero_ok = false; | ||||
|  | ||||
| 	if (sp[0] == '\0')	/* Bad variable name */ | ||||
| 	if ((stype = sp[0]) == '\0')	/* Bad variable name */ | ||||
| 		return (-1); | ||||
|  | ||||
| 	xp->var = NULL; | ||||
|  | ||||
| 	/* ${#var}, string length or array size */ | ||||
| 	if (sp[0] == '#' && (c = sp[1]) != '\0') { | ||||
| 		/* Can't have any modifiers for ${#...} */ | ||||
| 	/*- | ||||
| 	 * ${#var}, string length (-U: characters, +U: octets) or array size | ||||
| 	 * ${%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) | ||||
| 			return (-1); | ||||
| 		sp++; | ||||
| @@ -927,6 +933,8 @@ varsub(Expand *xp, const char *sp, const char *word, | ||||
| 		    p[2] == ']') { | ||||
| 			int n = 0; | ||||
|  | ||||
| 			if (stype != '#') | ||||
| 				return (-1); | ||||
| 			vp = global(arrayname(sp)); | ||||
| 			if (vp->flag & (ISSET|ARRAY)) | ||||
| 				zero_ok = true; | ||||
| @@ -934,17 +942,19 @@ varsub(Expand *xp, const char *sp, const char *word, | ||||
| 				if (vp->flag & ISSET) | ||||
| 					n++; | ||||
| 			c = n; | ||||
| 		} else if (c == '*' || c == '@') | ||||
| 		} else if (c == '*' || c == '@') { | ||||
| 			if (stype != '#') | ||||
| 				return (-1); | ||||
| 			c = e->loc->argc; | ||||
| 		else { | ||||
| 		} else { | ||||
| 			p = str_val(global(sp)); | ||||
| 			zero_ok = p != null; | ||||
| 			c = utflen(p); | ||||
| 			c = stype == '#' ? (int)utflen(p) : utf_mbswidth(p); | ||||
| 		} | ||||
| 		if (Flag(FNOUNSET) && c == 0 && !zero_ok) | ||||
| 			errorf("%s: parameter not set", sp); | ||||
| 		*stypep = 0; /* unqualified variable/string substitution */ | ||||
| 		xp->str = shf_smprintf("%lu", (unsigned long)c); | ||||
| 		xp->str = shf_smprintf("%u", (unsigned int)c); | ||||
| 		return (XSUB); | ||||
| 	} | ||||
|  | ||||
|   | ||||
							
								
								
									
										4
									
								
								lex.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								lex.c
									
									
									
									
									
								
							| @@ -22,7 +22,7 @@ | ||||
|  | ||||
| #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 | ||||
| @@ -1548,7 +1548,7 @@ get_brace_var(XString *wsp, char *wp) | ||||
| 		/* State machine to figure out where the variable part ends. */ | ||||
| 		switch (state) { | ||||
| 		case PS_INITIAL: | ||||
| 			if (c == '#' || c == '!') { | ||||
| 			if (c == '#' || c == '!' || c == '%') { | ||||
| 				state = PS_SAW_HASH; | ||||
| 				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 $ | ||||
| .\"- | ||||
| .\" 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 | ||||
| .Ar name . | ||||
| .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 } | ||||
| The name of the variable referred to by | ||||
| .Ar name . | ||||
|   | ||||
							
								
								
									
										4
									
								
								sh.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								sh.h
									
									
									
									
									
								
							| @@ -134,9 +134,9 @@ | ||||
| #endif | ||||
|  | ||||
| #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 | ||||
| #define MKSH_VERSION "R39 2009/11/09" | ||||
| #define MKSH_VERSION "R39 2009/11/21" | ||||
|  | ||||
| #ifndef MKSH_INCLUDES_ONLY | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user