summaryrefslogtreecommitdiff
path: root/arch.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch.c')
-rw-r--r--arch.c725
1 files changed, 304 insertions, 421 deletions
diff --git a/arch.c b/arch.c
index fa54908d8817..d0bc901171f6 100644
--- a/arch.c
+++ b/arch.c
@@ -1,4 +1,4 @@
-/* $NetBSD: arch.c,v 1.107 2020/08/30 11:15:05 rillig Exp $ */
+/* $NetBSD: arch.c,v 1.151 2020/10/31 18:41:07 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -68,19 +68,6 @@
* SUCH DAMAGE.
*/
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: arch.c,v 1.107 2020/08/30 11:15:05 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94";
-#else
-__RCSID("$NetBSD: arch.c,v 1.107 2020/08/30 11:15:05 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
/*-
* arch.c --
* Functions to manipulate libraries, archives and their members.
@@ -92,52 +79,53 @@ __RCSID("$NetBSD: arch.c,v 1.107 2020/08/30 11:15:05 rillig Exp $");
* is referenced.
*
* The interface to this module is:
- * Arch_ParseArchive Given an archive specification, return a list
- * of GNode's, one for each member in the spec.
- * FALSE is returned if the specification is
- * invalid for some reason.
+ * Arch_ParseArchive
+ * Given an archive specification, return a list
+ * of GNode's, one for each member in the spec.
+ * FALSE is returned if the specification is
+ * invalid for some reason.
*
- * Arch_Touch Alter the modification time of the archive
- * member described by the given node to be
- * the current time.
+ * Arch_Touch Alter the modification time of the archive
+ * member described by the given node to be
+ * the current time.
*
- * Arch_TouchLib Update the modification time of the library
- * described by the given node. This is special
- * because it also updates the modification time
- * of the library's table of contents.
+ * Arch_TouchLib Update the modification time of the library
+ * described by the given node. This is special
+ * because it also updates the modification time
+ * of the library's table of contents.
*
- * Arch_MTime Find the modification time of a member of
- * an archive *in the archive*. The time is also
- * placed in the member's GNode. Returns the
- * modification time.
+ * Arch_MTime Find the modification time of a member of
+ * an archive *in the archive*. The time is also
+ * placed in the member's GNode. Returns the
+ * modification time.
*
- * Arch_MemTime Find the modification time of a member of
- * an archive. Called when the member doesn't
- * already exist. Looks in the archive for the
- * modification time. Returns the modification
- * time.
+ * Arch_MemTime Find the modification time of a member of
+ * an archive. Called when the member doesn't
+ * already exist. Looks in the archive for the
+ * modification time. Returns the modification
+ * time.
*
- * Arch_FindLib Search for a library along a path. The
- * library name in the GNode should be in
- * -l<name> format.
+ * Arch_FindLib Search for a library along a path. The
+ * library name in the GNode should be in
+ * -l<name> format.
*
- * Arch_LibOODate Special function to decide if a library node
- * is out-of-date.
+ * Arch_LibOODate Special function to decide if a library node
+ * is out-of-date.
*
- * Arch_Init Initialize this module.
+ * Arch_Init Initialize this module.
*
- * Arch_End Cleanup this module.
+ * Arch_End Clean up this module.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/param.h>
#ifdef HAVE_AR_H
-#include <ar.h>
+#include <ar.h>
#else
struct ar_hdr {
char ar_name[16]; /* name */
@@ -153,17 +141,17 @@ struct ar_hdr {
};
#endif
#if defined(HAVE_RANLIB_H) && !(defined(__ELF__) || defined(NO_RANLIB))
-#include <ranlib.h>
+#include <ranlib.h>
#endif
-#include <stdio.h>
-#include <stdlib.h>
#ifdef HAVE_UTIME_H
-#include <utime.h>
+#include <utime.h>
#endif
-#include "make.h"
-#include "hash.h"
-#include "dir.h"
+#include "make.h"
+#include "dir.h"
+
+/* "@(#)arch.c 8.2 (Berkeley) 1/2/94" */
+MAKE_RCSID("$NetBSD: arch.c,v 1.151 2020/10/31 18:41:07 rillig Exp $");
#ifdef TARGET_MACHINE
#undef MAKE_MACHINE
@@ -174,17 +162,19 @@ struct ar_hdr {
#define MAKE_MACHINE_ARCH TARGET_MACHINE_ARCH
#endif
-static Lst archives; /* Lst of archives we've already examined */
+typedef struct List ArchList;
+typedef struct ListNode ArchListNode;
+
+static ArchList *archives; /* The archives we've already examined */
typedef struct Arch {
- char *name; /* Name of archive */
- Hash_Table members; /* All the members of the archive described
- * by <name, struct ar_hdr *> key/value pairs */
- char *fnametab; /* Extended name table strings */
- size_t fnamesize; /* Size of the string table */
+ char *name; /* Name of archive */
+ HashTable members; /* All the members of the archive described
+ * by <name, struct ar_hdr *> key/value pairs */
+ char *fnametab; /* Extended name table strings */
+ size_t fnamesize; /* Size of the string table */
} Arch;
-static struct ar_hdr *ArchStatMember(const char *, const char *, Boolean);
static FILE *ArchFindMember(const char *, const char *,
struct ar_hdr *, const char *);
#if defined(__svr4__) || defined(__SVR4) || defined(__ELF__)
@@ -219,25 +209,22 @@ static int ArchSVR4Entry(Arch *, char *, size_t, FILE *);
# define SARMAG 8
#endif
-#define AR_MAX_NAME_LEN (sizeof(arh.AR_NAME)-1)
#ifdef CLEANUP
static void
ArchFree(void *ap)
{
- Arch *a = (Arch *)ap;
- Hash_Search search;
- Hash_Entry *entry;
+ Arch *a = ap;
+ HashIter hi;
/* Free memory from hash entries */
- for (entry = Hash_EnumFirst(&a->members, &search);
- entry != NULL;
- entry = Hash_EnumNext(&search))
- free(Hash_GetValue(entry));
+ HashIter_Init(&hi, &a->members);
+ while (HashIter_Next(&hi) != NULL)
+ free(hi.entry->value);
free(a->name);
free(a->fnametab);
- Hash_DeleteTable(&a->members);
+ HashTable_Done(&a->members);
free(a);
}
#endif
@@ -262,46 +249,49 @@ ArchFree(void *ap)
*-----------------------------------------------------------------------
*/
Boolean
-Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
+Arch_ParseArchive(char **linePtr, GNodeList *nodeLst, GNode *ctxt)
{
- char *cp; /* Pointer into line */
- GNode *gn; /* New node */
- char *libName; /* Library-part of specification */
- char *memName; /* Member-part of specification */
- char saveChar; /* Ending delimiter of member-name */
- Boolean subLibName; /* TRUE if libName should have/had
- * variable substitution performed on it */
+ char *cp; /* Pointer into line */
+ GNode *gn; /* New node */
+ char *libName; /* Library-part of specification */
+ char *memName; /* Member-part of specification */
+ char saveChar; /* Ending delimiter of member-name */
+ Boolean subLibName; /* TRUE if libName should have/had
+ * variable substitution performed on it */
libName = *linePtr;
subLibName = FALSE;
- for (cp = libName; *cp != '(' && *cp != '\0'; cp++) {
+ for (cp = libName; *cp != '(' && *cp != '\0';) {
if (*cp == '$') {
/*
* Variable spec, so call the Var module to parse the puppy
* so we can safely advance beyond it...
*/
- int length;
- void *result_freeIt;
- const char *result;
+ const char *nested_p = cp;
+ void *result_freeIt;
+ const char *result;
Boolean isError;
- result = Var_Parse(cp, ctxt, VARE_UNDEFERR|VARE_WANTRES,
- &length, &result_freeIt);
+ (void)Var_Parse(&nested_p, ctxt, VARE_UNDEFERR|VARE_WANTRES,
+ &result, &result_freeIt);
+ /* TODO: handle errors */
isError = result == var_Error;
free(result_freeIt);
if (isError)
return FALSE;
subLibName = TRUE;
- cp += length - 1;
- }
+ cp += nested_p - cp;
+ } else
+ cp++;
}
*cp++ = '\0';
if (subLibName) {
- libName = Var_Subst(libName, ctxt, VARE_UNDEFERR|VARE_WANTRES);
+ (void)Var_Subst(libName, ctxt, VARE_UNDEFERR|VARE_WANTRES, &libName);
+ /* TODO: handle errors */
}
@@ -311,25 +301,25 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
* place and skip to the end of it (either white-space or
* a close paren).
*/
- Boolean doSubst = FALSE; /* TRUE if need to substitute in memName */
+ Boolean doSubst = FALSE; /* TRUE if need to substitute in memName */
+
+ pp_skip_whitespace(&cp);
- while (*cp != '\0' && *cp != ')' && isspace ((unsigned char)*cp)) {
- cp++;
- }
memName = cp;
- while (*cp != '\0' && *cp != ')' && !isspace ((unsigned char)*cp)) {
+ while (*cp != '\0' && *cp != ')' && !ch_isspace(*cp)) {
if (*cp == '$') {
/*
* Variable spec, so call the Var module to parse the puppy
* so we can safely advance beyond it...
*/
- int length;
- void *freeIt;
+ void *freeIt;
const char *result;
Boolean isError;
+ const char *nested_p = cp;
- result = Var_Parse(cp, ctxt, VARE_UNDEFERR|VARE_WANTRES,
- &length, &freeIt);
+ (void)Var_Parse(&nested_p, ctxt, VARE_UNDEFERR|VARE_WANTRES,
+ &result, &freeIt);
+ /* TODO: handle errors */
isError = result == var_Error;
free(freeIt);
@@ -337,7 +327,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
return FALSE;
doSubst = TRUE;
- cp += length;
+ cp += nested_p - cp;
} else {
cp++;
}
@@ -376,11 +366,13 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
* later.
*/
if (doSubst) {
- char *buf;
- char *sacrifice;
- char *oldMemName = memName;
+ char *buf;
+ char *sacrifice;
+ char *oldMemName = memName;
- memName = Var_Subst(memName, ctxt, VARE_UNDEFERR | VARE_WANTRES);
+ (void)Var_Subst(memName, ctxt, VARE_UNDEFERR|VARE_WANTRES,
+ &memName);
+ /* TODO: handle errors */
/*
* Now form an archive spec and recurse to deal with nested
@@ -395,85 +387,48 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
* Just create an ARCHV node for the thing and let
* SuffExpandChildren handle it...
*/
- gn = Targ_FindNode(buf, TARG_CREATE);
+ gn = Targ_GetNode(buf);
+ gn->type |= OP_ARCHV;
+ Lst_Append(nodeLst, gn);
- if (gn == NULL) {
- free(buf);
- return FALSE;
- } else {
- gn->type |= OP_ARCHV;
- Lst_Append(nodeLst, gn);
- }
} else if (!Arch_ParseArchive(&sacrifice, nodeLst, ctxt)) {
- /*
- * Error in nested call -- free buffer and return FALSE
- * ourselves.
- */
+ /* Error in nested call. */
free(buf);
return FALSE;
}
- /*
- * Free buffer and continue with our work.
- */
free(buf);
- } else if (Dir_HasWildcards(memName)) {
- Lst members = Lst_Init();
- Buffer nameBuf;
- Buf_Init(&nameBuf, 0);
+ } else if (Dir_HasWildcards(memName)) {
+ StringList *members = Lst_New();
Dir_Expand(memName, dirSearchPath, members);
+
while (!Lst_IsEmpty(members)) {
char *member = Lst_Dequeue(members);
-
- Buf_Empty(&nameBuf);
- Buf_AddStr(&nameBuf, libName);
- Buf_AddStr(&nameBuf, "(");
- Buf_AddStr(&nameBuf, member);
- Buf_AddStr(&nameBuf, ")");
+ char *fullname = str_concat4(libName, "(", member, ")");
free(member);
- gn = Targ_FindNode(Buf_GetAll(&nameBuf, NULL), TARG_CREATE);
- if (gn == NULL) {
- Buf_Destroy(&nameBuf, TRUE);
- return FALSE;
- } else {
- /*
- * We've found the node, but have to make sure the rest of
- * the world knows it's an archive member, without having
- * to constantly check for parentheses, so we type the
- * thing with the OP_ARCHV bit before we place it on the
- * end of the provided list.
- */
- gn->type |= OP_ARCHV;
- Lst_Append(nodeLst, gn);
- }
- }
- Lst_Free(members);
- Buf_Destroy(&nameBuf, TRUE);
- } else {
- Buffer nameBuf;
-
- Buf_Init(&nameBuf, 0);
- Buf_AddStr(&nameBuf, libName);
- Buf_AddStr(&nameBuf, "(");
- Buf_AddStr(&nameBuf, memName);
- Buf_AddStr(&nameBuf, ")");
+ gn = Targ_GetNode(fullname);
+ free(fullname);
- gn = Targ_FindNode(Buf_GetAll(&nameBuf, NULL), TARG_CREATE);
- Buf_Destroy(&nameBuf, TRUE);
- if (gn == NULL) {
- return FALSE;
- } else {
- /*
- * We've found the node, but have to make sure the rest of the
- * world knows it's an archive member, without having to
- * constantly check for parentheses, so we type the thing with
- * the OP_ARCHV bit before we place it on the end of the
- * provided list.
- */
gn->type |= OP_ARCHV;
Lst_Append(nodeLst, gn);
}
+ Lst_Free(members);
+
+ } else {
+ char *fullname = str_concat4(libName, "(", memName, ")");
+ gn = Targ_GetNode(fullname);
+ free(fullname);
+
+ /*
+ * We've found the node, but have to make sure the rest of the
+ * world knows it's an archive member, without having to
+ * constantly check for parentheses, so we type the thing with
+ * the OP_ARCHV bit before we place it on the end of the
+ * provided list.
+ */
+ gn->type |= OP_ARCHV;
+ Lst_Append(nodeLst, gn);
}
if (doSubst) {
free(memName);
@@ -489,91 +444,70 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
free(libName);
}
- /*
- * We promised the pointer would be set up at the next non-space, so
- * we must advance cp there before setting *linePtr... (note that on
- * entrance to the loop, cp is guaranteed to point at a ')')
- */
- do {
- cp++;
- } while (*cp != '\0' && isspace ((unsigned char)*cp));
-
+ cp++; /* skip the ')' */
+ /* We promised that linePtr would be set up at the next non-space. */
+ pp_skip_whitespace(&cp);
*linePtr = cp;
return TRUE;
}
-/* See if the given archive is the one we are looking for.
- * Called via Lst_Find. */
-static Boolean
-ArchFindArchive(const void *ar, const void *desiredName)
-{
- return strcmp(((const Arch *)ar)->name, desiredName) == 0;
-}
-
-/*-
- *-----------------------------------------------------------------------
- * ArchStatMember --
- * Locate a member of an archive, given the path of the archive and
- * the path of the desired member.
+/* Locate a member of an archive, given the path of the archive and the path
+ * of the desired member.
*
* Input:
* archive Path to the archive
- * member Name of member. If it is a path, only the last
- * component is used.
+ * member Name of member; only its basename is used.
* hash TRUE if archive should be hashed if not already so.
*
* Results:
- * A pointer to the current struct ar_hdr structure for the member. Note
- * That no position is returned, so this is not useful for touching
- * archive members. This is mostly because we have no assurances that
- * The archive will remain constant after we read all the headers, so
- * there's not much point in remembering the position...
- *-----------------------------------------------------------------------
+ * The ar_hdr for the member.
*/
static struct ar_hdr *
ArchStatMember(const char *archive, const char *member, Boolean hash)
{
- FILE * arch; /* Stream to archive */
- size_t size; /* Size of archive member */
- char magic[SARMAG];
- LstNode ln; /* Lst member containing archive descriptor */
- Arch *ar; /* Archive descriptor */
- Hash_Entry *he; /* Entry containing member's description */
- struct ar_hdr arh; /* archive-member header for reading archive */
- char memName[MAXPATHLEN+1];
- /* Current member name while hashing. */
+#define AR_MAX_NAME_LEN (sizeof(arh.AR_NAME) - 1)
+ FILE *arch; /* Stream to archive */
+ size_t size; /* Size of archive member */
+ char magic[SARMAG];
+ ArchListNode *ln;
+ Arch *ar; /* Archive descriptor */
+ struct ar_hdr arh; /* archive-member header for reading archive */
+ char memName[MAXPATHLEN + 1];
+ /* Current member name while hashing. */
/*
* Because of space constraints and similar things, files are archived
- * using their final path components, not the entire thing, so we need
- * to point 'member' to the final component, if there is one, to make
- * the comparisons easier...
+ * using their basename, not the entire path.
*/
- const char *base = strrchr(member, '/');
- if (base != NULL) {
- member = base + 1;
+ const char *lastSlash = strrchr(member, '/');
+ if (lastSlash != NULL)
+ member = lastSlash + 1;
+
+ for (ln = archives->first; ln != NULL; ln = ln->next) {
+ const Arch *archPtr = ln->datum;
+ if (strcmp(archPtr->name, archive) == 0)
+ break;
}
- ln = Lst_Find(archives, ArchFindArchive, archive);
if (ln != NULL) {
- ar = LstNode_Datum(ln);
+ struct ar_hdr *hdr;
- he = Hash_FindEntry(&ar->members, member);
+ ar = ln->datum;
+ hdr = HashTable_FindValue(&ar->members, member);
+ if (hdr != NULL)
+ return hdr;
- if (he != NULL) {
- return (struct ar_hdr *)Hash_GetValue(he);
- } else {
+ {
/* Try truncated name */
- char copy[AR_MAX_NAME_LEN+1];
+ char copy[AR_MAX_NAME_LEN + 1];
size_t len = strlen(member);
if (len > AR_MAX_NAME_LEN) {
len = AR_MAX_NAME_LEN;
snprintf(copy, sizeof copy, "%s", member);
}
- if ((he = Hash_FindEntry(&ar->members, copy)) != NULL)
- return (struct ar_hdr *)Hash_GetValue(he);
- return NULL;
+ hdr = HashTable_FindValue(&ar->members, copy);
+ return hdr;
}
}
@@ -585,16 +519,14 @@ ArchStatMember(const char *archive, const char *member, Boolean hash)
* no need to allocate extra room for the header we're returning,
* so just declare it static.
*/
- static struct ar_hdr sarh;
-
- arch = ArchFindMember(archive, member, &sarh, "r");
+ static struct ar_hdr sarh;
- if (arch == NULL) {
+ arch = ArchFindMember(archive, member, &sarh, "r");
+ if (arch == NULL)
return NULL;
- } else {
- fclose(arch);
- return &sarh;
- }
+
+ fclose(arch);
+ return &sarh;
}
/*
@@ -602,9 +534,8 @@ ArchStatMember(const char *archive, const char *member, Boolean hash)
* everything that's in it and cache it so we can get at it quickly.
*/
arch = fopen(archive, "r");
- if (arch == NULL) {
+ if (arch == NULL)
return NULL;
- }
/*
* We use the ARMAG string to make sure this is an archive we
@@ -612,19 +543,19 @@ ArchStatMember(const char *archive, const char *member, Boolean hash)
*/
if ((fread(magic, SARMAG, 1, arch) != 1) ||
(strncmp(magic, ARMAG, SARMAG) != 0)) {
- fclose(arch);
- return NULL;
+ fclose(arch);
+ return NULL;
}
ar = bmake_malloc(sizeof(Arch));
ar->name = bmake_strdup(archive);
ar->fnametab = NULL;
ar->fnamesize = 0;
- Hash_InitTable(&ar->members, -1);
+ HashTable_Init(&ar->members);
memName[AR_MAX_NAME_LEN] = '\0';
while (fread((char *)&arh, sizeof(struct ar_hdr), 1, arch) == 1) {
- if (strncmp( arh.AR_FMAG, ARFMAG, sizeof(arh.AR_FMAG)) != 0) {
+ if (strncmp(arh.AR_FMAG, ARFMAG, sizeof(arh.AR_FMAG)) != 0) {
/*
* The header is bogus, so the archive is bad
* and there's no way we can recover...
@@ -639,7 +570,7 @@ ArchStatMember(const char *archive, const char *member, Boolean hash)
* boundary, so we need to extract the size of the file from the
* 'size' field of the header and round it up during the seek.
*/
- arh.AR_SIZE[sizeof(arh.AR_SIZE)-1] = '\0';
+ arh.AR_SIZE[sizeof(arh.AR_SIZE) - 1] = '\0';
size = (size_t)strtol(arh.ar_size, NULL, 10);
memcpy(memName, arh.AR_NAME, sizeof(arh.AR_NAME));
@@ -658,15 +589,14 @@ ArchStatMember(const char *archive, const char *member, Boolean hash)
* svr4 magic mode; handle it
*/
switch (ArchSVR4Entry(ar, memName, size, arch)) {
- case -1: /* Invalid data */
+ case -1: /* Invalid data */
goto badarch;
- case 0: /* List of files entry */
+ case 0: /* List of files entry */
continue;
- default: /* Got the entry */
+ default: /* Got the entry */
break;
}
- }
- else {
+ } else {
if (nameend[0] == '/')
nameend[0] = '\0';
}
@@ -678,26 +608,30 @@ ArchStatMember(const char *archive, const char *member, Boolean hash)
* first <namelen> bytes of the file
*/
if (strncmp(memName, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 &&
- isdigit((unsigned char)memName[sizeof(AR_EFMT1) - 1])) {
+ ch_isdigit(memName[sizeof(AR_EFMT1) - 1])) {
- int elen = atoi(&memName[sizeof(AR_EFMT1)-1]);
+ int elen = atoi(&memName[sizeof(AR_EFMT1) - 1]);
if ((unsigned int)elen > MAXPATHLEN)
- goto badarch;
+ goto badarch;
if (fread(memName, (size_t)elen, 1, arch) != 1)
- goto badarch;
+ goto badarch;
memName[elen] = '\0';
if (fseek(arch, -elen, SEEK_CUR) != 0)
- goto badarch;
+ goto badarch;
if (DEBUG(ARCH) || DEBUG(MAKE)) {
- fprintf(debug_file, "ArchStat: Extended format entry for %s\n", memName);
+ debug_printf("ArchStat: Extended format entry for %s\n",
+ memName);
}
}
#endif
- he = Hash_CreateEntry(&ar->members, memName, NULL);
- Hash_SetValue(he, bmake_malloc(sizeof(struct ar_hdr)));
- memcpy(Hash_GetValue(he), &arh, sizeof(struct ar_hdr));
+ {
+ HashEntry *he;
+ he = HashTable_CreateEntry(&ar->members, memName, NULL);
+ HashEntry_Set(he, bmake_malloc(sizeof(struct ar_hdr)));
+ memcpy(HashEntry_Get(he), &arh, sizeof(struct ar_hdr));
+ }
}
if (fseek(arch, ((long)size + 1) & ~1, SEEK_CUR) != 0)
goto badarch;
@@ -711,17 +645,11 @@ ArchStatMember(const char *archive, const char *member, Boolean hash)
* Now that the archive has been read and cached, we can look into
* the hash table to find the desired member's header.
*/
- he = Hash_FindEntry(&ar->members, member);
-
- if (he != NULL) {
- return (struct ar_hdr *)Hash_GetValue(he);
- } else {
- return NULL;
- }
+ return HashTable_FindValue(&ar->members, member);
badarch:
fclose(arch);
- Hash_DeleteTable(&ar->members);
+ HashTable_Done(&ar->members);
free(ar->fnametab);
free(ar);
return NULL;
@@ -757,9 +685,7 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
strncmp(name, ARLONGNAMES2, sizeof(ARLONGNAMES2) - 1) == 0) {
if (ar->fnametab != NULL) {
- if (DEBUG(ARCH)) {
- fprintf(debug_file, "Attempted to redefine an SVR4 name table\n");
- }
+ DEBUG0(ARCH, "Attempted to redefine an SVR4 name table\n");
return -1;
}
@@ -771,29 +697,17 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
ar->fnamesize = size;
if (fread(ar->fnametab, size, 1, arch) != 1) {
- if (DEBUG(ARCH)) {
- fprintf(debug_file, "Reading an SVR4 name table failed\n");
- }
+ DEBUG0(ARCH, "Reading an SVR4 name table failed\n");
return -1;
}
eptr = ar->fnametab + size;
for (entry = 0, ptr = ar->fnametab; ptr < eptr; ptr++)
- switch (*ptr) {
- case '/':
+ if (*ptr == '/') {
entry++;
*ptr = '\0';
- break;
-
- case '\n':
- break;
-
- default:
- break;
}
- if (DEBUG(ARCH)) {
- fprintf(debug_file, "Found svr4 archive name table with %lu entries\n",
- (unsigned long)entry);
- }
+ DEBUG1(ARCH, "Found svr4 archive name table with %lu entries\n",
+ (unsigned long)entry);
return 0;
}
@@ -802,22 +716,16 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
entry = (size_t)strtol(&name[1], &eptr, 0);
if ((*eptr != ' ' && *eptr != '\0') || eptr == &name[1]) {
- if (DEBUG(ARCH)) {
- fprintf(debug_file, "Could not parse SVR4 name %s\n", name);
- }
+ DEBUG1(ARCH, "Could not parse SVR4 name %s\n", name);
return 2;
}
if (entry >= ar->fnamesize) {
- if (DEBUG(ARCH)) {
- fprintf(debug_file, "SVR4 entry offset %s is greater than %lu\n",
- name, (unsigned long)ar->fnamesize);
- }
+ DEBUG2(ARCH, "SVR4 entry offset %s is greater than %lu\n",
+ name, (unsigned long)ar->fnamesize);
return 2;
}
- if (DEBUG(ARCH)) {
- fprintf(debug_file, "Replaced %s with %s\n", name, &ar->fnametab[entry]);
- }
+ DEBUG2(ARCH, "Replaced %s with %s\n", name, &ar->fnametab[entry]);
snprintf(name, MAXPATHLEN + 1, "%s", &ar->fnametab[entry]);
return 1;
@@ -848,18 +756,17 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
*/
static FILE *
ArchFindMember(const char *archive, const char *member, struct ar_hdr *arhPtr,
- const char *mode)
+ const char *mode)
{
- FILE * arch; /* Stream to archive */
- int size; /* Size of archive member */
- char magic[SARMAG];
- size_t len, tlen;
- const char * base;
+ FILE *arch; /* Stream to archive */
+ int size; /* Size of archive member */
+ char magic[SARMAG];
+ size_t len, tlen;
+ const char *lastSlash;
arch = fopen(archive, mode);
- if (arch == NULL) {
+ if (arch == NULL)
return NULL;
- }
/*
* We use the ARMAG string to make sure this is an archive we
@@ -867,34 +774,35 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *arhPtr,
*/
if ((fread(magic, SARMAG, 1, arch) != 1) ||
(strncmp(magic, ARMAG, SARMAG) != 0)) {
- fclose(arch);
- return NULL;
+ fclose(arch);
+ return NULL;
}
/*
* Because of space constraints and similar things, files are archived
- * using their final path components, not the entire thing, so we need
- * to point 'member' to the final component, if there is one, to make
- * the comparisons easier...
+ * using their basename, not the entire path.
*/
- base = strrchr(member, '/');
- if (base != NULL) {
- member = base + 1;
- }
+ lastSlash = strrchr(member, '/');
+ if (lastSlash != NULL)
+ member = lastSlash + 1;
+
len = tlen = strlen(member);
if (len > sizeof(arhPtr->AR_NAME)) {
tlen = sizeof(arhPtr->AR_NAME);
}
while (fread((char *)arhPtr, sizeof(struct ar_hdr), 1, arch) == 1) {
- if (strncmp(arhPtr->AR_FMAG, ARFMAG, sizeof(arhPtr->AR_FMAG) ) != 0) {
- /*
- * The header is bogus, so the archive is bad
- * and there's no way we can recover...
- */
- fclose(arch);
- return NULL;
- } else if (strncmp(member, arhPtr->AR_NAME, tlen) == 0) {
+
+ if (strncmp(arhPtr->AR_FMAG, ARFMAG, sizeof(arhPtr->AR_FMAG)) != 0) {
+ /*
+ * The header is bogus, so the archive is bad
+ * and there's no way we can recover...
+ */
+ fclose(arch);
+ return NULL;
+ }
+
+ if (strncmp(member, arhPtr->AR_NAME, tlen) == 0) {
/*
* If the member's name doesn't take up the entire 'name' field,
* we have to be careful of matching prefixes. Names are space-
@@ -902,79 +810,76 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *arhPtr,
* of the matched string is anything but a space, this isn't the
* member we sought.
*/
- if (tlen != sizeof(arhPtr->AR_NAME) && arhPtr->AR_NAME[tlen] != ' '){
+ if (tlen != sizeof arhPtr->AR_NAME && arhPtr->AR_NAME[tlen] != ' ')
goto skip;
- } else {
- /*
- * To make life easier, we reposition the file at the start
- * of the header we just read before we return the stream.
- * In a more general situation, it might be better to leave
- * the file at the actual member, rather than its header, but
- * not here...
- */
- if (fseek(arch, -(long)sizeof(struct ar_hdr), SEEK_CUR) != 0) {
- fclose(arch);
- return NULL;
- }
- return arch;
+
+ /*
+ * To make life easier, we reposition the file at the start
+ * of the header we just read before we return the stream.
+ * In a more general situation, it might be better to leave
+ * the file at the actual member, rather than its header, but
+ * not here...
+ */
+ if (fseek(arch, -(long)sizeof(struct ar_hdr), SEEK_CUR) != 0) {
+ fclose(arch);
+ return NULL;
}
- } else
-#ifdef AR_EFMT1
- /*
- * BSD 4.4 extended AR format: #1/<namelen>, with name as the
- * first <namelen> bytes of the file
- */
- if (strncmp(arhPtr->AR_NAME, AR_EFMT1,
- sizeof(AR_EFMT1) - 1) == 0 &&
- isdigit((unsigned char)arhPtr->AR_NAME[sizeof(AR_EFMT1) - 1])) {
+ return arch;
+ }
- int elen = atoi(&arhPtr->AR_NAME[sizeof(AR_EFMT1)-1]);
- char ename[MAXPATHLEN + 1];
+#ifdef AR_EFMT1
+ /*
+ * BSD 4.4 extended AR format: #1/<namelen>, with name as the
+ * first <namelen> bytes of the file
+ */
+ if (strncmp(arhPtr->AR_NAME, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 &&
+ ch_isdigit(arhPtr->AR_NAME[sizeof(AR_EFMT1) - 1]))
+ {
+ int elen = atoi(&arhPtr->AR_NAME[sizeof(AR_EFMT1) - 1]);
+ char ename[MAXPATHLEN + 1];
- if ((unsigned int)elen > MAXPATHLEN) {
- fclose(arch);
- return NULL;
- }
- if (fread(ename, (size_t)elen, 1, arch) != 1) {
- fclose(arch);
- return NULL;
- }
- ename[elen] = '\0';
- if (DEBUG(ARCH) || DEBUG(MAKE)) {
- fprintf(debug_file, "ArchFind: Extended format entry for %s\n", ename);
- }
- if (strncmp(ename, member, len) == 0) {
- /* Found as extended name */
- if (fseek(arch, -(long)sizeof(struct ar_hdr) - elen,
- SEEK_CUR) != 0) {
- fclose(arch);
- return NULL;
- }
- return arch;
- }
- if (fseek(arch, -elen, SEEK_CUR) != 0) {
+ if ((unsigned int)elen > MAXPATHLEN) {
+ fclose(arch);
+ return NULL;
+ }
+ if (fread(ename, (size_t)elen, 1, arch) != 1) {
+ fclose(arch);
+ return NULL;
+ }
+ ename[elen] = '\0';
+ if (DEBUG(ARCH) || DEBUG(MAKE)) {
+ debug_printf("ArchFind: Extended format entry for %s\n", ename);
+ }
+ if (strncmp(ename, member, len) == 0) {
+ /* Found as extended name */
+ if (fseek(arch, -(long)sizeof(struct ar_hdr) - elen,
+ SEEK_CUR) != 0) {
fclose(arch);
return NULL;
}
- goto skip;
- } else
-#endif
- {
-skip:
- /*
- * This isn't the member we're after, so we need to advance the
- * stream's pointer to the start of the next header. Files are
- * padded with newlines to an even-byte boundary, so we need to
- * extract the size of the file from the 'size' field of the
- * header and round it up during the seek.
- */
- arhPtr->AR_SIZE[sizeof(arhPtr->AR_SIZE)-1] = '\0';
- size = (int)strtol(arhPtr->AR_SIZE, NULL, 10);
- if (fseek(arch, (size + 1) & ~1, SEEK_CUR) != 0) {
+ return arch;
+ }
+ if (fseek(arch, -elen, SEEK_CUR) != 0) {
fclose(arch);
return NULL;
}
}
+#endif
+
+skip:
+ /*
+ * This isn't the member we're after, so we need to advance the
+ * stream's pointer to the start of the next header. Files are
+ * padded with newlines to an even-byte boundary, so we need to
+ * extract the size of the file from the 'size' field of the
+ * header and round it up during the seek.
+ */
+ arhPtr->ar_size[sizeof(arhPtr->ar_size) - 1] = '\0';
+ size = (int)strtol(arhPtr->ar_size, NULL, 10);
+ if (fseek(arch, (size + 1) & ~1, SEEK_CUR) != 0) {
+ fclose(arch);
+ return NULL;
+ }
}
/*
@@ -1003,18 +908,13 @@ skip:
void
Arch_Touch(GNode *gn)
{
- FILE * arch; /* Stream open to archive, positioned properly */
- struct ar_hdr arh; /* Current header describing member */
- char *p1, *p2;
+ FILE *arch; /* Stream open to archive, positioned properly */
+ struct ar_hdr arh; /* Current header describing member */
- arch = ArchFindMember(Var_Value(ARCHIVE, gn, &p1),
- Var_Value(MEMBER, gn, &p2),
+ arch = ArchFindMember(GNode_VarArchive(gn), GNode_VarMember(gn),
&arh, "r+");
- bmake_free(p1);
- bmake_free(p2);
-
- snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now);
+ snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long)now);
if (arch != NULL) {
(void)fwrite((char *)&arh, sizeof(struct ar_hdr), 1, arch);
@@ -1036,7 +936,7 @@ Arch_TouchLib(GNode *gn)
{
#ifdef RANLIBMAG
FILE * arch; /* Stream open to archive */
- struct ar_hdr arh; /* Header describing table of contents */
+ struct ar_hdr arh; /* Header describing table of contents */
struct utimbuf times; /* Times for utime() call */
arch = ArchFindMember(gn->path, RANLIBMAG, &arh, "r+");
@@ -1063,17 +963,10 @@ Arch_TouchLib(GNode *gn)
time_t
Arch_MTime(GNode *gn)
{
- struct ar_hdr *arhPtr; /* Header of desired member */
- time_t modTime; /* Modification time as an integer */
- char *p1, *p2;
-
- arhPtr = ArchStatMember(Var_Value(ARCHIVE, gn, &p1),
- Var_Value(MEMBER, gn, &p2),
- TRUE);
-
- bmake_free(p1);
- bmake_free(p2);
+ struct ar_hdr *arhPtr; /* Header of desired member */
+ time_t modTime; /* Modification time as an integer */
+ arhPtr = ArchStatMember(GNode_VarArchive(gn), GNode_VarMember(gn), TRUE);
if (arhPtr != NULL) {
modTime = (time_t)strtol(arhPtr->AR_DATE, NULL, 10);
} else {
@@ -1089,12 +982,10 @@ Arch_MTime(GNode *gn)
time_t
Arch_MemMTime(GNode *gn)
{
- LstNode ln;
- GNode *pgn;
+ GNodeListNode *ln;
- Lst_Open(gn->parents);
- while ((ln = Lst_Next(gn->parents)) != NULL) {
- pgn = LstNode_Datum(ln);
+ for (ln = gn->parents->first; ln != NULL; ln = ln->next) {
+ GNode *pgn = ln->datum;
if (pgn->type & OP_ARCHV) {
/*
@@ -1122,8 +1013,6 @@ Arch_MemMTime(GNode *gn)
}
}
- Lst_Close(gn->parents);
-
return gn->mtime;
}
@@ -1140,26 +1029,19 @@ Arch_MemMTime(GNode *gn)
*
* Input:
* gn Node of library to find
- * path Search path
*/
void
-Arch_FindLib(GNode *gn, Lst path)
+Arch_FindLib(GNode *gn, SearchPath *path)
{
- char *libName; /* file name for archive */
- size_t sz = strlen(gn->name) + 6 - 2;
-
- libName = bmake_malloc(sz);
- snprintf(libName, sz, "lib%s.a", &gn->name[2]);
-
+ char *libName = str_concat3("lib", gn->name + 2, ".a");
gn->path = Dir_FindFile(libName, path);
-
free(libName);
#ifdef LIBRARIES
Var_Set(TARGET, gn->name, gn);
#else
Var_Set(TARGET, gn->path == NULL ? gn->name : gn->path, gn);
-#endif /* LIBRARIES */
+#endif
}
/* Decide if a node with the OP_LIB attribute is out-of-date. Called from
@@ -1176,7 +1058,7 @@ Arch_FindLib(GNode *gn, Lst path)
* given that it is a target on a dependency line somewhere:
*
* Its modification time is less than that of one of its sources
- * (gn->mtime < gn->cmgn->mtime).
+ * (gn->mtime < gn->youngestChild->mtime).
*
* Its modification time is greater than the time at which the make
* began (i.e. it's been modified in the course of the make, probably
@@ -1198,20 +1080,21 @@ Arch_FindLib(GNode *gn, Lst path)
Boolean
Arch_LibOODate(GNode *gn)
{
- Boolean oodate;
+ Boolean oodate;
if (gn->type & OP_PHONY) {
oodate = TRUE;
- } else if (OP_NOP(gn->type) && Lst_IsEmpty(gn->children)) {
+ } else if (!GNode_IsTarget(gn) && Lst_IsEmpty(gn->children)) {
oodate = FALSE;
- } else if ((!Lst_IsEmpty(gn->children) && gn->cmgn == NULL) ||
+ } else if ((!Lst_IsEmpty(gn->children) && gn->youngestChild == NULL) ||
(gn->mtime > now) ||
- (gn->cmgn != NULL && gn->mtime < gn->cmgn->mtime)) {
+ (gn->youngestChild != NULL &&
+ gn->mtime < gn->youngestChild->mtime)) {
oodate = TRUE;
} else {
#ifdef RANLIBMAG
- struct ar_hdr *arhPtr; /* Header for __.SYMDEF */
- int modTimeTOC; /* The table-of-contents's mod time */
+ struct ar_hdr *arhPtr; /* Header for __.SYMDEF */
+ int modTimeTOC; /* The table-of-contents's mod time */
arhPtr = ArchStatMember(gn->path, RANLIBMAG, FALSE);
@@ -1219,15 +1102,15 @@ Arch_LibOODate(GNode *gn)
modTimeTOC = (int)strtol(arhPtr->AR_DATE, NULL, 10);
if (DEBUG(ARCH) || DEBUG(MAKE)) {
- fprintf(debug_file, "%s modified %s...", RANLIBMAG, Targ_FmtTime(modTimeTOC));
+ debug_printf("%s modified %s...", RANLIBMAG, Targ_FmtTime(modTimeTOC));
}
- oodate = (gn->cmgn == NULL || gn->cmgn->mtime > modTimeTOC);
+ oodate = (gn->youngestChild == NULL || gn->youngestChild->mtime > modTimeTOC);
} else {
/*
* A library w/o a table of contents is out-of-date
*/
if (DEBUG(ARCH) || DEBUG(MAKE)) {
- fprintf(debug_file, "No t.o.c....");
+ debug_printf("No t.o.c....");
}
oodate = TRUE;
}
@@ -1238,14 +1121,14 @@ Arch_LibOODate(GNode *gn)
return oodate;
}
-/* Initialize things for this module. */
+/* Initialize the archives module. */
void
Arch_Init(void)
{
- archives = Lst_Init();
+ archives = Lst_New();
}
-/* Clean up things for this module. */
+/* Clean up the archives module. */
void
Arch_End(void)
{