Subject: make(1) patch
To: Keith Bostic <bostic@vangogh.CS.Berkeley.EDU>
From: Christos Zoulas <christos@deshaw.com>
List: current-users
Date: 02/19/1994 15:37:26
The SYSV ${VAR:src=dst} was broken; try:

SRC=foo.c bar.c

all:
	echo ${SRC:%.c=%.o}


Here's a patch:

*** nonints.h.dist	Sat Feb 19 15:31:21 1994
--- nonints.h	Sat Feb 19 15:32:50 1994
***************
*** 86,91 ****
--- 86,93 ----
  char **brk_string __P((char *, int *));
  char *Str_FindSubstring __P((char *, char *));
  int Str_Match __P((char *, char *));
+ char *Str_SYSVMatch __P((char *, char *, int *len));
+ void Str_SYSVSubst __P((Buffer, char *, char *, int));
  
  /* suff.c */
  void Suff_ClearSuffixes __P((void));
*** str.c.dist	Sat Feb 19 15:08:16 1994
--- str.c	Sat Feb 19 15:17:05 1994
***************
*** 339,341 ****
--- 339,436 ----
  		++string;
  	}
  }
+ 
+ 
+ /*-
+  *-----------------------------------------------------------------------
+  * Str_SYSVMatch --
+  *	Check word against pattern for a match (% is wild), 
+  *	
+  * Results:
+  *	Returns the beginning position of a match or null. The number
+  *	of characters matched is returned in len.
+  *
+  * Side Effects:
+  *	None
+  *
+  *-----------------------------------------------------------------------
+  */
+ char *
+ Str_SYSVMatch(word, pattern, len)
+     char	*word;		/* Word to examine */
+     char	*pattern;	/* Pattern to examine against */
+     int		*len;		/* Number of characters to substitute */
+ {
+     char *p = pattern;
+     char *w = word;
+     char *m;
+ 
+     if (*p == '\0')
+ 	return NULL;
+ 
+     if ((m = strchr(p, '%')) != NULL) {
+ 	/* check that the prefix matches */
+ 	for (; p != m && *w && *w == *p; w++, p++)
+ 	     continue;
+ 
+ 	if (p != m)
+ 	    return NULL;	/* No match */
+ 
+ 	if (*++p == '\0') {
+ 	    /* No more pattern, return the rest of the string */
+ 	    *len = strlen(w);
+ 	    return w;
+ 	}
+     }
+ 
+     m = w;
+ 
+     /* Find a matching tail */
+     do
+ 	if (strcmp(p, w) == 0) {
+ 	    *len = w - m;
+ 	    return m;
+ 	}
+     while (*w++ != '\0');
+ 	    
+     return NULL;
+ }
+ 
+ 
+ /*-
+  *-----------------------------------------------------------------------
+  * Str_SYSVSubst --
+  *	Substitute '%' on the pattern with len characters from src.
+  *	If the pattern does not contain a '%' prepend len characters
+  *	from src.
+  *	
+  * Results:
+  *	None
+  *
+  * Side Effects:
+  *	Places result on buf
+  *
+  *-----------------------------------------------------------------------
+  */
+ void
+ Str_SYSVSubst(buf, pat, src, len)
+     Buffer buf;
+     char *pat;
+     char *src;
+     int   len;
+ {
+     char *m;
+ 
+     if ((m = strchr(pat, '%')) != NULL) {
+ 	/* Copy the prefix */
+ 	Buf_AddBytes(buf, m - pat, (Byte *) pat);
+ 	/* skip the % */
+ 	pat = m + 1;
+     }
+ 
+     /* Copy the pattern */
+     Buf_AddBytes(buf, len, (Byte *) src);
+ 
+     /* append the rest */
+     Buf_AddBytes(buf, strlen(pat), (Byte *) pat);
+ }
*** var.c.dist	Fri Nov 19 15:21:39 1993
--- var.c	Sat Feb 19 15:19:58 1994
***************
*** 156,161 ****
--- 156,162 ----
  static Boolean VarSuffix __P((char *, Boolean, Buffer));
  static Boolean VarRoot __P((char *, Boolean, Buffer));
  static Boolean VarMatch __P((char *, Boolean, Buffer, char *));
+ static Boolean VarSYSVMatch __P((char *, Boolean, Buffer, VarPattern *));
  static Boolean VarNoMatch __P((char *, Boolean, Buffer, char *));
  static Boolean VarSubstitute __P((char *, Boolean, Buffer, VarPattern *));
  static char *VarModify __P((char *, Boolean (*modProc )(), ClientData));
***************
*** 737,744 ****
--- 738,789 ----
      return(addSpace);
  }
  
+ 
+ 
  /*-
   *-----------------------------------------------------------------------
+  * VarSYSVMatch --
+  *	Place the word in the buffer if it matches the given pattern.
+  *	Callback function for VarModify to implement the System V %
+  *	modifiers.
+  *	
+  * Results:
+  *	TRUE if a space should be placed in the buffer before the next
+  *	word.
+  *
+  * Side Effects:
+  *	The word may be copied to the buffer.
+  *
+  *-----------------------------------------------------------------------
+  */
+ static Boolean
+ VarSYSVMatch (word, addSpace, buf, pat)
+     char    	  *word;    	/* Word to examine */
+     Boolean 	  addSpace; 	/* TRUE if need to add a space to the
+ 				 * buffer before adding the word, if it
+ 				 * matches */
+     Buffer  	  buf;	    	/* Buffer in which to store it */
+     VarPattern 	  *pat; 	/* Pattern the word must match */
+ {
+     int len;
+     char *ptr;
+ 
+     if (addSpace)
+ 	Buf_AddByte(buf, (Byte)' ');
+ 
+     addSpace = TRUE;
+ 
+     if ((ptr = Str_SYSVMatch(word, pat->lhs, &len)) != NULL)
+ 	Str_SYSVSubst(buf, pat->rhs, ptr, len);
+     else
+ 	Buf_AddBytes(buf, strlen(word), (Byte *) word);
+ 
+     return(addSpace);
+ }
+ 
+ 
+ /*-
+  *-----------------------------------------------------------------------
   * VarNoMatch --
   *	Place the word in the buffer if it doesn't match the given pattern.
   *	Callback function for VarModify to implement the :N modifier.
***************
*** 1605,1613 ****
  			 * SYSV modifications happen through the whole
  			 * string. Note the pattern is anchored at the end.
  			 */
! 			pattern.flags |= VAR_SUB_GLOBAL|VAR_MATCH_END;
! 
! 			newStr = VarModify(str, VarSubstitute,
  					   (ClientData)&pattern);
  
  			/*
--- 1650,1656 ----
  			 * SYSV modifications happen through the whole
  			 * string. Note the pattern is anchored at the end.
  			 */
! 			newStr = VarModify(str, VarSYSVMatch,
  					   (ClientData)&pattern);
  
  			/*

------------------------------------------------------------------------------