NetBSD Problem Report #41700

From cheusov@tut.by  Sat Jul 11 11:16:50 2009
Return-Path: <cheusov@tut.by>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by www.NetBSD.org (Postfix) with ESMTP id 5E60963B913
	for <gnats-bugs@gnats.netbsd.org>; Sat, 11 Jul 2009 11:16:50 +0000 (UTC)
Message-Id: <s93hbxjbhfi.fsf@chen.chizhovka.net>
Date: Sat, 11 Jul 2009 14:14:09 +0300
From: cheusov@tut.by
To: gnats-bugs@gnats.NetBSD.org
Subject: :tr modifier for NetBSD make [patch]
X-Send-Pr-Version: 3.95

>Number:         41700
>Category:       bin
>Synopsis:       :tr modifier for NetBSD make [patch]
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    cheusov
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Jul 11 11:20:00 +0000 2009
>Last-Modified:  Mon May 08 22:50:01 +0000 2023
>Originator:     Aleksey Cheusov
>Release:        NetBSD 5.0_STABLE
>Organization:
>Environment:
System: NetBSD chen.chizhovka.net 5.0_STABLE NetBSD 5.0_STABLE (GENERIC) #5: Fri May 1 16:04:32 EEST 2009 cheusov@chen.chizhovka.net:/srv/obj/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
Some time ago I proposed to implement a new variable modifier for bmake, :tr
for character substitution in tr(1) manner.
http://mail-index.netbsd.org/tech-userlevel/2009/03/25/msg001973.html
There were short discussion and people agreed with my proposal.

Now I propose a patch.

>How-To-Repeat:

>Fix:

Index: var.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/var.c,v
retrieving revision 1.152
diff -u -r1.152 var.c
--- var.c	16 Jun 2009 05:44:06 -0000	1.152
+++ var.c	11 Jul 2009 11:13:54 -0000
@@ -130,6 +130,7 @@
 #include    <ctype.h>
 #include    <stdlib.h>
 #include    <limits.h>
+#include    <assert.h>

 #include    "make.h"
 #include    "buf.h"
@@ -2093,6 +2094,57 @@

 /*-
  *-----------------------------------------------------------------------
+ * VarTranslate --
+ *      Char to char translation like tr(1)
+ *
+ * Input:
+ *	str		String to modify
+ *	chars		characters to be replaced
+ *	repl		replacement characters
+ *
+ * Results:
+ *      The string with changed characters
+ *
+ * Side Effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static char *
+VarTranslate(char *str, char *chars, char *repl)
+{
+   Buffer  buf;
+   int     table [UCHAR_MAX+1];
+   int     r;
+   int     c;
+
+   /* initialization of translation table */
+   memset (table, -1, sizeof (table));
+
+   for (; *chars; ++chars, ++repl){
+       assert (*repl != 0);
+       table [(unsigned char) *chars] = (unsigned char) *repl;
+   }
+   assert (*repl == 0);
+
+   /* translation */
+   Buf_Init(&buf, 0);
+   for (; *str ; ++str) {
+       c = (unsigned char) *str;
+       r = table [c];
+       if (r == -1)
+	   Buf_AddByte(&buf, (Byte)c);
+       else
+	   Buf_AddByte(&buf, (Byte)r);
+   }
+   Buf_AddByte(&buf, (Byte)'\0');
+   str = (char *)Buf_GetAll(&buf, NULL);
+   Buf_Destroy(&buf, FALSE);
+   return str;
+}
+
+/*-
+ *-----------------------------------------------------------------------
  * VarChangeCase --
  *      Change the string to all uppercase or all lowercase
  *
@@ -2655,7 +2707,47 @@
 	case 't':
 	    {
 		cp = tstr + 1;	/* make sure it is set */
-		if (tstr[1] != endc && tstr[1] != ':') {
+		if (tstr[1] == 'r') {
+		    char *chars, *repl;
+		    int chars_len, repl_len;
+
+		    delim = tstr[2];
+		    tstr += 3;
+
+		    cp = tstr;
+		    chars = VarGetPattern(
+			ctxt, &parsestate, errnum,
+			&cp, delim, NULL,
+			&chars_len,
+			NULL);
+		    if (!chars)
+			goto cleanup;
+
+		    repl = VarGetPattern(
+			ctxt, &parsestate, errnum,
+			&cp, delim, NULL,
+			&repl_len,
+			NULL);
+		    if (!repl)
+			goto cleanup;
+
+		    delim = '\0';
+
+		    if (strlen (chars) != strlen (repl)){
+			free(chars);
+			free(repl);
+
+			Error("Bad arguments for :tr modifier for variable %s",
+			      v->name);
+			goto cleanup;
+		    }
+
+		    termc = *cp;
+		    newStr = VarTranslate(nstr, chars, repl);
+
+		    free(chars);
+		    free(repl);
+		}else if (tstr[1] != endc && tstr[1] != ':') {
 		    if (tstr[1] == 's') {
 			/*
 			 * Use the char (if any) at tstr[2]

>Release-Note:

>Audit-Trail:
From: Alan Barrett <apb@cequrux.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: bin/41700: :tr modifier for NetBSD make [patch]
Date: Sat, 11 Jul 2009 13:33:32 +0200

 On Sat, 11 Jul 2009, cheusov@tut.by wrote:
 > Some time ago I proposed to implement a new variable modifier for bmake, :tr
 > for character substitution in tr(1) manner.

 This looks OK in princple, but it also needs man page updates and
 regression tests.

 --apb (Alan Barrett)

From: Aleksey Cheusov <cheusov@tut.by>
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/41700: :tr modifier for NetBSD make [patch]
Date: Sat, 11 Jul 2009 15:08:00 +0300

  >> Some time ago I proposed to implement a new variable modifier for bmake, :tr
  >> for character substitution in tr(1) manner.
 >  
 >  This looks OK in princple, but it also needs man page updates and
 >  regression tests.

 I'll implement regression tests a bit later.

 Index: make.1
 ===================================================================
 RCS file: /cvsroot/src/usr.bin/make/make.1,v
 retrieving revision 1.158
 diff -u -r1.158 make.1
 --- make.1	1 Jun 2009 23:28:39 -0000	1.158
 +++ make.1	11 Jul 2009 12:09:20 -0000
 @@ -910,6 +910,19 @@
  If
  .Ar c
  is omitted, then no separator is used.
 +.Sm off
 +.It Cm \&:tr No \&/ Ar chars Xo
 +.No \&/ Ar repl \&/
 +.Xc
 +Converts variable by replacing character from
 +.Ar chars
 + with appropriate characters from
 +.Ar repl
 + .
 +.Ar chars
 + and
 +.Ar repl
 + must contain the same number of characters.
  .It Cm \&:tu
  Converts variable to upper-case letters.
  .It Cm \&:tW

 -- 
 Best regards, Aleksey Cheusov.

From: Aleksey Cheusov <cheusov@tut.by>
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/41700: :tr modifier for NetBSD make [patch]
Date: Sat, 11 Jul 2009 15:38:33 +0300

  >> Some time ago I proposed to implement a new variable modifier for bmake, :tr
  >> for character substitution in tr(1) manner.
 >  
 >  This looks OK in princple, but it also needs man page updates and
 >  regression tests.

 Index: unit-tests/Makefile
 ===================================================================
 RCS file: /cvsroot/src/usr.bin/make/unit-tests/Makefile,v
 retrieving revision 1.23
 diff -u -r1.23 Makefile
 --- unit-tests/Makefile	25 Oct 2008 22:27:39 -0000	1.23
 +++ unit-tests/Makefile	11 Jul 2009 12:39:15 -0000
 @@ -29,6 +29,7 @@
  	modmisc \
  	modorder \
  	modts \
 +	modtr \
  	modword \
  	posix \
  	qequals \
 Index: unit-tests/modtr
 ===================================================================
 RCS file: unit-tests/modtr
 diff -N unit-tests/modtr
 --- /dev/null	1 Jan 1970 00:00:00 -0000
 +++ unit-tests/modtr	11 Jul 2009 12:39:15 -0000
 @@ -0,0 +1,12 @@
 +
 +LIST= apple 0xf00dbeaf
 +
 +all:   mod-tr
 +
 +mod-tr:
 +	@echo 'LIST="${LIST}"'
 +	@echo 'LIST:tr///="${LIST:tr///}"'
 +	@echo 'LIST:tr|abcdef|ABCDEF|="${LIST:tr|abcdef|ABCDEF|}"'
 +#	1 is not implemented (yet?)
 +#	@echo 'LIST:tr///1="${LIST:tr///1}"'
 +#	@echo 'LIST:tr|abcdef|ABCDEF|1="${LIST:tr|abcdef|ABCDEF|1}"'
 Index: unit-tests/test.exp
 ===================================================================
 RCS file: /cvsroot/src/usr.bin/make/unit-tests/test.exp,v
 retrieving revision 1.27
 diff -u -r1.27 test.exp
 --- unit-tests/test.exp	3 Feb 2009 23:11:12 -0000	1.27
 +++ unit-tests/test.exp	11 Jul 2009 12:39:15 -0000
 @@ -147,6 +147,9 @@
  FU_mod-ts="a/b/cool"
  FU_mod-ts:ts:T="cool" == cool?
  B.${AAA:ts}="Baaa" == Baaa?
 +LIST="apple 0xf00dbeaf"
 +LIST:tr///="apple 0xf00dbeaf"
 +LIST:tr|abcdef|ABCDEF|="ApplE 0xF00DBEAF"
  make: Bad modifier `:[]' for LIST
  LIST:[]="" is an error
  LIST:[0]="one two three four five six"

 -- 
 Best regards, Aleksey Cheusov.

From: David Laight <david@l8s.co.uk>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: bin/41700: :tr modifier for NetBSD make [patch]
Date: Sat, 11 Jul 2009 14:13:00 +0100

 On Sat, Jul 11, 2009 at 11:20:00AM +0000, cheusov@tut.by wrote:
 > >Number:         41700
 > >Category:       bin
 > >Synopsis:       :tr modifier for NetBSD make [patch]
 ...
 > Now I propose a patch.

 Some comments about the code....
 (NB not about whether this is a good idea)

 > +static char *
 > +VarTranslate(char *str, char *chars, char *repl)
 > +{
 > +   Buffer  buf;
 > +   int     table [UCHAR_MAX+1];
 > +   int     r;
 > +   int     c;
 > +
 > +   /* initialization of translation table */
 > +   memset (table, -1, sizeof (table));

 initialize table[n] = n here, table can then be char.

 > +   for (; *chars; ++chars, ++repl){
 > +       assert (*repl != 0);

 Don't assert! I can't remember what tr(1) does, but terminating
 the action wouldn't be too bad.

 > +       table [(unsigned char) *chars] = (unsigned char) *repl;

 You need to support ranges!

 > +   }
 > +   assert (*repl == 0);
 > +
 > +   /* translation */

 Don't use 'buf', just tgt = malloc(strlen(str) + 1)

 > +   Buf_Init(&buf, 0);
 > +   for (; *str ; ++str) {
 > +       c = (unsigned char) *str;
 > +       r = table [c];
 > +       if (r == -1)
 > +	   Buf_AddByte(&buf, (Byte)c);
 > +       else
 > +	   Buf_AddByte(&buf, (Byte)r);
 > +   }
 > +   Buf_AddByte(&buf, (Byte)'\0');
 In any case Buf_Addbyte guarantees \0 terminated

 > +   str = (char *)Buf_GetAll(&buf, NULL);
 > +   Buf_Destroy(&buf, FALSE);
 > +   return str;
 > +}
 > +
 > +/*-
 > + *-----------------------------------------------------------------------
 >   * VarChangeCase --
 >   *      Change the string to all uppercase or all lowercase
 >   *
 > @@ -2655,7 +2707,47 @@
 >  	case 't':
 >  	    {
 >  		cp = tstr + 1;	/* make sure it is set */
 > -		if (tstr[1] != endc && tstr[1] != ':') {
 > +		if (tstr[1] == 'r') {
 > +		    char *chars, *repl;
 > +		    int chars_len, repl_len;
 > +
 > +		    delim = tstr[2];
 > +		    tstr += 3;
 > +
 > +		    cp = tstr;
 > +		    chars = VarGetPattern(
 > +			ctxt, &parsestate, errnum,
 > +			&cp, delim, NULL,
 > +			&chars_len,
 > +			NULL);
 > +		    if (!chars)
 > +			goto cleanup;
 > +
 > +		    repl = VarGetPattern(
 > +			ctxt, &parsestate, errnum,
 > +			&cp, delim, NULL,
 > +			&repl_len,
 > +			NULL);
 > +		    if (!repl)
 > +			goto cleanup;
 > +
 > +		    delim = '\0';

 No need to do the check below twice!
 > +		    if (strlen (chars) != strlen (repl)){
 > +			free(chars);
 > +			free(repl);
 > +
 > +			Error("Bad arguments for :tr modifier for variable %s",
 > +			      v->name);
 > +			goto cleanup;
 > +		    }
 > +
 > +		    termc = *cp;
 > +		    newStr = VarTranslate(nstr, chars, repl);
 > +
 > +		    free(chars);
 > +		    free(repl);
 > +		}else if (tstr[1] != endc && tstr[1] != ':') {
 >  		    if (tstr[1] == 's') {
 >  			/*
 >  			 * Use the char (if any) at tstr[2]
 > 


 	David

 -- 
 David Laight: david@l8s.co.uk

Responsible-Changed-From-To: bin-bug-people->cheusov
Responsible-Changed-By: cheusov@NetBSD.org
Responsible-Changed-When: Sat, 28 May 2011 11:51:37 +0000
Responsible-Changed-Why:
I'll work on my own PR


From: Roland Illig <roland.illig@gmx.de>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: bin/41700: :tr modifier for NetBSD make [patch]
Date: Mon, 8 May 2023 22:42:59 +0200

 Hi Aleksey,

 Are you still interested in implementing the ':tr' modifier? The example
 you gave in the discussion on tech-userlevel can be simplified using a
 ':C' modifier for translating several characters to underscores.

 SIZEOF.${t:S|.|_|g:S|-|_|g:S|*|P|g:S|/|_|g:S|:|.|g}   !=3D   env
 ${mkc.environ}

 =3D>

 SIZEOF.${t:C,[-./],_,g:S,*,P,g:S,:,.,g} !=3D env ${mkc.environ} ...

 Instead of repeating the complicated expression 3 times, you can compute
 it once in a nested .for loop:

 .for t in ...
 .  for tt in ${t:C,[-./],_,g:S,*,P,g:S,:,.,g}
 SIZEOF.${tt}!=3D env ${mkc.environ} ...
 .  endfor
 .endfor

 Roland

From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: bin/41700: :tr modifier for NetBSD make [patch]
Date: Mon, 8 May 2023 22:49:08 +0000

 On Mon, May 08, 2023 at 08:50:01PM +0000, Roland Illig wrote:
  >  Hi Aleksey,
  >  
  >  Are you still interested in implementing the ':tr' modifier? The example
  >  you gave in the discussion on tech-userlevel can be simplified using a
  >  ':C' modifier for translating several characters to underscores.

 I don't think he's around much at this point, but in general it seems
 like a good idea, for the same reason tr(1) exists at all and sed has
 'y'; in general it's quite verbose written out using other mechanisms.

 -- 
 David A. Holland
 dholland@netbsd.org

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: gnats-precook-prs,v 1.4 2018/12/21 14:20:20 maya Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2017 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.