Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make Implement :[] modifier to allow picking a range...



details:   https://anonhg.NetBSD.org/src/rev/64eff6752ac2
branches:  trunk
changeset: 552587:64eff6752ac2
user:      sjg <sjg%NetBSD.org@localhost>
date:      Sat Sep 27 21:29:37 2003 +0000

description:
Implement :[] modifier to allow picking a range of words out of a variable.
Also :tW and a W flag to :C and :S to allow treating value as a single word.
Add unit tests for the above, and fix some corner cases.
Based on patches supplied by Alan Barrett <apb%cequrux.com@localhost>

diffstat:

 usr.bin/make/make.1              |   94 +++++-
 usr.bin/make/make.h              |    9 +-
 usr.bin/make/str.c               |    9 +-
 usr.bin/make/unit-tests/Makefile |   17 +-
 usr.bin/make/unit-tests/modword  |  151 ++++++++++
 usr.bin/make/unit-tests/test.exp |  124 ++++++++
 usr.bin/make/var.c               |  579 +++++++++++++++++++++++++++++++-------
 7 files changed, 858 insertions(+), 125 deletions(-)

diffs (truncated from 1656 to 300 lines):

diff -r 3d6839200dec -r 64eff6752ac2 usr.bin/make/make.1
--- a/usr.bin/make/make.1       Sat Sep 27 21:17:31 2003 +0000
+++ b/usr.bin/make/make.1       Sat Sep 27 21:29:37 2003 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: make.1,v 1.88 2003/09/10 18:04:23 jmmv Exp $
+.\"    $NetBSD: make.1,v 1.89 2003/09/27 21:29:37 sjg Exp $
 .\"
 .\" Copyright (c) 1990, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -471,7 +471,6 @@
 .Ql \&$$
 expands to a single dollar
 sign.
-.Pq Va argv[0]
 .It Va .ALLTARGETS
 The list of all targets encountered in the Makefile.
 If evaluated during
@@ -483,7 +482,8 @@
 .It Ev MAKE
 The name that
 .Nm
-was executed with.
+was executed with
+.Pq Va argv[0] .
 For compatibily
 .Nm
 also sets
@@ -637,10 +637,20 @@
 is omitted, then no separator is used.
 .It Cm tu
 Converts variable to upper-case letters.
+.It Cm tW
+Causes the value to be treated as a single word
+(possibly containing embedded white space).
+See also
+.Ql \&:[*] .
+.It Cm tw
+Causes the value to be treated as a sequence of
+words delimited by white space.
+See also
+.Ql \&:[@] .
 .Sm off
 .It Cm S No \&/ Ar old_string Xo
 .No \&/ Ar new_string
-.No \&/ Op Cm 1g
+.No \&/ Op Cm 1gW
 .Xc
 .Sm on
 Modify the first occurrence of
@@ -655,6 +665,11 @@
 .Ql 1
 is appended to the last slash of the pattern, only the first word
 is affected.
+If a
+.Ql W
+is appended to the last slash of the pattern,
+then the value is treated as a single word
+(possibly containing embedded white space).
 If
 .Ar old_string
 begins with a caret
@@ -693,7 +708,7 @@
 .Sm off
 .It Cm C No \&/ Ar pattern Xo
 .No \&/ Ar replacement
-.No \&/ Op Cm 1g
+.No \&/ Op Cm 1gW
 .Xc
 .Sm on
 The
@@ -720,7 +735,10 @@
 modifier causes the substitution to apply to as many instances of the
 search pattern
 .Ar pattern
-as occur in the word or words it is found in.
+as occur in the word or words it is found in; the
+.Ql W
+modifier causes the value to be treated as a single word
+(possibly containing embedded white space).
 Note that
 .Ql 1
 and
@@ -849,6 +867,70 @@
 Assign the output of
 .Ar cmd
 to the variable.
+.It Cm \&[ Ns Ar range Ns Cm \&]
+Selects one or more words from the value,
+or performs other operations related to the way in which the
+value is divided into words.
+.Pp
+Ordinarily, a value is treated as a sequence of words
+delimited by white space.
+Some modifiers suppress this behaviour,
+causing a value to be treated as a single word
+(possibly containing embedded white space).
+An empty value, or a value that consists entirely of white-space,
+is treated as a single word.
+For the purposes of the
+.Ql \&:[]
+modifier, the words are indexed both forwards using positive integers
+(where index 1 represents the first word),
+and backwards using negative integers
+(where index -1 represents the last word).
+.Pp
+The
+.Ar range
+is subjected to variable expansion, and the expanded result is
+then interpreted as follows:
+.Bl -tag -width index
+\" :[n]
+.It Ar index
+Selects a single word from the value.
+\" :[start..end]
+.It Ar start Ns Cm \&.. Ns Ar end
+Selects all words from
+.Ar start
+to
+.Ar end ,
+inclusive.
+For example,
+.Ql \&:[2..-1]
+selects all words from the second word to the last word.
+If
+.Ar start
+is greater than
+.Ar end ,
+then the words are output in reverse order.  For example,
+.Ql \&:[-1..1]
+selects all the words from last to first.
+\" :[*]
+.It Cm \&*
+Causes subsequent modifiers to treat the value as a single word
+(possibly containing embedded white space).  Analogous to the effect of
+\&"$*\&" 
+in Bourne shell.
+\" :[0]
+.It 0
+Means the same as
+.Ql \&:[*] .
+\" :[*]
+.It Cm \&@
+Causes subsequent modifiers to treat the value as a sequence of words
+delimited by white space.  Analogous to the effect of
+\&"$@\&" 
+in Bourne shell.
+\" :[#]
+.It Cm \&#
+Returns the number of words in the value.
+.El \" :[range]
 .El
 .Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS
 Makefile inclusion, conditional structures and for loops  reminiscent
diff -r 3d6839200dec -r 64eff6752ac2 usr.bin/make/make.h
--- a/usr.bin/make/make.h       Sat Sep 27 21:17:31 2003 +0000
+++ b/usr.bin/make/make.h       Sat Sep 27 21:29:37 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: make.h,v 1.48 2003/09/10 18:04:23 jmmv Exp $   */
+/*     $NetBSD: make.h,v 1.49 2003/09/27 21:29:37 sjg Exp $    */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -449,4 +449,11 @@
 #define UNCONST(ptr)   (void *)(ptr)
 #endif
 
+#ifndef MIN
+#define MIN(a, b) ((a < b) ? a : b)
+#endif
+#ifndef MAX
+#define MAX(a, b) ((a > b) ? a : b)
+#endif
+
 #endif /* _MAKE_H_ */
diff -r 3d6839200dec -r 64eff6752ac2 usr.bin/make/str.c
--- a/usr.bin/make/str.c        Sat Sep 27 21:17:31 2003 +0000
+++ b/usr.bin/make/str.c        Sat Sep 27 21:29:37 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: str.c,v 1.20 2003/08/07 11:14:57 agc Exp $     */
+/*     $NetBSD: str.c,v 1.21 2003/09/27 21:29:37 sjg Exp $     */
 
 /*-
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
  */
 
 #ifdef MAKE_BOOTSTRAP
-static char rcsid[] = "$NetBSD: str.c,v 1.20 2003/08/07 11:14:57 agc Exp $";
+static char rcsid[] = "$NetBSD: str.c,v 1.21 2003/09/27 21:29:37 sjg Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char     sccsid[] = "@(#)str.c  5.8 (Berkeley) 6/1/90";
 #else
-__RCSID("$NetBSD: str.c,v 1.20 2003/08/07 11:14:57 agc Exp $");
+__RCSID("$NetBSD: str.c,v 1.21 2003/09/27 21:29:37 sjg Exp $");
 #endif
 #endif                         /* not lint */
 #endif
@@ -129,8 +129,7 @@
  *     are ignored.
  *
  * returns --
- *     Pointer to the array of pointers to the words.  To make life easier,
- *     the first word is always the value of the .MAKE variable.
+ *     Pointer to the array of pointers to the words.
  */
 char **
 brk_string(const char *str, int *store_argc, Boolean expand, char **buffer)
diff -r 3d6839200dec -r 64eff6752ac2 usr.bin/make/unit-tests/Makefile
--- a/usr.bin/make/unit-tests/Makefile  Sat Sep 27 21:17:31 2003 +0000
+++ b/usr.bin/make/unit-tests/Makefile  Sat Sep 27 21:29:37 2003 +0000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.7 2003/08/08 06:42:38 sjg Exp $
+# $Id: Makefile,v 1.8 2003/09/27 21:29:37 sjg Exp $
 #
 # Unit tests for make(1)
 # The main targets are:
@@ -16,17 +16,22 @@
 
 UNIT_TESTS:= ${.PARSEDIR}
 
-all: mod-ts varcmd
+all: mod-ts varcmd modword
 
 LIST= one two three
 LIST+= four five six
 
 FU_mod-ts = a / b / cool
 
+AAA= a a a
+B.aaa= Baaa
+
 mod-ts:
        @echo 'LIST="${LIST}"'
        @echo 'LIST:ts,="${LIST:ts,}"'
        @echo 'LIST:ts/:tu="${LIST:ts/:tu}"'
+       @echo 'LIST:ts::tu="${LIST:ts::tu}"'
+       @echo 'LIST:ts:tu="${LIST:ts:tu}"'
        @echo 'LIST:tu:ts/="${LIST:tu:ts/}"'
        @echo 'LIST:ts:="${LIST:ts:}"'
        @echo 'LIST:ts="${LIST:ts}"'
@@ -41,10 +46,12 @@
        @echo 'LIST:ts/x:tu="${LIST:ts\x:tu}"'
        @echo 'FU_$@="${FU_${@:ts}:ts}"'
        @echo 'FU_$@:ts:T="${FU_${@:ts}:ts:T}" == cool?'
+       @echo 'B.$${AAA:ts}="${B.${AAA:ts}}" == Baaa?'
 
-.PHONY: varcmd
-varcmd:
-       @${.MAKE} -f ${UNIT_TESTS}/varcmd
+# Some tests are best handled via a sub-make
+.PHONY: varcmd modword
+varcmd modword:
+       @${.MAKE} -k -f ${UNIT_TESTS}/$@
 
 clean:
        rm -f *.out *.fail *.core
diff -r 3d6839200dec -r 64eff6752ac2 usr.bin/make/unit-tests/modword
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/modword   Sat Sep 27 21:29:37 2003 +0000
@@ -0,0 +1,151 @@
+# $Id: modword,v 1.1 2003/09/27 21:29:37 sjg Exp $
+#
+# Test behaviour of new :[] modifier
+
+all: mod-squarebrackets mod-S-W mod-C-W mod-tW-tw
+
+LIST= one two three
+LIST+= four five six
+LONGLIST= 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+
+EMPTY= # the space should be ignored
+ESCAPEDSPACE=\ # escaped space before the '#'
+REALLYSPACE:=${EMPTY:C/^/ /W}
+HASH= \#
+AT= @
+STAR= *
+ZERO= 0
+ONE= 1
+MINUSONE= -1
+
+mod-squarebrackets: mod-squarebrackets-0-star-at \
+       mod-squarebrackets-hash \
+       mod-squarebrackets-n \
+       mod-squarebrackets-start-end \
+       mod-squarebrackets-nested
+
+mod-squarebrackets-0-star-at:
+       @echo 'LIST:[]="${LIST:[]}" is an error'
+       @echo 'LIST:[0]="${LIST:[0]}"'
+       @echo 'LIST:[0x0]="${LIST:[0x0]}"'
+       @echo 'LIST:[000]="${LIST:[000]}"'
+       @echo 'LIST:[*]="${LIST:[*]}"'
+       @echo 'LIST:[@]="${LIST:[@]}"'
+       @echo 'LIST:[0]:C/ /,/="${LIST:[0]:C/ /,/}"'
+       @echo 'LIST:[0]:C/ /,/g="${LIST:[0]:C/ /,/g}"'
+       @echo 'LIST:[0]:C/ /,/1g="${LIST:[0]:C/ /,/1g}"'
+       @echo 'LIST:[*]:C/ /,/="${LIST:[*]:C/ /,/}"'



Home | Main Index | Thread Index | Old Index