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: 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 | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user