1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-20 15:43:16 +00:00

Bring in a number of changes from NetBSD's make, fixing quite a few

problems in the process:

1. Quoting should work properly now.  In particular, Chet's reported bash
   make problem has gone away.
2. A lot of memory that just wasn't being free'd after use is now freed.
   This should cause make to take up a LOT less memory when dealing with
   archive targets.
3. Give proper credit to Adam de Boor in a number of files.
Obtained from: NetBSD (and Adam de Boor)
This commit is contained in:
Jordan K. Hubbard 1995-01-23 21:03:17 +00:00
parent 8d81c12227
commit 9f574f9a90
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=5814
33 changed files with 1494 additions and 754 deletions

View File

@ -1,7 +1,8 @@
# @(#)Makefile 8.1 (Berkeley) 6/6/93
# from: @(#)Makefile 5.2 (Berkeley) 12/28/90
# $Id: Makefile,v 1.6 1994/06/30 05:33:39 cgd Exp $
PROG= make
CFLAGS+=-I${.CURDIR}
CFLAGS+= -I${.CURDIR} -DPOSIX
SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \
make.c parse.c str.c suff.c targ.c var.c
SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \

View File

@ -84,15 +84,19 @@ static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94";
* is out-of-date.
*
* Arch_Init Initialize this module.
*
* Arch_End Cleanup this module.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/param.h>
#include <ctype.h>
#include <ar.h>
#include <ranlib.h>
#include <stdio.h>
#include <stdlib.h>
#include "make.h"
#include "hash.h"
#include "dir.h"
@ -106,10 +110,45 @@ typedef struct Arch {
* by <name, struct ar_hdr *> key/value pairs */
} Arch;
static int ArchFindArchive __P((Arch *, char *));
static int ArchFindArchive __P((ClientData, ClientData));
static void ArchFree __P((ClientData));
static struct ar_hdr *ArchStatMember __P((char *, char *, Boolean));
static FILE *ArchFindMember __P((char *, char *, struct ar_hdr *, char *));
/*-
*-----------------------------------------------------------------------
* ArchFree --
* Free memory used by an archive
*
* Results:
* None.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
static void
ArchFree(ap)
ClientData ap;
{
Arch *a = (Arch *) ap;
Hash_Search search;
Hash_Entry *entry;
/* Free memory from hash entries */
for (entry = Hash_EnumFirst(&a->members, &search);
entry != (Hash_Entry *)NULL;
entry = Hash_EnumNext(&search))
free((Address) Hash_GetValue (entry));
free(a->name);
Hash_DeleteTable(&a->members);
free((Address) a);
}
/*-
*-----------------------------------------------------------------------
* Arch_ParseArchive --
@ -375,10 +414,10 @@ Arch_ParseArchive (linePtr, nodeLst, ctxt)
*/
static int
ArchFindArchive (ar, archName)
Arch *ar; /* Current list element */
char *archName; /* Name we want */
ClientData ar; /* Current list element */
ClientData archName; /* Name we want */
{
return (strcmp (archName, ar->name));
return (strcmp ((char *) archName, ((Arch *) ar)->name));
}
/*-
@ -411,19 +450,12 @@ ArchStatMember (archive, member, hash)
int size; /* Size of archive member */
char *cp; /* Useful character pointer */
char magic[SARMAG];
int len;
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[AR_MAX_NAME_LEN+1];
/* Current member name while hashing. The name is
* truncated to AR_MAX_NAME_LEN bytes, but we need
* room for the null byte... */
char copy[AR_MAX_NAME_LEN+1];
/* Holds copy of last path element from member, if
* it has to be truncated, so we don't have to
* figure it out again once the table is hashed. */
char memName[MAXPATHLEN+1];
/* Current member name while hashing. */
/*
* Because of space constraints and similar things, files are archived
@ -435,13 +467,6 @@ ArchStatMember (archive, member, hash)
if (cp != (char *) NULL) {
member = cp + 1;
}
len = strlen (member);
if (len > AR_MAX_NAME_LEN) {
len = AR_MAX_NAME_LEN;
strncpy(copy, member, AR_MAX_NAME_LEN);
copy[AR_MAX_NAME_LEN] = '\0';
member = copy;
}
ln = Lst_Find (archives, (ClientData) archive, ArchFindArchive);
if (ln != NILLNODE) {
@ -452,6 +477,17 @@ ArchStatMember (archive, member, hash)
if (he != (Hash_Entry *) NULL) {
return ((struct ar_hdr *) Hash_GetValue (he));
} else {
/* Try truncated name */
char copy[AR_MAX_NAME_LEN+1];
int len = strlen (member);
if (len > AR_MAX_NAME_LEN) {
len = AR_MAX_NAME_LEN;
strncpy(copy, member, AR_MAX_NAME_LEN);
copy[AR_MAX_NAME_LEN] = '\0';
}
if (he = Hash_FindEntry (&ar->members, copy))
return ((struct ar_hdr *) Hash_GetValue (he));
return ((struct ar_hdr *) NULL);
}
}
@ -517,10 +553,39 @@ ArchStatMember (archive, member, hash)
}
cp[1] = '\0';
he = Hash_CreateEntry (&ar->members, strdup (memName),
(Boolean *)NULL);
#ifdef AR_EFMT1
/*
* BSD 4.4 extended AR format: #1/<namelen>, with name as the
* first <namelen> bytes of the file
*/
if (strncmp(memName, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 &&
isdigit(memName[sizeof(AR_EFMT1) - 1])) {
unsigned int elen = atoi(&memName[sizeof(AR_EFMT1)-1]);
if (elen > MAXPATHLEN) {
fclose (arch);
Hash_DeleteTable (&ar->members);
free ((Address)ar);
return ((struct ar_hdr *) NULL);
}
if (fread (memName, elen, 1, arch) != 1) {
fclose (arch);
Hash_DeleteTable (&ar->members);
free ((Address)ar);
return ((struct ar_hdr *) NULL);
}
memName[elen] = '\0';
fseek (arch, -elen, 1);
if (DEBUG(ARCH) || DEBUG(MAKE)) {
printf("ArchStat: Extended format entry for %s\n", memName);
}
}
#endif
he = Hash_CreateEntry (&ar->members, memName, (Boolean *)NULL);
Hash_SetValue (he, (ClientData)emalloc (sizeof (struct ar_hdr)));
memcpy ((Address)Hash_GetValue (he), (Address)&arh,
memcpy ((Address)Hash_GetValue (he), (Address)&arh,
sizeof (struct ar_hdr));
}
/*
@ -530,7 +595,7 @@ ArchStatMember (archive, member, hash)
* 'size' field of the header and round it up during the seek.
*/
arh.ar_size[sizeof(arh.ar_size)-1] = '\0';
(void) sscanf (arh.ar_size, "%10d", &size);
size = (int) strtol(arh.ar_size, NULL, 10);
fseek (arch, (size + 1) & ~1, 1);
}
@ -580,7 +645,7 @@ ArchFindMember (archive, member, arhPtr, mode)
int size; /* Size of archive member */
char *cp; /* Useful character pointer */
char magic[SARMAG];
int len;
int len, tlen;
arch = fopen (archive, mode);
if (arch == (FILE *) NULL) {
@ -607,9 +672,9 @@ ArchFindMember (archive, member, arhPtr, mode)
if (cp != (char *) NULL) {
member = cp + 1;
}
len = strlen (member);
len = tlen = strlen (member);
if (len > sizeof (arhPtr->ar_name)) {
len = sizeof (arhPtr->ar_name);
tlen = sizeof (arhPtr->ar_name);
}
while (fread ((char *)arhPtr, sizeof (struct ar_hdr), 1, arch) == 1) {
@ -620,7 +685,7 @@ ArchFindMember (archive, member, arhPtr, mode)
*/
fclose (arch);
return ((FILE *) NULL);
} else if (strncmp (member, arhPtr->ar_name, len) == 0) {
} else 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-
@ -628,8 +693,8 @@ ArchFindMember (archive, member, arhPtr, mode)
* of the matched string is anything but a space, this isn't the
* member we sought.
*/
if (len != sizeof(arhPtr->ar_name) && arhPtr->ar_name[len] != ' '){
continue;
if (tlen != sizeof(arhPtr->ar_name) && arhPtr->ar_name[tlen] != ' '){
goto skip;
} else {
/*
* To make life easier, we reposition the file at the start
@ -641,7 +706,42 @@ ArchFindMember (archive, member, arhPtr, mode)
fseek (arch, -sizeof(struct ar_hdr), 1);
return (arch);
}
} else {
} 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(arhPtr->ar_name[sizeof(AR_EFMT1) - 1])) {
unsigned int elen = atoi(&arhPtr->ar_name[sizeof(AR_EFMT1)-1]);
char ename[MAXPATHLEN];
if (elen > MAXPATHLEN) {
fclose (arch);
return NULL;
}
if (fread (ename, elen, 1, arch) != 1) {
fclose (arch);
return NULL;
}
ename[elen] = '\0';
if (DEBUG(ARCH) || DEBUG(MAKE)) {
printf("ArchFind: Extended format entry for %s\n", ename);
}
if (strncmp(ename, member, len) == 0) {
/* Found as extended name */
fseek (arch, -sizeof(struct ar_hdr) - elen, 1);
return (arch);
}
fseek (arch, -elen, 1);
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
@ -650,7 +750,7 @@ ArchFindMember (archive, member, arhPtr, mode)
* header and round it up during the seek.
*/
arhPtr->ar_size[sizeof(arhPtr->ar_size)-1] = '\0';
(void)sscanf (arhPtr->ar_size, "%10d", &size);
size = (int) strtol(arhPtr->ar_size, NULL, 10);
fseek (arch, (size + 1) & ~1, 1);
}
}
@ -684,10 +784,15 @@ Arch_Touch (gn)
{
FILE * arch; /* Stream open to archive, positioned properly */
struct ar_hdr arh; /* Current header describing member */
char *p1, *p2;
arch = ArchFindMember(Var_Value (ARCHIVE, gn),
Var_Value (TARGET, gn),
arch = ArchFindMember(Var_Value (ARCHIVE, gn, &p1),
Var_Value (TARGET, gn, &p2),
&arh, "r+");
if (p1)
free(p1);
if (p2)
free(p2);
sprintf(arh.ar_date, "%-12ld", (long) now);
if (arch != (FILE *) NULL) {
@ -752,12 +857,18 @@ Arch_MTime (gn)
{
struct ar_hdr *arhPtr; /* Header of desired member */
int modTime; /* Modification time as an integer */
char *p1, *p2;
arhPtr = ArchStatMember (Var_Value (ARCHIVE, gn),
Var_Value (TARGET, gn),
arhPtr = ArchStatMember (Var_Value (ARCHIVE, gn, &p1),
Var_Value (TARGET, gn, &p2),
TRUE);
if (p1)
free(p1);
if (p2)
free(p2);
if (arhPtr != (struct ar_hdr *) NULL) {
(void)sscanf (arhPtr->ar_date, "%12d", &modTime);
modTime = (int) strtol(arhPtr->ar_date, NULL, 10);
} else {
modTime = 0;
}
@ -886,10 +997,14 @@ Arch_FindLib (gn, path)
* 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 by archiving).
* Its modification time doesn't agree with the modification
* time of its RANLIBMAG member (i.e. its table of contents
* is out-of-date).
*
* The modification time of one of its sources is greater than
* the one of its RANLIBMAG member (i.e. its table of contents
* is out-of-date). We don't compare of the archive time
* vs. TOC time because they can be too close. In my
* opinion we should not bother with the TOC at all since
* this is used by 'ar' rules that affect the data contents
* of the archive, not by ranlib rules, which affect the
* TOC.
*
* Results:
* TRUE if the library is out-of-date. FALSE otherwise.
@ -916,12 +1031,12 @@ Arch_LibOODate (gn)
arhPtr = ArchStatMember (gn->path, RANLIBMAG, FALSE);
if (arhPtr != (struct ar_hdr *)NULL) {
(void)sscanf (arhPtr->ar_date, "%12d", &modTimeTOC);
modTimeTOC = (int) strtol(arhPtr->ar_date, NULL, 10);
if (DEBUG(ARCH) || DEBUG(MAKE)) {
printf("%s modified %s...", RANLIBMAG, Targ_FmtTime(modTimeTOC));
}
oodate = (gn->mtime > modTimeTOC);
oodate = (gn->cmtime > modTimeTOC);
} else {
/*
* A library w/o a table of contents is out-of-date
@ -953,3 +1068,24 @@ Arch_Init ()
{
archives = Lst_Init (FALSE);
}
/*-
*-----------------------------------------------------------------------
* Arch_End --
* Cleanup things for this module.
*
* Results:
* None.
*
* Side Effects:
* The 'archives' list is freed
*
*-----------------------------------------------------------------------
*/
void
Arch_End ()
{
Lst_Destroy(archives, ArchFree);
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@ -94,9 +94,9 @@ Buf_OvAddByte (bp, byte)
register Buffer bp;
int byte;
{
int nbytes = 1;
bp->left = 0;
BufExpand (bp, 1);
BufExpand (bp, nbytes);
*bp->inPtr++ = byte;
bp->left--;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@ -48,7 +48,7 @@
#include "sprite.h"
typedef unsigned char Byte;
typedef char Byte;
typedef struct Buffer {
int size; /* Current size of the buffer */
@ -65,16 +65,16 @@ typedef struct Buffer {
#define BUF_ERROR 256
void Buf_AddBytes __P((Buffer, int, Byte *));
void Buf_Destroy __P((Buffer, Boolean));
void Buf_Discard __P((Buffer, int));
Byte *Buf_GetAll __P((Buffer, int *));
int Buf_GetByte __P((Buffer));
int Buf_GetBytes __P((Buffer, int, Byte *));
Buffer Buf_Init __P((int));
void Buf_OvAddByte __P((Buffer, int));
int Buf_Size __P((Buffer));
void Buf_UngetByte __P((Buffer, int));
void Buf_UngetBytes __P((Buffer, int, Byte *));
void Buf_OvAddByte __P((Buffer, int));
void Buf_AddBytes __P((Buffer, int, Byte *));
void Buf_UngetByte __P((Buffer, int));
void Buf_UngetBytes __P((Buffer, int, Byte *));
int Buf_GetByte __P((Buffer));
int Buf_GetBytes __P((Buffer, int, Byte *));
Byte *Buf_GetAll __P((Buffer, int *));
void Buf_Discard __P((Buffer, int));
int Buf_Size __P((Buffer));
Buffer Buf_Init __P((int));
void Buf_Destroy __P((Buffer, Boolean));
#endif /* _BUF_H */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@ -53,15 +53,13 @@ static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
* thems as need creatin'
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/signal.h>
#include <sys/wait.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <ctype.h>
#include "make.h"
#include "hash.h"
#include "dir.h"
@ -80,8 +78,8 @@ static char meta[256];
static GNode *curTarg = NILGNODE;
static GNode *ENDNode;
static void CompatInterrupt __P((int));
static int CompatRunCommand __P((char *, GNode *));
static int CompatMake __P((GNode *, GNode *));
static int CompatRunCommand __P((ClientData, ClientData));
static int CompatMake __P((ClientData, ClientData));
/*-
*-----------------------------------------------------------------------
@ -102,16 +100,19 @@ static void
CompatInterrupt (signo)
int signo;
{
struct stat sb;
GNode *gn;
if ((curTarg != NILGNODE) && !Targ_Precious (curTarg)) {
char *file = Var_Value (TARGET, curTarg);
char *p1;
char *file = Var_Value (TARGET, curTarg, &p1);
struct stat st;
if (!stat(file, &sb) && S_ISREG(sb.st_mode) &&
unlink (file) == SUCCESS) {
if (!noExecute && lstat(file, &st) != -1 && !S_ISDIR(st.st_mode) &&
unlink(file) != -1) {
printf ("*** %s removed\n", file);
}
if (p1)
free(p1);
/*
* Run .INTERRUPT only if hit with interrupt signal
@ -122,8 +123,9 @@ CompatInterrupt (signo)
Lst_ForEach(gn->commands, CompatRunCommand, (ClientData)gn);
}
}
}
exit (0);
exit (signo);
}
/*-
@ -141,9 +143,9 @@ CompatInterrupt (signo)
*-----------------------------------------------------------------------
*/
static int
CompatRunCommand (cmd, gn)
char *cmd; /* Command to execute */
GNode *gn; /* Node from which the command came */
CompatRunCommand (cmdp, gnp)
ClientData cmdp; /* Command to execute */
ClientData gnp; /* Node from which the command came */
{
char *cmdStart; /* Start of expanded command */
register char *cp;
@ -159,16 +161,17 @@ CompatRunCommand (cmd, gn)
* dynamically allocated */
Boolean local; /* TRUE if command should be executed
* locally */
char *cmd = (char *) cmdp;
GNode *gn = (GNode *) gnp;
/*
/*
* Avoid clobbered variable warnings by forcing the compiler
* to ``unregister'' variables
*/
*/
#if __GNUC__
(void) &av;
(void) &av;
(void) &errCheck;
#endif
#endif
silent = gn->type & OP_SILENT;
errCheck = !(gn->type & OP_IGNORE);
@ -183,6 +186,7 @@ CompatRunCommand (cmd, gn)
*/
if (*cmdStart == '\0') {
free(cmdStart);
Error("%s expands to empty string", cmd);
return(0);
} else {
@ -257,7 +261,7 @@ CompatRunCommand (cmd, gn)
* brk_string sticks our name in av[0], so we have to
* skip over it...
*/
av = brk_string(cmd, &argc);
av = brk_string(cmd, &argc, TRUE);
av += 1;
}
@ -280,16 +284,13 @@ CompatRunCommand (cmd, gn)
}
exit(1);
}
free(cmdStart);
Lst_Replace (cmdNode, (ClientData) NULL);
/*
* The child is off and running. Now all we can do is wait...
*/
while (1) {
int id;
if (!local) {
id = 0;
}
while ((stat = wait((int *)&reason)) != cpid) {
if (stat == -1 && errno != EINTR) {
@ -354,10 +355,12 @@ CompatRunCommand (cmd, gn)
*-----------------------------------------------------------------------
*/
static int
CompatMake (gn, pgn)
GNode *gn; /* The node to make */
GNode *pgn; /* Parent to abort if necessary */
CompatMake (gnp, pgnp)
ClientData gnp; /* The node to make */
ClientData pgnp; /* Parent to abort if necessary */
{
GNode *gn = (GNode *) gnp;
GNode *pgn = (GNode *) pgnp;
if (gn->type & OP_USE) {
Make_HandleUse(gn, pgn);
} else if (gn->made == UNMADE) {
@ -380,7 +383,10 @@ CompatMake (gn, pgn)
}
if (Lst_Member (gn->iParents, pgn) != NILLNODE) {
Var_Set (IMPSRC, Var_Value(TARGET, gn), pgn);
char *p1;
Var_Set (IMPSRC, Var_Value(TARGET, gn, &p1), pgn);
if (p1)
free(p1);
}
/*
@ -528,7 +534,10 @@ CompatMake (gn, pgn)
pgn->make = FALSE;
} else {
if (Lst_Member (gn->iParents, pgn) != NILLNODE) {
Var_Set (IMPSRC, Var_Value(TARGET, gn), pgn);
char *p1;
Var_Set (IMPSRC, Var_Value(TARGET, gn, &p1), pgn);
if (p1)
free(p1);
}
switch(gn->made) {
case BEINGMADE:

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@ -96,7 +96,7 @@ typedef enum {
*/
static int CondGetArg __P((char **, char **, char *, Boolean));
static Boolean CondDoDefined __P((int, char *));
static int CondStrMatch __P((char *, char *));
static int CondStrMatch __P((ClientData, ClientData));
static Boolean CondDoMake __P((int, char *));
static Boolean CondDoExists __P((int, char *));
static Boolean CondDoTarget __P((int, char *));
@ -277,14 +277,17 @@ CondDoDefined (argLen, arg)
char *arg;
{
char savec = arg[argLen];
char *p1;
Boolean result;
arg[argLen] = '\0';
if (Var_Value (arg, VAR_CMD) != (char *)NULL) {
if (Var_Value (arg, VAR_CMD, &p1) != (char *)NULL) {
result = TRUE;
} else {
result = FALSE;
}
if (p1)
free(p1);
arg[argLen] = savec;
return (result);
}
@ -305,10 +308,10 @@ CondDoDefined (argLen, arg)
*/
static int
CondStrMatch(string, pattern)
char *string;
char *pattern;
ClientData string;
ClientData pattern;
{
return(!Str_Match(string,pattern));
return(!Str_Match((char *) string,(char *) pattern));
}
/*-
@ -532,7 +535,8 @@ CondToken(doEval)
}
condExpr += varSpecLen;
if (!isspace(*condExpr) && strchr("!=><", *condExpr) == NULL) {
if (!isspace((unsigned char) *condExpr) &&
strchr("!=><", *condExpr) == NULL) {
Buffer buf;
char *cp;
@ -544,7 +548,8 @@ CondToken(doEval)
if (doFree)
free(lhs);
for (;*condExpr && !isspace(*condExpr); condExpr++)
for (;*condExpr && !isspace((unsigned char) *condExpr);
condExpr++)
Buf_AddByte(buf, (Byte)*condExpr);
Buf_AddByte(buf, (Byte)'\0');
@ -557,7 +562,7 @@ CondToken(doEval)
/*
* Skip whitespace to get to the operator
*/
while (isspace(*condExpr))
while (isspace((unsigned char) *condExpr))
condExpr++;
/*
@ -583,7 +588,7 @@ CondToken(doEval)
goto do_compare;
}
while (isspace(*condExpr)) {
while (isspace((unsigned char) *condExpr)) {
condExpr++;
}
if (*condExpr == '\0') {
@ -703,7 +708,8 @@ CondToken(doEval)
/*
* Skip over the right-hand side
*/
while(!isspace(*condExpr) && (*condExpr != '\0')) {
while(!isspace((unsigned char) *condExpr) &&
(*condExpr != '\0')) {
condExpr++;
}
}
@ -810,9 +816,8 @@ CondToken(doEval)
for (arglen = 0;
condExpr[arglen] != '(' && condExpr[arglen] != '\0';
arglen += 1)
{
/* void */ ;
}
continue;
if (condExpr[arglen] != '\0') {
val = Var_Parse(&condExpr[arglen - 1], VAR_CMD,
doEval, &length, &doFree);
@ -824,7 +829,7 @@ CondToken(doEval)
* spaces... 4/15/92, christos
*/
char *p;
for (p = val; *p && isspace(*p); p++)
for (p = val; *p && isspace((unsigned char)*p); p++)
continue;
t = (*p == '\0') ? True : False;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@ -49,6 +49,8 @@ static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94";
* The interface for this module is:
* Dir_Init Initialize the module.
*
* Dir_End Cleanup the module.
*
* Dir_HasWildcards Returns TRUE if the name given it needs to
* be wildcard-expanded.
*
@ -184,12 +186,12 @@ static Hash_Table mtimes; /* Results of doing a last-resort stat in
* should be ok, but... */
static int DirFindName __P((Path *, char *));
static int DirFindName __P((ClientData, ClientData));
static int DirMatchFiles __P((char *, Path *, Lst));
static void DirExpandCurly __P((char *, char *, Lst, Lst));
static void DirExpandInt __P((char *, Lst, Lst));
static int DirPrintWord __P((char *));
static int DirPrintDir __P((Path *));
static int DirPrintWord __P((ClientData, ClientData));
static int DirPrintDir __P((ClientData, ClientData));
/*-
*-----------------------------------------------------------------------
@ -226,6 +228,30 @@ Dir_Init ()
dot->refCount += 1;
}
/*-
*-----------------------------------------------------------------------
* Dir_End --
* cleanup things for this module
*
* Results:
* none
*
* Side Effects:
* none
*-----------------------------------------------------------------------
*/
void
Dir_End()
{
dot->refCount -= 1;
Dir_Destroy((ClientData) dot);
Dir_ClearPath(dirSearchPath);
Lst_Destroy(dirSearchPath, NOFREE);
Dir_ClearPath(openDirectories);
Lst_Destroy(openDirectories, NOFREE);
Hash_DeleteTable(&mtimes);
}
/*-
*-----------------------------------------------------------------------
* DirFindName --
@ -242,10 +268,10 @@ Dir_Init ()
*/
static int
DirFindName (p, dname)
Path *p; /* Current name */
char *dname; /* Desired name */
ClientData p; /* Current name */
ClientData dname; /* Desired name */
{
return (strcmp (p->name, dname));
return (strcmp (((Path *)p)->name, (char *) dname));
}
/*-
@ -490,12 +516,13 @@ DirExpandInt(word, path, expansions)
*-----------------------------------------------------------------------
*/
static int
DirPrintWord(word)
char *word;
DirPrintWord(word, dummy)
ClientData word;
ClientData dummy;
{
printf("%s ", word);
printf("%s ", (char *) word);
return(0);
return(dummy ? 0 : 0);
}
/*-
@ -606,7 +633,7 @@ Dir_Expand (word, path, expansions)
}
}
if (DEBUG(DIR)) {
Lst_ForEach(expansions, DirPrintWord, NULL);
Lst_ForEach(expansions, DirPrintWord, (ClientData) 0);
fputc('\n', stdout);
}
}
@ -712,7 +739,7 @@ Dir_FindFile (name, path)
*/
p1 = p->name + strlen (p->name) - 1;
p2 = cp - 2;
while (p2 >= name && *p1 == *p2) {
while (p2 >= name && p1 >= p->name && *p1 == *p2) {
p1 -= 1; p2 -= 1;
}
if (p2 >= name || (p1 >= p->name && *p1 != '/')) {
@ -824,7 +851,7 @@ Dir_FindFile (name, path)
}
entry = Hash_CreateEntry(&mtimes, (char *) file,
(Boolean *)NULL);
Hash_SetValue(entry, stb.st_mtime);
Hash_SetValue(entry, (long)stb.st_mtime);
nearmisses += 1;
return (file);
} else {
@ -902,7 +929,7 @@ Dir_FindFile (name, path)
printf("Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
name);
}
Hash_SetValue(entry, stb.st_mtime);
Hash_SetValue(entry, (long)stb.st_mtime);
return (strdup (name));
} else {
if (DEBUG(DIR)) {
@ -946,7 +973,7 @@ Dir_MTime (gn)
}
if (fullName == (char *)NULL) {
fullName = gn->name;
fullName = strdup(gn->name);
}
entry = Hash_FindEntry(&mtimes, fullName);
@ -958,12 +985,14 @@ Dir_MTime (gn)
*/
if (DEBUG(DIR)) {
printf("Using cached time %s for %s\n",
Targ_FmtTime((time_t) Hash_GetValue(entry)), fullName);
Targ_FmtTime((time_t)(long)Hash_GetValue(entry)), fullName);
}
stb.st_mtime = (time_t)Hash_GetValue(entry);
stb.st_mtime = (time_t)(long)Hash_GetValue(entry);
Hash_DeleteEntry(&mtimes, entry);
} else if (stat (fullName, &stb) < 0) {
if (gn->type & OP_MEMBER) {
if (fullName != gn->path)
free(fullName);
return Arch_MemMTime (gn);
} else {
stb.st_mtime = 0;
@ -1039,7 +1068,7 @@ Dir_AddDir (path, name)
if (dp->d_fileno == 0) {
continue;
}
#endif sun
#endif /* sun */
(void)Hash_CreateEntry(&p->files, dp->d_name, (Boolean *)NULL);
}
(void) closedir (d);
@ -1068,9 +1097,9 @@ Dir_AddDir (path, name)
*/
ClientData
Dir_CopyDir(p)
Path *p; /* Directory descriptor to copy */
ClientData p;
{
p->refCount += 1;
((Path *) p)->refCount += 1;
return ((ClientData)p);
}
@ -1132,9 +1161,10 @@ Dir_MakeFlags (flag, path)
*-----------------------------------------------------------------------
*/
void
Dir_Destroy (p)
Path *p; /* The directory descriptor to nuke */
Dir_Destroy (pp)
ClientData pp; /* The directory descriptor to nuke */
{
Path *p = (Path *) pp;
p->refCount -= 1;
if (p->refCount == 0) {
@ -1170,7 +1200,7 @@ Dir_ClearPath(path)
Path *p;
while (!Lst_IsEmpty(path)) {
p = (Path *)Lst_DeQueue(path);
Dir_Destroy(p);
Dir_Destroy((ClientData) p);
}
}
@ -1228,7 +1258,13 @@ Dir_PrintDirectories()
}
}
static int DirPrintDir (p) Path *p; { printf ("%s ", p->name); return (0); }
static int DirPrintDir (p, dummy)
ClientData p;
ClientData dummy;
{
printf ("%s ", ((Path *) p)->name);
return (dummy ? 0 : 0);
}
void
Dir_PrintPath (path)

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@ -52,19 +52,19 @@ typedef struct Path {
Hash_Table files; /* Hash table of files in directory */
} Path;
void Dir_AddDir __P((Lst, char *));
void Dir_ClearPath __P((Lst));
void Dir_Concat __P((Lst, Lst));
ClientData
Dir_CopyDir __P((Path *));
void Dir_Destroy __P((Path *));
void Dir_Expand __P((char *, Lst, Lst));
char *Dir_FindFile __P((char *, Lst));
Boolean Dir_HasWildcards __P((char *));
void Dir_Init __P((void));
char *Dir_MakeFlags __P((char *, Lst));
int Dir_MTime __P((GNode *));
void Dir_PrintDirectories __P((void));
void Dir_PrintPath __P((Lst));
void Dir_Init __P((void));
void Dir_End __P((void));
Boolean Dir_HasWildcards __P((char *));
void Dir_Expand __P((char *, Lst, Lst));
char *Dir_FindFile __P((char *, Lst));
int Dir_MTime __P((GNode *));
void Dir_AddDir __P((Lst, char *));
char *Dir_MakeFlags __P((char *, Lst));
void Dir_ClearPath __P((Lst));
void Dir_Concat __P((Lst, Lst));
void Dir_PrintDirectories __P((void));
void Dir_PrintPath __P((Lst));
void Dir_Destroy __P((ClientData));
ClientData Dir_CopyDir __P((ClientData));
#endif /* _DIR */

View File

@ -1,9 +1,6 @@
/*
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Christos Zoulas.
* Copyright (c) 1992, The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -76,13 +73,13 @@ static Lst forLst; /* List of items */
/*
* State of a for loop.
*/
struct For {
typedef struct _For {
Buffer buf; /* Unexpanded buffer */
char* var; /* Index name */
Lst lst; /* List of variables */
};
} For;
static int ForExec __P((char *, struct For *));
static int ForExec __P((ClientData, ClientData));
@ -118,27 +115,28 @@ For_Eval (line)
Buffer buf;
int varlen;
for (ptr++; *ptr && isspace(*ptr); ptr++)
for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
continue;
/*
* If we are not in a for loop quickly determine if the statement is
* a for.
*/
if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' || !isspace(ptr[3]))
if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' ||
!isspace((unsigned char) ptr[3]))
return FALSE;
ptr += 3;
/*
* we found a for loop, and now we are going to parse it.
*/
while (*ptr && isspace(*ptr))
while (*ptr && isspace((unsigned char) *ptr))
ptr++;
/*
* Grab the variable
*/
buf = Buf_Init(0);
for (wrd = ptr; *ptr && !isspace(*ptr); ptr++)
for (wrd = ptr; *ptr && !isspace((unsigned char) *ptr); ptr++)
continue;
Buf_AddBytes(buf, ptr - wrd, (Byte *) wrd);
@ -149,20 +147,21 @@ For_Eval (line)
}
Buf_Destroy(buf, FALSE);
while (*ptr && isspace(*ptr))
while (*ptr && isspace((unsigned char) *ptr))
ptr++;
/*
* Grab the `in'
*/
if (ptr[0] != 'i' || ptr[1] != 'n' || !isspace(ptr[2])) {
if (ptr[0] != 'i' || ptr[1] != 'n' ||
!isspace((unsigned char) ptr[2])) {
Parse_Error (level, "missing `in' in for");
printf("%s\n", ptr);
return 0;
}
ptr += 3;
while (*ptr && isspace(*ptr))
while (*ptr && isspace((unsigned char) *ptr))
ptr++;
/*
@ -178,14 +177,14 @@ For_Eval (line)
Lst_AtEnd(forLst, (ClientData) Buf_GetAll(buf, &varlen)), \
Buf_Destroy(buf, FALSE)
for (ptr = sub; *ptr && isspace(*ptr); ptr++)
for (ptr = sub; *ptr && isspace((unsigned char) *ptr); ptr++)
continue;
for (wrd = ptr; *ptr; ptr++)
if (isspace(*ptr)) {
if (isspace((unsigned char) *ptr)) {
ADDWORD();
buf = Buf_Init(0);
while (*ptr && isspace(*ptr))
while (*ptr && isspace((unsigned char) *ptr))
ptr++;
wrd = ptr--;
}
@ -203,10 +202,11 @@ For_Eval (line)
}
else if (*ptr == '.') {
for (ptr++; *ptr && isspace(*ptr); ptr++)
for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
continue;
if (strncmp(ptr, "endfor", 6) == 0 && (isspace(ptr[6]) || !ptr[6])) {
if (strncmp(ptr, "endfor", 6) == 0 &&
(isspace((unsigned char) ptr[6]) || !ptr[6])) {
if (DEBUG(FOR))
(void) fprintf(stderr, "For: end for %d\n", forLevel);
if (--forLevel < 0) {
@ -214,7 +214,8 @@ For_Eval (line)
return 0;
}
}
else if (strncmp(ptr, "for", 3) == 0 && isspace(ptr[3])) {
else if (strncmp(ptr, "for", 3) == 0 &&
isspace((unsigned char) ptr[3])) {
forLevel++;
if (DEBUG(FOR))
(void) fprintf(stderr, "For: new loop %d\n", forLevel);
@ -245,10 +246,12 @@ For_Eval (line)
*-----------------------------------------------------------------------
*/
static int
ForExec(name, arg)
char *name;
struct For *arg;
ForExec(namep, argp)
ClientData namep;
ClientData argp;
{
char *name = (char *) namep;
For *arg = (For *) argp;
int len;
Var_Set(arg->var, name, VAR_GLOBAL);
if (DEBUG(FOR))
@ -277,7 +280,7 @@ ForExec(name, arg)
void
For_Run()
{
struct For arg;
For arg;
if (forVar == NULL || forBuf == NULL || forLst == NULL)
return;
@ -291,6 +294,6 @@ For_Run()
Lst_ForEach(arg.lst, ForExec, (ClientData) &arg);
free((Address)arg.var);
Lst_Destroy(arg.lst, free);
Lst_Destroy(arg.lst, (void (*) __P((ClientData))) free);
Buf_Destroy(arg.buf, TRUE);
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@ -105,12 +105,12 @@ typedef struct Hash_Search {
#define Hash_Size(n) (((n) + sizeof (int) - 1) / sizeof (int))
Hash_Entry *Hash_CreateEntry __P((Hash_Table *, char *, Boolean *));
void Hash_DeleteEntry __P((Hash_Table *, Hash_Entry *));
void Hash_DeleteTable __P((Hash_Table *));
Hash_Entry *Hash_EnumFirst __P((Hash_Table *, Hash_Search *));
Hash_Entry *Hash_EnumNext __P((Hash_Search *));
Hash_Entry *Hash_FindEntry __P((Hash_Table *, char *));
void Hash_InitTable __P((Hash_Table *, int));
void Hash_InitTable __P((Hash_Table *, int));
void Hash_DeleteTable __P((Hash_Table *));
Hash_Entry *Hash_FindEntry __P((Hash_Table *, char *));
Hash_Entry *Hash_CreateEntry __P((Hash_Table *, char *, Boolean *));
void Hash_DeleteEntry __P((Hash_Table *, Hash_Entry *));
Hash_Entry *Hash_EnumFirst __P((Hash_Table *, Hash_Search *));
Hash_Entry *Hash_EnumNext __P((Hash_Search *));
#endif /* _HASH */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@ -97,17 +97,16 @@ static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
*/
#include <sys/types.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include "make.h"
#include "hash.h"
#include "dir.h"
@ -202,10 +201,10 @@ static char *shellPath = (char *) NULL, /* full pathname of
static int maxJobs; /* The most children we can run at once */
static int maxLocal; /* The most local ones we can have */
static int nJobs; /* The number of children currently running */
static int nLocal; /* The number of local children */
static Lst jobs; /* The structures that describe them */
static Boolean jobFull; /* Flag to tell when the job table is full. It
int nJobs; /* The number of children currently running */
int nLocal; /* The number of local children */
Lst jobs; /* The structures that describe them */
Boolean jobFull; /* Flag to tell when the job table is full. It
* is set TRUE when (1) the total number of
* running jobs equals the maximum allowed or
* (2) a job can only be run locally, but
@ -215,9 +214,9 @@ static fd_set outputs; /* Set of descriptors of pipes connected to
* the output channels of children */
#endif
static GNode *lastNode; /* The node for which output was most recently
GNode *lastNode; /* The node for which output was most recently
* produced. */
static char *targFmt; /* Format string to use to head output from a
char *targFmt; /* Format string to use to head output from a
* job when it's not the most-recent job heard
* from */
#define TARG_FMT "--- %s ---\n" /* Default format */
@ -228,7 +227,7 @@ static char *targFmt; /* Format string to use to head output from a
* been migrated home, the job is placed on the stoppedJobs queue to be run
* when the next job finishes.
*/
static Lst stoppedJobs; /* Lst of Job structures describing
Lst stoppedJobs; /* Lst of Job structures describing
* jobs that were stopped due to concurrency
* limits or migration home */
@ -243,11 +242,11 @@ static Lst stoppedJobs; /* Lst of Job structures describing
# endif
#endif
static int JobCondPassSig __P((Job *, int));
static int JobCondPassSig __P((ClientData, ClientData));
static void JobPassSig __P((int));
static int JobCmpPid __P((Job *, int));
static int JobPrintCommand __P((char *, Job *));
static int JobSaveCommand __P((char *, GNode *));
static int JobCmpPid __P((ClientData, ClientData));
static int JobPrintCommand __P((ClientData, ClientData));
static int JobSaveCommand __P((ClientData, ClientData));
static void JobFinish __P((Job *, union wait));
static void JobExec __P((Job *, char **));
static void JobMakeArgv __P((Job *, char **));
@ -272,10 +271,12 @@ static void JobInterrupt __P((int));
*-----------------------------------------------------------------------
*/
static int
JobCondPassSig(job, signo)
Job *job; /* Job to biff */
int signo; /* Signal to send it */
JobCondPassSig(jobp, signop)
ClientData jobp; /* Job to biff */
ClientData signop; /* Signal to send it */
{
Job *job = (Job *) jobp;
int signo = *(int *) signop;
#ifdef RMT_WANTS_SIGNALS
if (job->flags & JOB_REMOTE) {
(void)Rmt_Signal(job, signo);
@ -312,7 +313,7 @@ JobPassSig(signo)
{
int mask;
Lst_ForEach(jobs, JobCondPassSig, (ClientData)signo);
Lst_ForEach(jobs, JobCondPassSig, (ClientData)(long)signo);
/*
* Deal with proper cleanup based on the signal received. We only run
@ -344,7 +345,8 @@ JobPassSig(signo)
kill(getpid(), signo);
Lst_ForEach(jobs, JobCondPassSig, (ClientData)SIGCONT);
signo = SIGCONT;
Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo);
sigsetmask(mask);
signal(signo, JobPassSig);
@ -367,10 +369,10 @@ JobPassSig(signo)
*/
static int
JobCmpPid (job, pid)
int pid; /* process id desired */
Job *job; /* job to examine */
ClientData job; /* job to examine */
ClientData pid; /* process id desired */
{
return (pid - job->pid);
return ( *(int *) pid - ((Job *) job)->pid);
}
/*-
@ -401,9 +403,9 @@ JobCmpPid (job, pid)
*-----------------------------------------------------------------------
*/
static int
JobPrintCommand (cmd, job)
char *cmd; /* command string to print */
Job *job; /* job for which to print it */
JobPrintCommand (cmdp, jobp)
ClientData cmdp; /* command string to print */
ClientData jobp; /* job for which to print it */
{
Boolean noSpecials; /* true if we shouldn't worry about
* inserting special commands into
@ -417,6 +419,8 @@ JobPrintCommand (cmd, job)
* command */
char *cmdStart; /* Start of expanded command */
LstNode cmdNode; /* Node for replacing the command */
char *cmd = (char *) cmdp;
Job *job = (Job *) jobp;
noSpecials = (noExecute && ! (job->node->type & OP_MAKE));
@ -556,11 +560,11 @@ JobPrintCommand (cmd, job)
*/
static int
JobSaveCommand (cmd, gn)
char *cmd;
GNode *gn;
ClientData cmd;
ClientData gn;
{
cmd = Var_Subst (NULL, cmd, gn, FALSE);
(void)Lst_AtEnd (postCommands->commands, (ClientData)cmd);
cmd = (ClientData) Var_Subst (NULL, (char *) cmd, (GNode *) gn, FALSE);
(void)Lst_AtEnd (postCommands->commands, cmd);
return (0);
}
@ -904,7 +908,7 @@ Boolean
Job_CheckCommands (gn, abortProc)
GNode *gn; /* The target whose commands need
* verifying */
void (*abortProc) __P((const char *, ...));
void (*abortProc) __P((char *, ...));
/* Function to abort with message */
{
if (OP_NOP(gn->type) && Lst_IsEmpty (gn->commands) &&
@ -914,6 +918,7 @@ Job_CheckCommands (gn, abortProc)
* commands
*/
if ((DEFAULT != NILGNODE) && !Lst_IsEmpty(DEFAULT->commands)) {
char *p1;
/*
* Make only looks for a .DEFAULT if the node was never the
* target of an operator, so that's what we do too. If
@ -924,7 +929,9 @@ Job_CheckCommands (gn, abortProc)
* .DEFAULT itself.
*/
Make_HandleUse(DEFAULT, gn);
Var_Set (IMPSRC, Var_Value (TARGET, gn), gn);
Var_Set (IMPSRC, Var_Value (TARGET, gn, &p1), gn);
if (p1)
free(p1);
} else if (Dir_MTime (gn) == 0) {
/*
* The node wasn't the target of an operator we have no .DEFAULT
@ -1361,7 +1368,7 @@ JobRestart(job)
static int
JobStart (gn, flags, previous)
GNode *gn; /* target to create */
short flags; /* flags for the job to override normal ones.
int flags; /* flags for the job to override normal ones.
* e.g. JOB_SPECIAL or JOB_IGNDOTS */
Job *previous; /* The previous Job structure for this node,
* if any. */
@ -1949,11 +1956,11 @@ Job_CatchChildren (block)
printf("Process %d exited or stopped.\n", pid);
jnode = Lst_Find (jobs, (ClientData)pid, JobCmpPid);
jnode = Lst_Find (jobs, (ClientData)&pid, JobCmpPid);
if (jnode == NILLNODE) {
if (WIFSIGNALED(status) && (status.w_termsig == SIGCONT)) {
jnode = Lst_Find(stoppedJobs, (ClientData)pid, JobCmpPid);
jnode = Lst_Find(stoppedJobs, (ClientData) &pid, JobCmpPid);
if (jnode == NILLNODE) {
Error("Resumed child (%d) not in table", pid);
continue;
@ -2352,7 +2359,7 @@ Job_ParseShell (line)
while (isspace (*line)) {
line++;
}
words = brk_string (line, &wordCount);
words = brk_string (line, &wordCount, TRUE);
memset ((Address)&newShell, 0, sizeof(newShell));
@ -2479,7 +2486,6 @@ JobInterrupt (runINTERRUPT)
LstNode ln; /* element in job table */
Job *job; /* job descriptor in that element */
GNode *interrupt; /* the node describing the .INTERRUPT target */
struct stat sb;
aborting = ABORT_INTERRUPT;
@ -2491,8 +2497,9 @@ JobInterrupt (runINTERRUPT)
char *file = (job->node->path == (char *)NULL ?
job->node->name :
job->node->path);
if (!stat(file, &sb) && S_ISREG(sb.st_mode) &&
unlink (file) == 0) {
struct stat st;
if (!noExecute && lstat(file, &st) != -1 && !S_ISDIR(st.st_mode) &&
unlink(file) != -1) {
Error ("*** %s removed", file);
}
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@ -215,19 +215,19 @@ extern Lst stoppedJobs; /* List of jobs that are stopped or didn't
* quite get started */
extern Boolean jobFull; /* Non-zero if no more jobs should/will start*/
void JobFlagForMigration __P((int));
void Job_AbortAll __P((void));
void Job_CatchChildren __P((Boolean));
void Job_CatchOutput __P((void));
Boolean Job_CheckCommands __P((GNode *,
void (*abortProc )(const char *, ...)));
Boolean Job_Empty __P((void));
int Job_End __P((void));
Boolean Job_Full __P((void));
void Job_Init __P((int, int));
void Job_Make __P((GNode *));
ReturnStatus Job_ParseShell __P((char *));
void Job_Touch __P((GNode *, Boolean));
void Job_Wait __P((void));
void Job_Touch __P((GNode *, Boolean));
Boolean Job_CheckCommands __P((GNode *, void (*abortProc )(char *, ...)));
void Job_CatchChildren __P((Boolean));
void Job_CatchOutput __P((void));
void Job_Make __P((GNode *));
void Job_Init __P((int, int));
Boolean Job_Full __P((void));
Boolean Job_Empty __P((void));
ReturnStatus Job_ParseShell __P((char *));
int Job_End __P((void));
void Job_Wait __P((void));
void Job_AbortAll __P((void));
void JobFlagForMigration __P((int));
#endif /* _JOB_H_ */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@ -46,6 +46,7 @@
#define _LST_H_
#include <sprite.h>
#include <sys/cdefs.h>
#if __STDC__
#include <stdlib.h>
#endif
@ -65,8 +66,8 @@ typedef struct LstNode *LstNode;
* not to be freed.
* NOCOPY performs similarly when given as the copyProc to Lst_Duplicate.
*/
#define NOFREE ((void (*)()) 0)
#define NOCOPY ((ClientData (*)()) 0)
#define NOFREE ((void (*) __P((ClientData))) 0)
#define NOCOPY ((ClientData (*) __P((ClientData))) 0)
#define LST_CONCNEW 0 /* create new LstNode's when using Lst_Concat */
#define LST_CONCLINK 1 /* relink LstNode's when using Lst_Concat */
@ -74,72 +75,90 @@ typedef struct LstNode *LstNode;
/*
* Creation/destruction functions
*/
Lst Lst_Init(); /* Create a new list */
Lst Lst_Duplicate(); /* Duplicate an existing list */
void Lst_Destroy(); /* Destroy an old one */
int Lst_Length(); /* Find the length of a list */
Boolean Lst_IsEmpty(); /* True if list is empty */
/* Create a new list */
Lst Lst_Init __P((Boolean));
/* Duplicate an existing list */
Lst Lst_Duplicate __P((Lst, ClientData (*)(ClientData)));
/* Destroy an old one */
void Lst_Destroy __P((Lst, void (*)(ClientData)));
/* True if list is empty */
Boolean Lst_IsEmpty __P((Lst));
/*
* Functions to modify a list
*/
ReturnStatus Lst_Insert(); /* Insert an element before another */
ReturnStatus Lst_Append(); /* Insert an element after another */
ReturnStatus Lst_AtFront(); /* Place an element at the front of
* a lst. */
ReturnStatus Lst_AtEnd(); /* Place an element at the end of a
* lst. */
ReturnStatus Lst_Remove(); /* Remove an element */
ReturnStatus Lst_Replace(); /* Replace a node with a new value */
ReturnStatus Lst_Move(); /* Move an element to another place */
ReturnStatus Lst_Concat(); /* Concatenate two lists */
/* Insert an element before another */
ReturnStatus Lst_Insert __P((Lst, LstNode, ClientData));
/* Insert an element after another */
ReturnStatus Lst_Append __P((Lst, LstNode, ClientData));
/* Place an element at the front of a lst. */
ReturnStatus Lst_AtFront __P((Lst, ClientData));
/* Place an element at the end of a lst. */
ReturnStatus Lst_AtEnd __P((Lst, ClientData));
/* Remove an element */
ReturnStatus Lst_Remove __P((Lst, LstNode));
/* Replace a node with a new value */
ReturnStatus Lst_Replace __P((LstNode, ClientData));
/* Concatenate two lists */
ReturnStatus Lst_Concat __P((Lst, Lst, int));
/*
* Node-specific functions
*/
LstNode Lst_First(); /* Return first element in list */
LstNode Lst_Last(); /* Return last element in list */
LstNode Lst_Succ(); /* Return successor to given element */
LstNode Lst_Pred(); /* Return predecessor to given
* element */
ClientData Lst_Datum(); /* Get datum from LstNode */
/* Return first element in list */
LstNode Lst_First __P((Lst));
/* Return last element in list */
LstNode Lst_Last __P((Lst));
/* Return successor to given element */
LstNode Lst_Succ __P((LstNode));
/* Get datum from LstNode */
ClientData Lst_Datum __P((LstNode));
/*
* Functions for entire lists
*/
LstNode Lst_Find(); /* Find an element in a list */
LstNode Lst_FindFrom(); /* Find an element starting from
* somewhere */
LstNode Lst_Member(); /* See if the given datum is on the
* list. Returns the LstNode containing
* the datum */
int Lst_Index(); /* Returns the index of a datum in the
* list, starting from 0 */
void Lst_ForEach(); /* Apply a function to all elements of
* a lst */
void Lst_ForEachFrom(); /* Apply a function to all elements of
* a lst starting from a certain point.
* If the list is circular, the
* application will wrap around to the
* beginning of the list again. */
/* Find an element in a list */
LstNode Lst_Find __P((Lst, ClientData,
int (*)(ClientData, ClientData)));
/* Find an element starting from somewhere */
LstNode Lst_FindFrom __P((Lst, LstNode, ClientData,
int (*cProc)(ClientData, ClientData)));
/*
* See if the given datum is on the list. Returns the LstNode containing
* the datum
*/
LstNode Lst_Member __P((Lst, ClientData));
/* Apply a function to all elements of a lst */
void Lst_ForEach __P((Lst, int (*)(ClientData, ClientData),
ClientData));
/*
* Apply a function to all elements of a lst starting from a certain point.
* If the list is circular, the application will wrap around to the
* beginning of the list again.
*/
void Lst_ForEachFrom __P((Lst, LstNode,
int (*)(ClientData, ClientData),
ClientData));
/*
* these functions are for dealing with a list as a table, of sorts.
* An idea of the "current element" is kept and used by all the functions
* between Lst_Open() and Lst_Close().
*/
ReturnStatus Lst_Open(); /* Open the list */
LstNode Lst_Prev(); /* Previous element */
LstNode Lst_Cur(); /* The current element, please */
LstNode Lst_Next(); /* Next element please */
Boolean Lst_IsAtEnd(); /* Done yet? */
void Lst_Close(); /* Finish table access */
/* Open the list */
ReturnStatus Lst_Open __P((Lst));
/* Next element please */
LstNode Lst_Next __P((Lst));
/* Done yet? */
Boolean Lst_IsAtEnd __P((Lst));
/* Finish table access */
void Lst_Close __P((Lst));
/*
* for using the list as a queue
*/
ReturnStatus Lst_EnQueue(); /* Place an element at tail of queue */
ClientData Lst_DeQueue(); /* Remove an element from head of
* queue */
/* Place an element at tail of queue */
ReturnStatus Lst_EnQueue __P((Lst, ClientData));
/* Remove an element from head of queue */
ClientData Lst_DeQueue __P((Lst));
#endif _LST_H_
#endif /* _LST_H_ */

View File

@ -102,6 +102,8 @@ Lst_Concat (l1, l2, flags)
list2->firstPtr->prevPtr = list1->lastPtr;
if (list1->lastPtr != NilListNode) {
list1->lastPtr->nextPtr = list2->firstPtr;
} else {
list1->firstPtr = list2->firstPtr;
}
list1->lastPtr = list2->lastPtr;
}

View File

@ -63,7 +63,7 @@ static char sccsid[] = "@(#)lstDestroy.c 8.1 (Berkeley) 6/6/93";
void
Lst_Destroy (l, freeProc)
Lst l;
register void (*freeProc)();
register void (*freeProc) __P((ClientData));
{
register ListNode ln;
register ListNode tln = NilListNode;
@ -76,21 +76,25 @@ Lst_Destroy (l, freeProc)
*/
return;
}
/* To ease scanning */
if (list->lastPtr != NilListNode)
list->lastPtr->nextPtr = NilListNode;
else {
free ((Address)l);
return;
}
if (freeProc) {
for (ln = list->firstPtr;
ln != NilListNode && tln != list->firstPtr;
ln = tln) {
tln = ln->nextPtr;
(*freeProc) (ln->datum);
free ((Address)ln);
for (ln = list->firstPtr; ln != NilListNode; ln = tln) {
tln = ln->nextPtr;
(*freeProc) (ln->datum);
free ((Address)ln);
}
} else {
for (ln = list->firstPtr;
ln != NilListNode && tln != list->firstPtr;
ln = tln) {
tln = ln->nextPtr;
free ((Address)ln);
for (ln = list->firstPtr; ln != NilListNode; ln = tln) {
tln = ln->nextPtr;
free ((Address)ln);
}
}

View File

@ -62,7 +62,8 @@ static char sccsid[] = "@(#)lstDupl.c 8.1 (Berkeley) 6/6/93";
Lst
Lst_Duplicate (l, copyProc)
Lst l; /* the list to duplicate */
ClientData (*copyProc)(); /* A function to duplicate each ClientData */
/* A function to duplicate each ClientData */
ClientData (*copyProc) __P((ClientData));
{
register Lst nl;
register ListNode ln;

View File

@ -63,7 +63,7 @@ LstNode
Lst_Find (l, d, cProc)
Lst l;
ClientData d;
int (*cProc)();
int (*cProc) __P((ClientData, ClientData));
{
return (Lst_FindFrom (l, Lst_First(l), d, cProc));
}

View File

@ -65,7 +65,7 @@ Lst_FindFrom (l, ln, d, cProc)
Lst l;
register LstNode ln;
register ClientData d;
register int (*cProc)();
register int (*cProc) __P((ClientData, ClientData));
{
register ListNode tln;
Boolean found = FALSE;

View File

@ -64,7 +64,7 @@ static char sccsid[] = "@(#)lstForEach.c 8.1 (Berkeley) 6/6/93";
void
Lst_ForEach (l, proc, d)
Lst l;
register int (*proc)();
register int (*proc) __P((ClientData, ClientData));
register ClientData d;
{
Lst_ForEachFrom(l, Lst_First(l), proc, d);

View File

@ -79,6 +79,7 @@ static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#include <sys/resource.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@ -148,7 +149,7 @@ MainParseArgs(argc, argv)
{
extern int optind;
extern char *optarg;
char c;
int c;
optind = 1; /* since we're called more than once */
#ifdef notyet
@ -156,7 +157,7 @@ MainParseArgs(argc, argv)
#else
# define OPTFLAGS "D:I:d:ef:ij:knqrst"
#endif
rearg: while ((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
switch(c) {
case 'D':
Var_Set(optarg, "1", VAR_GLOBAL);
@ -308,7 +309,7 @@ rearg: while ((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
optind = 1; /* - */
goto rearg;
}
(void)Lst_AtEnd(create, (ClientData)*argv);
(void)Lst_AtEnd(create, (ClientData)strdup(*argv));
}
}
@ -341,7 +342,7 @@ Main_ParseArgLine(line)
if (!*line)
return;
argv = brk_string(line, &argc);
argv = brk_string(line, &argc, TRUE);
MainParseArgs(argc, argv);
}
@ -370,10 +371,12 @@ main(argc, argv)
Lst targs; /* target nodes to create -- passed to Make_Init */
Boolean outOfDate = TRUE; /* FALSE if all targets up to date */
struct stat sb, sa;
char *p, *path, *pwd, *getenv(), *getwd();
char *p, *p1, *path, *pwd, *getenv(), *getwd();
char mdpath[MAXPATHLEN + 1];
char obpath[MAXPATHLEN + 1];
char cdpath[MAXPATHLEN + 1];
struct utsname utsname;
char *machine = getenv("MACHINE");
/*
* Find where we are and take care of PWD for the automounter...
@ -381,8 +384,8 @@ main(argc, argv)
* on a different machine with pmake.
*/
curdir = cdpath;
if (getwd(curdir) == NULL) {
(void)fprintf(stderr, "make: %s.\n", curdir);
if (getcwd(curdir, MAXPATHLEN) == NULL) {
(void)fprintf(stderr, "make: %s.\n", strerror(errno));
exit(2);
}
@ -398,6 +401,21 @@ main(argc, argv)
(void) strcpy(curdir, pwd);
}
/*
* Get the name of this type of MACHINE from utsname
* so we can share an executable for similar machines.
* (i.e. m68k: amiga hp300, mac68k, sun3, ...)
*
* Note that while MACHINE is decided at run-time,
* MACHINE_ARCH is always known at compile time.
*/
if (!machine) {
if (uname(&utsname)) {
perror("make: uname");
exit(2);
}
machine = utsname.machine;
}
/*
* if the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
@ -408,7 +426,7 @@ main(argc, argv)
*/
if (!(path = getenv("MAKEOBJDIR"))) {
path = _PATH_OBJDIR;
(void) sprintf(mdpath, "%s.%s", path, MACHINE);
(void) sprintf(mdpath, "%s.%s", path, machine);
}
else
(void) strncpy(mdpath, path, MAXPATHLEN + 1);
@ -487,6 +505,7 @@ main(argc, argv)
* directories */
Var_Init(); /* As well as the lists of variables for
* parsing arguments */
str_init();
if (objdir != curdir)
Dir_AddDir(dirSearchPath, curdir);
Var_Set(".CURDIR", curdir, VAR_GLOBAL);
@ -501,9 +520,7 @@ main(argc, argv)
Var_Set("MAKE", argv[0], VAR_GLOBAL);
Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
Var_Set("MFLAGS", "", VAR_GLOBAL);
#ifdef MACHINE
Var_Set("MACHINE", MACHINE, VAR_GLOBAL);
#endif
Var_Set("MACHINE", machine, VAR_GLOBAL);
#ifdef MACHINE_ARCH
Var_Set("MACHINE_ARCH", MACHINE_ARCH, VAR_GLOBAL);
#endif
@ -568,15 +585,19 @@ main(argc, argv)
(void)ReadMakefile(".depend");
Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);
Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
if (p1)
free(p1);
/* Install all the flags into the MAKE envariable. */
if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL)) != NULL) && *p)
if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
#ifdef POSIX
setenv("MAKEFLAGS", p, 1);
#else
setenv("MAKE", p, 1);
#endif
if (p1)
free(p1);
/*
* For compatibility, look at the directories in the VPATH variable
@ -657,10 +678,22 @@ main(argc, argv)
*/
Compat_Run(targs);
Lst_Destroy(targs, NOFREE);
Lst_Destroy(makefiles, NOFREE);
Lst_Destroy(create, (void (*) __P((ClientData))) free);
/* print the graph now it's been processed if the user requested it */
if (DEBUG(GRAPH2))
Targ_PrintGraph(2);
Suff_End();
Targ_End();
Arch_End();
str_end();
Var_End();
Parse_End();
Dir_End();
if (queryFlag && outOfDate)
return(1);
else
@ -731,7 +764,7 @@ found: Var_Set("MAKEFILE", fname, VAR_GLOBAL);
/* VARARGS */
void
#if __STDC__
Error(const char *fmt, ...)
Error(char *fmt, ...)
#else
Error(va_alist)
va_dcl
@ -766,7 +799,7 @@ Error(va_alist)
/* VARARGS */
void
#if __STDC__
Fatal(const char *fmt, ...)
Fatal(char *fmt, ...)
#else
Fatal(va_alist)
va_dcl
@ -808,7 +841,7 @@ Fatal(va_alist)
/* VARARGS */
void
#if __STDC__
Punt(const char *fmt, ...)
Punt(char *fmt, ...)
#else
Punt(va_alist)
va_dcl
@ -877,11 +910,11 @@ Finish(errors)
*/
char *
emalloc(len)
u_int len;
size_t len;
{
char *p;
if (!(p = malloc(len)))
if ((p = (char *) malloc(len)) == NULL)
enomem();
return(p);
}
@ -909,3 +942,13 @@ usage()
[-I directory] [-j max_jobs] [variable=value]\n");
exit(2);
}
int
PrintAddr(a, b)
ClientData a;
ClientData b;
{
printf("%lx ", (unsigned long) a);
return b ? 0 : 0;
}

View File

@ -86,10 +86,10 @@ static int numNodes; /* Number of nodes to be processed. If this
* is non-zero when Job_Empty() returns
* TRUE, there's a cycle in the graph */
static int MakeAddChild __P((GNode *, Lst));
static int MakeAddAllSrc __P((GNode *, GNode *));
static int MakeAddChild __P((ClientData, ClientData));
static int MakeAddAllSrc __P((ClientData, ClientData));
static Boolean MakeStartJobs __P((void));
static int MakePrintStatus __P((GNode *, Boolean));
static int MakePrintStatus __P((ClientData, ClientData));
/*-
*-----------------------------------------------------------------------
* Make_TimeStamp --
@ -106,14 +106,22 @@ static int MakePrintStatus __P((GNode *, Boolean));
*/
int
Make_TimeStamp (pgn, cgn)
register GNode *pgn; /* the current parent */
register GNode *cgn; /* the child we've just examined */
GNode *pgn; /* the current parent */
GNode *cgn; /* the child we've just examined */
{
if (cgn->mtime > pgn->cmtime) {
pgn->cmtime = cgn->mtime;
}
return (0);
}
static int
MakeTimeStamp (pgn, cgn)
ClientData pgn; /* the current parent */
ClientData cgn; /* the child we've just examined */
{
return Make_TimeStamp((GNode *) pgn, (GNode *) cgn);
}
/*-
*-----------------------------------------------------------------------
@ -181,7 +189,13 @@ Make_OODate (gn)
if (DEBUG(MAKE)) {
printf("library...");
}
oodate = Arch_LibOODate (gn);
/*
* always out of date if no children and :: target
*/
oodate = Arch_LibOODate (gn) ||
((gn->cmtime == 0) && (gn->type & OP_DOUBLEDEP));
} else if (gn->type & OP_JOIN) {
/*
* A target with the .JOIN attribute is only considered
@ -245,7 +259,7 @@ Make_OODate (gn)
* thinking they're out-of-date.
*/
if (!oodate) {
Lst_ForEach (gn->parents, Make_TimeStamp, (ClientData)gn);
Lst_ForEach (gn->parents, MakeTimeStamp, (ClientData)gn);
}
return (oodate);
@ -265,10 +279,12 @@ Make_OODate (gn)
*-----------------------------------------------------------------------
*/
static int
MakeAddChild (gn, l)
GNode *gn; /* the node to add */
Lst l; /* the list to which to add it */
MakeAddChild (gnp, lp)
ClientData gnp; /* the node to add */
ClientData lp; /* the list to which to add it */
{
GNode *gn = (GNode *) gnp;
Lst l = (Lst) lp;
if (!gn->make && !(gn->type & OP_USE)) {
(void)Lst_EnQueue (l, (ClientData)gn);
}
@ -343,6 +359,13 @@ Make_HandleUse (cgn, pgn)
}
return (0);
}
static int
MakeHandleUse (pgn, cgn)
ClientData pgn; /* the current parent */
ClientData cgn; /* the child we've just examined */
{
return Make_HandleUse((GNode *) pgn, (GNode *) cgn);
}
/*-
*-----------------------------------------------------------------------
@ -376,8 +399,11 @@ Make_Update (cgn)
register GNode *pgn; /* the parent node */
register char *cname; /* the child's name */
register LstNode ln; /* Element in parents and iParents lists */
char *p1;
cname = Var_Value (TARGET, cgn);
cname = Var_Value (TARGET, cgn, &p1);
if (p1)
free(p1);
/*
* If the child was actually made, see what its modification time is
@ -496,7 +522,8 @@ Make_Update (cgn)
* of this node.
*/
if (Lst_Open (cgn->iParents) == SUCCESS) {
char *cpref = Var_Value(PREFIX, cgn);
char *p1;
char *cpref = Var_Value(PREFIX, cgn, &p1);
while ((ln = Lst_Next (cgn->iParents)) != NILLNODE) {
pgn = (GNode *)Lst_Datum (ln);
@ -505,6 +532,8 @@ Make_Update (cgn)
Var_Set (PREFIX, cpref, pgn);
}
}
if (p1)
free(p1);
Lst_Close (cgn->iParents);
}
}
@ -530,15 +559,18 @@ Make_Update (cgn)
*-----------------------------------------------------------------------
*/
static int
MakeAddAllSrc (cgn, pgn)
GNode *cgn; /* The child to add */
GNode *pgn; /* The parent to whose ALLSRC variable it should be */
MakeAddAllSrc (cgnp, pgnp)
ClientData cgnp; /* The child to add */
ClientData pgnp; /* The parent to whose ALLSRC variable it should be */
/* added */
{
GNode *cgn = (GNode *) cgnp;
GNode *pgn = (GNode *) pgnp;
if ((cgn->type & (OP_EXEC|OP_USE|OP_INVISIBLE)) == 0) {
register char *child;
char *child;
char *p1;
child = Var_Value(TARGET, cgn);
child = Var_Value(TARGET, cgn, &p1);
Var_Append (ALLSRC, child, pgn);
if (pgn->type & OP_JOIN) {
if (cgn->made == MADE) {
@ -565,6 +597,8 @@ MakeAddAllSrc (cgn, pgn)
*/
Var_Append(OODATE, child, pgn);
}
if (p1)
free(p1);
}
return (0);
}
@ -595,7 +629,7 @@ void
Make_DoAllVar (gn)
GNode *gn;
{
Lst_ForEach (gn->children, MakeAddAllSrc, gn);
Lst_ForEach (gn->children, MakeAddAllSrc, (ClientData) gn);
if (!Var_Exists (OODATE, gn)) {
Var_Set (OODATE, "", gn);
@ -605,7 +639,10 @@ Make_DoAllVar (gn)
}
if (gn->type & OP_JOIN) {
Var_Set (TARGET, Var_Value (ALLSRC, gn), gn);
char *p1;
Var_Set (TARGET, Var_Value (ALLSRC, gn, &p1), gn);
if (p1)
free(p1);
}
}
@ -710,16 +747,19 @@ MakeStartJobs ()
*-----------------------------------------------------------------------
*/
static int
MakePrintStatus(gn, cycle)
GNode *gn; /* Node to examine */
Boolean cycle; /* True if gn->unmade being non-zero implies
MakePrintStatus(gnp, cyclep)
ClientData gnp; /* Node to examine */
ClientData cyclep; /* True if gn->unmade being non-zero implies
* a cycle in the graph, not an error in an
* inferior */
{
GNode *gn = (GNode *) gnp;
Boolean cycle = *(Boolean *) cyclep;
if (gn->made == UPTODATE) {
printf ("`%s' is up to date.\n", gn->name);
} else if (gn->unmade != 0) {
if (cycle) {
Boolean t = TRUE;
/*
* If printing cycles and came to one that has unmade children,
* print out the cycle by recursing on its children. Note a
@ -733,11 +773,11 @@ MakePrintStatus(gn, cycle)
if (gn->made == CYCLE) {
Error("Graph cycles through `%s'", gn->name);
gn->made = ENDCYCLE;
Lst_ForEach(gn->children, MakePrintStatus, (ClientData)TRUE);
Lst_ForEach(gn->children, MakePrintStatus, (ClientData) &t);
gn->made = UNMADE;
} else if (gn->made != ENDCYCLE) {
gn->made = CYCLE;
Lst_ForEach(gn->children, MakePrintStatus, (ClientData)TRUE);
Lst_ForEach(gn->children, MakePrintStatus, (ClientData) &t);
}
} else {
printf ("`%s' not remade because of errors.\n", gn->name);
@ -799,7 +839,7 @@ Make_Run (targs)
* Apply any .USE rules before looking for implicit dependencies
* to make sure everything has commands that should...
*/
Lst_ForEach (gn->children, Make_HandleUse, (ClientData)gn);
Lst_ForEach (gn->children, MakeHandleUse, (ClientData)gn);
Suff_FindDeps (gn);
if (gn->unmade != 0) {
@ -852,8 +892,8 @@ Make_Run (targs)
* Print the final status of each target. E.g. if it wasn't made
* because some inferior reported an error.
*/
Lst_ForEach(targs, MakePrintStatus,
(ClientData)((errors == 0) && (numNodes != 0)));
errors = ((errors == 0) && (numNodes != 0));
Lst_ForEach(targs, MakePrintStatus, (ClientData) &errors);
return (TRUE);
}

View File

@ -50,7 +50,15 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#ifndef MAKE_BOOTSTRAP
#include <sys/cdefs.h>
#else
#if defined(__STDC__) || defined(__cplusplus)
#define __P(protos) protos /* full-blown ANSI C */
#else
#define __P(protos) () /* traditional C preprocessor */
#endif
#endif
#if __STDC__
#include <stdlib.h>
#include <unistd.h>
@ -347,11 +355,11 @@ extern int debug;
*/
#include "nonints.h"
void Make_DoAllVar __P((GNode *));
int Make_HandleUse __P((GNode *, GNode *));
Boolean Make_OODate __P((GNode *));
Boolean Make_Run __P((Lst));
int Make_TimeStamp __P((GNode *, GNode *));
void Make_Update __P((GNode *));
int Make_TimeStamp __P((GNode *, GNode *));
Boolean Make_OODate __P((GNode *));
int Make_HandleUse __P((GNode *, GNode *));
void Make_Update __P((GNode *));
void Make_DoAllVar __P((GNode *));
Boolean Make_Run __P((Lst));
#endif /* _MAKE_H_ */

View File

@ -47,7 +47,8 @@ int Arch_MemMTime __P((GNode *));
void Arch_FindLib __P((GNode *, Lst));
Boolean Arch_LibOODate __P((GNode *));
void Arch_Init __P((void));
void Arch_End __P((void));
/* compat.c */
void Compat_Run __P((Lst));
@ -62,28 +63,32 @@ void For_Run __P((void));
/* main.c */
void Main_ParseArgLine __P((char *));
int main __P((int, char **));
void Error __P((const char *, ...));
void Fatal __P((const char *, ...));
void Punt __P((const char *, ...));
void Error __P((char *, ...));
void Fatal __P((char *, ...));
void Punt __P((char *, ...));
void DieHorribly __P((void));
int PrintAddr __P((ClientData, ClientData));
void Finish __P((int));
char *emalloc __P((u_int));
char *emalloc __P((size_t));
void enomem __P((void));
/* parse.c */
void Parse_Error __P((int, const char *, ...));
void Parse_Error __P((int, char *, ...));
Boolean Parse_AnyExport __P((void));
Boolean Parse_IsVar __P((char *));
void Parse_DoVar __P((char *, GNode *));
void Parse_AddIncludeDir __P((char *));
void Parse_File __P((char *, FILE *));
void Parse_Init __P((void));
void Parse_End __P((void));
void Parse_FromString __P((char *));
Lst Parse_MainName __P((void));
/* str.c */
void str_init __P((void));
void str_end __P((void));
char *str_concat __P((char *, char *, int));
char **brk_string __P((char *, int *));
char **brk_string __P((char *, int *, Boolean));
char *Str_FindSubstring __P((char *, char *));
int Str_Match __P((char *, char *));
char *Str_SYSVMatch __P((char *, char *, int *len));
@ -93,7 +98,7 @@ void Str_SYSVSubst __P((Buffer, char *, char *, int));
void Suff_ClearSuffixes __P((void));
Boolean Suff_IsTransform __P((char *));
GNode *Suff_AddTransform __P((char *));
int Suff_EndTransform __P((GNode *));
int Suff_EndTransform __P((ClientData, ClientData));
void Suff_AddSuffix __P((char *));
Lst Suff_GetPath __P((char *));
void Suff_DoPaths __P((void));
@ -102,10 +107,12 @@ void Suff_AddLib __P((char *));
void Suff_FindDeps __P((GNode *));
void Suff_SetNull __P((char *));
void Suff_Init __P((void));
void Suff_End __P((void));
void Suff_PrintAll __P((void));
/* targ.c */
void Targ_Init __P((void));
void Targ_End __P((void));
GNode *Targ_NewGN __P((char *));
GNode *Targ_FindNode __P((char *, int));
Lst Targ_FindList __P((Lst, int));
@ -113,7 +120,7 @@ Boolean Targ_Ignore __P((GNode *));
Boolean Targ_Silent __P((GNode *));
Boolean Targ_Precious __P((GNode *));
void Targ_SetMain __P((GNode *));
int Targ_PrintCmd __P((char *));
int Targ_PrintCmd __P((ClientData, ClientData));
char *Targ_FmtTime __P((time_t));
void Targ_PrintType __P((int));
void Targ_PrintGraph __P((int));
@ -123,10 +130,11 @@ void Var_Delete __P((char *, GNode *));
void Var_Set __P((char *, char *, GNode *));
void Var_Append __P((char *, char *, GNode *));
Boolean Var_Exists __P((char *, GNode *));
char *Var_Value __P((char *, GNode *));
char *Var_Value __P((char *, GNode *, char **));
char *Var_Parse __P((char *, GNode *, Boolean, int *, Boolean *));
char *Var_Subst __P((char *, char *, GNode *, Boolean));
char *Var_GetTail __P((char *));
char *Var_GetHead __P((char *));
void Var_Init __P((void));
void Var_End __P((void));
void Var_Dump __P((GNode *));

View File

@ -63,6 +63,8 @@ static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
* called before anything else in this module
* is used.
*
* Parse_End Cleanup the module
*
* Parse_File Function used to parse a makefile. It must
* be given the name of the file, which should
* already have been opened, and a function
@ -104,6 +106,7 @@ static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
#define CONTINUE 1
#define DONE 0
static Lst targets; /* targets we're working on */
static Lst targCmds; /* command lines for targets */
static Boolean inLine; /* true if currently in a dependency
* line or its commands */
typedef struct {
@ -218,17 +221,17 @@ static struct {
};
static int ParseFindKeyword __P((char *));
static int ParseLinkSrc __P((GNode *, GNode *));
static int ParseDoOp __P((GNode *, int));
static int ParseLinkSrc __P((ClientData, ClientData));
static int ParseDoOp __P((ClientData, ClientData));
static void ParseDoSrc __P((int, char *));
static int ParseFindMain __P((GNode *));
static int ParseAddDir __P((Lst, char *));
static int ParseClearPath __P((Lst));
static int ParseFindMain __P((ClientData, ClientData));
static int ParseAddDir __P((ClientData, ClientData));
static int ParseClearPath __P((ClientData, ClientData));
static void ParseDoDependency __P((char *));
static int ParseAddCmd __P((GNode *, char *));
static int ParseAddCmd __P((ClientData, ClientData));
static int ParseReadc __P((void));
static void ParseUnreadc __P((int));
static int ParseHasCommands __P((GNode *));
static void ParseHasCommands __P((ClientData));
static void ParseDoInclude __P((char *));
#ifdef SYSVINCLUDE
static void ParseTraditionalInclude __P((char *));
@ -292,7 +295,7 @@ ParseFindKeyword (str)
/* VARARGS */
void
#if __STDC__
Parse_Error(int type, const char *fmt, ...)
Parse_Error(int type, char *fmt, ...)
#else
Parse_Error(va_alist)
va_dcl
@ -338,10 +341,12 @@ Parse_Error(va_alist)
*---------------------------------------------------------------------
*/
static int
ParseLinkSrc (pgn, cgn)
GNode *pgn; /* The parent node */
GNode *cgn; /* The child node */
ParseLinkSrc (pgnp, cgnp)
ClientData pgnp; /* The parent node */
ClientData cgnp; /* The child node */
{
GNode *pgn = (GNode *) pgnp;
GNode *cgn = (GNode *) cgnp;
if (Lst_Member (pgn->children, (ClientData)cgn) == NILLNODE) {
(void)Lst_AtEnd (pgn->children, (ClientData)cgn);
if (specType == Not) {
@ -369,11 +374,13 @@ ParseLinkSrc (pgn, cgn)
*---------------------------------------------------------------------
*/
static int
ParseDoOp (gn, op)
GNode *gn; /* The node to which the operator is to be
ParseDoOp (gnp, opp)
ClientData gnp; /* The node to which the operator is to be
* applied */
int op; /* The operator to apply */
ClientData opp; /* The operator to apply */
{
GNode *gn = (GNode *) gnp;
int op = *(int *) opp;
/*
* If the dependency mask of the operator and the node don't match and
* the node has actually had an operator applied to it before, and
@ -461,7 +468,7 @@ ParseDoSrc (tOp, src)
}
}
if (op != 0) {
Lst_ForEach (targets, ParseDoOp, (ClientData)op);
Lst_ForEach (targets, ParseDoOp, (ClientData)&op);
} else if (specType == Main) {
/*
* If we have noted the existence of a .MAIN, it means we need
@ -541,15 +548,17 @@ ParseDoSrc (tOp, src)
*-----------------------------------------------------------------------
*/
static int
ParseFindMain(gn)
GNode *gn; /* Node to examine */
ParseFindMain(gnp, dummy)
ClientData gnp; /* Node to examine */
ClientData dummy;
{
GNode *gn = (GNode *) gnp;
if ((gn->type & (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM)) == 0) {
mainNode = gn;
Targ_SetMain(gn);
return (1);
return (dummy ? 1 : 1);
} else {
return (0);
return (dummy ? 0 : 0);
}
}
@ -568,10 +577,10 @@ ParseFindMain(gn)
*/
static int
ParseAddDir(path, name)
Lst path;
char *name;
ClientData path;
ClientData name;
{
Dir_AddDir(path, name);
Dir_AddDir((Lst) path, (char *) name);
return(0);
}
@ -589,11 +598,12 @@ ParseAddDir(path, name)
*-----------------------------------------------------------------------
*/
static int
ParseClearPath(path)
Lst path;
ParseClearPath(path, dummy)
ClientData path;
ClientData dummy;
{
Dir_ClearPath(path);
return(0);
Dir_ClearPath((Lst) path);
return(dummy ? 0 : 0);
}
/*-
@ -634,9 +644,9 @@ static void
ParseDoDependency (line)
char *line; /* the line to parse */
{
register char *cp; /* our current position */
register GNode *gn; /* a general purpose temporary node */
register int op; /* the operator on the line */
char *cp; /* our current position */
GNode *gn; /* a general purpose temporary node */
int op; /* the operator on the line */
char savec; /* a place to save a character */
Lst paths; /* List of search paths to alter when parsing
* a list of .PATH targets */
@ -931,7 +941,7 @@ ParseDoDependency (line)
cp++; /* Advance beyond operator */
Lst_ForEach (targets, ParseDoOp, (ClientData)op);
Lst_ForEach (targets, ParseDoOp, (ClientData)&op);
/*
* Get to the first source
@ -1225,20 +1235,20 @@ Parse_DoVar (line, ctxt)
* assignment. This reduces error checks */
GNode *ctxt; /* Context in which to do the assignment */
{
char *cp; /* pointer into line */
char *cp; /* pointer into line */
enum {
VAR_SUBST, VAR_APPEND, VAR_SHELL, VAR_NORMAL
} type; /* Type of assignment */
char *opc; /* ptr to operator character to
* null-terminate the variable name */
/*
/*
* Avoid clobbered variable warnings by forcing the compiler
* to ``unregister'' variables
*/
*/
#if __GNUC__
(void) &cp;
(void) &line;
#endif
(void) &cp;
(void) &line;
#endif
/*
* Skip to variable name
@ -1328,13 +1338,14 @@ Parse_DoVar (line, ctxt)
Boolean freeCmd; /* TRUE if the command needs to be freed, i.e.
* if any variable expansion was performed */
/*
/*
* Avoid clobbered variable warnings by forcing the compiler
* to ``unregister'' variables
*/
*/
#if __GNUC__
(void) &freeCmd;
#endif
#endif
/*
* Set up arguments for shell
*/
@ -1402,7 +1413,7 @@ Parse_DoVar (line, ctxt)
char result[BUFSIZ];
cc = read(fds[0], result, sizeof(result));
if (cc > 0)
Buf_AddBytes(buf, cc, (unsigned char *) result);
Buf_AddBytes(buf, cc, (Byte *) result);
}
while (cc > 0 || (cc == -1 && errno == EINTR));
@ -1481,14 +1492,15 @@ Parse_DoVar (line, ctxt)
* A new element is added to the commands list of the node.
*/
static int
ParseAddCmd(gn, cmd)
GNode *gn; /* the node to which the command is to be added */
char *cmd; /* the command to add */
ParseAddCmd(gnp, cmd)
ClientData gnp; /* the node to which the command is to be added */
ClientData cmd; /* the command to add */
{
/* if target already supplied, ignore commands */
if (!(gn->type & OP_HAS_COMMANDS))
(void)Lst_AtEnd(gn->commands, (ClientData)cmd);
return(0);
GNode *gn = (GNode *) gnp;
/* if target already supplied, ignore commands */
if (!(gn->type & OP_HAS_COMMANDS))
(void)Lst_AtEnd(gn->commands, cmd);
return(0);
}
/*-
@ -1500,21 +1512,21 @@ ParseAddCmd(gn, cmd)
* on multiple dependency lines.
*
* Results:
* Always 0.
* None
*
* Side Effects:
* OP_HAS_COMMANDS may be set for the target.
*
*-----------------------------------------------------------------------
*/
static int
ParseHasCommands(gn)
GNode *gn; /* Node to examine */
static void
ParseHasCommands(gnp)
ClientData gnp; /* Node to examine */
{
GNode *gn = (GNode *) gnp;
if (!Lst_IsEmpty(gn->commands)) {
gn->type |= OP_HAS_COMMANDS;
}
return(0);
}
/*-
@ -1633,7 +1645,10 @@ ParseDoInclude (file)
char *newName;
*prefEnd = '\0';
newName = str_concat (fname, file, STR_ADDSLASH);
if (file[0] == '/')
newName = strdup(file);
else
newName = str_concat (fname, file, STR_ADDSLASH);
fullname = Dir_FindFile (newName, parseIncPath);
if (fullname == (char *)NULL) {
fullname = Dir_FindFile(newName, dirSearchPath);
@ -1674,6 +1689,8 @@ ParseDoInclude (file)
return;
}
free(file);
/*
* Once we find the absolute path to the file, we get to save all the
* state from the current file before we can start reading this
@ -2071,7 +2088,8 @@ ParseReadLine ()
* for the purposes of setting semiNL */
Boolean ignComment; /* TRUE if should ignore comments (in a
* shell command */
char *line; /* Result */
char *line; /* Result */
char *ep; /* to strip trailing blanks */
int lineLength; /* Length of result */
semiNL = FALSE;
@ -2181,7 +2199,7 @@ ParseReadLine ()
break;
case '#':
if (!ignComment) {
if (compatMake || (lastc != '\\')) {
if (compatMake && (lastc != '\\')) {
/*
* If the character is a hash mark and it isn't escaped
* (or we're being compatible), the thing is a comment.
@ -2229,6 +2247,21 @@ ParseReadLine ()
Buf_AddByte (buf, (Byte)'\0');
line = (char *)Buf_GetAll (buf, &lineLength);
Buf_Destroy (buf, FALSE);
/*
* Strip trailing blanks and tabs from the line.
* Do not strip a blank or tab that is preceeded by
* a '\'
*/
ep = line;
while (*ep)
++ep;
while (ep > line && (ep[-1] == ' ' || ep[-1] == '\t')) {
if (ep > line + 1 && ep[-2] == '\\')
break;
--ep;
}
*ep = 0;
if (line[0] == '.') {
/*
@ -2302,11 +2335,10 @@ ParseReadLine ()
static void
ParseFinishLine()
{
extern int Suff_EndTransform();
if (inLine) {
Lst_ForEach(targets, Suff_EndTransform, (ClientData)NULL);
Lst_Destroy (targets, ParseHasCommands);
targets = NULL;
inLine = FALSE;
}
}
@ -2356,11 +2388,12 @@ Parse_File(name, stream)
goto nextLine;
} else if (strncmp(cp, "undef", 5) == 0) {
char *cp2;
for (cp += 5; isspace(*cp); cp++) {
for (cp += 5; isspace((unsigned char) *cp); cp++) {
continue;
}
for (cp2 = cp; !isspace(*cp2) && (*cp2 != '\0'); cp2++) {
for (cp2 = cp; !isspace((unsigned char) *cp2) &&
(*cp2 != '\0'); cp2++) {
continue;
}
@ -2375,17 +2408,14 @@ Parse_File(name, stream)
goto nextLine;
}
if (*line == '\t'
#ifdef POSIX
|| *line == ' '
#endif
)
{
if (*line == '\t') {
/*
* If a line starts with a tab (or space in POSIX-land), it
* can only hope to be a creation command.
* If a line starts with a tab, it can only hope to be
* a creation command.
*/
#ifndef POSIX
shellCommand:
#endif
for (cp = line + 1; isspace (*cp); cp++) {
continue;
}
@ -2396,7 +2426,8 @@ Parse_File(name, stream)
* in a dependency spec, add the command to the list of
* commands of all targets in the dependency spec
*/
Lst_ForEach (targets, ParseAddCmd, (ClientData)cp);
Lst_ForEach (targets, ParseAddCmd, cp);
Lst_AtEnd(targCmds, (ClientData) line);
continue;
} else {
Parse_Error (PARSE_FATAL,
@ -2426,24 +2457,28 @@ Parse_File(name, stream)
* If it doesn't have an operator and we're in a dependency
* line's script, we assume it's actually a shell command
* and add it to the current list of targets.
*
* Note that POSIX declares all lines that start with
* whitespace are shell commands, so there's no need to check
* here...
*/
#ifndef POSIX
Boolean nonSpace = FALSE;
#endif
cp = line;
#ifndef POSIX
if (line[0] == ' ') {
while ((*cp != ':') && (*cp != '!') && (*cp != '\0')) {
if (!isspace(*cp)) {
nonSpace = TRUE;
}
if (isspace((unsigned char) line[0])) {
while ((*cp != '\0') && isspace((unsigned char) *cp)) {
cp++;
}
if (*cp == '\0') {
goto nextLine;
}
#ifndef POSIX
while ((*cp != ':') && (*cp != '!') && (*cp != '\0')) {
nonSpace = TRUE;
cp++;
}
#endif
}
#ifndef POSIX
if (*cp == '\0') {
if (inLine) {
Parse_Error (PARSE_WARNING,
@ -2463,6 +2498,9 @@ Parse_File(name, stream)
/*
* Need a non-circular list for the target nodes
*/
if (targets)
Lst_Destroy(targets, NOFREE);
targets = Lst_Init (FALSE);
inLine = TRUE;
@ -2515,6 +2553,7 @@ Parse_Init ()
parseIncPath = Lst_Init (FALSE);
sysIncPath = Lst_Init (FALSE);
includes = Lst_Init (FALSE);
targCmds = Lst_Init (FALSE);
/*
* Add the directories from the DEFSYSPATH (more than one may be given
@ -2532,6 +2571,18 @@ Parse_Init ()
}
}
void
Parse_End()
{
Lst_Destroy(targCmds, (void (*) __P((ClientData))) free);
if (targets)
Lst_Destroy(targets, NOFREE);
Lst_Destroy(sysIncPath, Dir_Destroy);
Lst_Destroy(parseIncPath, Dir_Destroy);
Lst_Destroy(includes, NOFREE); /* Should be empty now */
}
/*-
*-----------------------------------------------------------------------
* Parse_MainName --

View File

@ -30,10 +30,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pathnames.h 8.1 (Berkeley) 6/6/93
* from: @(#)pathnames.h 5.2 (Berkeley) 6/1/90
* $Id: pathnames.h,v 1.2 1993/08/01 18:11:58 mycroft Exp $
*/
#define _PATH_OBJDIR "obj"
#define _PATH_DEFSHELLDIR "/bin"
#define _PATH_DEFSYSMK "sys.mk"
#define _PATH_DEFSYSMK "/usr/share/mk/sys.mk"
#define _PATH_DEFSYSPATH "/usr/share/mk"

View File

@ -86,7 +86,7 @@ typedef int ReturnStatus;
* by user processes.
*/
#define NIL (~0)
#define NIL ~0
#define USER_NIL 0
#ifndef NULL
#define NULL 0
@ -103,12 +103,9 @@ typedef char *Address;
* ClientData is an uninterpreted word. It is defined as an int so that
* kdbx will not interpret client data as a string. Unlike an "Address",
* client data will generally not be used in arithmetic.
* But we don't have kdbx anymore so we define it as void (christos)
*/
typedef int *ClientData;
typedef void *ClientData;
#ifdef notdef
#include "status.h"
#endif
#endif _SPRITE
#endif /* _SPRITE */

View File

@ -37,11 +37,43 @@
*/
#ifndef lint
static char sccsid[] = "@(#)str.c 8.4 (Berkeley) 3/21/94";
#endif /* not lint */
/* from: static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90"; */
static char *rcsid = "$Id: str.c,v 1.8 1994/06/16 18:50:18 jtc Exp $";
#endif /* not lint */
#include "make.h"
static char **argv, *buffer;
static int argmax, curlen;
/*
* str_init --
* Initialize the strings package
*
*/
void
str_init()
{
char *p1;
argv = (char **)emalloc((argmax = 50) * sizeof(char *));
argv[0] = Var_Value(".MAKE", VAR_GLOBAL, &p1);
}
/*
* str_end --
* Cleanup the strings package
*
*/
void
str_end()
{
free(argv[0]);
free((Address) argv);
if (buffer)
free(buffer);
}
/*-
* str_concat --
* concatenate the two strings, inserting a space or slash between them,
@ -99,29 +131,25 @@ str_concat(s1, s2, flags)
* the first word is always the value of the .MAKE variable.
*/
char **
brk_string(str, store_argc)
brk_string(str, store_argc, expand)
register char *str;
int *store_argc;
Boolean expand;
{
static int argmax, curlen;
static char **argv, *buf;
register int argc, ch;
register char inquote, *p, *start, *t;
int len;
/* save off pmake variable */
if (!argv) {
argv = (char **)emalloc((argmax = 50) * sizeof(char *));
argv[0] = Var_Value(".MAKE", VAR_GLOBAL);
}
/* skip leading space chars. */
for (; *str == ' ' || *str == '\t'; ++str)
continue;
/* allocate room for a copy of the string */
if ((len = strlen(str) + 1) > curlen)
buf = emalloc(curlen = len);
if ((len = strlen(str) + 1) > curlen) {
if (buffer)
free(buffer);
buffer = emalloc(curlen = len);
}
/*
* copy the string; at the same time, parse backslashes,
@ -129,34 +157,45 @@ brk_string(str, store_argc)
*/
argc = 1;
inquote = '\0';
for (p = str, start = t = buf;; ++p) {
for (p = str, start = t = buffer;; ++p) {
switch(ch = *p) {
case '"':
case '\'':
if (inquote) {
if (inquote)
if (inquote == ch)
inquote = '\0';
else
break;
} else {
else {
inquote = (char) ch;
start = t;
continue;
/* Don't miss "" or '' */
if (start == NULL && p[1] == inquote) {
start = t + 1;
break;
}
}
/* FALLTHROUGH */
if (!expand) {
if (!start)
start = t;
*t++ = ch;
}
continue;
case ' ':
case '\t':
case '\n':
if (inquote)
break;
if (!start)
continue;
/* FALLTHROUGH */
case '\n':
case '\0':
/*
* end of a token -- make sure there's enough argv
* space and save off a pointer.
*/
if (!start)
goto done;
*t++ = '\0';
if (argc == argmax) {
argmax *= 2; /* ramp up fast */
@ -170,6 +209,14 @@ brk_string(str, store_argc)
goto done;
continue;
case '\\':
if (!expand) {
if (!start)
start = t;
*t++ = '\\';
ch = *++p;
break;
}
switch (ch = *++p) {
case '\0':
case '\n':

View File

@ -48,6 +48,8 @@ static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94";
* Interface:
* Suff_Init Initialize all things to do with suffixes.
*
* Suff_End Cleanup the module
*
* Suff_DoPaths This function is used to make life easier
* when searching for a file according to its
* suffix. It takes the global search path,
@ -96,6 +98,8 @@ static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94";
#include "bit.h"
static Lst sufflist; /* Lst of suffixes */
static Lst suffClean; /* Lst of suffixes to be cleaned */
static Lst srclist; /* Lst of sources */
static Lst transforms; /* Lst of transformation rules */
static int sNum = 0; /* Counter for assigning suffix numbers */
@ -113,8 +117,10 @@ typedef struct _Suff {
Lst searchPath; /* The path along which files of this suffix
* may be found */
int sNum; /* The suffix number */
int refCount; /* Reference count of list membership */
Lst parents; /* Suffixes we have a transformation to */
Lst children; /* Suffixes we have a transformation from */
Lst ref; /* List of lists this suffix is referenced */
} Suff;
/*
@ -128,6 +134,9 @@ typedef struct _Src {
GNode *node; /* The node describing the file */
int children; /* Count of existing children (so we don't free
* this thing too early or never nuke it) */
#ifdef DEBUG_SRC
Lst cp; /* Debug; children list */
#endif
} Src;
/*
@ -146,27 +155,28 @@ static Suff *emptySuff; /* The empty suffix required for POSIX
static char *SuffStrIsPrefix __P((char *, char *));
static char *SuffSuffIsSuffix __P((Suff *, char *));
static int SuffSuffIsSuffixP __P((Suff *, char *));
static int SuffSuffHasNameP __P((Suff *, char *));
static int SuffSuffIsPrefix __P((Suff *, char *));
static int SuffGNHasNameP __P((GNode *, char *));
static void SuffFree __P((Suff *));
static Suff* SuffCopy __P((Suff *));
static int SuffSuffIsSuffixP __P((ClientData, ClientData));
static int SuffSuffHasNameP __P((ClientData, ClientData));
static int SuffSuffIsPrefix __P((ClientData, ClientData));
static int SuffGNHasNameP __P((ClientData, ClientData));
static void SuffFree __P((ClientData));
static void SuffInsert __P((Lst, Suff *));
static void SuffRemove __P((Lst, Suff *));
static Boolean SuffParseTransform __P((char *, Suff **, Suff **));
static int SuffRebuildGraph __P((GNode *, Suff *));
static int SuffAddSrc __P((Suff *, LstSrc *));
static int SuffRebuildGraph __P((ClientData, ClientData));
static int SuffAddSrc __P((ClientData, ClientData));
static int SuffRemoveSrc __P((Lst));
static void SuffAddLevel __P((Lst, Src *));
static void SuffFreeSrc __P((Src *));
static Src *SuffFindThem __P((Lst));
static Src *SuffFindCmds __P((Src *));
static int SuffExpandChildren __P((GNode *, GNode *));
static Src *SuffFindThem __P((Lst, Lst));
static Src *SuffFindCmds __P((Src *, Lst));
static int SuffExpandChildren __P((ClientData, ClientData));
static Boolean SuffApplyTransform __P((GNode *, GNode *, Suff *, Suff *));
static void SuffFindArchiveDeps __P((GNode *));
static void SuffFindNormalDeps __P((GNode *));
static int SuffPrintName __P((Suff *));
static int SuffPrintSuff __P((Suff *));
static int SuffPrintTrans __P((GNode *));
static void SuffFindDeps __P((GNode *, Lst));
static void SuffFindArchiveDeps __P((GNode *, Lst));
static void SuffFindNormalDeps __P((GNode *, Lst));
static int SuffPrintName __P((ClientData, ClientData));
static int SuffPrintSuff __P((ClientData, ClientData));
static int SuffPrintTrans __P((ClientData, ClientData));
/*************** Lst Predicates ****************/
/*-
@ -243,10 +253,10 @@ SuffSuffIsSuffix (s, str)
*/
static int
SuffSuffIsSuffixP(s, str)
Suff *s;
char *str;
ClientData s;
ClientData str;
{
return(!SuffSuffIsSuffix(s, str));
return(!SuffSuffIsSuffix((Suff *) s, (char *) str));
}
/*-
@ -264,10 +274,10 @@ SuffSuffIsSuffixP(s, str)
*/
static int
SuffSuffHasNameP (s, sname)
Suff *s; /* Suffix to check */
char *sname; /* Desired name */
ClientData s; /* Suffix to check */
ClientData sname; /* Desired name */
{
return (strcmp (sname, s->name));
return (strcmp ((char *) sname, ((Suff *) s)->name));
}
/*-
@ -287,10 +297,10 @@ SuffSuffHasNameP (s, sname)
*/
static int
SuffSuffIsPrefix (s, str)
Suff *s; /* suffix to compare */
char *str; /* string to examine */
ClientData s; /* suffix to compare */
ClientData str; /* string to examine */
{
return (SuffStrIsPrefix (s->name, str) == NULL ? 1 : 0);
return (SuffStrIsPrefix (((Suff *) s)->name, (char *) str) == NULL ? 1 : 0);
}
/*-
@ -307,13 +317,28 @@ SuffSuffIsPrefix (s, str)
*/
static int
SuffGNHasNameP (gn, name)
GNode *gn; /* current node we're looking at */
char *name; /* name we're looking for */
ClientData gn; /* current node we're looking at */
ClientData name; /* name we're looking for */
{
return (strcmp (name, gn->name));
return (strcmp ((char *) name, ((GNode *) gn)->name));
}
/*********** Maintenance Functions ************/
static void
SuffUnRef(lp, sp)
ClientData lp;
ClientData sp;
{
Lst l = (Lst) lp;
LstNode ln = Lst_Member(l, sp);
if (ln != NILLNODE) {
Lst_Remove(l, ln);
((Suff *) sp)->refCount--;
}
}
/*-
*-----------------------------------------------------------------------
* SuffFree --
@ -327,16 +352,49 @@ SuffGNHasNameP (gn, name)
*-----------------------------------------------------------------------
*/
static void
SuffFree (s)
Suff *s;
SuffFree (sp)
ClientData sp;
{
Suff *s = (Suff *) sp;
if (s == suffNull)
suffNull = NULL;
if (s == emptySuff)
emptySuff = NULL;
Lst_Destroy (s->ref, NOFREE);
Lst_Destroy (s->children, NOFREE);
Lst_Destroy (s->parents, NOFREE);
Lst_Destroy (s->searchPath, Dir_Destroy);
free ((Address)s->name);
free ((Address)s);
}
/*-
*-----------------------------------------------------------------------
* SuffRemove --
* Remove the suffix into the list
*
* Results:
* None
*
* Side Effects:
* The reference count for the suffix is decremented and the
* suffix is possibly freed
*-----------------------------------------------------------------------
*/
static void
SuffRemove(l, s)
Lst l;
Suff *s;
{
SuffUnRef((ClientData) l, (ClientData) s);
if (s->refCount == 0)
SuffFree((ClientData) s);
}
/*-
*-----------------------------------------------------------------------
* SuffInsert --
@ -347,7 +405,7 @@ SuffFree (s)
* None
*
* Side Effects:
* Not really
* The reference count of the suffix is incremented
*-----------------------------------------------------------------------
*/
static void
@ -377,11 +435,15 @@ SuffInsert (l, s)
printf("at end of list\n");
}
(void)Lst_AtEnd (l, (ClientData)s);
s->refCount++;
(void)Lst_AtEnd(s->ref, (ClientData) l);
} else if (s2->sNum != s->sNum) {
if (DEBUG(SUFF)) {
printf("before %s(%d)\n", s2->name, s2->sNum);
}
(void)Lst_Insert (l, ln, (ClientData)s);
s->refCount++;
(void)Lst_AtEnd(s->ref, (ClientData) l);
} else if (DEBUG(SUFF)) {
printf("already there\n");
}
@ -407,8 +469,7 @@ SuffInsert (l, s)
void
Suff_ClearSuffixes ()
{
Lst_Destroy (sufflist, SuffFree);
Lst_Concat (suffClean, sufflist, LST_CONCLINK);
sufflist = Lst_Init(FALSE);
sNum = 0;
suffNull = emptySuff;
@ -473,7 +534,7 @@ SuffParseTransform(str, srcPtr, targPtr)
* XXX: Use emptySuff over suffNull?
*/
*srcPtr = single;
*targPtr = SuffCopy(suffNull);
*targPtr = suffNull;
return(TRUE);
}
return (FALSE);
@ -597,14 +658,16 @@ Suff_AddTransform (line)
*-----------------------------------------------------------------------
*/
int
Suff_EndTransform(gn)
GNode *gn; /* Node for transformation */
Suff_EndTransform(gnp, dummy)
ClientData gnp; /* Node for transformation */
ClientData dummy; /* Node for transformation */
{
GNode *gn = (GNode *) gnp;
if ((gn->type & OP_TRANSFORM) && Lst_IsEmpty(gn->commands) &&
Lst_IsEmpty(gn->children))
{
Suff *s, *t;
LstNode ln;
(void)SuffParseTransform(gn->name, &s, &t);
@ -621,23 +684,17 @@ Suff_EndTransform(gn)
* We'll be called twice when the next target is seen, but .c and .o
* are only linked once...
*/
ln = Lst_Member(t->children, (ClientData)s);
if (ln != NILLNODE) {
(void)Lst_Remove(t->children, ln);
}
SuffRemove(t->children, s);
/*
* Remove the target from the source's parents list
*/
ln = Lst_Member(s->parents, (ClientData)t);
if (ln != NILLNODE) {
(void)Lst_Remove(s->parents, ln);
}
SuffRemove(s->parents, t);
} else if ((gn->type & OP_TRANSFORM) && DEBUG(SUFF)) {
printf("transformation %s complete\n", gn->name);
}
return(0);
return(dummy ? 0 : 0);
}
/*-
@ -660,13 +717,15 @@ Suff_EndTransform(gn)
*-----------------------------------------------------------------------
*/
static int
SuffRebuildGraph(transform, s)
GNode *transform; /* Transformation to test */
Suff *s; /* Suffix to rebuild */
SuffRebuildGraph(transformp, sp)
ClientData transformp; /* Transformation to test */
ClientData sp; /* Suffix to rebuild */
{
register char *cp;
register LstNode ln;
register Suff *s2;
GNode *transform = (GNode *) transformp;
Suff *s = (Suff *) sp;
char *cp;
LstNode ln;
Suff *s2;
/*
* First see if it is a transformation from this suffix.
@ -742,8 +801,10 @@ Suff_AddSuffix (str)
s->searchPath = Lst_Init (FALSE);
s->children = Lst_Init (FALSE);
s->parents = Lst_Init (FALSE);
s->ref = Lst_Init (FALSE);
s->sNum = sNum++;
s->flags = 0;
s->refCount = 0;
(void)Lst_AtEnd (sufflist, (ClientData)s);
/*
@ -806,6 +867,7 @@ Suff_DoPaths()
{
register Suff *s;
register LstNode ln;
char *ptr;
Lst inIncludes; /* Cumulative .INCLUDES path */
Lst inLibs; /* Cumulative .LIBS path */
@ -836,8 +898,10 @@ Suff_DoPaths()
}
}
Var_Set(".INCLUDES", Dir_MakeFlags("-I", inIncludes), VAR_GLOBAL);
Var_Set(".LIBS", Dir_MakeFlags("-L", inLibs), VAR_GLOBAL);
Var_Set(".INCLUDES", ptr = Dir_MakeFlags("-I", inIncludes), VAR_GLOBAL);
free(ptr);
Var_Set(".LIBS", ptr = Dir_MakeFlags("-L", inLibs), VAR_GLOBAL);
free(ptr);
Lst_Destroy(inIncludes, Dir_Destroy);
Lst_Destroy(inLibs, Dir_Destroy);
@ -921,10 +985,12 @@ Suff_AddLib (sname)
*-----------------------------------------------------------------------
*/
static int
SuffAddSrc (s, ls)
Suff *s; /* suffix for which to create a Src structure */
LstSrc *ls; /* list and parent for the new Src */
SuffAddSrc (sp, lsp)
ClientData sp; /* suffix for which to create a Src structure */
ClientData lsp; /* list and parent for the new Src */
{
Suff *s = (Suff *) sp;
LstSrc *ls = (LstSrc *) lsp;
Src *s2; /* new Src structure */
Src *targ; /* Target structure */
@ -942,9 +1008,17 @@ SuffAddSrc (s, ls)
s2->parent = targ;
s2->node = NILGNODE;
s2->suff = s;
s->refCount++;
s2->children = 0;
targ->children += 1;
(void)Lst_AtEnd (ls->l, (ClientData)s2);
#ifdef DEBUG_SRC
s2->cp = Lst_Init(FALSE);
Lst_AtEnd(targ->cp, (ClientData) s2);
printf("1 add %x %x to %x:", targ, s2, ls->l);
Lst_ForEach(ls->l, PrintAddr, (ClientData) 0);
printf("\n");
#endif
}
s2 = (Src *) emalloc (sizeof (Src));
s2->file = str_concat (targ->pref, s->name, 0);
@ -952,9 +1026,17 @@ SuffAddSrc (s, ls)
s2->parent = targ;
s2->node = NILGNODE;
s2->suff = s;
s->refCount++;
s2->children = 0;
targ->children += 1;
(void)Lst_AtEnd (ls->l, (ClientData)s2);
#ifdef DEBUG_SRC
s2->cp = Lst_Init(FALSE);
Lst_AtEnd(targ->cp, (ClientData) s2);
printf("2 add %x %x to %x:", targ, s2, ls->l);
Lst_ForEach(ls->l, PrintAddr, (ClientData) 0);
printf("\n");
#endif
return(0);
}
@ -986,31 +1068,70 @@ SuffAddLevel (l, targ)
/*-
*----------------------------------------------------------------------
* SuffFreeSrc --
* Free all memory associated with a Src structure
* SuffRemoveSrc --
* Free all src structures in list that don't have a reference count
*
* Results:
* None
* Ture if an src was removed
*
* Side Effects:
* The memory is free'd.
*----------------------------------------------------------------------
*/
static void
SuffFreeSrc (s)
Src *s;
static int
SuffRemoveSrc (l)
Lst l;
{
free ((Address)s->file);
if (!s->parent) {
free((Address)s->pref);
} else if (--s->parent->children == 0 && s->parent->parent) {
/*
* Parent has no more children, now we're gone, and it's not
* at the top of the tree, so blow it away too.
*/
SuffFreeSrc(s->parent);
LstNode ln;
Src *s;
int t = 0;
if (Lst_Open (l) == FAILURE) {
return 0;
}
free ((Address)s);
#ifdef DEBUG_SRC
printf("cleaning %lx: ", (unsigned long) l);
Lst_ForEach(l, PrintAddr, (ClientData) 0);
printf("\n");
#endif
while ((ln = Lst_Next (l)) != NILLNODE) {
s = (Src *) Lst_Datum (ln);
if (s->children == 0) {
free ((Address)s->file);
if (!s->parent)
free((Address)s->pref);
else {
#ifdef DEBUG_SRC
LstNode ln = Lst_Member(s->parent->cp, (ClientData)s);
if (ln != NILLNODE)
Lst_Remove(s->parent->cp, ln);
#endif
--s->parent->children;
}
#ifdef DEBUG_SRC
printf("free: [l=%x] p=%x %d\n", l, s, s->children);
Lst_Destroy(s->cp, NOFREE);
#endif
Lst_Remove(l, ln);
free ((Address)s);
t |= 1;
Lst_Close(l);
return TRUE;
}
#ifdef DEBUG_SRC
else {
printf("keep: [l=%x] p=%x %d: ", l, s, s->children);
Lst_ForEach(s->cp, PrintAddr, (ClientData) 0);
printf("\n");
}
#endif
}
Lst_Close(l);
return t;
}
/*-
@ -1026,11 +1147,13 @@ SuffFreeSrc (s)
*-----------------------------------------------------------------------
*/
static Src *
SuffFindThem (srcs)
SuffFindThem (srcs, slst)
Lst srcs; /* list of Src structures to search through */
Lst slst;
{
Src *s; /* current Src */
Src *rs; /* returned Src */
char *ptr;
rs = (Src *) NULL;
@ -1040,24 +1163,38 @@ SuffFindThem (srcs)
if (DEBUG(SUFF)) {
printf ("\ttrying %s...", s->file);
}
/*
* A file is considered to exist if either a node exists in the
* graph for it or the file actually exists.
*/
if ((Targ_FindNode(s->file, TARG_NOCREATE) != NILGNODE) ||
(Dir_FindFile (s->file, s->suff->searchPath) != (char *) NULL))
{
if (DEBUG(SUFF)) {
printf ("got it\n");
}
if (Targ_FindNode(s->file, TARG_NOCREATE) != NILGNODE) {
#ifdef DEBUG_SRC
printf("remove %x from %x\n", s, srcs);
#endif
rs = s;
break;
} else {
if (DEBUG(SUFF)) {
printf ("not there\n");
}
SuffAddLevel (srcs, s);
}
if ((ptr = Dir_FindFile (s->file, s->suff->searchPath)) != NULL) {
rs = s;
#ifdef DEBUG_SRC
printf("remove %x from %x\n", s, srcs);
#endif
free(ptr);
break;
}
if (DEBUG(SUFF)) {
printf ("not there\n");
}
SuffAddLevel (srcs, s);
Lst_AtEnd(slst, (ClientData) s);
}
if (DEBUG(SUFF) && rs) {
printf ("got it\n");
}
return (rs);
}
@ -1078,8 +1215,9 @@ SuffFindThem (srcs)
*-----------------------------------------------------------------------
*/
static Src *
SuffFindCmds (targ)
Src *targ; /* Src structure to play with */
SuffFindCmds (targ, slst)
Src *targ; /* Src structure to play with */
Lst slst;
{
LstNode ln; /* General-purpose list node */
register GNode *t, /* Target GNode */
@ -1127,14 +1265,21 @@ SuffFindCmds (targ)
* source node's name so Suff_FindDeps can free it
* again (ick)), and return the new structure.
*/
ret = (Src *)emalloc (sizeof(Src));
ret = (Src *)emalloc (sizeof (Src));
ret->file = strdup(s->name);
ret->pref = targ->pref;
ret->suff = suff;
suff->refCount++;
ret->parent = targ;
ret->node = s;
ret->children = 0;
targ->children += 1;
#ifdef DEBUG_SRC
ret->cp = Lst_Init(FALSE);
printf("3 add %x %x\n", targ, ret);
Lst_AtEnd(targ->cp, (ClientData) ret);
#endif
Lst_AtEnd(slst, (ClientData) ret);
if (DEBUG(SUFF)) {
printf ("\tusing existing source %s\n", s->name);
}
@ -1164,10 +1309,12 @@ SuffFindCmds (targ)
*-----------------------------------------------------------------------
*/
static int
SuffExpandChildren(cgn, pgn)
GNode *cgn; /* Child to examine */
GNode *pgn; /* Parent node being processed */
SuffExpandChildren(cgnp, pgnp)
ClientData cgnp; /* Child to examine */
ClientData pgnp; /* Parent node being processed */
{
GNode *cgn = (GNode *) cgnp;
GNode *pgn = (GNode *) pgnp;
GNode *gn; /* New source 8) */
LstNode prevLN; /* Node after which new source should be put */
LstNode ln; /* List element for old source */
@ -1510,8 +1657,9 @@ SuffApplyTransform(tGn, sGn, t, s)
*-----------------------------------------------------------------------
*/
static void
SuffFindArchiveDeps(gn)
SuffFindArchiveDeps(gn, slst)
GNode *gn; /* Node for which to locate dependencies */
Lst slst;
{
char *eoarch; /* End of archive portion */
char *eoname; /* End of member portion */
@ -1520,7 +1668,6 @@ SuffFindArchiveDeps(gn)
TARGET, /* Must be first */
PREFIX, /* Must be second */
};
char *vals[sizeof(copy)/sizeof(copy[0])];
int i; /* Index into copy and vals */
Suff *ms; /* Suffix descriptor for member */
char *name; /* Start of member's name */
@ -1545,7 +1692,7 @@ SuffFindArchiveDeps(gn)
* suffix list, backtracking for each one...
*/
mem = Targ_FindNode(name, TARG_CREATE);
Suff_FindDeps(mem);
SuffFindDeps(mem, slst);
/*
* Create the link between the two nodes right off
@ -1560,8 +1707,11 @@ SuffFindArchiveDeps(gn)
* Copy in the variables from the member node to this one.
*/
for (i = (sizeof(copy)/sizeof(copy[0]))-1; i >= 0; i--) {
vals[i] = Var_Value(copy[i], mem);
Var_Set(copy[i], vals[i], gn);
char *p1;
Var_Set(copy[i], Var_Value(copy[i], mem, &p1), gn);
if (p1)
free(p1);
}
ms = mem->suffix;
@ -1645,8 +1795,9 @@ SuffFindArchiveDeps(gn)
*-----------------------------------------------------------------------
*/
static void
SuffFindNormalDeps(gn)
SuffFindNormalDeps(gn, slst)
GNode *gn; /* Node for which to find sources */
Lst slst;
{
char *eoname; /* End of name */
char *sopref; /* Start of prefix */
@ -1703,12 +1854,16 @@ SuffFindNormalDeps(gn)
/*
* Allocate a Src structure to which things can be transformed
*/
targ = (Src *)emalloc(sizeof(Src));
targ = (Src *)emalloc(sizeof (Src));
targ->file = strdup(gn->name);
targ->suff = (Suff *)Lst_Datum(ln);
targ->suff->refCount++;
targ->node = gn;
targ->parent = (Src *)NULL;
targ->children = 0;
#ifdef DEBUG_SRC
targ->cp = Lst_Init(FALSE);
#endif
/*
* Allocate room for the prefix, whose end is found by subtracting
@ -1744,13 +1899,17 @@ SuffFindNormalDeps(gn)
printf("\tNo known suffix on %s. Using .NULL suffix\n", gn->name);
}
targ = (Src *)emalloc(sizeof(Src));
targ = (Src *)emalloc(sizeof (Src));
targ->file = strdup(gn->name);
targ->suff = suffNull;
targ->suff->refCount++;
targ->node = gn;
targ->parent = (Src *)NULL;
targ->children = 0;
targ->pref = strdup(sopref);
#ifdef DEBUG_SRC
targ->cp = Lst_Init(FALSE);
#endif
SuffAddLevel(srcs, targ);
(void)Lst_AtEnd(targs, (ClientData)targ);
@ -1760,7 +1919,7 @@ SuffFindNormalDeps(gn)
* Using the list of possible sources built up from the target suffix(es),
* try and find an existing file/target that matches.
*/
bottom = SuffFindThem(srcs);
bottom = SuffFindThem(srcs, slst);
if (bottom == (Src *)NULL) {
/*
@ -1826,7 +1985,10 @@ SuffFindNormalDeps(gn)
int len = strlen(gn->path);
char savec;
if (gn->suffix)
gn->suffix->refCount--;
gn->suffix = targ->suff;
gn->suffix->refCount++;
savec = gn->path[len-targ->suff->nameLen];
gn->path[len-targ->suff->nameLen] = '\0';
@ -1839,6 +2001,8 @@ SuffFindNormalDeps(gn)
* The .PREFIX gets the full path if the target has
* no known suffix.
*/
if (gn->suffix)
gn->suffix->refCount--;
gn->suffix = NULL;
Var_Set(PREFIX, gn->path, gn);
@ -1850,8 +2014,14 @@ SuffFindNormalDeps(gn)
* path to be the name so Dir_MTime won't go grovelling for
* it.
*/
if (gn->suffix)
gn->suffix->refCount--;
gn->suffix = (targ == NULL) ? NULL : targ->suff;
gn->path = gn->name;
if (gn->suffix)
gn->suffix->refCount++;
if (gn->path != NULL)
free(gn->path);
gn->path = strdup(gn->name);
}
goto sfnd_return;
@ -1869,7 +2039,7 @@ SuffFindNormalDeps(gn)
* Check for overriding transformation rule implied by sources
*/
if (!Lst_IsEmpty(gn->children)) {
src = SuffFindCmds(targ);
src = SuffFindCmds(targ, slst);
if (src != (Src *)NULL) {
/*
@ -1877,10 +2047,10 @@ SuffFindNormalDeps(gn)
* up to, but not including, the parent node.
*/
while (bottom && bottom->parent != NULL) {
Src *p = bottom->parent;
SuffFreeSrc(bottom);
bottom = p;
if (Lst_Member(slst, (ClientData) bottom) == NILLNODE) {
Lst_AtEnd(slst, (ClientData) bottom);
}
bottom = bottom->parent;
}
bottom = src;
}
@ -1912,7 +2082,10 @@ SuffFindNormalDeps(gn)
for (src = bottom; src->parent != (Src *)NULL; src = src->parent) {
targ = src->parent;
if (src->node->suffix)
src->node->suffix->refCount--;
src->node->suffix = src->suff;
src->node->suffix->refCount++;
if (targ->node == NILGNODE) {
targ->node = Targ_FindNode(targ->file, TARG_CREATE);
@ -1939,28 +2112,35 @@ SuffFindNormalDeps(gn)
}
}
if (gn->suffix)
gn->suffix->refCount--;
gn->suffix = src->suff;
gn->suffix->refCount++;
/*
* So Dir_MTime doesn't go questing for it...
*/
gn->path = gn->name;
if (gn->path)
free(gn->path);
gn->path = strdup(gn->name);
/*
* Nuke the transformation path and the Src structures left over in the
* two lists.
*/
SuffFreeSrc(bottom);
sfnd_return:
Lst_Destroy(srcs, SuffFreeSrc);
Lst_Destroy(targs, SuffFreeSrc);
if (bottom)
if (Lst_Member(slst, (ClientData) bottom) == NILLNODE)
Lst_AtEnd(slst, (ClientData) bottom);
while (SuffRemoveSrc(srcs) || SuffRemoveSrc(targs))
continue;
Lst_Concat(slst, srcs, LST_CONCLINK);
Lst_Concat(slst, targs, LST_CONCLINK);
}
/*-
*-----------------------------------------------------------------------
* Suff_FindDeps --
@ -1988,9 +2168,22 @@ SuffFindNormalDeps(gn)
*
*-----------------------------------------------------------------------
*/
void
Suff_FindDeps (gn)
Suff_FindDeps(gn)
GNode *gn;
{
SuffFindDeps(gn, srclist);
while (SuffRemoveSrc(srclist))
continue;
}
static void
SuffFindDeps (gn, slst)
GNode *gn; /* node we're dealing with */
Lst slst;
{
if (gn->type & OP_DEPS_FOUND) {
/*
@ -2002,11 +2195,11 @@ Suff_FindDeps (gn)
}
if (DEBUG(SUFF)) {
printf ("Suff_FindDeps (%s)\n", gn->name);
printf ("SuffFindDeps (%s)\n", gn->name);
}
if (gn->type & OP_ARCHV) {
SuffFindArchiveDeps(gn);
SuffFindArchiveDeps(gn, slst);
} else if (gn->type & OP_LIB) {
/*
* If the node is a library, it is the arch module's job to find it
@ -2020,8 +2213,11 @@ Suff_FindDeps (gn)
Suff *s;
ln = Lst_Find (sufflist, (ClientData)LIBSUFF, SuffSuffHasNameP);
if (gn->suffix)
gn->suffix->refCount--;
if (ln != NILLNODE) {
gn->suffix = s = (Suff *) Lst_Datum (ln);
gn->suffix->refCount++;
Arch_FindLib (gn, s->searchPath);
} else {
gn->suffix = NULL;
@ -2034,7 +2230,7 @@ Suff_FindDeps (gn)
*/
Var_Set(PREFIX, "", gn);
} else {
SuffFindNormalDeps(gn);
SuffFindNormalDeps(gn, slst);
}
}
@ -2095,6 +2291,8 @@ void
Suff_Init ()
{
sufflist = Lst_Init (FALSE);
suffClean = Lst_Init(FALSE);
srclist = Lst_Init (FALSE);
transforms = Lst_Init (FALSE);
sNum = 0;
@ -2111,54 +2309,59 @@ Suff_Init ()
Dir_Concat(suffNull->searchPath, dirSearchPath);
suffNull->children = Lst_Init (FALSE);
suffNull->parents = Lst_Init (FALSE);
suffNull->ref = Lst_Init (FALSE);
suffNull->sNum = sNum++;
suffNull->flags = SUFF_NULL;
suffNull->refCount = 1;
}
/*-
*-----------------------------------------------------------------------
* SuffCopy --
* Create a copy of the source suffix.
* Currently does not copy children or parents
*----------------------------------------------------------------------
* Suff_End --
* Cleanup the this module
*
* Results:
* a new suffix is returned
* None
*
* Side Effects:
* none
*-----------------------------------------------------------------------
* The memory is free'd.
*----------------------------------------------------------------------
*/
static Suff *
SuffCopy(s)
Suff *s;
void
Suff_End()
{
Suff *n = (Suff *) emalloc (sizeof (Suff));
n->name = strdup (s->name);
n->nameLen = s->nameLen;
n->searchPath = Lst_Init (FALSE);
Dir_Concat(suffNull->searchPath, s->searchPath);
n->children = Lst_Init (FALSE);
n->parents = Lst_Init (FALSE);
n->sNum = s->sNum;
n->flags = s->flags;
return n;
Lst_Destroy(sufflist, SuffFree);
Lst_Destroy(suffClean, SuffFree);
if (suffNull)
SuffFree(suffNull);
Lst_Destroy(srclist, NOFREE);
Lst_Destroy(transforms, NOFREE);
}
/********************* DEBUGGING FUNCTIONS **********************/
static int SuffPrintName(s) Suff *s; {printf ("%s ", s->name); return (0);}
static int SuffPrintName(s, dummy)
ClientData s;
ClientData dummy;
{
printf ("%s ", ((Suff *) s)->name);
return (dummy ? 0 : 0);
}
static int
SuffPrintSuff (s)
Suff *s;
SuffPrintSuff (sp, dummy)
ClientData sp;
ClientData dummy;
{
Suff *s = (Suff *) sp;
int flags;
int flag;
printf ("# `%s'", s->name);
printf ("# `%s' [%d] ", s->name, s->refCount);
flags = s->flags;
if (flags) {
@ -2190,21 +2393,22 @@ SuffPrintSuff (s)
printf ("#\tSearch Path: ");
Dir_PrintPath (s->searchPath);
fputc ('\n', stdout);
return (0);
return (dummy ? 0 : 0);
}
static int
SuffPrintTrans (t)
GNode *t;
SuffPrintTrans (tp, dummy)
ClientData tp;
ClientData dummy;
{
extern int Targ_PrintCmd();
GNode *t = (GNode *) tp;
printf ("%-16s: ", t->name);
Targ_PrintType (t->type);
fputc ('\n', stdout);
Lst_ForEach (t->commands, Targ_PrintCmd, (ClientData)0);
fputc ('\n', stdout);
return(0);
return(dummy ? 0 : 0);
}
void

View File

@ -49,6 +49,8 @@ static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94";
* Interface:
* Targ_Init Initialization procedure.
*
* Targ_End Cleanup the module
*
* Targ_NewGN Create a new GNode for the passed target
* (string). The node is *not* placed in the
* hash table, though all its fields are
@ -86,10 +88,16 @@ static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94";
#include "dir.h"
static Lst allTargets; /* the list of all targets found so far */
static Lst allGNs; /* List of all the GNodes */
static Hash_Table targets; /* a hash table of same */
#define HTSIZE 191 /* initial size of hash table */
static int TargPrintOnlySrc __P((ClientData, ClientData));
static int TargPrintName __P((ClientData, ClientData));
static int TargPrintNode __P((ClientData, ClientData));
static void TargFreeGN __P((ClientData));
/*-
*-----------------------------------------------------------------------
* Targ_Init --
@ -109,6 +117,27 @@ Targ_Init ()
Hash_InitTable (&targets, HTSIZE);
}
/*-
*-----------------------------------------------------------------------
* Targ_End --
* Finalize this module
*
* Results:
* None
*
* Side Effects:
* All lists and gnodes are cleared
*-----------------------------------------------------------------------
*/
void
Targ_End ()
{
Lst_Destroy(allTargets, NOFREE);
if (allGNs)
Lst_Destroy(allGNs, TargFreeGN);
Hash_DeleteTable(&targets);
}
/*-
*-----------------------------------------------------------------------
* Targ_NewGN --
@ -119,7 +148,7 @@ Targ_Init ()
* of the passed name
*
* Side Effects:
* None.
* The gnode is added to the list of all gnodes.
*-----------------------------------------------------------------------
*/
GNode *
@ -145,15 +174,54 @@ Targ_NewGN (name)
gn->cohorts = Lst_Init (FALSE);
gn->parents = Lst_Init (FALSE);
gn->children = Lst_Init (FALSE);
gn->successors = Lst_Init(FALSE);
gn->preds = Lst_Init(FALSE);
gn->successors = Lst_Init (FALSE);
gn->preds = Lst_Init (FALSE);
gn->context = Lst_Init (FALSE);
gn->commands = Lst_Init (FALSE);
gn->suffix = NULL;
if (allGNs == NULL)
allGNs = Lst_Init(FALSE);
Lst_AtEnd(allGNs, (ClientData) gn);
return (gn);
}
/*-
*-----------------------------------------------------------------------
* TargFreeGN --
* Destroy a GNode
*
* Results:
* None.
*
* Side Effects:
* None.
*-----------------------------------------------------------------------
*/
static void
TargFreeGN (gnp)
ClientData gnp;
{
GNode *gn = (GNode *) gnp;
free(gn->name);
if (gn->path)
free(gn->path);
Lst_Destroy(gn->iParents, NOFREE);
Lst_Destroy(gn->cohorts, NOFREE);
Lst_Destroy(gn->parents, NOFREE);
Lst_Destroy(gn->children, NOFREE);
Lst_Destroy(gn->successors, NOFREE);
Lst_Destroy(gn->preds, NOFREE);
Lst_Destroy(gn->context, NOFREE);
Lst_Destroy(gn->commands, NOFREE);
free((Address)gn);
}
/*-
*-----------------------------------------------------------------------
* Targ_FindNode --
@ -343,11 +411,11 @@ Targ_SetMain (gn)
}
static int
/*ARGSUSED*/
TargPrintName (gn, ppath)
GNode *gn;
int ppath;
TargPrintName (gnp, ppath)
ClientData gnp;
ClientData ppath;
{
GNode *gn = (GNode *) gnp;
printf ("%s ", gn->name);
#ifdef notdef
if (ppath) {
@ -359,16 +427,17 @@ TargPrintName (gn, ppath)
}
}
#endif /* notdef */
return (0);
return (ppath ? 0 : 0);
}
int
Targ_PrintCmd (cmd)
char *cmd;
Targ_PrintCmd (cmd, dummy)
ClientData cmd;
ClientData dummy;
{
printf ("\t%s\n", cmd);
return (0);
printf ("\t%s\n", (char *) cmd);
return (dummy ? 0 : 0);
}
/*-
@ -462,10 +531,12 @@ Targ_PrintType (type)
*-----------------------------------------------------------------------
*/
static int
TargPrintNode (gn, pass)
GNode *gn;
int pass;
TargPrintNode (gnp, passp)
ClientData gnp;
ClientData passp;
{
GNode *gn = (GNode *) gnp;
int pass = *(int *) passp;
if (!OP_NOP(gn->type)) {
printf("#\n");
if (gn == mainTarg) {
@ -522,7 +593,7 @@ TargPrintNode (gn, pass)
Lst_ForEach (gn->commands, Targ_PrintCmd, (ClientData)0);
printf("\n\n");
if (gn->type & OP_DOUBLEDEP) {
Lst_ForEach (gn->cohorts, TargPrintNode, (ClientData)pass);
Lst_ForEach (gn->cohorts, TargPrintNode, (ClientData)&pass);
}
}
return (0);
@ -542,14 +613,15 @@ TargPrintNode (gn, pass)
*-----------------------------------------------------------------------
*/
static int
TargPrintOnlySrc(gn)
GNode *gn;
TargPrintOnlySrc(gnp, dummy)
ClientData gnp;
ClientData dummy;
{
if (OP_NOP(gn->type)) {
printf("#\t%s [%s]\n", gn->name,
gn->path ? gn->path : gn->name);
}
return (0);
GNode *gn = (GNode *) gnp;
if (OP_NOP(gn->type))
printf("#\t%s [%s]\n", gn->name, gn->path ? gn->path : gn->name);
return (dummy ? 0 : 0);
}
/*-
@ -570,10 +642,10 @@ Targ_PrintGraph (pass)
* 2 => processing done */
{
printf("#*** Input graph:\n");
Lst_ForEach (allTargets, TargPrintNode, (ClientData)pass);
Lst_ForEach (allTargets, TargPrintNode, (ClientData)&pass);
printf("\n\n");
printf("#\n# Files that are only sources:\n");
Lst_ForEach (allTargets, TargPrintOnlySrc);
Lst_ForEach (allTargets, TargPrintOnlySrc, (ClientData) 0);
printf("#*** Global Variables:\n");
Var_Dump (VAR_GLOBAL);
printf("#*** Command-line Variables:\n");

View File

@ -119,6 +119,8 @@ static char varNoError[] = "";
GNode *VAR_GLOBAL; /* variables from the makefile */
GNode *VAR_CMD; /* variables defined on the command-line */
static Lst allVars; /* List of all variables */
#define FIND_CMD 0x1 /* look in VAR_CMD when searching */
#define FIND_GLOBAL 0x2 /* look in VAR_GLOBAL as well */
#define FIND_ENV 0x4 /* look in the environment also */
@ -148,19 +150,22 @@ typedef struct {
#define VAR_NO_SUB 8 /* Substitution is non-global and already done */
} VarPattern;
static int VarCmp __P((Var *, char *));
static int VarCmp __P((ClientData, ClientData));
static Var *VarFind __P((char *, GNode *, int));
static void VarAdd __P((char *, char *, GNode *));
static Boolean VarHead __P((char *, Boolean, Buffer));
static Boolean VarTail __P((char *, Boolean, Buffer));
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));
static int VarPrintVar __P((Var *));
static void VarDelete __P((ClientData));
static Boolean VarHead __P((char *, Boolean, Buffer, ClientData));
static Boolean VarTail __P((char *, Boolean, Buffer, ClientData));
static Boolean VarSuffix __P((char *, Boolean, Buffer, ClientData));
static Boolean VarRoot __P((char *, Boolean, Buffer, ClientData));
static Boolean VarMatch __P((char *, Boolean, Buffer, ClientData));
static Boolean VarSYSVMatch __P((char *, Boolean, Buffer, ClientData));
static Boolean VarNoMatch __P((char *, Boolean, Buffer, ClientData));
static Boolean VarSubstitute __P((char *, Boolean, Buffer, ClientData));
static char *VarModify __P((char *, Boolean (*)(char *, Boolean, Buffer,
ClientData),
ClientData));
static int VarPrintVar __P((ClientData, ClientData));
/*-
*-----------------------------------------------------------------------
@ -177,10 +182,10 @@ static int VarPrintVar __P((Var *));
*/
static int
VarCmp (v, name)
Var *v; /* VAR structure to compare */
char *name; /* name to look for */
ClientData v; /* VAR structure to compare */
ClientData name; /* name to look for */
{
return (strcmp (name, v->name));
return (strcmp ((char *) name, ((Var *) v)->name));
}
/*-
@ -217,7 +222,7 @@ VarFind (name, ctxt, flags)
* and substitute the short version in for 'name' if it matches one of
* them.
*/
if (*name == '.' && isupper(name[1]))
if (*name == '.' && isupper((unsigned char) name[1]))
switch (name[1]) {
case 'A':
if (!strcmp(name, ".ALLSRC"))
@ -265,15 +270,10 @@ VarFind (name, ctxt, flags)
char *env;
if ((env = getenv (name)) != NULL) {
/*
* If the variable is found in the environment, we only duplicate
* its value (since eVarVal was allocated on the stack). The name
* doesn't need duplication since it's always in the environment
*/
int len;
v = (Var *) emalloc(sizeof(Var));
v->name = name;
v->name = strdup(name);
len = strlen(env);
@ -335,11 +335,37 @@ VarAdd (name, val, ctxt)
v->flags = 0;
(void) Lst_AtFront (ctxt->context, (ClientData)v);
(void) Lst_AtEnd (allVars, (ClientData) v);
if (DEBUG(VAR)) {
printf("%s:%s = %s\n", ctxt->name, name, val);
}
}
/*-
*-----------------------------------------------------------------------
* VarDelete --
* Delete a variable and all the space associated with it.
*
* Results:
* None
*
* Side Effects:
* None
*-----------------------------------------------------------------------
*/
static void
VarDelete(vp)
ClientData vp;
{
Var *v = (Var *) vp;
free(v->name);
Buf_Destroy(v->val, TRUE);
free((Address) v);
}
/*-
*-----------------------------------------------------------------------
* Var_Delete --
@ -369,9 +395,9 @@ Var_Delete(name, ctxt)
v = (Var *)Lst_Datum(ln);
Lst_Remove(ctxt->context, ln);
Buf_Destroy(v->val, TRUE);
free(v->name);
free((char *)v);
ln = Lst_Member(allVars, v);
Lst_Remove(allVars, ln);
VarDelete((ClientData) v);
}
}
@ -529,15 +555,23 @@ Var_Exists(name, ctxt)
*-----------------------------------------------------------------------
*/
char *
Var_Value (name, ctxt)
Var_Value (name, ctxt, frp)
char *name; /* name to find */
GNode *ctxt; /* context in which to search for it */
char **frp;
{
Var *v;
v = VarFind (name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
*frp = NULL;
if (v != (Var *) NIL) {
return ((char *)Buf_GetAll(v->val, (int *)NULL));
char *p = ((char *)Buf_GetAll(v->val, (int *)NULL));
if (v->flags & VAR_FROM_ENV) {
Buf_Destroy(v->val, FALSE);
free((Address) v);
*frp = p;
}
return p;
} else {
return ((char *) NULL);
}
@ -559,11 +593,12 @@ Var_Value (name, ctxt)
*-----------------------------------------------------------------------
*/
static Boolean
VarHead (word, addSpace, buf)
VarHead (word, addSpace, buf, dummy)
char *word; /* Word to trim */
Boolean addSpace; /* True if need to add a space to the buffer
* before sticking in the head */
Buffer buf; /* Buffer in which to store it */
ClientData dummy;
{
register char *slash;
@ -585,8 +620,8 @@ VarHead (word, addSpace, buf)
} else {
Buf_AddByte(buf, (Byte)'.');
}
return(TRUE);
}
return(dummy ? TRUE : TRUE);
}
/*-
@ -605,11 +640,12 @@ VarHead (word, addSpace, buf)
*-----------------------------------------------------------------------
*/
static Boolean
VarTail (word, addSpace, buf)
VarTail (word, addSpace, buf, dummy)
char *word; /* Word to trim */
Boolean addSpace; /* TRUE if need to stick a space in the
* buffer before adding the tail */
Buffer buf; /* Buffer in which to store it */
ClientData dummy;
{
register char *slash;
@ -625,7 +661,7 @@ VarTail (word, addSpace, buf)
} else {
Buf_AddBytes (buf, strlen(word), (Byte *)word);
}
return (TRUE);
return (dummy ? TRUE : TRUE);
}
/*-
@ -643,11 +679,12 @@ VarTail (word, addSpace, buf)
*-----------------------------------------------------------------------
*/
static Boolean
VarSuffix (word, addSpace, buf)
VarSuffix (word, addSpace, buf, dummy)
char *word; /* Word to trim */
Boolean addSpace; /* TRUE if need to add a space before placing
* the suffix in the buffer */
Buffer buf; /* Buffer in which to store it */
ClientData dummy;
{
register char *dot;
@ -659,10 +696,9 @@ VarSuffix (word, addSpace, buf)
*dot++ = '\0';
Buf_AddBytes (buf, strlen (dot), (Byte *)dot);
dot[-1] = '.';
return (TRUE);
} else {
return (addSpace);
addSpace = TRUE;
}
return (dummy ? addSpace : addSpace);
}
/*-
@ -681,11 +717,12 @@ VarSuffix (word, addSpace, buf)
*-----------------------------------------------------------------------
*/
static Boolean
VarRoot (word, addSpace, buf)
VarRoot (word, addSpace, buf, dummy)
char *word; /* Word to trim */
Boolean addSpace; /* TRUE if need to add a space to the buffer
* before placing the root in it */
Buffer buf; /* Buffer in which to store it */
ClientData dummy;
{
register char *dot;
@ -701,7 +738,7 @@ VarRoot (word, addSpace, buf)
} else {
Buf_AddBytes (buf, strlen(word), (Byte *)word);
}
return (TRUE);
return (dummy ? TRUE : TRUE);
}
/*-
@ -726,9 +763,9 @@ VarMatch (word, addSpace, buf, pattern)
* buffer before adding the word, if it
* matches */
Buffer buf; /* Buffer in which to store it */
char *pattern; /* Pattern the word must match */
ClientData pattern; /* Pattern the word must match */
{
if (Str_Match(word, pattern)) {
if (Str_Match(word, (char *) pattern)) {
if (addSpace) {
Buf_AddByte(buf, (Byte)' ');
}
@ -757,16 +794,17 @@ VarMatch (word, addSpace, buf, pattern)
*-----------------------------------------------------------------------
*/
static Boolean
VarSYSVMatch (word, addSpace, buf, pat)
VarSYSVMatch (word, addSpace, buf, patp)
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 */
ClientData patp; /* Pattern the word must match */
{
int len;
char *ptr;
VarPattern *pat = (VarPattern *) patp;
if (addSpace)
Buf_AddByte(buf, (Byte)' ');
@ -804,9 +842,9 @@ VarNoMatch (word, addSpace, buf, pattern)
* buffer before adding the word, if it
* matches */
Buffer buf; /* Buffer in which to store it */
char *pattern; /* Pattern the word must match */
ClientData pattern; /* Pattern the word must match */
{
if (!Str_Match(word, pattern)) {
if (!Str_Match(word, (char *) pattern)) {
if (addSpace) {
Buf_AddByte(buf, (Byte)' ');
}
@ -832,15 +870,16 @@ VarNoMatch (word, addSpace, buf, pattern)
*-----------------------------------------------------------------------
*/
static Boolean
VarSubstitute (word, addSpace, buf, pattern)
VarSubstitute (word, addSpace, buf, patternp)
char *word; /* Word to modify */
Boolean addSpace; /* True if space should be added before
* other characters */
Buffer buf; /* Buffer for result */
register VarPattern *pattern; /* Pattern for substitution */
ClientData patternp; /* Pattern for substitution */
{
register int wordLen; /* Length of word */
register char *cp; /* General pointer */
VarPattern *pattern = (VarPattern *) patternp;
wordLen = strlen(word);
if ((pattern->flags & VAR_NO_SUB) == 0) {
@ -1010,53 +1049,29 @@ VarSubstitute (word, addSpace, buf, pattern)
static char *
VarModify (str, modProc, datum)
char *str; /* String whose words should be trimmed */
Boolean (*modProc)(); /* Function to use to modify them */
/* Function to use to modify them */
Boolean (*modProc) __P((char *, Boolean, Buffer, ClientData));
ClientData datum; /* Datum to pass it */
{
Buffer buf; /* Buffer for the new string */
register char *cp; /* Pointer to end of current word */
char endc; /* Character that ended the word */
Boolean addSpace; /* TRUE if need to add a space to the
* buffer before adding the trimmed
* word */
char **av; /* word list [first word does not count] */
int ac, i;
buf = Buf_Init (0);
cp = str;
addSpace = FALSE;
av = brk_string(str, &ac, FALSE);
for (i = 1; i < ac; i++)
addSpace = (*modProc)(av[i], addSpace, buf, datum);
for (;;) {
/*
* Skip to next word and place cp at its end.
*/
while (isspace (*str)) {
str++;
}
for (cp = str; *cp != '\0' && !isspace (*cp); cp++)
continue;
if (cp == str) {
/*
* If we didn't go anywhere, we must be done!
*/
Buf_AddByte (buf, '\0');
str = (char *)Buf_GetAll (buf, (int *)NULL);
Buf_Destroy (buf, FALSE);
return (str);
}
/*
* Nuke terminating character, but save it in endc b/c if str was
* some variable's value, it would not be good to screw it
* over...
*/
endc = *cp;
*cp = '\0';
addSpace = (* modProc) (str, addSpace, buf, datum);
if (endc) {
*cp++ = endc;
}
str = cp;
}
Buf_AddByte (buf, '\0');
str = (char *)Buf_GetAll (buf, (int *)NULL);
Buf_Destroy (buf, FALSE);
return (str);
}
/*-
@ -1094,6 +1109,10 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
Boolean haveModifier;/* TRUE if have modifiers for the variable */
register char endc; /* Ending character when variable in parens
* or braces */
register char startc; /* Starting character when variable in parens
* or braces */
int cnt; /* Used to count brace pairs when variable in
* in parens or braces */
char *start;
Boolean dynamic; /* TRUE if the variable is local and we're
* expanding it in a non-local context. This
@ -1150,7 +1169,8 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
endc = str[1];
}
} else {
endc = str[1] == '(' ? ')' : '}';
startc = str[1];
endc = startc == '(' ? ')' : '}';
/*
* Skip to the end character or a colon, whichever comes first.
@ -1253,7 +1273,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
break;
}
} else if (((tstr-str) > 4) && (str[2] == '.') &&
isupper(str[3]) &&
isupper((unsigned char) str[3]) &&
((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
{
int len;
@ -1621,11 +1641,19 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
* to verify it is a SYSV-make-style translation:
* it must be: <string1>=<string2>)
*/
for (cp = tstr; *cp != '\0' && *cp != endc; cp++) {
cp = tstr;
cnt = 1;
while (*cp != '\0' && cnt) {
if (*cp == '=') {
eqFound = TRUE;
/* continue looking for endc */
}
else if (*cp == endc)
cnt--;
else if (*cp == startc)
cnt++;
if (cnt)
cp++;
}
if (*cp == endc && eqFound) {
@ -1640,8 +1668,14 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
*cp++ = '\0';
pattern.rhs = cp;
while (*cp != endc) {
cp++;
cnt = 1;
while (cnt) {
if (*cp == endc)
cnt--;
else if (*cp == startc)
cnt++;
if (cnt)
cp++;
}
pattern.rightLen = cp - pattern.rhs;
*cp = '\0';
@ -1721,6 +1755,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
free(str);
}
*freePtr = FALSE;
Buf_Destroy(v->val, TRUE);
free((Address)v);
if (dynamic) {
str = emalloc(*lengthPtr + 1);
@ -1960,16 +1995,27 @@ Var_Init ()
{
VAR_GLOBAL = Targ_NewGN ("Global");
VAR_CMD = Targ_NewGN ("Command");
allVars = Lst_Init(FALSE);
}
void
Var_End ()
{
Lst_Destroy(allVars, VarDelete);
}
/****************** PRINT DEBUGGING INFO *****************/
static int
VarPrintVar (v)
Var *v;
VarPrintVar (vp, dummy)
ClientData vp;
ClientData dummy;
{
Var *v = (Var *) vp;
printf ("%-16s = %s\n", v->name, (char *) Buf_GetAll(v->val, (int *)NULL));
return (0);
return (dummy ? 0 : 0);
}
/*-
@ -1982,5 +2028,5 @@ void
Var_Dump (ctxt)
GNode *ctxt;
{
Lst_ForEach (ctxt->context, VarPrintVar);
Lst_ForEach (ctxt->context, VarPrintVar, (ClientData) 0);
}