Module Name:    src
Committed By:   kre
Date:           Sun May 14 11:28:49 UTC 2017

Modified Files:
        src/tests/bin/sh: t_expand.sh

Log Message:
Add a test case for the various ways that ${xxx} expansions, which
contain a # character, can get parsed (which amounts to 86 extra checks,
any Australian can tell you why I decided to stop there and not add one
more...)


To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/tests/bin/sh/t_expand.sh

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/bin/sh/t_expand.sh
diff -u src/tests/bin/sh/t_expand.sh:1.11 src/tests/bin/sh/t_expand.sh:1.12
--- src/tests/bin/sh/t_expand.sh:1.11	Mon Mar 20 11:48:41 2017
+++ src/tests/bin/sh/t_expand.sh	Sun May 14 11:28:49 2017
@@ -1,4 +1,4 @@
-# $NetBSD: t_expand.sh,v 1.11 2017/03/20 11:48:41 kre Exp $
+# $NetBSD: t_expand.sh,v 1.12 2017/05/14 11:28:49 kre Exp $
 #
 # Copyright (c) 2007, 2009 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -430,13 +430,170 @@ var_with_embedded_cmdsub_body() {
 	results
 }
 
+atf_test_case dollar_hash
+dollar_hash_head() {
+	atf_set "descr" 'Test expansion of various aspects of $#'
+}
+dollar_hash_body() {
+
+#
+#	$# looks like it should be so simple that it doesn't really
+#	need a test of its own, and used in that way, it really doesn't.
+#	But when we add braces ${#} we need to deal with the three
+#	(almost 4) different meanings of a # inside a ${} expansion...
+#	
+#		1.   ${#} is just $# (number of params)
+#		1.a	${\#} is nothing at all (error: invalid expansion)
+#		1.b	${\#...} (anything after) is the same (invalid)
+#		2.   ${#VAR} is the length of the value VAR
+#		2.a	Including ${##} - the length of ${#}
+#		3    ${VAR#pat} is the value of VAR with leading pat removed
+#		3.a	Including ${VAR#} which just removes leading nothing
+#			This is relevant in case of ${VAR#${X}} with X=''
+#		3.b	${##} is not a case of 3.a but rather 2.a 
+#		3.c	Yet ${##pat} is a case of 3.a
+#			Including ${##${X}} where X='' or X='#'
+#		3.d	And ${#\#} is invalid (error)
+#		3.e	But ${##\#} removes a leading # from the value of $#
+#			(so is just $# as there is no leading # there)
+#		4    ${VAR##pat} is the value of VAR with longest pat removed
+#		4.a	Including ${VAR##} which removes the longest nothing
+#		4.b	Which in this case includes ${###} (so is == $#)
+#		4.c	But not ${##\#} which is $# with a leading '#' removed
+#			(and so is also == $#), i.e.: like ${###} but different.
+#		4.d	As is ${###\#} or just ${####} - remove  # (so just $#)
+#
+
+	reset dollar_hash
+
+	check 'set -- ; echo $#'			'0'		0  # 1
+	check 'set -- a b c; echo $#'			'3'		0  # 2
+	check 'set -- a b c d e f g h i j; echo $#'	'10'		0  # 3
+# rule 1
+	check 'set -- ; echo ${#}'			'0'		0  # 4
+	check 'set -- a b c; echo ${#}'			'3'		0  # 5
+	check 'set -- a b c d e f g h i j; echo ${#}'	'10'		0  # 6
+# rule 1.a
+	check 'set -- a b c; echo ${\#}'		''		2  # 7
+# rule 1.b
+	check 'set -- a b c; echo ${\#:-foo}'		''		2  # 8
+# rule 2
+	check 'VAR=12345; echo ${#VAR}'			'5'		0  # 9
+	check 'VAR=123456789012; echo ${#VAR}'		'12'		0  #10
+# rule 2.a
+	check 'set -- ; echo ${##}'			'1'		0  #11
+	check 'set -- a b c; echo ${##}'		'1'		0  #12
+	check 'set -- a b c d e f g h i j; echo ${##}'	'2'		0  #13
+# rule 3
+	check 'VAR=12345; echo ${VAR#1}'		'2345'		0  #14
+	check 'VAR=12345; echo ${VAR#2}'		'12345'		0  #15
+	check 'VAR=#2345; echo ${VAR#\#}'		'2345'		0  #16
+	check 'X=1; VAR=12345; echo ${VAR#${X}}'	'2345'		0  #17
+	check 'X=1; VAR=#2345; echo ${VAR#${X}}'	'#2345'		0  #18
+# rule 3.a
+	check 'VAR=12345; echo ${VAR#}'			'12345'		0  #19
+	check 'X=; VAR=12345; echo ${VAR#${X}}'		'12345'		0  #20
+# rule 3.b (tested above, rule 2.a)
+# rule 3.c
+	check 'set -- ; echo ${##0}'			''		0  #21
+	check 'set -- a b c; echo ${##1}'		'3'		0  #22
+	check 'set -- a b c d e f g h i j; echo ${##1}'	'0'		0  #23
+	check 'X=0; set -- ; echo ${##${X}}'		''		0  #24
+	check 'X=; set -- ; echo ${##${X}}'		'0'		0  #25
+	check 'X=1; set -- a b c; echo ${##${X}}'	'3'		0  #26
+	check 'X=1; set -- a b c d e f g h i j; echo ${##${X}}'	'0'	0  #27
+	check 'X=; set -- a b c d e f g h i j; echo ${##${X}}'	'10'	0  #28
+	check 'X=#; VAR=#2345; echo ${VAR#${X}}'	'2345'		0  #29
+	check 'X=#; VAR=12345; echo ${VAR#${X}}'	'12345'		0  #30
+# rule 3.d
+	check 'set -- a b c; echo ${#\#}'		''		2  #31
+# rule 3.e
+	check 'set -- ; echo ${##\#}'			'0'		0  #32
+	check 'set -- a b c d e f g h i j; echo ${##\#}' '10'		0  #33
+
+# rule 4
+	check 'VAR=12345; echo ${VAR##1}'		'2345'		0  #34
+	check 'VAR=12345; echo ${VAR##\1}'		'2345'		0  #35
+# rule 4.a
+	check 'VAR=12345; echo ${VAR##}'		'12345'		0  #36
+# rule 4.b
+	check 'set -- ; echo ${###}'			'0'		0  #37
+	check 'set -- a b c d e f g h i j; echo ${###}'	'10'		0  #38
+# rule 4.c
+	check 'VAR=12345; echo ${VAR#\#}'		'12345'		0  #39
+	check 'VAR=12345; echo ${VAR#\#1}'		'12345'		0  #40
+	check 'VAR=#2345; echo ${VAR#\#}'		'2345'		0  #41
+	check 'VAR=#12345; echo ${VAR#\#1}'		'2345'		0  #42
+	check 'VAR=#2345; echo ${VAR#\#1}'		'#2345'		0  #43
+	check 'set -- ; echo ${####}'			'0'		0  #44
+	check 'set -- ; echo ${###\#}'			'0'		0  #45
+	check 'set -- a b c d e f g h i j; echo ${####}' '10'		0  #46
+	check 'set -- a b c d e f g h i j; echo ${###\#}' '10'		0  #47
+
+# now check for some more utter nonsense, not mentioned in the rules
+# above (doesn't need to be)
+
+	check 'x=hello; set -- a b c; echo ${#x:-1}'	''		2  #48
+	check 'x=hello; set -- a b c; echo ${#x-1}'	''		2  #49
+	check 'x=hello; set -- a b c; echo ${#x:+1}'	''		2  #50
+	check 'x=hello; set -- a b c; echo ${#x+1}'	''		2  #51
+	check 'x=hello; set -- a b c; echo ${#x+1}'	''		2  #52
+	check 'x=hello; set -- a b c; echo ${#x:?msg}'	''		2  #53
+	check 'x=hello; set -- a b c; echo ${#x?msg}'	''		2  #54
+	check 'x=hello; set -- a b c; echo ${#x:=val}'	''		2  #55
+	check 'x=hello; set -- a b c; echo ${#x=val}'	''		2  #56
+	check 'x=hello; set -- a b c; echo ${#x#h}'	''		2  #57
+	check 'x=hello; set -- a b c; echo ${#x#*l}'	''		2  #58
+	check 'x=hello; set -- a b c; echo ${#x##*l}'	''		2  #59
+	check 'x=hello; set -- a b c; echo ${#x%o}'	''		2  #60
+	check 'x=hello; set -- a b c; echo ${#x%l*}'	''		2  #61
+	check 'x=hello; set -- a b c; echo ${#x%%l*}'	''		2  #62
+
+# but just to be complete, these ones should work
+
+	check 'x=hello; set -- a b c; echo ${#%5}'	'3'		0  #63
+	check 'x=hello; set -- a b c; echo ${#%3}'	''		0  #64
+	check 'x=hello; set -- a b c; echo ${#%?}'	''		0  #65
+	check 'X=#; set -- a b c; echo ${#%${X}}'	'3'		0  #66
+	check 'X=3; set -- a b c; echo ${#%${X}}'	''		0  #67
+	check 'set -- a b c; echo ${#%%5}'		'3'		0  #68
+	check 'set -- a b c; echo ${#%%3}'		''		0  #69
+	check 'set -- a b c d e f g h i j k l; echo ${#%1}' '12'	0  #70
+	check 'set -- a b c d e f g h i j k l; echo ${#%2}' '1'		0  #71
+	check 'set -- a b c d e f g h i j k l; echo ${#%?}' '1'		0  #72
+	check 'set -- a b c d e f g h i j k l; echo ${#%[012]}' '1'	0  #73
+	check 'set -- a b c d e f g h i j k l; echo ${#%[0-4]}' '1'	0  #74
+	check 'set -- a b c d e f g h i j k l; echo ${#%?2}' ''		0  #75
+	check 'set -- a b c d e f g h i j k l; echo ${#%1*}' ''		0  #76
+	check 'set -- a b c d e f g h i j k l; echo ${#%%2}' '1'	0  #77
+	check 'set -- a b c d e f g h i j k l; echo ${#%%1*}' ''	0  #78
+
+# and this lot are stupid, as $# is never unset or null, but they do work...
+
+	check 'set -- a b c; echo ${#:-99}'		'3'		0  #79
+	check 'set -- a b c; echo ${#-99}'		'3'		0  #80
+	check 'set -- a b c; echo ${#:+99}'		'99'		0  #81
+	check 'set -- a b c; echo ${#+99}'		'99'		0  #82
+	check 'set -- a b c; echo ${#:?bogus}'		'3'		0  #83
+	check 'set -- a b c; echo ${#?bogus}'		'3'		0  #84
+
+# even this utter nonsense is OK, as while special params cannot be
+# set this way, here, as $# is not unset, or null, the assignment
+# never happens (isn't even attempted)
+
+	check 'set -- a b c; echo ${#:=bogus}'		'3'		0  #85
+	check 'set -- a b c; echo ${#=bogus}'		'3'		0  #86
+
+	results
+}
+
 atf_test_case dollar_star
 dollar_star_head() {
 	atf_set "descr" 'Test expansion of various aspects of $*'
 }
 dollar_star_body() {
 
-	reset # dollar_star
+	reset dollar_star
 
 	check 'set -- a b c; echo $# $*'		'3 a b c'	0  # 1
 	check 'set -- a b c; echo $# "$*"'		'3 a b c'	0  # 2
@@ -668,6 +825,7 @@ atf_init_test_cases() {
 	atf_add_test_case arithmetic
 	atf_add_test_case dollar_at
 	atf_add_test_case dollar_at_with_text
+	atf_add_test_case dollar_hash
 	atf_add_test_case dollar_star
 	atf_add_test_case dollar_star_in_quoted_word
 	atf_add_test_case dollar_star_in_word

Reply via email to