home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bsd / src / make / make-amiga / targ.c < prev    next >
C/C++ Source or Header  |  1993-09-23  |  16KB  |  582 lines

  1. /*
  2.  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
  3.  * Copyright (c) 1988, 1989 by Adam de Boor
  4.  * Copyright (c) 1989 by Berkeley Softworks
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Adam de Boor.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  * 3. All advertising materials mentioning features or use of this software
  19.  *    must display the following acknowledgement:
  20.  *    This product includes software developed by the University of
  21.  *    California, Berkeley and its contributors.
  22.  * 4. Neither the name of the University nor the names of its contributors
  23.  *    may be used to endorse or promote products derived from this software
  24.  *    without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36.  * SUCH DAMAGE.
  37.  */
  38.  
  39. #ifndef lint
  40. static char sccsid[] = "@(#)targ.c    5.9 (Berkeley) 3/1/91";
  41. #endif /* not lint */
  42.  
  43. /*-
  44.  * targ.c --
  45.  *    Functions for maintaining the Lst allTargets. Target nodes are
  46.  * kept in two structures: a Lst, maintained by the list library, and a
  47.  * hash table, maintained by the hash library.
  48.  *
  49.  * Interface:
  50.  *    Targ_Init             Initialization procedure.
  51.  *
  52.  *    Targ_NewGN            Create a new GNode for the passed target
  53.  *                          (string). The node is *not* placed in the
  54.  *                          hash table, though all its fields are
  55.  *                          initialized.
  56.  *
  57.  *    Targ_FindNode            Find the node for a given target, creating
  58.  *                          and storing it if it doesn't exist and the
  59.  *                          flags are right (TARG_CREATE)
  60.  *
  61.  *    Targ_FindList            Given a list of names, find nodes for all
  62.  *                          of them. If a name doesn't exist and the
  63.  *                          TARG_NOCREATE flag was given, an error message
  64.  *                          is printed. Else, if a name doesn't exist,
  65.  *                          its node is created.
  66.  *
  67.  *    Targ_Ignore            Return TRUE if errors should be ignored when
  68.  *                          creating the given target.
  69.  *
  70.  *    Targ_Silent            Return TRUE if we should be silent when
  71.  *                          creating the given target.
  72.  *
  73.  *    Targ_Precious            Return TRUE if the target is precious and
  74.  *                          should not be removed if we are interrupted.
  75.  *
  76.  * Debugging:
  77.  *    Targ_PrintGraph            Print out the entire graphm all variables
  78.  *                          and statistics for the directory cache. Should
  79.  *                          print something for suffixes, too, but...
  80.  */
  81.  
  82. #include      <stdio.h>
  83. #include      <time.h>
  84. #include      "make.h"
  85. #include      "hash.h"
  86.  
  87. static Lst        allTargets;    /* the list of all targets found so far */
  88. static Hash_Table targets;    /* a hash table of same */
  89.  
  90. #define HTSIZE    191        /* initial size of hash table */
  91.  
  92. /*-
  93.  *-----------------------------------------------------------------------
  94.  * Targ_Init --
  95.  *    Initialize this module
  96.  *
  97.  * Results:
  98.  *    None
  99.  *
  100.  * Side Effects:
  101.  *    The allTargets list and the targets hash table are initialized
  102.  *-----------------------------------------------------------------------
  103.  */
  104. void
  105. Targ_Init ()
  106. {
  107.     allTargets = Lst_Init (FALSE);
  108.     Hash_InitTable (&targets, HTSIZE);
  109. }
  110.  
  111. /*-
  112.  *-----------------------------------------------------------------------
  113.  * Targ_NewGN  --
  114.  *    Create and initialize a new graph node
  115.  *
  116.  * Results:
  117.  *    An initialized graph node with the name field filled with a copy
  118.  *    of the passed name
  119.  *
  120.  * Side Effects:
  121.  *    None.
  122.  *-----------------------------------------------------------------------
  123.  */
  124. GNode *
  125. Targ_NewGN (name)
  126.     char           *name;    /* the name to stick in the new node */
  127. {
  128.     register GNode *gn;
  129.  
  130.     gn = (GNode *) emalloc (sizeof (GNode));
  131.     gn->name = strdup (name);
  132.     gn->path = (char *) 0;
  133.     if (name[0] == '-' && name[1] == 'l') {
  134.     gn->type = OP_LIB;
  135.     } else {
  136.     gn->type = 0;
  137.     }
  138.     gn->unmade =        0;
  139.     gn->make =             FALSE;
  140.     gn->made =             UNMADE;
  141.     gn->childMade =     FALSE;
  142.     gn->mtime = gn->cmtime = 0;
  143.     gn->iParents =      Lst_Init (FALSE);
  144.     gn->cohorts =       Lst_Init (FALSE);
  145.     gn->parents =       Lst_Init (FALSE);
  146.     gn->children =      Lst_Init (FALSE);
  147.     gn->successors =     Lst_Init(FALSE);
  148.     gn->preds =         Lst_Init(FALSE);
  149.     gn->context =       Lst_Init (FALSE);
  150.     gn->commands =      Lst_Init (FALSE);
  151.  
  152.     return (gn);
  153. }
  154.  
  155. /*-
  156.  *-----------------------------------------------------------------------
  157.  * Targ_FindNode  --
  158.  *    Find a node in the list using the given name for matching
  159.  *
  160.  * Results:
  161.  *    The node in the list if it was. If it wasn't, return NILGNODE of
  162.  *    flags was TARG_NOCREATE or the newly created and initialized node
  163.  *    if it was TARG_CREATE
  164.  *
  165.  * Side Effects:
  166.  *    Sometimes a node is created and added to the list
  167.  *-----------------------------------------------------------------------
  168.  */
  169. GNode *
  170. Targ_FindNode (name, flags)
  171.     char           *name;    /* the name to find */
  172.     int             flags;    /* flags governing events when target not
  173.                  * found */
  174. {
  175.     GNode         *gn;          /* node in that element */
  176.     Hash_Entry      *he;          /* New or used hash entry for node */
  177.     Boolean      isNew;      /* Set TRUE if Hash_CreateEntry had to create */
  178.                   /* an entry for the node */
  179.  
  180.  
  181.     if (flags & TARG_CREATE) {
  182.     he = Hash_CreateEntry (&targets, name, &isNew);
  183.     if (isNew) {
  184.         gn = Targ_NewGN (name);
  185.         Hash_SetValue (he, gn);
  186.         (void) Lst_AtEnd (allTargets, (ClientData)gn);
  187.     }
  188.     } else {
  189.     he = Hash_FindEntry (&targets, name);
  190.     }
  191.  
  192.     if (he == (Hash_Entry *) NULL) {
  193.     return (NILGNODE);
  194.     } else {
  195.     return ((GNode *) Hash_GetValue (he));
  196.     }
  197. }
  198.  
  199. /*-
  200.  *-----------------------------------------------------------------------
  201.  * Targ_FindList --
  202.  *    Make a complete list of GNodes from the given list of names 
  203.  *
  204.  * Results:
  205.  *    A complete list of graph nodes corresponding to all instances of all
  206.  *    the names in names. 
  207.  *
  208.  * Side Effects:
  209.  *    If flags is TARG_CREATE, nodes will be created for all names in
  210.  *    names which do not yet have graph nodes. If flags is TARG_NOCREATE,
  211.  *    an error message will be printed for each name which can't be found.
  212.  * -----------------------------------------------------------------------
  213.  */
  214. Lst
  215. Targ_FindList (names, flags)
  216.     Lst               names;    /* list of names to find */
  217.     int            flags;    /* flags used if no node is found for a given
  218.                  * name */
  219. {
  220.     Lst            nodes;    /* result list */
  221.     register LstNode  ln;        /* name list element */
  222.     register GNode *gn;        /* node in tLn */
  223.     char          *name;
  224.  
  225.     nodes = Lst_Init (FALSE);
  226.  
  227.     if (Lst_Open (names) == FAILURE) {
  228.     return (nodes);
  229.     }
  230.     while ((ln = Lst_Next (names)) != NILLNODE) {
  231.     name = (char *)Lst_Datum(ln);
  232.     gn = Targ_FindNode (name, flags);
  233.     if (gn != NILGNODE) {
  234.         /*
  235.          * Note: Lst_AtEnd must come before the Lst_Concat so the nodes
  236.          * are added to the list in the order in which they were
  237.          * encountered in the makefile.
  238.          */
  239.         (void) Lst_AtEnd (nodes, (ClientData)gn);
  240.         if (gn->type & OP_DOUBLEDEP) {
  241.         (void)Lst_Concat (nodes, gn->cohorts, LST_CONCNEW);
  242.         }
  243.     } else if (flags == TARG_NOCREATE) {
  244.