From nobody@FreeBSD.org  Sat Jan  6 04:05:47 2001
Return-Path: <nobody@FreeBSD.org>
Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21])
	by hub.freebsd.org (Postfix) with ESMTP id 949BD37B400
	for <freebsd-gnats-submit@FreeBSD.org>; Sat,  6 Jan 2001 04:05:47 -0800 (PST)
Received: (from nobody@localhost)
	by freefall.freebsd.org (8.11.1/8.11.1) id f06C5ld98080;
	Sat, 6 Jan 2001 04:05:47 -0800 (PST)
	(envelope-from nobody)
Message-Id: <200101061205.f06C5ld98080@freefall.freebsd.org>
Date: Sat, 6 Jan 2001 04:05:47 -0800 (PST)
From: tmoestl@gmx.net
Sender: nobody@FreeBSD.org
To: freebsd-gnats-submit@FreeBSD.org
Subject: Fix for make(1) null suffixes after cleaning all suffixes
X-Send-Pr-Version: www-1.0

>Number:         24102
>Category:       bin
>Synopsis:       Fix for make(1) null suffixes after cleaning all suffixes
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    tmm
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sat Jan 06 04:10:01 PST 2001
>Closed-Date:    Wed Mar 7 17:01:45 PST 2001
>Last-Modified:  Wed Mar 07 17:02:25 PST 2001
>Originator:     Thomas Moestl
>Release:        5.0-CURRENT and 4.2-STABLE
>Organization:
>Environment:
FreeBSD raven.local 5.0-CURRENT FreeBSD 5.0-CURRENT #8: 
Thu Jan  4 13:44:12 CET 2001
thomas@raven.local:/usr/src/sys/compile/RAVEN  i386

>Description:
This is a fix for PR bin/23328. It has been ported to -STABLE and
successfully tested by the PR originator.
The patched make also did a world build without any problems.

The problem is that null suffixes will not be cleared using
.SUFFIXES:
, and additions of new suffix rules thereafter may not have the desired
effect.

>How-To-Repeat:
See PR bin/23328 for a full description.
The bug did apparently surface in some autoconf-generated Makefiles, like
the one of amanda 2.4.2 (specifically in the module amplot).

>Fix:
See the patch below. The first hunk is a fix for Suff_ClearSuffixes.
First, sNum should not be reset to 0, because 0 is the sNum of suffNull.
Instead, it is set to 1, so SuffClearSuffixes restores the same state
that was present after SuffInit.
Second, all old suffixes are removed in Suff_ClearSuffixes (and the
graph is later rebuilt in SuffRebuildGraph), _except_ suffNull, which
is used later on and may still contain old entries in its child list!
This causes old null suffix rules not to be cleared, and adding
new rules may fail if an old rule is present which has by chance the
same sNum (which is possible since sNum is reset to 1). As a fix, the
child list of suffNull is destroyed (without freeing the entries, because
those should already be in suffClean) and reinitialized.

The second hunk fixes another problem: when the graph is rebuilt in
SuffRebuildGraph, transformations to the null suffix were not included,
because the null suffix is not in the suffix list. This is now done
with that fix.

The third hunk is merely a cosmetical change: it causes `' to be printed
around the debug output of suffixes. This is done already in other
places and makes it possible to know the null suffix from an empty list.

Here comes the diff for -CURRENT; in case that it gets munged somehow, 
it is also available at http://www.tu-bs.de/~y0015675/make.diff.

*** src/usr.bin/make/suff.c~	Sat Dec  2 21:24:38 2000
--- src/usr.bin/make/suff.c	Fri Jan  5 02:12:31 2001
***************
*** 460,467 ****
  {
      Lst_Concat (suffClean, sufflist, LST_CONCLINK);
      sufflist = Lst_Init(FALSE);
!     sNum = 0;
      suffNull = emptySuff;
  }
  
  /*-
--- 460,475 ----
  {
      Lst_Concat (suffClean, sufflist, LST_CONCLINK);
      sufflist = Lst_Init(FALSE);
!     sNum = 1;
      suffNull = emptySuff;
+     /*
+      * Clear suffNull's children list (the other suffixes are built new, but
+      * suffNull is used as is).
+      * NOFREE is used because all suffixes are are on the suffClean list.
+      * suffNull should not have parents.
+      */
+     Lst_Destroy(suffNull->children, NOFREE); 
+     suffNull->children = Lst_Init(FALSE);
  }
  
  /*-
***************
*** 714,733 ****
      Suff    	*s = (Suff *) sp;
      char 	*cp;
      LstNode	ln;
!     Suff  	*s2;
  
      /*
       * First see if it is a transformation from this suffix.
       */
      cp = SuffStrIsPrefix(s->name, transform->name);
      if (cp != (char *)NULL) {
! 	ln = Lst_Find(sufflist, (void *)cp, SuffSuffHasNameP);
! 	if (ln != NULL) {
  	    /*
  	     * Found target. Link in and return, since it can't be anything
  	     * else.
  	     */
- 	    s2 = (Suff *)Lst_Datum(ln);
  	    SuffInsert(s2->children, s);
  	    SuffInsert(s->parents, s2);
  	    return(0);
--- 722,746 ----
      Suff    	*s = (Suff *) sp;
      char 	*cp;
      LstNode	ln;
!     Suff  	*s2 = NULL;
  
      /*
       * First see if it is a transformation from this suffix.
       */
      cp = SuffStrIsPrefix(s->name, transform->name);
      if (cp != (char *)NULL) {
!         if (cp[0] == '\0')  /* null rule */
! 	    s2 = suffNull;
! 	else {
! 	    ln = Lst_Find(sufflist, (void *)cp, SuffSuffHasNameP);
! 	    if (ln != NULL) 
! 	        s2 = (Suff *)Lst_Datum(ln);
! 	}
! 	if (s2 != NULL) {
  	    /*
  	     * Found target. Link in and return, since it can't be anything
  	     * else.
  	     */
  	    SuffInsert(s2->children, s);
  	    SuffInsert(s->parents, s2);
  	    return(0);
***************
*** 2359,2365 ****
      void * s;
      void * dummy;
  {
!     printf ("%s ", ((Suff *) s)->name);
      return (dummy ? 0 : 0);
  }
  
--- 2372,2378 ----
      void * s;
      void * dummy;
  {
!     printf ("`%s' ", ((Suff *) s)->name);
      return (dummy ? 0 : 0);
  }
  
Next, the diff for -STABLE (ported by David Wolfskill); in case that it
gets munged somehow, it is also available at 
http://www.tu-bs.de/~y0015675/make-stable.diff.

diff -c make.orig/suff.c make/suff.c
*** make.orig/suff.c	Sat Sep 11 15:08:01 1999
--- make/suff.c	Sat Jan  6 12:49:40 2001
***************
*** 462,469 ****
  {
      Lst_Concat (suffClean, sufflist, LST_CONCLINK);
      sufflist = Lst_Init(FALSE);
!     sNum = 0;
      suffNull = emptySuff;
  }
  
  /*-
--- 462,477 ----
  {
      Lst_Concat (suffClean, sufflist, LST_CONCLINK);
      sufflist = Lst_Init(FALSE);
!     sNum = 1;
      suffNull = emptySuff;
+     /*
+      * Clear suffNull's children list (the other suffixes are built new, but
+      * suffNull is used as is).
+      * NOFREE is used because all suffixes are are on the suffClean list.
+      * suffNull should not have parents.
+      */
+     Lst_Destroy(suffNull->children, NOFREE);
+     suffNull->children = Lst_Init(FALSE);
  }
  
  /*-
***************
*** 716,735 ****
      Suff    	*s = (Suff *) sp;
      char 	*cp;
      LstNode	ln;
!     Suff  	*s2;
  
      /*
       * First see if it is a transformation from this suffix.
       */
      cp = SuffStrIsPrefix(s->name, transform->name);
      if (cp != (char *)NULL) {
! 	ln = Lst_Find(sufflist, (ClientData)cp, SuffSuffHasNameP);
! 	if (ln != NILLNODE) {
  	    /*
  	     * Found target. Link in and return, since it can't be anything
  	     * else.
  	     */
- 	    s2 = (Suff *)Lst_Datum(ln);
  	    SuffInsert(s2->children, s);
  	    SuffInsert(s->parents, s2);
  	    return(0);
--- 724,748 ----
      Suff    	*s = (Suff *) sp;
      char 	*cp;
      LstNode	ln;
!     Suff  	*s2 = NULL;
  
      /*
       * First see if it is a transformation from this suffix.
       */
      cp = SuffStrIsPrefix(s->name, transform->name);
      if (cp != (char *)NULL) {
! 	if (cp[0] == '\0')  /* null rule */
! 	    s2 = suffNull;
! 	else {
! 	    ln = Lst_Find(sufflist, (ClientData)cp, SuffSuffHasNameP);
! 	    if (ln != NILLNODE)
! 	        s2 = (Suff *)Lst_Datum(ln);
! 	}
! 	if (s2 != NULL) {
  	    /*
  	     * Found target. Link in and return, since it can't be anything
  	     * else.
  	     */
  	    SuffInsert(s2->children, s);
  	    SuffInsert(s->parents, s2);
  	    return(0);
***************
*** 2361,2367 ****
      ClientData s;
      ClientData dummy;
  {
!     printf ("%s ", ((Suff *) s)->name);
      return (dummy ? 0 : 0);
  }
  
--- 2374,2380 ----
      ClientData s;
      ClientData dummy;
  {
!     printf ("`%s' ", ((Suff *) s)->name);
      return (dummy ? 0 : 0);
  }


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->will 
Responsible-Changed-By: obrien 
Responsible-Changed-When: Wed Feb 7 13:04:17 PST 2001 
Responsible-Changed-Why:  
Will is looking after Make(1) these days. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=24102 
Responsible-Changed-From-To: will->tmm 
Responsible-Changed-By: tmm 
Responsible-Changed-When: Wed Mar 7 15:17:16 PST 2001 
Responsible-Changed-Why:  
I'll take this over (with permission from will) 

http://www.freebsd.org/cgi/query-pr.cgi?pr=24102 
State-Changed-From-To: open->closed 
State-Changed-By: tmm 
State-Changed-When: Wed Mar 7 17:01:45 PST 2001 
State-Changed-Why:  
Committed to -CURRENT. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=24102 
>Unformatted:
