home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bsd / src / make / make-amiga / arch.c next >
C/C++ Source or Header  |  1993-09-23  |  30KB  |  952 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[] = "@(#)arch.c    5.7 (Berkeley) 12/28/90";
  41. #endif /* not lint */
  42.  
  43. /*-
  44.  * arch.c --
  45.  *    Functions to manipulate libraries, archives and their members.
  46.  *
  47.  *    Once again, cacheing/hashing comes into play in the manipulation
  48.  * of archives. The first time an archive is referenced, all of its members'
  49.  * headers are read and hashed and the archive closed again. All hashed
  50.  * archives are kept on a list which is searched each time an archive member
  51.  * is referenced.
  52.  *
  53.  * The interface to this module is:
  54.  *    Arch_ParseArchive       Given an archive specification, return a list
  55.  *                          of GNode's, one for each member in the spec.
  56.  *                          FAILURE is returned if the specification is
  57.  *                          invalid for some reason.
  58.  *
  59.  *    Arch_Touch            Alter the modification time of the archive
  60.  *                          member described by the given node to be
  61.  *                          the current time.
  62.  *
  63.  *    Arch_TouchLib            Update the modification time of the library
  64.  *                          described by the given node. This is special
  65.  *                          because it also updates the modification time
  66.  *                          of the library's table of contents.
  67.  *
  68.  *    Arch_MTime            Find the modification time of a member of
  69.  *                          an archive *in the archive*. The time is also
  70.  *                          placed in the member's GNode. Returns the
  71.  *                          modification time.
  72.  *
  73.  *    Arch_MemTime            Find the modification time of a member of
  74.  *                          an archive. Called when the member doesn't
  75.  *                          already exist. Looks in the archive for the
  76.  *                          modification time. Returns the modification
  77.  *                          time.
  78.  *
  79.  *    Arch_FindLib            Search for a library along a path. The
  80.  *                          library name in the GNode should be in
  81.  *                          -l<name> format.
  82.  *
  83.  *    Arch_LibOODate            Special function to decide if a library node
  84.  *                          is out-of-date.
  85.  *
  86.  *    Arch_Init             Initialize this module.
  87.  */
  88.  
  89. #include    <sys/types.h>
  90. #include    <sys/stat.h>
  91. #include    <sys/time.h>
  92. #include    <ctype.h>
  93. #include    <ar.h>
  94. #include <ranlib.h>
  95. #include    <stdio.h>
  96. #include    "make.h"
  97. #include    "hash.h"
  98.  
  99. static Lst      archives;   /* Lst of archives we've already examined */
  100.  
  101. typedef struct Arch {
  102.     char      *name;      /* Name of archive */
  103.     Hash_Table      members;    /* All the members of the archive described
  104.                    * by <name, struct ar_hdr *> key/value pairs */
  105. } Arch;
  106.  
  107. static FILE *ArchFindMember();
  108.  
  109. /*-
  110.  *-----------------------------------------------------------------------
  111.  * Arch_ParseArchive --
  112.  *    Parse the archive specification in the given line and find/create
  113.  *    the nodes for the specified archive members, placing their nodes
  114.  *    on the given list.
  115.  *
  116.  * Results:
  117.  *    SUCCESS if it was a valid specification. The linePtr is updated
  118.  *    to point to the first non-space after the archive spec. The
  119.  *    nodes for the members are placed on the given list.
  120.  *
  121.  * Side Effects:
  122.  *    Some nodes may be created. The given list is extended.
  123.  *
  124.  *-----------------------------------------------------------------------
  125.  */
  126. ReturnStatus
  127. Arch_ParseArchive (linePtr, nodeLst, ctxt)
  128.     char        **linePtr;      /* Pointer to start of specification */
  129.     Lst                nodeLst;           /* Lst on which to place the nodes */
  130.     GNode           *ctxt;          /* Context in which to expand variables */
  131. {
  132.     register char   *cp;        /* Pointer into line */
  133.     GNode        *gn;             /* New node */
  134.     char        *libName;          /* Library-part of specification */
  135.     char        *memName;          /* Member-part of specification */
  136.     char        nameBuf[BSIZE]; /* temporary place for node name */
  137.     char        saveChar;          /* Ending delimiter of member-name */
  138.     Boolean         subLibName;        /* TRUE if libName should have/had
  139.                      * variable substitution performed on it */
  140.  
  141.     libName = *linePtr;
  142.     
  143.     subLibName = FALSE;
  144.  
  145.     for (cp = libName; *cp != '(' && *cp != '\0'; cp++) {
  146.     if (*cp == '$') {
  147.         /*
  148.          * Variable spec, so call the Var module to parse the puppy
  149.          * so we can safely advance beyond it...
  150.          */
  151.         int     length;
  152.         Boolean    freeIt;
  153.         char    *result;
  154.         
  155.         result=Var_Parse(cp, ctxt, TRUE, &length, &freeIt);
  156.         if (result == var_Error) {
  157.         return(FAILURE);
  158.         } else {
  159.         subLibName = TRUE;
  160.         }
  161.         
  162.         if (freeIt) {
  163.         free(result);
  164.         }
  165.         cp += length-1;
  166.     }
  167.     }
  168.  
  169.     *cp++ = '\0';
  170.     if (subLibName) {
  171.     libName = Var_Subst(libName, ctxt, TRUE);
  172.     }
  173.     
  174.  
  175.     while (1) {
  176.     /*
  177.      * First skip to the start of the member's name, mark that
  178.      * place and skip to the end of it (either white-space or
  179.      * a close paren).
  180.      */
  181.     Boolean    doSubst = FALSE; /* TRUE if need to substitute in memName */
  182.  
  183.     while (*cp != '\0' && *cp != ')' && isspace (*cp)) {
  184.         cp++;
  185.     }
  186.     memName = cp;
  187.     while (*cp != '\0' && *cp != ')' && !isspace (*cp)) {
  188.         if (*cp == '$') {
  189.         /*
  190.          * Variable spec, so call the Var module to parse the puppy
  191.          * so we can safely advance beyond it...
  192.          */
  193.         int     length;
  194.         Boolean    freeIt;
  195.         char    *result;
  196.  
  197.         result=Var_Parse(cp, ctxt, TRUE, &length, &freeIt);
  198.         if (result == var_Error) {
  199.             return(FAILURE);
  200.         } else {
  201.             doSubst = TRUE;
  202.         }
  203.  
  204.         if (freeIt) {
  205.             free(result);
  206.         }
  207.         cp += length;
  208.         } else {
  209.         cp++;
  210.         }
  211.     }
  212.  
  213.     /*
  214.      * If the specification ends without a closing parenthesis,
  215.      * chances are there's something wrong (like a missing backslash),
  216.      * so it's better to return failure than allow such things to happen
  217.      */
  218.     if (*cp == '\0') {
  219.         printf("No closing parenthesis in archive specification\n");
  220.         return (FAILURE);
  221.     }
  222.  
  223.     /*
  224.      * If we didn't move anywhere, we must be done
  225.      */
  226.     if (cp == memName) {
  227.         break;
  228.     }
  229.  
  230.     saveChar = *cp;
  231.     *cp = '\0';
  232.  
  233.     /*
  234.      * XXX: This should be taken care of intelligently by
  235.      * SuffExpandChildren, both for the archive and the member portions.
  236.      */
  237.     /*
  238.      * If member contains variables, try and substitute for them.
  239.      * This will slow down archive specs with dynamic sources, of course,
  240.      * since we'll be (non-)substituting them three times, but them's
  241.      * the breaks -- we need to do this since SuffExpandChildren calls
  242.      * us, otherwise we could assume the thing woul