Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 17 Jul 2003 17:16:20 -0400 (EDT)
From:      Mikhail Teterin <mteterin@250-217.customer.cloud9.net>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/54594: Apply regexps to the entire variable -- a new variable modifier
Message-ID:  <200307172116.h6HLGKEv045641@mteterin.us.murex.com>
Resent-Message-ID: <200307172120.h6HLK0ML081234@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         54594
>Category:       bin
>Synopsis:       Apply regexps to the entire variable -- a new variable modifier
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jul 17 14:20:00 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Mikhail Teterin
>Release:        FreeBSD 5.1-CURRENT i386
>Organization:
Virtual Estates, Inc.
>Environment:
System: FreeBSD mi.us.murex.com 5.1-CURRENT FreeBSD 5.1-CURRENT #3: Fri Jul 11 18:12:03 EDT 2003 root@mi.us.murex.com:/misha/obj/misha/src/sys/Misha-g i386


>Description:

	Writing a Makefile for a Java project, I was unable to easily
	construct a long enough CLASSPATH inside the Makefile without
	resorting to very:long:string or using shell commands.

	The patch below adds another variable modifier, which works
	just like C/pattern/replacement/[1g], but operates on the entire
	value of the variable, rather then on each individual word of it.

	Not only can this be a little faster (as a replacement for the
	C modifier, where possible), it will also allow to operate on
	the very word-separators (blanks) themselves -- such as turning
	sequences of them into CLASSPATH-like colons or whatever:

	JARS=	...
	JARS+=	...
	JARS+=	...

	CLASSPATH=${JARS:A/ +/:/g}

	This is a more general solution than join/split modifiers, one
	could think of.

	I picked 'A' (as in "all") for the new modifier, but that is, of
	course, arbitrary.
	
>How-To-Repeat:

>Fix:

cvs server: Diffing .
Index: make.1
===================================================================
RCS file: /home/ncvs/src/usr.bin/make/make.1,v
retrieving revision 1.62
diff -U2 -r1.62 make.1
--- make.1	23 Dec 2002 16:04:51 -0000	1.62
+++ make.1	17 Jul 2003 20:59:02 -0000
@@ -595,4 +595,18 @@
 .Bl -tag -width Cm
 .Sm off
+.It Cm A No \&/ Ar pattern Xo
+.No \&/ Ar replacement
+.No \&/ Op Cm 1g
+.Xc
+.Sm on
+The
+.Cm A
+modifier is just like the
+.Cm C
+modifier (see below) except that the transformation is applied to the whole
+value of the variable at once, rather than to each word of it. This makes it
+possible, for example, to join lists of files or directories together -- such
+as when constructing a Java CLASSPATH.
+.Sm off
 .It Cm C No \&/ Ar pattern Xo
 .No \&/ Ar replacement
Index: var.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/make/var.c,v
retrieving revision 1.42
diff -U2 -r1.42 var.c
--- var.c	15 Jan 2003 22:36:15 -0000	1.42
+++ var.c	17 Jul 2003 20:59:02 -0000
@@ -1372,4 +1372,5 @@
 		    break;
 		}
+		case 'A':
 		case 'C':
 		{
@@ -1442,6 +1443,18 @@
 		    pattern.matches = emalloc(pattern.nsub *
 					      sizeof(regmatch_t));
-		    newStr = VarModify(str, VarRESubstitute,
-				       (void *) &pattern);
+		    if (*tstr == 'C')
+			/* Apply to each word of the string */
+			newStr = VarModify(str, VarRESubstitute,
+				           &pattern);
+		    else {
+			/* Apply to the whole string */
+			Buffer	buf;
+
+			buf = Buf_Init (0);
+			VarRESubstitute(str, FALSE, buf, &pattern);
+			Buf_AddByte(buf, '\0'); /* XXX Needed? */
+			newStr = Buf_GetAll (buf, (int *)NULL);
+			Buf_Destroy (buf, FALSE);
+		    }
 		    regfree(&pattern.re);
 		    free(pattern.replace);
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200307172116.h6HLGKEv045641>