mirror of
https://github.com/openbsd/src.git
synced 2025-01-03 06:45:37 -08:00
more changes, discussed and tested by various people.
- put back some job control, turns out it's necessary when we don't run a shell. - zap old #ifdef CLEANUP code... probably doesn't even compile. - kill most of the OP_LIB code. Just keep a wee little bit for compatibility (deprecated .LIBS and .INCLUDES, warns for weird dependencies instead of erroring out). - much improved debugging and -p output: sort variables, targets, rules, output stuff in a nicer format mimicing input. - better error message when no command is found, explain where the target comes from. - sort final error list by file. - show system files in errors as <bsd.prog.mk> - reincorporate random delay, that was dropped - optimize siginfo output by not regenerating the whole string each time. - finish zapping old LocationInfo field that's no longer used.
This commit is contained in:
parent
613b479708
commit
1bae8e1fd6
@ -1,10 +1,10 @@
|
||||
# $OpenBSD: Makefile,v 1.54 2012/09/21 10:01:52 espie Exp $
|
||||
# $OpenBSD: Makefile,v 1.55 2012/10/02 10:29:30 espie Exp $
|
||||
|
||||
PROG= make
|
||||
CFLAGS+= -I${.OBJDIR} -I${.CURDIR}
|
||||
HOSTCFLAGS+= -I${.OBJDIR} -I${.CURDIR}
|
||||
CDIAGFLAGS=-Wall -W -Wno-char-subscripts -Wstrict-prototypes -pedantic \
|
||||
-Wmissing-prototypes
|
||||
-Wmissing-prototypes -Wdeclaration-after-statement
|
||||
|
||||
CDEFS+=-DUSE_TIMESPEC
|
||||
CDEFS+=-DHAS_BOOL_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: arch.c,v 1.79 2010/07/19 19:46:43 espie Exp $ */
|
||||
/* $OpenBSD: arch.c,v 1.80 2012/10/02 10:29:30 espie Exp $ */
|
||||
/* $NetBSD: arch.c,v 1.17 1996/11/06 17:58:59 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -155,9 +155,6 @@ static TIMESTAMP mtime_of_member(struct arch_member *);
|
||||
static long field2long(const char *, size_t);
|
||||
static Arch *read_archive(const char *, const char *);
|
||||
|
||||
#ifdef CLEANUP
|
||||
static void ArchFree(Arch *);
|
||||
#endif
|
||||
static TIMESTAMP ArchMTimeMember(const char *, const char *, bool);
|
||||
static FILE *ArchFindMember(const char *, const char *, struct ar_hdr *, const char *);
|
||||
static void ArchTouch(const char *, const char *);
|
||||
@ -203,16 +200,6 @@ mtime_of_member(struct arch_member *m)
|
||||
return m->mtime;
|
||||
}
|
||||
|
||||
#ifdef CLEANUP
|
||||
static void
|
||||
ArchFree(Arch *a)
|
||||
{
|
||||
/* Free memory from hash entries */
|
||||
free_hash(&a->members);
|
||||
free(a);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
Arch_ParseArchive(const char **line, Lst nodes, SymTable *ctxt)
|
||||
{
|
||||
@ -878,19 +865,6 @@ Arch_Touch(GNode *gn)
|
||||
ArchTouch(Var(ARCHIVE_INDEX, gn), Var(MEMBER_INDEX, gn));
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
Arch_TouchLib(GNode *gn UNUSED)
|
||||
/* ^ Non RANLIBMAG does nothing with it */
|
||||
{
|
||||
#ifdef RANLIBMAG
|
||||
if (gn->path != NULL) {
|
||||
ArchTouch(gn->path, RANLIBMAG);
|
||||
set_times(gn->path);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TIMESTAMP
|
||||
Arch_MTime(GNode *gn)
|
||||
{
|
||||
@ -939,117 +913,8 @@ Arch_MemMTime(GNode *gn)
|
||||
return gn->mtime;
|
||||
}
|
||||
|
||||
/* we assume the system knows how to find libraries */
|
||||
void
|
||||
Arch_FindLib(GNode *gn, Lst path UNUSED)
|
||||
{
|
||||
Var(TARGET_INDEX, gn) = gn->name;
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Arch_LibOODate --
|
||||
* Decide if a node with the OP_LIB attribute is out-of-date. Called
|
||||
* from Make_OODate to make its life easier.
|
||||
*
|
||||
* There are several ways for a library to be out-of-date that are
|
||||
* not available to ordinary files. In addition, there are ways
|
||||
* that are open to regular files that are not available to
|
||||
* libraries. A library that is only used as a source is never
|
||||
* considered out-of-date by itself. This does not preclude the
|
||||
* library's modification time from making its parent be out-of-date.
|
||||
* A library will be considered out-of-date for any of these reasons,
|
||||
* given that it is a target on a dependency line somewhere:
|
||||
* Its modification time is less than that of one of its
|
||||
* sources (gn->mtime < gn->cmtime).
|
||||
* 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).
|
||||
* 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.
|
||||
*
|
||||
* Side Effects:
|
||||
* The library will be hashed if it hasn't been already.
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
bool
|
||||
Arch_LibOODate(GNode *gn)
|
||||
{
|
||||
#ifdef RANLIBMAG
|
||||
TIMESTAMP modTimeTOC; /* mod time of __.SYMDEF */
|
||||
#endif
|
||||
|
||||
if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->children))
|
||||
return false;
|
||||
if (is_strictly_before(now, gn->mtime) ||
|
||||
is_strictly_before(gn->mtime, gn->cmtime) ||
|
||||
is_out_of_date(gn->mtime))
|
||||
return true;
|
||||
#ifdef RANLIBMAG
|
||||
/* non existent libraries are always out-of-date. */
|
||||
if (gn->path == NULL)
|
||||
return true;
|
||||
modTimeTOC = ArchMTimeMember(gn->path, RANLIBMAG, false);
|
||||
|
||||
if (!is_out_of_date(modTimeTOC)) {
|
||||
if (DEBUG(ARCH) || DEBUG(MAKE))
|
||||
printf("%s modified %s...", RANLIBMAG,
|
||||
time_to_string(modTimeTOC));
|
||||
return is_strictly_before(modTimeTOC, gn->cmtime);
|
||||
}
|
||||
/* A library w/o a table of contents is out-of-date. */
|
||||
if (DEBUG(ARCH) || DEBUG(MAKE))
|
||||
printf("No t.o.c....");
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Arch_Init(void)
|
||||
{
|
||||
ohash_init(&archives, 4, &arch_info);
|
||||
}
|
||||
|
||||
#ifdef CLEANUP
|
||||
void
|
||||
Arch_End(void)
|
||||
{
|
||||
Arch *e;
|
||||
unsigned int i;
|
||||
|
||||
for (e = ohash_first(&archives, &i); e != NULL;
|
||||
e = ohash_next(&archives, &i))
|
||||
ArchFree(e);
|
||||
ohash_delete(&archives);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
Arch_IsLib(GNode *gn)
|
||||
{
|
||||
char buf[SARMAG];
|
||||
int fd;
|
||||
|
||||
if (gn->path == NULL || (fd = open(gn->path, O_RDONLY)) == -1)
|
||||
return false;
|
||||
|
||||
if (read(fd, buf, SARMAG) != SARMAG) {
|
||||
(void)close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
(void)close(fd);
|
||||
|
||||
return memcmp(buf, ARMAG, SARMAG) == 0;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef ARCH_H
|
||||
#define ARCH_H
|
||||
/* $OpenBSD: arch.h,v 1.6 2010/07/19 19:46:43 espie Exp $ */
|
||||
/* $OpenBSD: arch.h,v 1.7 2012/10/02 10:29:30 espie Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Marc Espie.
|
||||
@ -38,11 +38,6 @@
|
||||
|
||||
/* Initialization and cleanup */
|
||||
extern void Arch_Init(void);
|
||||
#ifdef CLEANUP
|
||||
extern void Arch_End(void);
|
||||
#else
|
||||
#define Arch_End()
|
||||
#endif
|
||||
|
||||
/* ok = Arch_ParseArchive(&begin, nodeLst, ctxt);
|
||||
* Given an archive specification, add list of corresponding GNodes to
|
||||
@ -54,11 +49,6 @@ extern bool Arch_ParseArchive(const char **, Lst, SymTable *);
|
||||
* Alter the modification time of the archive member described by node
|
||||
* to the current time. */
|
||||
extern void Arch_Touch(GNode *);
|
||||
/* Arch_TouchLib(node);
|
||||
* Update the modification time of the library described by node.
|
||||
* This is distinct from Arch_Touch, as it also updates the mtime
|
||||
* of the library's table of contents. */
|
||||
extern void Arch_TouchLib(GNode *);
|
||||
/* stamp = Arch_MTime(node);
|
||||
* Find the modification time of a member of an archive *in the
|
||||
* archive*, and returns it.
|
||||
@ -68,18 +58,5 @@ extern TIMESTAMP Arch_MTime(GNode *);
|
||||
* Find the modification time of a member of an archive and returns it.
|
||||
* To use when the member only exists within the archive. */
|
||||
extern TIMESTAMP Arch_MemMTime(GNode *);
|
||||
/* Arch_FindLib(node, path);
|
||||
* Search for a library node along a path, and fills the gnode's path
|
||||
* field to the actual complete path. If we don't find it, we set the
|
||||
* library name to libname.a, assuming some other mechanism will take
|
||||
* care of finding it. The library name should be in -l<name> format. */
|
||||
extern void Arch_FindLib(GNode *, Lst);
|
||||
/* bool = Arch_LibOODate(node);
|
||||
* Decide whether a library node is out-of-date. */
|
||||
extern bool Arch_LibOODate(GNode *);
|
||||
|
||||
/* bool = Arch_IsLib(node);
|
||||
* Decide whether a node is a library. */
|
||||
extern bool Arch_IsLib(GNode *);
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef _BUF_H
|
||||
#define _BUF_H
|
||||
|
||||
/* $OpenBSD: buf.h,v 1.20 2012/09/21 07:55:20 espie Exp $ */
|
||||
/* $OpenBSD: buf.h,v 1.21 2012/10/02 10:29:30 espie Exp $ */
|
||||
/* $NetBSD: buf.h,v 1.7 1996/12/31 17:53:22 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -93,9 +93,11 @@ extern void BufOverflow(Buffer);
|
||||
/* Buf_AddChars(buf, n, str);
|
||||
* Adds n chars to buffer buf starting from str. */
|
||||
extern void Buf_AddChars(Buffer, size_t, const char *);
|
||||
/* Buf_Truncate(buffer, length) */
|
||||
#define Buf_Truncate(bp, len) ((void)((bp)->inPtr = (bp)->buffer + (len)))
|
||||
/* Buf_Reset(buf);
|
||||
* Empties buffer. */
|
||||
#define Buf_Reset(bp) ((void)((bp)->inPtr = (bp)->buffer))
|
||||
#define Buf_Reset(bp) Buf_Truncate(bp, 0)
|
||||
/* n = Buf_Size(buf);
|
||||
* Returns number of chars currently in buf.
|
||||
* Doesn't include the null-terminating char. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: dir.c,v 1.59 2010/07/19 19:46:44 espie Exp $ */
|
||||
/* $OpenBSD: dir.c,v 1.60 2012/10/02 10:29:30 espie Exp $ */
|
||||
/* $NetBSD: dir.c,v 1.14 1997/03/29 16:51:26 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -369,25 +369,6 @@ Dir_Init(void)
|
||||
Fatal("Can't access current directory");
|
||||
}
|
||||
|
||||
#ifdef CLEANUP
|
||||
void
|
||||
Dir_End(void)
|
||||
{
|
||||
struct PathEntry *p;
|
||||
unsigned int i;
|
||||
|
||||
dot->refCount--;
|
||||
Dir_Destroy(dot);
|
||||
Lst_Destroy(defaultPath, Dir_Destroy);
|
||||
for (p = ohash_first(&knownDirectories, &i); p != NULL;
|
||||
p = ohash_next(&knownDirectories, &i))
|
||||
Dir_Destroy(p);
|
||||
ohash_delete(&knownDirectories);
|
||||
free_hash(&mtimes);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Dir_MatchFilesi --
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef DIR_H
|
||||
#define DIR_H
|
||||
|
||||
/* $OpenBSD: dir.h,v 1.26 2010/07/19 19:46:44 espie Exp $ */
|
||||
/* $OpenBSD: dir.h,v 1.27 2012/10/02 10:29:30 espie Exp $ */
|
||||
/* $NetBSD: dir.h,v 1.4 1996/11/06 17:59:05 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -55,15 +55,6 @@
|
||||
*/
|
||||
extern void Dir_Init(void);
|
||||
|
||||
/* Dir_End()
|
||||
* Cleanup the module.
|
||||
*/
|
||||
#ifdef CLEANUP
|
||||
extern void Dir_End(void);
|
||||
#else
|
||||
#define Dir_End()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Manipulating paths. By convention, the empty path always allows for
|
||||
* finding files in the current directory.
|
||||
|
@ -1,9 +1,7 @@
|
||||
/* $OpenBSD: dump.c,v 1.1 2012/09/21 07:55:20 espie Exp $ */
|
||||
/* $OpenBSD: dump.c,v 1.2 2012/10/02 10:29:30 espie Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012 Marc Espie.
|
||||
*
|
||||
* Extensive code modifications for the OpenBSD project.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -25,12 +23,201 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include "ohash.h"
|
||||
#include "defines.h"
|
||||
#include "gnode.h"
|
||||
#include "dump.h"
|
||||
#include "targ.h"
|
||||
#include "var.h"
|
||||
#include "memory.h"
|
||||
#include "suff.h"
|
||||
#include "lst.h"
|
||||
#include "timestamp.h"
|
||||
#include "dir.h"
|
||||
|
||||
/* since qsort doesn't have user data, this needs to be a global... */
|
||||
static ptrdiff_t cmp_offset;
|
||||
static void targ_dump(bool);
|
||||
|
||||
static int
|
||||
compare_names(const void *a, const void *b)
|
||||
{
|
||||
const char **pa = (const char **)a;
|
||||
const char **pb = (const char **)b;
|
||||
return strcmp((*pa) + cmp_offset, (*pb) + cmp_offset);
|
||||
}
|
||||
|
||||
void *
|
||||
sort_ohash_by_name(struct ohash *h)
|
||||
{
|
||||
cmp_offset = h->info.key_offset;
|
||||
|
||||
return sort_ohash(h, compare_names);
|
||||
}
|
||||
|
||||
void *
|
||||
sort_ohash(struct ohash *h, int (*comparison)(const void *, const void *))
|
||||
{
|
||||
unsigned int i, j;
|
||||
void *e;
|
||||
size_t n = ohash_entries(h);
|
||||
void **t = emalloc(sizeof(void *) * (n+1));
|
||||
cmp_offset = h->info.key_offset;
|
||||
|
||||
for (i = 0, e = ohash_first(h, &j); e != NULL; e = ohash_next(h, &j))
|
||||
t[i++] = e;
|
||||
qsort(t, n, sizeof(void *), comparison);
|
||||
/* add an extra entry to be able to figure out the end without needing
|
||||
* to keep a counter */
|
||||
t[n] = NULL;
|
||||
return t;
|
||||
}
|
||||
|
||||
static void
|
||||
TargPrintName(void *gnp)
|
||||
{
|
||||
GNode *gn = (GNode *)gnp;
|
||||
printf("%s ", gn->name);
|
||||
}
|
||||
|
||||
static void
|
||||
TargPrintOnlySrc(GNode *gn)
|
||||
{
|
||||
if (OP_NOP(gn->type) && gn->special == SPECIAL_NONE &&
|
||||
!(gn->type & OP_DUMMY)) {
|
||||
if (gn->path != NULL)
|
||||
printf("#\t%s [%s]\n", gn->name,
|
||||
strcmp(gn->path, gn->name) == 0 ? "=" : gn->path);
|
||||
else
|
||||
printf("#\t%s\n", gn->name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
TargPrintNode(GNode *gn, bool full)
|
||||
{
|
||||
if (OP_NOP(gn->type))
|
||||
return;
|
||||
switch((gn->special & SPECIAL_MASK)) {
|
||||
case SPECIAL_SUFFIXES:
|
||||
case SPECIAL_PHONY:
|
||||
case SPECIAL_ORDER:
|
||||
case SPECIAL_DEPRECATED:
|
||||
case SPECIAL_MAIN:
|
||||
case SPECIAL_IGNORE:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (full) {
|
||||
printf("# %d unmade prerequisites\n", gn->unmade);
|
||||
if (! (gn->type & (OP_JOIN|OP_USE|OP_EXEC))) {
|
||||
if (!is_out_of_date(gn->mtime)) {
|
||||
printf("# last modified %s: %s\n",
|
||||
time_to_string(gn->mtime),
|
||||
status_to_string(gn));
|
||||
} else if (gn->built_status != UNKNOWN) {
|
||||
printf("# non-existent (maybe): %s\n",
|
||||
status_to_string(gn));
|
||||
} else {
|
||||
printf("# unmade\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Lst_IsEmpty(&gn->parents)) {
|
||||
printf("# parent targets: ");
|
||||
Lst_Every(&gn->parents, TargPrintName);
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
if (gn->impliedsrc)
|
||||
printf("# implied prerequisite: %s\n", gn->impliedsrc->name);
|
||||
|
||||
printf("%-16s", gn->name);
|
||||
switch (gn->type & OP_OPMASK) {
|
||||
case OP_DEPENDS:
|
||||
printf(": "); break;
|
||||
case OP_FORCE:
|
||||
printf("! "); break;
|
||||
case OP_DOUBLEDEP:
|
||||
printf(":: "); break;
|
||||
}
|
||||
Targ_PrintType(gn->type);
|
||||
Lst_Every(&gn->children, TargPrintName);
|
||||
fputc('\n', stdout);
|
||||
Lst_Every(&gn->commands, Targ_PrintCmd);
|
||||
printf("\n\n");
|
||||
if (gn->type & OP_DOUBLEDEP) {
|
||||
LstNode ln;
|
||||
|
||||
for (ln = Lst_First(&gn->cohorts); ln != NULL; ln = Lst_Adv(ln))
|
||||
TargPrintNode((GNode *)Lst_Datum(ln), full);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dump_special(GNode **t, const char *name, int prop)
|
||||
{
|
||||
unsigned int i;
|
||||
bool first = true;
|
||||
|
||||
for (i = 0; t[i] != NULL; i++)
|
||||
if (t[i]->type & prop) {
|
||||
if (first) {
|
||||
printf("%s:", name);
|
||||
first = false;
|
||||
}
|
||||
printf(" %s", t[i]->name);
|
||||
}
|
||||
if (!first)
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
static void
|
||||
targ_dump(bool full)
|
||||
{
|
||||
GNode **t = sort_ohash_by_name(targets_hash());
|
||||
unsigned int i;
|
||||
bool first;
|
||||
|
||||
printf("# Input graph:\n");
|
||||
for (i = 0; t[i] != NULL; i++)
|
||||
TargPrintNode(t[i], full);
|
||||
printf("\n\n");
|
||||
|
||||
dump_special(t, ".PHONY", OP_PHONY);
|
||||
dump_special(t, ".PRECIOUS", OP_PRECIOUS);
|
||||
dump_special(t, ".SILENT", OP_SILENT);
|
||||
dump_special(t, ".IGNORE", OP_IGNORE);
|
||||
printf("# Other target names:\n");
|
||||
for (i = 0; t[i] != NULL; i++)
|
||||
TargPrintOnlySrc(t[i]);
|
||||
printf("\n");
|
||||
free(t);
|
||||
}
|
||||
|
||||
static bool dumped_once = false;
|
||||
|
||||
void
|
||||
dump_data(void)
|
||||
{
|
||||
Targ_PrintGraph(1);
|
||||
Var_Dump();
|
||||
Suff_PrintAll();
|
||||
targ_dump(false);
|
||||
dumped_once = true;
|
||||
}
|
||||
|
||||
void
|
||||
post_mortem(void)
|
||||
{
|
||||
if (!dumped_once) {
|
||||
Var_Dump();
|
||||
Suff_PrintAll();
|
||||
}
|
||||
targ_dump(true);
|
||||
}
|
||||
|
@ -1,12 +1,10 @@
|
||||
/* $OpenBSD: dump.h,v 1.1 2012/09/21 07:55:20 espie Exp $ */
|
||||
/* $OpenBSD: dump.h,v 1.2 2012/10/02 10:29:30 espie Exp $ */
|
||||
#ifndef _DUMP_H_
|
||||
#define _DUMP_H_
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 Marc Espie.
|
||||
*
|
||||
* Extensive code modifications for the OpenBSD project.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -31,4 +29,23 @@
|
||||
/* implementation of -p option */
|
||||
extern void dump_data(void);
|
||||
|
||||
/* and of graph debugging options */
|
||||
extern void post_mortem(void);
|
||||
|
||||
struct ohash;
|
||||
/* utility functions for both var and targ */
|
||||
|
||||
|
||||
/* t = sort_ohash_by_name(h):
|
||||
* returns a NULL terminated array holding hash entries, sorted by name.
|
||||
* free(t) when done with it.
|
||||
*/
|
||||
extern void *sort_ohash_by_name(struct ohash *);
|
||||
/* t = sort_ohash(h, cmp_f);
|
||||
* returns a NULL terminated array holding hash entries, pass comparison
|
||||
* function.
|
||||
* free(t) when done with it.
|
||||
*/
|
||||
extern void * sort_ohash(struct ohash *, int (*)(const void *, const void *));
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: engine.c,v 1.33 2012/09/21 07:55:20 espie Exp $ */
|
||||
/* $OpenBSD: engine.c,v 1.34 2012/10/02 10:29:30 espie Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012 Marc Espie.
|
||||
*
|
||||
@ -97,6 +97,7 @@ static int rewrite_time(const char *);
|
||||
static void setup_meta(void);
|
||||
static void setup_engine(void);
|
||||
static char **recheck_command_for_shell(char **);
|
||||
static void list_parents(GNode *, FILE *);
|
||||
|
||||
bool
|
||||
node_find_valid_commands(GNode *gn)
|
||||
@ -109,8 +110,14 @@ node_find_valid_commands(GNode *gn)
|
||||
if (Targ_Silent(gn))
|
||||
gn->type |= OP_SILENT;
|
||||
|
||||
if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->commands) &&
|
||||
(gn->type & OP_LIB) == 0) {
|
||||
if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->commands)) {
|
||||
/* XXX */
|
||||
if ((gn->type & OP_LIB)) {
|
||||
printf("Warning: target %s", gn->name);
|
||||
list_parents(gn, stdout);
|
||||
printf(" does not have any command\n");
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
* No commands. Look for .DEFAULT rule from which we might infer
|
||||
* commands
|
||||
@ -142,6 +149,26 @@ node_find_valid_commands(GNode *gn)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
list_parents(GNode *gn, FILE *out)
|
||||
{
|
||||
LstNode ln;
|
||||
bool first = true;
|
||||
|
||||
for (ln = Lst_First(&gn->parents); ln != NULL; ln = Lst_Adv(ln)) {
|
||||
GNode *p = Lst_Datum(ln);
|
||||
if (!p->must_make)
|
||||
continue;
|
||||
if (first) {
|
||||
fprintf(out, " (prerequisite of:");
|
||||
first = false;
|
||||
}
|
||||
fprintf(out, " %s", p->name);
|
||||
}
|
||||
if (!first)
|
||||
fprintf(out, ")");
|
||||
}
|
||||
|
||||
void
|
||||
node_failure(GNode *gn)
|
||||
{
|
||||
@ -150,19 +177,28 @@ node_failure(GNode *gn)
|
||||
* our tracks, otherwise we just don't update this
|
||||
* node's parents so they never get examined.
|
||||
*/
|
||||
static const char msg[] =
|
||||
"make: don't know how to make";
|
||||
const char *diag;
|
||||
FILE *out;
|
||||
|
||||
if (gn->type & OP_OPTIONAL) {
|
||||
printf("%s %s(ignored)\n", msg, gn->name);
|
||||
out = stdout;
|
||||
diag = "(ignored)";
|
||||
} else if (keepgoing) {
|
||||
(void)printf("%s %s(continuing)\n", msg, gn->name);
|
||||
out = stdout;
|
||||
diag = "(continuing)";
|
||||
} else {
|
||||
fprintf(stderr, "%s %s\n", msg, gn->name);
|
||||
out = stderr;
|
||||
diag = "";
|
||||
}
|
||||
fprintf(out, "make: don't know how to make %s", gn->name);
|
||||
list_parents(gn, out);
|
||||
fprintf(out, "%s\n", diag);
|
||||
if (out == stdout)
|
||||
fflush(stdout);
|
||||
else {
|
||||
print_errors();
|
||||
Punt(NULL);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* touch files the hard way, by writing stuff to them */
|
||||
@ -212,8 +248,6 @@ Job_Touch(GNode *gn)
|
||||
|
||||
if (gn->type & OP_ARCHV) {
|
||||
Arch_Touch(gn);
|
||||
} else if (gn->type & OP_LIB) {
|
||||
Arch_TouchLib(gn);
|
||||
} else {
|
||||
const char *file = gn->path != NULL ? gn->path : gn->name;
|
||||
|
||||
@ -272,12 +306,6 @@ Make_HandleUse(GNode *cgn, /* The .USE node */
|
||||
*/
|
||||
if (cgn->type & OP_USE)
|
||||
pgn->unmade--;
|
||||
|
||||
/* if the parent node doesn't have any location, then inherit the
|
||||
* use stuff, since that gives us better error messages.
|
||||
*/
|
||||
if (!pgn->origin.lineno)
|
||||
pgn->origin = cgn->origin;
|
||||
}
|
||||
|
||||
void
|
||||
@ -401,8 +429,6 @@ Make_OODate(GNode *gn)
|
||||
* - it has no children, was on the lhs of an operator and doesn't
|
||||
* exist already.
|
||||
*
|
||||
* Libraries are only considered out-of-date if the archive module says
|
||||
* they are.
|
||||
*/
|
||||
if (gn->type & OP_USE) {
|
||||
/*
|
||||
@ -412,13 +438,6 @@ Make_OODate(GNode *gn)
|
||||
if (DEBUG(MAKE))
|
||||
printf(".USE node...");
|
||||
oodate = false;
|
||||
} else if ((gn->type & OP_LIB) && Arch_IsLib(gn)) {
|
||||
if (DEBUG(MAKE))
|
||||
printf("library...");
|
||||
|
||||
/* always out of date if no children and :: target */
|
||||
oodate = Arch_LibOODate(gn) ||
|
||||
(is_out_of_date(gn->cmtime) && (gn->type & OP_DOUBLEDEP));
|
||||
} else if (gn->type & OP_JOIN) {
|
||||
/*
|
||||
* A target with the .JOIN attribute is only considered
|
||||
@ -562,6 +581,7 @@ void
|
||||
job_attach_node(Job *job, GNode *node)
|
||||
{
|
||||
job->node = node;
|
||||
job->node->built_status = BUILDING;
|
||||
job->next_cmd = Lst_First(&node->commands);
|
||||
job->exit_type = JOB_EXIT_OKAY;
|
||||
job->location = NULL;
|
||||
@ -710,6 +730,14 @@ do_run_command(Job *job)
|
||||
Punt("Could not fork");
|
||||
/*NOTREACHED*/
|
||||
case 0:
|
||||
/* place ourselves in a different process group */
|
||||
setpgid(0, 0);
|
||||
/* put a random delay unless we're the only job running
|
||||
* and there's nothing left to do.
|
||||
*/
|
||||
if (random_delay)
|
||||
if (!(runningJobs == NULL && no_jobs_left()))
|
||||
usleep(random() % random_delay);
|
||||
run_command(cmd, errCheck);
|
||||
/*NOTREACHED*/
|
||||
default:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: error.c,v 1.22 2012/09/21 07:55:20 espie Exp $ */
|
||||
/* $OpenBSD: error.c,v 1.23 2012/10/02 10:29:30 espie Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Marc Espie.
|
||||
@ -42,6 +42,7 @@
|
||||
#endif
|
||||
|
||||
#include "lowparse.h"
|
||||
#include "dump.h"
|
||||
|
||||
int fatal_errors = 0;
|
||||
|
||||
@ -84,7 +85,7 @@ Fatal(char *fmt, ...)
|
||||
(void)fprintf(stderr, "\n");
|
||||
|
||||
if (DEBUG(GRAPH2))
|
||||
Targ_PrintGraph(2);
|
||||
post_mortem();
|
||||
exit(2); /* Not 1 so -q can distinguish error */
|
||||
}
|
||||
|
||||
@ -112,7 +113,7 @@ Punt(char *fmt, ...)
|
||||
|
||||
Job_AbortAll();
|
||||
if (DEBUG(GRAPH2))
|
||||
Targ_PrintGraph(2);
|
||||
post_mortem();
|
||||
exit(2); /* Not 1, so -q can distinguish error */
|
||||
}
|
||||
|
||||
@ -129,7 +130,7 @@ Finish()
|
||||
Job_Wait();
|
||||
print_errors();
|
||||
if (DEBUG(GRAPH2))
|
||||
Targ_PrintGraph(2);
|
||||
post_mortem();
|
||||
exit(2); /* Not 1 so -q can distinguish error */
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef GNODE_H
|
||||
#define GNODE_H
|
||||
/* $OpenBSD: gnode.h,v 1.20 2012/09/21 07:55:20 espie Exp $ */
|
||||
/* $OpenBSD: gnode.h,v 1.21 2012/10/02 10:29:30 espie Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Marc Espie.
|
||||
@ -79,6 +79,7 @@ struct Suff_;
|
||||
#define CYCLE 6
|
||||
#define ENDCYCLE 7
|
||||
#define NOSUCHNODE 8
|
||||
#define BUILDING 9
|
||||
|
||||
#define SPECIAL_NONE 0U
|
||||
#define SPECIAL_PATH 21U
|
||||
@ -87,6 +88,32 @@ struct Suff_;
|
||||
#define SPECIAL_SOURCE 128U
|
||||
#define SPECIAL_TARGETSOURCE (SPECIAL_TARGET|SPECIAL_SOURCE)
|
||||
|
||||
#define SPECIAL_EXEC 4U
|
||||
#define SPECIAL_IGNORE 5U
|
||||
#define SPECIAL_INVISIBLE 8U
|
||||
#define SPECIAL_JOIN 9U
|
||||
#define SPECIAL_MADE 11U
|
||||
#define SPECIAL_MAIN 12U
|
||||
#define SPECIAL_MAKE 13U
|
||||
#define SPECIAL_MFLAGS 14U
|
||||
#define SPECIAL_NOTMAIN 15U
|
||||
#define SPECIAL_NOTPARALLEL 16U
|
||||
#define SPECIAL_OPTIONAL 18U
|
||||
#define SPECIAL_ORDER 19U
|
||||
#define SPECIAL_PARALLEL 20U
|
||||
#define SPECIAL_PHONY 22U
|
||||
#define SPECIAL_PRECIOUS 23U
|
||||
#define SPECIAL_SILENT 25U
|
||||
#define SPECIAL_SINGLESHELL 26U
|
||||
#define SPECIAL_SUFFIXES 27U
|
||||
#define SPECIAL_USE 28U
|
||||
#define SPECIAL_WAIT 29U
|
||||
#define SPECIAL_NOPATH 30U
|
||||
#define SPECIAL_ERROR 31U
|
||||
#define SPECIAL_CHEAP 32U
|
||||
#define SPECIAL_EXPENSIVE 33U
|
||||
#define SPECIAL_DEPRECATED 6U
|
||||
|
||||
struct GNode_ {
|
||||
unsigned int special_op; /* special op to apply */
|
||||
unsigned char special;/* type of special node */
|
||||
@ -97,6 +124,7 @@ struct GNode_ {
|
||||
* on this node:
|
||||
* UNKNOWN - Not examined yet
|
||||
* BEINGMADE - Target is currently being made.
|
||||
* BUILDING - There is a job running
|
||||
* MADE - Was out-of-date and has been made
|
||||
* UPTODATE - Was already up-to-date
|
||||
* ERROR - An error occurred while it was being
|
||||
@ -130,7 +158,6 @@ struct GNode_ {
|
||||
LIST preds; /* Nodes that must be made before this one */
|
||||
|
||||
SymTable context; /* The local variables */
|
||||
Location origin; /* First line number and file name of commands. */
|
||||
LIST commands; /* Creation commands */
|
||||
struct Suff_ *suffix;/* Suffix for the node (determined by
|
||||
* Suff_FindDeps and opaque to everyone
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: init.c,v 1.6 2010/07/19 19:46:44 espie Exp $ */
|
||||
/* $OpenBSD: init.c,v 1.7 2012/10/02 10:29:30 espie Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Marc Espie.
|
||||
@ -53,17 +53,3 @@ Init(void)
|
||||
Arch_Init();
|
||||
Suff_Init();
|
||||
}
|
||||
|
||||
#ifdef CLEANUP
|
||||
void
|
||||
End(void)
|
||||
{
|
||||
Suff_End();
|
||||
Targ_End();
|
||||
Arch_End();
|
||||
Var_End();
|
||||
Parse_End();
|
||||
Dir_End();
|
||||
Job_End();
|
||||
}
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: job.c,v 1.125 2012/09/21 08:18:40 espie Exp $ */
|
||||
/* $OpenBSD: job.c,v 1.126 2012/10/02 10:29:30 espie Exp $ */
|
||||
/* $NetBSD: job.c,v 1.16 1996/11/06 17:59:08 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -73,8 +73,6 @@
|
||||
* Job_Begin execute commands attached to the .BEGIN target
|
||||
* if any.
|
||||
*
|
||||
* Job_End Should cleanup any memory used.
|
||||
*
|
||||
* can_start_job Return true if we can start job
|
||||
*
|
||||
* Job_Empty Return true if the job table is completely
|
||||
@ -133,14 +131,16 @@ Job *errorJobs; /* Jobs in error at end */
|
||||
static Job *heldJobs; /* Jobs not running yet because of expensive */
|
||||
static pid_t mypid;
|
||||
|
||||
static volatile sig_atomic_t got_fatal;
|
||||
static volatile sig_atomic_t got_fatal, got_other;
|
||||
|
||||
static volatile sig_atomic_t got_SIGINT, got_SIGHUP, got_SIGQUIT, got_SIGTERM,
|
||||
got_SIGINFO;
|
||||
got_SIGINFO, got_SIGTSTP, got_SIGTTOU, got_SIGTTIN, got_SIGCONT,
|
||||
got_SIGWINCH;
|
||||
|
||||
static sigset_t sigset, emptyset;
|
||||
|
||||
static void handle_signal(int);
|
||||
static void handle_fatal_signal(int);
|
||||
static void pass_job_control_signal(int);
|
||||
static void handle_siginfo(void);
|
||||
static void postprocess_job(Job *, bool);
|
||||
static Job *prepare_job(GNode *);
|
||||
@ -157,40 +157,54 @@ static bool expensive_command(const char *);
|
||||
static void setup_signal(int);
|
||||
static void notice_signal(int);
|
||||
static void setup_all_signals(void);
|
||||
static void really_kill(int, pid_t);
|
||||
static void setup_job_control_interrupts(void);
|
||||
|
||||
static void
|
||||
print_error(Job *j, Job *k)
|
||||
{
|
||||
const char *type;
|
||||
|
||||
if (j->exit_type == JOB_EXIT_BAD)
|
||||
type = "Exit status";
|
||||
else if (j->exit_type == JOB_SIGNALED)
|
||||
type = "Received signal";
|
||||
else
|
||||
type = "Should not happen";
|
||||
fprintf(stderr, " %s %d (", type, j->code);
|
||||
fprintf(stderr, "line %lu",
|
||||
j->location->lineno);
|
||||
if (j == k)
|
||||
fprintf(stderr, " of %s,", j->location->fname);
|
||||
else
|
||||
fputs(",", stderr);
|
||||
if ((j->flags & (JOB_SILENT | JOB_IS_EXPENSIVE)) == JOB_SILENT)
|
||||
fprintf(stderr, "\n target %s: %s", j->node->name, j->cmd);
|
||||
else
|
||||
fprintf(stderr, " target %s", j->node->name);
|
||||
fputs(")\n", stderr);
|
||||
free(j->cmd);
|
||||
}
|
||||
|
||||
void
|
||||
print_errors(void)
|
||||
{
|
||||
Job *j;
|
||||
const char *previous = NULL;
|
||||
Job *j, *k, *jnext;
|
||||
|
||||
fprintf(stderr, "\nStop in %s%c\n", Var_Value(".CURDIR"),
|
||||
errorJobs ? ':' : '.');
|
||||
|
||||
for (j = errorJobs; j != NULL; j = j->next) {
|
||||
const char *type;
|
||||
|
||||
if (j->exit_type == JOB_EXIT_BAD)
|
||||
type = "Exit status";
|
||||
else if (j->exit_type == JOB_SIGNALED)
|
||||
type = "Received signal";
|
||||
else
|
||||
type = "Should not happen";
|
||||
fprintf(stderr, " %s %d (", type, j->code);
|
||||
fprintf(stderr, "line %lu",
|
||||
j->location->lineno);
|
||||
if (j->location->fname == previous)
|
||||
fputs(",", stderr);
|
||||
else
|
||||
fprintf(stderr, " of %s,", j->location->fname);
|
||||
previous = j->location->fname;
|
||||
if ((j->flags & (JOB_SILENT | JOB_IS_EXPENSIVE)) == JOB_SILENT)
|
||||
fprintf(stderr, "\n target %s: %s", j->node->name, j->cmd);
|
||||
else
|
||||
fprintf(stderr, " target %s", j->node->name);
|
||||
fputs(")\n", stderr);
|
||||
free(j->cmd);
|
||||
while (errorJobs != NULL) {
|
||||
k = errorJobs;
|
||||
errorJobs = NULL;
|
||||
for (j = k; j != NULL; j = jnext) {
|
||||
jnext = j->next;
|
||||
if (j->location->fname == k->location->fname)
|
||||
print_error(j, k);
|
||||
else {
|
||||
j->next = errorJobs;
|
||||
errorJobs = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,6 +220,7 @@ setup_signal(int sig)
|
||||
static void
|
||||
notice_signal(int sig)
|
||||
{
|
||||
|
||||
switch(sig) {
|
||||
case SIGINT:
|
||||
got_SIGINT++;
|
||||
@ -228,9 +243,37 @@ notice_signal(int sig)
|
||||
break;
|
||||
case SIGCHLD:
|
||||
break;
|
||||
case SIGTSTP:
|
||||
got_SIGTSTP++;
|
||||
got_other = 1;
|
||||
break;
|
||||
case SIGTTOU:
|
||||
got_SIGTTOU++;
|
||||
got_other = 1;
|
||||
break;
|
||||
case SIGTTIN:
|
||||
got_SIGTTIN++;
|
||||
got_other = 1;
|
||||
break;
|
||||
case SIGCONT:
|
||||
got_SIGCONT++;
|
||||
got_other = 1;
|
||||
break;
|
||||
case SIGWINCH:
|
||||
got_SIGWINCH++;
|
||||
got_other = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setup_job_control_interrupts(void)
|
||||
{
|
||||
setup_signal(SIGTSTP);
|
||||
setup_signal(SIGTTOU);
|
||||
setup_signal(SIGTTIN);
|
||||
}
|
||||
|
||||
void
|
||||
setup_all_signals(void)
|
||||
{
|
||||
@ -249,22 +292,32 @@ setup_all_signals(void)
|
||||
/* Have to see SIGCHLD */
|
||||
setup_signal(SIGCHLD);
|
||||
got_fatal = 0;
|
||||
setup_job_control_interrupts();
|
||||
setup_signal(SIGWINCH);
|
||||
setup_signal(SIGCONT);
|
||||
got_other = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_siginfo(void)
|
||||
{
|
||||
static BUFFER buf;
|
||||
static size_t length = 0;
|
||||
|
||||
Job *job;
|
||||
BUFFER buf;
|
||||
bool first = true;
|
||||
|
||||
got_SIGINFO = 0;
|
||||
/* we have to store the info in a buffer, because status from all
|
||||
* makes running would get intermixed otherwise
|
||||
*/
|
||||
Buf_Init(&buf, 0);
|
||||
|
||||
Buf_printf(&buf, "%s in %s: ", Var_Value("MAKE"), Var_Value(".CURDIR"));
|
||||
if (length == 0) {
|
||||
Buf_Init(&buf, 0);
|
||||
Buf_printf(&buf, "%s in %s: ", Var_Value("MAKE"), Var_Value(".CURDIR"));
|
||||
length = Buf_Size(&buf);
|
||||
} else
|
||||
Buf_Truncate(&buf, length);
|
||||
|
||||
for (job = runningJobs; job != NULL ; job = job->next) {
|
||||
if (!first)
|
||||
@ -275,7 +328,6 @@ handle_siginfo(void)
|
||||
Buf_puts(&buf, first ? "nothing running\n" : "\n");
|
||||
|
||||
fputs(Buf_Retrieve(&buf), stderr);
|
||||
Buf_Destroy(&buf);
|
||||
}
|
||||
|
||||
void
|
||||
@ -283,25 +335,48 @@ handle_all_signals(void)
|
||||
{
|
||||
if (got_SIGINFO)
|
||||
handle_siginfo();
|
||||
while (got_other) {
|
||||
got_other = 0;
|
||||
if (got_SIGWINCH) {
|
||||
got_SIGWINCH=0;
|
||||
pass_job_control_signal(SIGWINCH);
|
||||
}
|
||||
if (got_SIGTTIN) {
|
||||
got_SIGTTIN=0;
|
||||
pass_job_control_signal(SIGTTIN);
|
||||
}
|
||||
if (got_SIGTTOU) {
|
||||
got_SIGTTOU=0;
|
||||
pass_job_control_signal(SIGTTOU);
|
||||
}
|
||||
if (got_SIGTSTP) {
|
||||
got_SIGTSTP=0;
|
||||
pass_job_control_signal(SIGTSTP);
|
||||
}
|
||||
if (got_SIGCONT) {
|
||||
got_SIGCONT=0;
|
||||
pass_job_control_signal(SIGCONT);
|
||||
}
|
||||
}
|
||||
while (got_fatal) {
|
||||
got_fatal = 0;
|
||||
aborting = ABORT_INTERRUPT;
|
||||
|
||||
if (got_SIGINT) {
|
||||
got_SIGINT=0;
|
||||
handle_signal(SIGINT);
|
||||
handle_fatal_signal(SIGINT);
|
||||
}
|
||||
if (got_SIGHUP) {
|
||||
got_SIGHUP=0;
|
||||
handle_signal(SIGHUP);
|
||||
handle_fatal_signal(SIGHUP);
|
||||
}
|
||||
if (got_SIGQUIT) {
|
||||
got_SIGQUIT=0;
|
||||
handle_signal(SIGQUIT);
|
||||
handle_fatal_signal(SIGQUIT);
|
||||
}
|
||||
if (got_SIGTERM) {
|
||||
got_SIGTERM=0;
|
||||
handle_signal(SIGTERM);
|
||||
handle_fatal_signal(SIGTERM);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -353,7 +428,7 @@ postprocess_job(Job *job, bool okay)
|
||||
aborting = ABORT_ERROR;
|
||||
|
||||
if (aborting == ABORT_ERROR && DEBUG(QUICKDEATH))
|
||||
handle_signal(SIGINT);
|
||||
handle_fatal_signal(SIGINT);
|
||||
if (aborting == ABORT_ERROR && Job_Empty())
|
||||
Finish();
|
||||
}
|
||||
@ -517,7 +592,6 @@ void
|
||||
Job_Make(GNode *gn)
|
||||
{
|
||||
Job *job;
|
||||
bool finished;
|
||||
|
||||
job = prepare_job(gn);
|
||||
if (!job)
|
||||
@ -700,28 +774,48 @@ Job_Empty(void)
|
||||
}
|
||||
|
||||
static void
|
||||
really_kill(pid_t pid, int sig)
|
||||
{
|
||||
killpg(pid, sig);
|
||||
if (killpg(pid, sig) == - 1 && errno == ESRCH)
|
||||
kill(pid, sig);
|
||||
}
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* handle_signal --
|
||||
* Handle the receipt of an interrupt.
|
||||
*
|
||||
* Side Effects:
|
||||
* All children are killed. Another job may be started if the
|
||||
* .INTERRUPT target was given.
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
handle_signal(int signo)
|
||||
pass_job_control_signal(int signo)
|
||||
{
|
||||
Job *job;
|
||||
|
||||
debug_job_printf("handle_signal(%d) called.\n", signo);
|
||||
debug_job_printf("pass_job_control_signal(%d) called.\n", signo);
|
||||
|
||||
|
||||
for (job = runningJobs; job != NULL; job = job->next) {
|
||||
debug_job_printf("pass_job_control_signal to "
|
||||
"child %ld running %s.\n", (long)job->pid,
|
||||
job->node->name);
|
||||
killpg(job->pid, signo);
|
||||
}
|
||||
/* after forwarding the signal, those should interrupt us */
|
||||
if (signo == SIGTSTP || signo == SIGTTOU || signo == SIGTTIN) {
|
||||
sigprocmask(SIG_BLOCK, &sigset, NULL);
|
||||
signal(signo, SIG_DFL);
|
||||
kill(getpid(), signo);
|
||||
sigprocmask(SIG_SETMASK, &emptyset, NULL);
|
||||
}
|
||||
/* SIGWINCH is irrelevant for us, SIGCONT must put back normal
|
||||
* handling for other job control signals */
|
||||
if (signo == SIGCONT)
|
||||
setup_job_control_interrupts();
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* handle_fatal_signal --
|
||||
* Handle the receipt of a fatal interrupt
|
||||
*
|
||||
* Side Effects:
|
||||
* All children are killed. Another job may be started if there
|
||||
* is an interrupt target and the signal was SIGINT.
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
handle_fatal_signal(int signo)
|
||||
{
|
||||
Job *job;
|
||||
|
||||
debug_job_printf("handle_fatal_signal(%d) called.\n", signo);
|
||||
|
||||
|
||||
for (job = runningJobs; job != NULL; job = job->next) {
|
||||
@ -731,10 +825,10 @@ handle_signal(int signo)
|
||||
if (!noExecute && eunlink(file) != -1)
|
||||
Error("*** %s removed", file);
|
||||
}
|
||||
debug_job_printf("handle_signal passing signal to "
|
||||
debug_job_printf("handle_fatal_signal: passing to "
|
||||
"child %ld running %s.\n", (long)job->pid,
|
||||
job->node->name);
|
||||
really_kill(job->pid, signo);
|
||||
killpg(job->pid, signo);
|
||||
}
|
||||
|
||||
if (signo == SIGINT && !touchFlag) {
|
||||
@ -750,7 +844,7 @@ handle_signal(int signo)
|
||||
/* die by that signal */
|
||||
sigprocmask(SIG_BLOCK, &sigset, NULL);
|
||||
signal(signo, SIG_DFL);
|
||||
really_kill(getpid(), signo);
|
||||
kill(getpid(), signo);
|
||||
sigprocmask(SIG_SETMASK, &emptyset, NULL);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
@ -789,13 +883,6 @@ Job_Begin(void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CLEANUP
|
||||
void
|
||||
Job_End(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Job_Wait --
|
||||
@ -835,8 +922,8 @@ Job_AbortAll(void)
|
||||
aborting = ABORT_ERROR;
|
||||
|
||||
for (job = runningJobs; job != NULL; job = job->next) {
|
||||
really_kill(job->pid, SIGINT);
|
||||
really_kill(job->pid, SIGKILL);
|
||||
killpg(job->pid, SIGINT);
|
||||
killpg(job->pid, SIGKILL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef _JOB_H_
|
||||
#define _JOB_H_
|
||||
|
||||
/* $OpenBSD: job.h,v 1.26 2012/09/21 07:55:20 espie Exp $ */
|
||||
/* $OpenBSD: job.h,v 1.27 2012/10/02 10:29:31 espie Exp $ */
|
||||
/* $NetBSD: job.h,v 1.5 1996/11/06 17:59:10 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -51,11 +51,6 @@ extern bool can_start_job(void);
|
||||
extern bool Job_Empty(void);
|
||||
extern int Job_Finish(void);
|
||||
extern void Job_Begin(void);
|
||||
#ifdef CLEANUP
|
||||
extern void Job_End(void);
|
||||
#else
|
||||
#define Job_End()
|
||||
#endif
|
||||
|
||||
extern void Job_Wait(void);
|
||||
extern void Job_AbortAll(void);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: lowparse.c,v 1.29 2012/09/21 07:55:20 espie Exp $ */
|
||||
/* $OpenBSD: lowparse.c,v 1.30 2012/10/02 10:29:31 espie Exp $ */
|
||||
|
||||
/* low-level parsing functions. */
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
#include "error.h"
|
||||
#include "lst.h"
|
||||
#include "memory.h"
|
||||
#include "pathnames.h"
|
||||
#ifndef LOCATION_TYPE
|
||||
#include "location.h"
|
||||
#endif
|
||||
@ -126,13 +127,26 @@ Parse_setcurdir(const char *dir)
|
||||
curdir_len = strlen(dir);
|
||||
}
|
||||
|
||||
static bool
|
||||
startswith(const char *f, const char *s, size_t len)
|
||||
{
|
||||
return strncmp(f, s, len) == 0 && f[len] == '/';
|
||||
}
|
||||
|
||||
static const char *
|
||||
simplify(const char *filename)
|
||||
{
|
||||
if (strncmp(curdir, filename, curdir_len) == 0 &&
|
||||
filename[curdir_len] == '/')
|
||||
if (startswith(filename, curdir, curdir_len))
|
||||
return filename + curdir_len + 1;
|
||||
else
|
||||
else if (startswith(filename, _PATH_DEFSYSPATH,
|
||||
sizeof(_PATH_DEFSYSPATH)-1)) {
|
||||
size_t sz;
|
||||
char *buf;
|
||||
sz = strlen(filename) - sizeof(_PATH_DEFSYSPATH)+3;
|
||||
buf = emalloc(sz);
|
||||
snprintf(buf, sz, "<%s>", filename+sizeof(_PATH_DEFSYSPATH));
|
||||
return buf;
|
||||
} else
|
||||
return filename;
|
||||
}
|
||||
|
||||
@ -472,33 +486,10 @@ Parse_FillLocation(Location *origin)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CLEANUP
|
||||
void
|
||||
LowParse_Init(void)
|
||||
{
|
||||
Static_Lst_Init(&input_stack);
|
||||
current = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
LowParse_End(void)
|
||||
{
|
||||
Lst_Destroy(&input_stack, NOFREE); /* Should be empty now */
|
||||
#if 0
|
||||
Lst_Destroy(&fileNames, (SimpleProc)free);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
Parse_ReportErrors(void)
|
||||
{
|
||||
if (fatal_errors) {
|
||||
#ifdef CLEANUP
|
||||
while (Parse_NextFile())
|
||||
;
|
||||
#endif
|
||||
fprintf(stderr,
|
||||
"Fatal errors encountered -- cannot continue\n");
|
||||
exit(1);
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef LOWPARSE_H
|
||||
#define LOWPARSE_H
|
||||
|
||||
/* $OpenBSD: lowparse.h,v 1.10 2012/09/21 07:55:20 espie Exp $ */
|
||||
/* $OpenBSD: lowparse.h,v 1.11 2012/10/02 10:29:31 espie Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 Marc Espie.
|
||||
@ -46,15 +46,6 @@
|
||||
* } while (Parse_NextFile());
|
||||
*/
|
||||
|
||||
/* Initialization and cleanup */
|
||||
#ifdef CLEANUP
|
||||
extern void LowParse_Init(void);
|
||||
extern void LowParse_End(void);
|
||||
#else
|
||||
#define LowParse_Init()
|
||||
#define LowParse_End()
|
||||
#endif
|
||||
|
||||
/* Selection of input stream */
|
||||
/* Parse_FromFile(filename, filehandle);
|
||||
* Push given filehandle on the input stack, using filename for diagnostic
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: main.c,v 1.96 2012/09/21 07:55:20 espie Exp $ */
|
||||
/* $OpenBSD: main.c,v 1.97 2012/10/02 10:29:31 espie Exp $ */
|
||||
/* $NetBSD: main.c,v 1.34 1997/03/24 20:56:36 gwr Exp $ */
|
||||
|
||||
/*
|
||||
@ -568,17 +568,6 @@ setup_CURDIR_OBJDIR(struct dirs *d, const char *machine)
|
||||
d->object = d->current;
|
||||
}
|
||||
|
||||
#ifdef CLEANUP
|
||||
static void
|
||||
free_CURDIR_OBJDIR(struct dirs *d)
|
||||
{
|
||||
if (d->object != d->current)
|
||||
free(d->object);
|
||||
free(d->current);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* if the VPATH variable is defined, add its contents to the search path.
|
||||
* Uses the same format as the PATH env variable, i.e.,
|
||||
@ -623,9 +612,6 @@ read_all_make_rules(bool noBuiltins, bool read_depend,
|
||||
Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
|
||||
|
||||
read_makefile_list(&sysMkPath, d);
|
||||
#ifdef CLEANUP
|
||||
Lst_Destroy(&sysMkPath, (SimpleProc)free);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!Lst_IsEmpty(makefiles)) {
|
||||
@ -730,10 +716,9 @@ main(int argc, char **argv)
|
||||
MainParseArgs(argc, argv);
|
||||
|
||||
/*
|
||||
* Be compatible if user did not specify -j and did not explicitly
|
||||
* turn compatibility on
|
||||
* Be compatible if user did not specify -j
|
||||
*/
|
||||
if (!compatMake && !forceJobs)
|
||||
if (!forceJobs)
|
||||
compatMake = true;
|
||||
|
||||
/* And set up everything for sub-makes */
|
||||
@ -780,14 +765,15 @@ main(int argc, char **argv)
|
||||
|
||||
process_suffixes_after_makefile_is_read();
|
||||
|
||||
/* Print the initial graph, if the user requested it. */
|
||||
if (DEBUG(GRAPH1))
|
||||
Targ_PrintGraph(1);
|
||||
|
||||
if (dumpData) {
|
||||
dump_data();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Print the initial graph, if the user requested it. */
|
||||
if (DEBUG(GRAPH1))
|
||||
dump_data();
|
||||
|
||||
/* Print the values of any variables requested by the user. */
|
||||
if (!Lst_IsEmpty(&varstoprint)) {
|
||||
LstNode ln;
|
||||
@ -823,21 +809,10 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CLEANUP
|
||||
Lst_Destroy(&targs, NOFREE);
|
||||
Lst_Destroy(&varstoprint, NOFREE);
|
||||
Lst_Destroy(&makefiles, NOFREE);
|
||||
Lst_Destroy(create, (SimpleProc)free);
|
||||
#endif
|
||||
|
||||
/* print the graph now it's been processed if the user requested it */
|
||||
if (DEBUG(GRAPH2))
|
||||
Targ_PrintGraph(2);
|
||||
post_mortem();
|
||||
|
||||
#ifdef CLEANUP
|
||||
free_CURDIR_OBJDIR(&d);
|
||||
End();
|
||||
#endif
|
||||
if (queryFlag && outOfDate)
|
||||
return 1;
|
||||
else
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: parse.c,v 1.105 2012/09/21 07:55:20 espie Exp $ */
|
||||
/* $OpenBSD: parse.c,v 1.106 2012/10/02 10:29:31 espie Exp $ */
|
||||
/* $NetBSD: parse.c,v 1.29 1997/03/10 21:20:04 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -106,10 +106,6 @@ static LIST theSysIncPath; /* list of directories for <...> includes */
|
||||
Lst systemIncludePath = &theSysIncPath;
|
||||
Lst userIncludePath = &theUserIncPath;
|
||||
|
||||
#ifdef CLEANUP
|
||||
static LIST targCmds; /* command lines for targets */
|
||||
#endif
|
||||
|
||||
static GNode *mainNode; /* The main target to create. This is the
|
||||
* first target on the first dependency
|
||||
* line in the first makefile */
|
||||
@ -169,34 +165,6 @@ static bool found_delimiter(const char *);
|
||||
static unsigned int handle_special_targets(Lst);
|
||||
static void dump_targets(void);
|
||||
|
||||
#define SPECIAL_EXEC 4U
|
||||
#define SPECIAL_IGNORE 5U
|
||||
#define SPECIAL_INCLUDES 6U
|
||||
#define SPECIAL_INVISIBLE 8U
|
||||
#define SPECIAL_JOIN 9U
|
||||
#define SPECIAL_LIBS 10U
|
||||
#define SPECIAL_MADE 11U
|
||||
#define SPECIAL_MAIN 12U
|
||||
#define SPECIAL_MAKE 13U
|
||||
#define SPECIAL_MFLAGS 14U
|
||||
#define SPECIAL_NOTMAIN 15U
|
||||
#define SPECIAL_NOTPARALLEL 16U
|
||||
#define SPECIAL_NULL 17U
|
||||
#define SPECIAL_OPTIONAL 18U
|
||||
#define SPECIAL_ORDER 19U
|
||||
#define SPECIAL_PARALLEL 20U
|
||||
#define SPECIAL_PHONY 22U
|
||||
#define SPECIAL_PRECIOUS 23U
|
||||
#define SPECIAL_SILENT 25U
|
||||
#define SPECIAL_SINGLESHELL 26U
|
||||
#define SPECIAL_SUFFIXES 27U
|
||||
#define SPECIAL_USE 28U
|
||||
#define SPECIAL_WAIT 29U
|
||||
#define SPECIAL_NOPATH 30U
|
||||
#define SPECIAL_ERROR 31U
|
||||
#define SPECIAL_CHEAP 32U
|
||||
#define SPECIAL_EXPENSIVE 33U
|
||||
|
||||
|
||||
#define P(k) k, sizeof(k), K_##k
|
||||
|
||||
@ -209,10 +177,10 @@ static struct {
|
||||
} specials[] = {
|
||||
{ P(NODE_EXEC), SPECIAL_EXEC | SPECIAL_TARGETSOURCE, OP_EXEC, },
|
||||
{ P(NODE_IGNORE), SPECIAL_IGNORE | SPECIAL_TARGETSOURCE, OP_IGNORE, },
|
||||
{ P(NODE_INCLUDES), SPECIAL_INCLUDES | SPECIAL_TARGET, 0, },
|
||||
{ P(NODE_INCLUDES), SPECIAL_DEPRECATED | SPECIAL_TARGET, 0, },
|
||||
{ P(NODE_INVISIBLE),SPECIAL_INVISIBLE | SPECIAL_TARGETSOURCE,OP_INVISIBLE, },
|
||||
{ P(NODE_JOIN), SPECIAL_JOIN | SPECIAL_TARGETSOURCE, OP_JOIN, },
|
||||
{ P(NODE_LIBS), SPECIAL_LIBS | SPECIAL_TARGET, 0, },
|
||||
{ P(NODE_LIBS), SPECIAL_DEPRECATED | SPECIAL_TARGET, 0, },
|
||||
{ P(NODE_MADE), SPECIAL_MADE | SPECIAL_TARGETSOURCE, OP_MADE, },
|
||||
{ P(NODE_MAIN), SPECIAL_MAIN | SPECIAL_TARGET, 0, },
|
||||
{ P(NODE_MAKE), SPECIAL_MAKE | SPECIAL_TARGETSOURCE, OP_MAKE, },
|
||||
@ -221,7 +189,7 @@ static struct {
|
||||
{ P(NODE_NOTMAIN), SPECIAL_NOTMAIN | SPECIAL_TARGETSOURCE, OP_NOTMAIN, },
|
||||
{ P(NODE_NOTPARALLEL),SPECIAL_NOTPARALLEL | SPECIAL_TARGET, 0, },
|
||||
{ P(NODE_NO_PARALLEL),SPECIAL_NOTPARALLEL | SPECIAL_TARGET, 0, },
|
||||
{ P(NODE_NULL), SPECIAL_NULL | SPECIAL_TARGET, 0, },
|
||||
{ P(NODE_NULL), SPECIAL_DEPRECATED | SPECIAL_TARGET, 0, },
|
||||
{ P(NODE_OPTIONAL), SPECIAL_OPTIONAL | SPECIAL_TARGETSOURCE,OP_OPTIONAL, },
|
||||
{ P(NODE_ORDER), SPECIAL_ORDER | SPECIAL_TARGET, 0, },
|
||||
{ P(NODE_PARALLEL), SPECIAL_PARALLEL | SPECIAL_TARGET, 0, },
|
||||
@ -547,13 +515,6 @@ add_target_node(const char *line, const char *end)
|
||||
gn->type &= ~OP_DUMMY;
|
||||
}
|
||||
|
||||
/* try to find a proper location for a target in a file, by
|
||||
* filling it repeatedly until the target has commands..
|
||||
* This is not perfect for .USE targets...
|
||||
*/
|
||||
if ((gn->type & OP_HAS_COMMANDS) == 0)
|
||||
Parse_FillLocation(&gn->origin);
|
||||
|
||||
Array_AtEnd(>argets, gn);
|
||||
}
|
||||
|
||||
@ -737,8 +698,7 @@ handle_special_targets(Lst paths)
|
||||
if (seen_normal != 0) {
|
||||
specType = SPECIAL_NONE;
|
||||
return 0;
|
||||
}
|
||||
else if (seen_path != 0) {
|
||||
} else if (seen_path != 0) {
|
||||
specType = SPECIAL_PATH;
|
||||
return 0;
|
||||
} else if (seen_special == 0) {
|
||||
@ -910,8 +870,7 @@ ParseDoDependency(const char *line) /* the line to parse */
|
||||
* NOW GO FOR THE SOURCES
|
||||
*/
|
||||
if (specType == SPECIAL_SUFFIXES || specType == SPECIAL_PATH ||
|
||||
specType == SPECIAL_INCLUDES || specType == SPECIAL_LIBS ||
|
||||
specType == SPECIAL_NULL) {
|
||||
specType == SPECIAL_DEPRECATED) {
|
||||
while (*line) {
|
||||
/*
|
||||
* If the target was one that doesn't take files as its
|
||||
@ -952,15 +911,6 @@ ParseDoDependency(const char *line) /* the line to parse */
|
||||
Dir_AddDiri((Lst)Lst_Datum(ln), line, cp);
|
||||
break;
|
||||
}
|
||||
case SPECIAL_INCLUDES:
|
||||
Suff_AddIncludei(line, cp);
|
||||
break;
|
||||
case SPECIAL_LIBS:
|
||||
Suff_AddLibi(line, cp);
|
||||
break;
|
||||
case SPECIAL_NULL:
|
||||
Suff_SetNulli(line, cp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1454,9 +1404,6 @@ parse_commands(struct growableArray *targets, const char *line)
|
||||
|
||||
|
||||
Array_ForEach(targets, ParseAddCmd, cmd);
|
||||
#ifdef CLEANUP
|
||||
Lst_AtEnd(&targCmds, cmd);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -1595,25 +1542,8 @@ Parse_Init(void)
|
||||
Array_Init(>argets, TARGETS_SIZE);
|
||||
Array_Init(&gsources, SOURCES_SIZE);
|
||||
create_special_nodes();
|
||||
|
||||
LowParse_Init();
|
||||
#ifdef CLEANUP
|
||||
Static_Lst_Init(&targCmds);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CLEANUP
|
||||
void
|
||||
Parse_End(void)
|
||||
{
|
||||
Lst_Destroy(&targCmds, (SimpleProc)free);
|
||||
Lst_Destroy(systemIncludePath, Dir_Destroy);
|
||||
Lst_Destroy(userIncludePath, Dir_Destroy);
|
||||
LowParse_End();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
Parse_MainName(Lst listmain) /* result list */
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef PARSE_H
|
||||
#define PARSE_H
|
||||
/* $OpenBSD: parse.h,v 1.5 2010/07/19 19:46:44 espie Exp $ */
|
||||
/* $OpenBSD: parse.h,v 1.6 2012/10/02 10:29:31 espie Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Marc Espie.
|
||||
*
|
||||
@ -31,12 +31,6 @@
|
||||
*/
|
||||
|
||||
extern void Parse_Init(void);
|
||||
#ifdef CLEANUP
|
||||
extern void Parse_End(void);
|
||||
#else
|
||||
#define Parse_End()
|
||||
#endif
|
||||
|
||||
extern Lst systemIncludePath;
|
||||
extern Lst userIncludePath;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: suff.c,v 1.80 2012/04/21 04:35:32 guenther Exp $ */
|
||||
/* $OpenBSD: suff.c,v 1.81 2012/10/02 10:29:31 espie Exp $ */
|
||||
/* $NetBSD: suff.c,v 1.13 1996/11/06 17:59:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -43,10 +43,7 @@
|
||||
* Interface:
|
||||
* Suff_Init Initialize all things to do with suffixes.
|
||||
*
|
||||
* Suff_End Cleanup the module
|
||||
*
|
||||
* Suff_ClearSuffixes Clear out all the suffixes and defined
|
||||
* transformations.
|
||||
* Suff_ClearSuffixes Clear out all the suffixes.
|
||||
*
|
||||
* Suff_AddSuffix Add the passed string as another known suffix.
|
||||
*
|
||||
@ -63,9 +60,6 @@
|
||||
* Returns GNode suitable for framing, I mean,
|
||||
* tacking commands, attributes, etc. on.
|
||||
*
|
||||
* Suff_SetNull Define the suffix to consider the suffix of
|
||||
* any file that doesn't have a known one.
|
||||
*
|
||||
* Suff_FindDeps Find implicit sources for and the location of
|
||||
* a target based on its suffix. Returns the
|
||||
* bottom-most node added to the graph or NULL
|
||||
@ -96,6 +90,7 @@
|
||||
#include "gnode.h"
|
||||
#include "make.h"
|
||||
#include "stats.h"
|
||||
#include "dump.h"
|
||||
|
||||
/* XXX the suffixes hash is stored using a specific hash function, suitable
|
||||
* for looking up suffixes in reverse.
|
||||
@ -131,10 +126,6 @@ static int order = 0;
|
||||
typedef struct Suff_ {
|
||||
size_t nameLen; /* optimisation: strlen(name) */
|
||||
short flags;
|
||||
#define SUFF_INCLUDE 0x01 /* suffix marked with .INCLUDES keyword */
|
||||
#define SUFF_LIBRARY 0x02 /* suffix marked with .LIBS keyword */
|
||||
#define SUFF_NULL 0x04 /* The empty suffix (normally '', */
|
||||
/* but see .EMPTY keyword) */
|
||||
#define SUFF_ACTIVE 0x08 /* We never destroy suffixes and rules, */
|
||||
/* we just deactivate them. */
|
||||
#define SUFF_PATH 0x10 /* False suffix: actually, the path keyword */
|
||||
@ -177,13 +168,10 @@ typedef struct {
|
||||
Src *s;
|
||||
} LstSrc;
|
||||
|
||||
static Suff *suffNull; /* The NULL suffix for this run */
|
||||
static Suff *emptySuff; /* The empty suffix required for POSIX
|
||||
* single-suffix transformation rules */
|
||||
|
||||
|
||||
static void build_path_variable(struct ohash *, int, const char *, const char *);
|
||||
static void add_property(const char *, const char *, int);
|
||||
#define parse_transform(s, p, q) parse_transformi(s, s + strlen(s), p, q)
|
||||
static bool parse_transformi(const char *, const char *, Suff **, Suff **);
|
||||
#define new_suffix(s) new_suffixi(s, NULL)
|
||||
@ -197,9 +185,6 @@ static void record_possible_suffixes(GNode *, Lst, Lst);
|
||||
static Suff *find_suffix_as_suffix(Lst, const char *, const char *);
|
||||
static Suff *add_suffixi(const char *, const char *);
|
||||
|
||||
#ifdef CLEANUP
|
||||
static void SuffFree(void *);
|
||||
#endif
|
||||
static void SuffInsert(Lst, Suff *);
|
||||
static void SuffAddSrc(void *, void *);
|
||||
static int SuffRemoveSrc(Lst);
|
||||
@ -333,34 +318,6 @@ find_or_create_transformi(const char *name, const char *end)
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef CLEANUP
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* SuffFree --
|
||||
* Free up all memory associated with the given suffix structure.
|
||||
*
|
||||
* Side Effects:
|
||||
* the suffix entry is detroyed
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
SuffFree(void *sp)
|
||||
{
|
||||
Suff *s = (Suff *)sp;
|
||||
|
||||
if (s == emptySuff)
|
||||
emptySuff = NULL;
|
||||
|
||||
Lst_Destroy(&s->children, NOFREE);
|
||||
Lst_Destroy(&s->parents, NOFREE);
|
||||
Lst_Destroy(&s->searchPath, Dir_Destroy);
|
||||
|
||||
free(s->name);
|
||||
free(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* SuffInsert --
|
||||
@ -420,7 +377,6 @@ clear_suffixes(void)
|
||||
|
||||
order = 0;
|
||||
maxLen = 0;
|
||||
suffNull = emptySuff;
|
||||
}
|
||||
|
||||
void
|
||||
@ -494,7 +450,7 @@ parse_transformi(const char *str, const char *e, Suff **srcPtr, Suff **targPtr)
|
||||
src = ohash_find(&suffixes, slot);
|
||||
if (src != NULL && (src->flags & (SUFF_ACTIVE | SUFF_PATH))) {
|
||||
best_src = src;
|
||||
best_target = suffNull;
|
||||
best_target = emptySuff;
|
||||
}
|
||||
}
|
||||
if (best_src != NULL) {
|
||||
@ -652,55 +608,6 @@ find_suffix_path(GNode *gn)
|
||||
return defaultPath;
|
||||
}
|
||||
|
||||
/* find out the tagged suffixes, build a temporary path, and construct
|
||||
* a variable based on that.
|
||||
*/
|
||||
static void
|
||||
build_path_variable(struct ohash *h, int opt, const char *name,
|
||||
const char *flag)
|
||||
{
|
||||
char *value;
|
||||
LIST path;
|
||||
Suff *s;
|
||||
unsigned int i;
|
||||
|
||||
Lst_Init(&path);
|
||||
for (s = ohash_first(h, &i); s != NULL; s = ohash_next(h, &i)) {
|
||||
if (Lst_IsEmpty(&s->searchPath))
|
||||
continue;
|
||||
if (s->flags & opt)
|
||||
Dir_Concat(&path, &s->searchPath);
|
||||
}
|
||||
|
||||
value = Dir_MakeFlags(flag, &path);
|
||||
Var_Set(name, value);
|
||||
free(value);
|
||||
Lst_Destroy(&path, Dir_Destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
add_property(const char *sname, const char *end, int opt)
|
||||
{
|
||||
Suff *s;
|
||||
|
||||
s = find_suffi(sname, end);
|
||||
if (s != NULL) {
|
||||
s->flags |= opt;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Suff_AddIncludei(const char *sname, const char *end)
|
||||
{
|
||||
add_property(sname, end, SUFF_INCLUDE);
|
||||
}
|
||||
|
||||
void
|
||||
Suff_AddLibi(const char *sname, const char *end)
|
||||
{
|
||||
add_property(sname, end, SUFF_LIBRARY);
|
||||
}
|
||||
|
||||
static void
|
||||
build_suffixes_graph(void)
|
||||
{
|
||||
@ -749,9 +656,6 @@ setup_paths(void)
|
||||
else
|
||||
Lst_Clone(&s->searchPath, defaultPath, Dir_CopyDir);
|
||||
}
|
||||
|
||||
build_path_variable(&suffixes, SUFF_INCLUDE, ".INCLUDES", "-I");
|
||||
build_path_variable(&suffixes, SUFF_LIBRARY, ".LIBS", "-L");
|
||||
}
|
||||
|
||||
void
|
||||
@ -789,29 +693,6 @@ SuffAddSrc(
|
||||
|
||||
targ = ls->s;
|
||||
|
||||
if ((s->flags & SUFF_NULL) && *s->name != '\0') {
|
||||
/*
|
||||
* If the suffix has been marked as the NULL suffix, also
|
||||
* create a Src structure for a file with no suffix attached.
|
||||
* Two birds, and all that...
|
||||
*/
|
||||
s2 = emalloc(sizeof(Src));
|
||||
s2->file = estrdup(targ->pref);
|
||||
s2->pref = targ->pref;
|
||||
s2->parent = targ;
|
||||
s2->node = NULL;
|
||||
s2->suff = s;
|
||||
s2->children = 0;
|
||||
targ->children++;
|
||||
Lst_AtEnd(ls->l, s2);
|
||||
#ifdef DEBUG_SRC
|
||||
Lst_Init(&s2->cp);
|
||||
Lst_AtEnd(&targ->cp, s2);
|
||||
printf("1 add %x %x to %x:", targ, s2, ls->l);
|
||||
Lst_Every(ls->l, PrintAddr);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
s2 = emalloc(sizeof(Src));
|
||||
s2->file = Str_concat(targ->pref, s->name, 0);
|
||||
s2->pref = targ->pref;
|
||||
@ -1406,8 +1287,8 @@ SuffFindArchiveDeps(
|
||||
/* Didn't know what it was -- use .NULL suffix if not in make
|
||||
* mode. */
|
||||
if (DEBUG(SUFF))
|
||||
printf("using null suffix\n");
|
||||
ms = suffNull;
|
||||
printf("using empty suffix\n");
|
||||
ms = emptySuff;
|
||||
}
|
||||
|
||||
|
||||
@ -1555,12 +1436,12 @@ SuffFindNormalDeps(
|
||||
/* Handle target of unknown suffix... */
|
||||
if (Lst_IsEmpty(&srcs)) {
|
||||
if (DEBUG(SUFF))
|
||||
printf("\tNo known suffix on %s. Using .NULL suffix\n",
|
||||
printf("\tNo known suffix on %s. Using empty suffix\n",
|
||||
gn->name);
|
||||
|
||||
targ = emalloc(sizeof(Src));
|
||||
targ->file = estrdup(gn->name);
|
||||
targ->suff = suffNull;
|
||||
targ->suff = emptySuff;
|
||||
targ->node = gn;
|
||||
targ->parent = NULL;
|
||||
targ->children = 0;
|
||||
@ -1681,12 +1562,6 @@ sfnd_abort:
|
||||
goto sfnd_return;
|
||||
}
|
||||
|
||||
/* If the suffix indicates that the target is a library, mark that in
|
||||
* the node's type field. */
|
||||
if (targ->suff->flags & SUFF_LIBRARY) {
|
||||
gn->type |= OP_LIB;
|
||||
}
|
||||
|
||||
/* Check for overriding transformation rule implied by sources. */
|
||||
if (!Lst_IsEmpty(&gn->children)) {
|
||||
src = SuffFindCmds(targ, slst);
|
||||
@ -1817,64 +1692,12 @@ SuffFindDeps(GNode *gn, Lst slst)
|
||||
if (DEBUG(SUFF))
|
||||
printf("SuffFindDeps (%s)\n", gn->name);
|
||||
|
||||
if (gn->type & OP_ARCHV) {
|
||||
if (gn->type & OP_ARCHV)
|
||||
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 and set the TARGET variable accordingly. We merely
|
||||
* provide the search path, assuming all libraries end in ".a"
|
||||
* (if the suffix hasn't been defined, there's nothing we can
|
||||
* do for it, so we just set the TARGET variable to the node's
|
||||
* name in order to give it a value).
|
||||
*/
|
||||
Suff *s;
|
||||
|
||||
s = find_suff(LIBSUFF);
|
||||
if (s != NULL) {
|
||||
gn->suffix = s;
|
||||
Arch_FindLib(gn, &s->searchPath);
|
||||
} else {
|
||||
gn->suffix = NULL;
|
||||
Var(TARGET_INDEX, gn) = gn->name;
|
||||
}
|
||||
/*
|
||||
* Because a library (-lfoo) target doesn't follow the standard
|
||||
* filesystem conventions, we don't set the regular variables
|
||||
* for the thing. .PREFIX is simply made empty...
|
||||
*/
|
||||
Var(PREFIX_INDEX, gn) = "";
|
||||
} else
|
||||
else
|
||||
SuffFindNormalDeps(gn, slst);
|
||||
}
|
||||
|
||||
/*-
|
||||
* Notes:
|
||||
*/
|
||||
void
|
||||
Suff_SetNulli(const char *name, const char *end)
|
||||
{
|
||||
Suff *s;
|
||||
|
||||
s= find_suffi(name, end);
|
||||
if (s != NULL) {
|
||||
/* pass the pumpkin */
|
||||
suffNull->flags &= ~SUFF_NULL;
|
||||
s->flags |= SUFF_NULL;
|
||||
/*
|
||||
* XXX: Here's where the transformation mangling would take
|
||||
* place
|
||||
* we would need to handle the changing of the null suffix
|
||||
* gracefully so the old transformation rules don't just go
|
||||
* away.
|
||||
*/
|
||||
suffNull = s;
|
||||
} else {
|
||||
Parse_Error(PARSE_WARNING,
|
||||
"Desired null suffix %s not defined.", name);
|
||||
}
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Suff_Init --
|
||||
@ -1896,7 +1719,6 @@ Suff_Init(void)
|
||||
* suffix.
|
||||
*/
|
||||
emptySuff = new_suffix("");
|
||||
emptySuff->flags |= SUFF_NULL;
|
||||
make_suffix_known(emptySuff);
|
||||
Dir_Concat(&emptySuff->searchPath, defaultPath);
|
||||
ohash_init(&suffixes, 4, &suff_info);
|
||||
@ -1907,75 +1729,30 @@ Suff_Init(void)
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
*----------------------------------------------------------------------
|
||||
* Suff_End --
|
||||
* Cleanup the this module
|
||||
*
|
||||
* Side Effects:
|
||||
* The memory is free'd.
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifdef CLEANUP
|
||||
void
|
||||
Suff_End(void)
|
||||
{
|
||||
free_hash(&suffixes);
|
||||
if (emptySuff)
|
||||
SuffFree(emptySuff);
|
||||
Lst_Destroy(&srclist, NOFREE);
|
||||
ohash_delete(&transforms);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/********************* DEBUGGING FUNCTIONS **********************/
|
||||
|
||||
static void
|
||||
SuffPrintName(void *s)
|
||||
SuffPrintName(void *p)
|
||||
{
|
||||
printf("%s ", ((Suff *)s)->name);
|
||||
Suff *s = (Suff *)p;
|
||||
printf("%s ", s == emptySuff ? "<empty>" : s->name);
|
||||
}
|
||||
|
||||
static void
|
||||
SuffPrintSuff(void *sp)
|
||||
{
|
||||
Suff *s = (Suff *)sp;
|
||||
int flags;
|
||||
int flag;
|
||||
|
||||
printf("# `%s' ", s->name);
|
||||
printf("# %-5s ", s->name);
|
||||
|
||||
flags = s->flags;
|
||||
if (flags) {
|
||||
fputs(" (", stdout);
|
||||
while (flags) {
|
||||
flag = 1 << (ffs(flags) - 1);
|
||||
flags &= ~flag;
|
||||
switch (flag) {
|
||||
case SUFF_NULL:
|
||||
printf("NULL");
|
||||
break;
|
||||
case SUFF_INCLUDE:
|
||||
printf("INCLUDE");
|
||||
break;
|
||||
case SUFF_LIBRARY:
|
||||
printf("LIBRARY");
|
||||
break;
|
||||
}
|
||||
fputc(flags ? '|' : ')', stdout);
|
||||
}
|
||||
if (!Lst_IsEmpty(&s->parents)) {
|
||||
printf(" ->");
|
||||
Lst_Every(&s->parents, SuffPrintName);
|
||||
}
|
||||
if (!Lst_IsEmpty(&s->children)) {
|
||||
printf(" <-");
|
||||
Lst_Every(&s->children, SuffPrintName);
|
||||
}
|
||||
fputc('\n', stdout);
|
||||
printf("#\tTo: ");
|
||||
Lst_Every(&s->parents, SuffPrintName);
|
||||
fputc('\n', stdout);
|
||||
printf("#\tFrom: ");
|
||||
Lst_Every(&s->children, SuffPrintName);
|
||||
fputc('\n', stdout);
|
||||
printf("#\tSearch Path: ");
|
||||
Dir_PrintPath(&s->searchPath);
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
@ -1989,23 +1766,85 @@ SuffPrintTrans(GNode *t)
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_order(const void *a, const void *b)
|
||||
{
|
||||
const Suff **pa = (const Suff **)a;
|
||||
const Suff **pb = (const Suff **)b;
|
||||
return (*pb)->order - (*pa)->order;
|
||||
}
|
||||
|
||||
static void
|
||||
print_path(Suff *s)
|
||||
{
|
||||
/* do we need to print it ? compare against defaultPath */
|
||||
LstNode ln1, ln2;
|
||||
bool first = true;
|
||||
|
||||
for (ln1 = Lst_First(&s->searchPath), ln2 = Lst_First(defaultPath);
|
||||
ln1 != NULL && ln2 != NULL;
|
||||
ln1 = Lst_Adv(ln1)) {
|
||||
if (Lst_Datum(ln1) == Lst_Datum(ln2)) {
|
||||
ln2 = Lst_Adv(ln2);
|
||||
continue;
|
||||
}
|
||||
if (first) {
|
||||
printf(".PATH%s:", s->name);
|
||||
first = false;
|
||||
}
|
||||
printf(" %s", PathEntry_name(Lst_Datum(ln1)));
|
||||
}
|
||||
if (!first)
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
void
|
||||
Suff_PrintAll(void)
|
||||
{
|
||||
Suff *s;
|
||||
GNode *gn;
|
||||
Suff **t;
|
||||
GNode **u;
|
||||
unsigned int i;
|
||||
bool reprint;
|
||||
|
||||
printf("#*** Suffixes:\n");
|
||||
|
||||
for (s = ohash_first(&suffixes, &i); s != NULL;
|
||||
s = ohash_next(&suffixes, &i))
|
||||
SuffPrintSuff(s);
|
||||
printf("# Suffixes graph\n");
|
||||
t = sort_ohash_by_name(&suffixes);
|
||||
for (i = 0; t[i] != NULL; i++)
|
||||
if (!(t[i]->flags & SUFF_PATH))
|
||||
SuffPrintSuff(t[i]);
|
||||
|
||||
printf("#*** Transformations:\n");
|
||||
for (gn = ohash_first(&transforms, &i); gn != NULL;
|
||||
gn = ohash_next(&transforms, &i))
|
||||
SuffPrintTrans(gn);
|
||||
printf("\n.PATH: ");
|
||||
Dir_PrintPath(defaultPath);
|
||||
printf("\n\n");
|
||||
for (i = 0; t[i] != NULL; i++)
|
||||
if (!(t[i]->flags & SUFF_PATH))
|
||||
print_path(t[i]);
|
||||
free(t);
|
||||
|
||||
reprint = false;
|
||||
t = sort_ohash(&suffixes, compare_order);
|
||||
printf(".SUFFIXES:");
|
||||
for (i = 0; t[i] != NULL; i++) {
|
||||
if (t[i]->flags & SUFF_PATH)
|
||||
continue;
|
||||
printf(" %s", t[i]->name);
|
||||
if (!(t[i]->flags & SUFF_ACTIVE))
|
||||
reprint = true;
|
||||
}
|
||||
printf("\n\n");
|
||||
u = sort_ohash_by_name(&transforms);
|
||||
for (i = 0; u[i] != NULL; i++)
|
||||
SuffPrintTrans(u[i]);
|
||||
free(u);
|
||||
|
||||
if (reprint) {
|
||||
printf(".SUFFIXES:");
|
||||
for (i = 0; t[i] != NULL; i++)
|
||||
if (t[i]->flags & SUFF_ACTIVE)
|
||||
printf(" %s", t[i]->name);
|
||||
printf("\n");
|
||||
}
|
||||
free(t);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SRC
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef SUFF_H
|
||||
#define SUFF_H
|
||||
/* $OpenBSD: suff.h,v 1.6 2010/07/19 19:46:44 espie Exp $ */
|
||||
/* $OpenBSD: suff.h,v 1.7 2012/10/02 10:29:31 espie Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Marc Espie.
|
||||
@ -38,11 +38,6 @@ extern void Suff_SetNulli(const char *, const char *);
|
||||
extern void Suff_Init(void);
|
||||
extern void process_suffixes_after_makefile_is_read(void);
|
||||
extern Lst find_suffix_path(GNode *);
|
||||
#ifdef CLEANUP
|
||||
extern void Suff_End(void);
|
||||
#else
|
||||
#define Suff_End()
|
||||
#endif
|
||||
extern void Suff_PrintAll(void);
|
||||
extern void expand_children_from(GNode *, LstNode);
|
||||
#define expand_all_children(gn) \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: targ.c,v 1.66 2012/09/21 07:55:20 espie Exp $ */
|
||||
/* $OpenBSD: targ.c,v 1.67 2012/10/02 10:29:31 espie Exp $ */
|
||||
/* $NetBSD: targ.c,v 1.11 1997/02/20 16:51:50 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -68,8 +68,6 @@
|
||||
* 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
|
||||
@ -101,6 +99,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
#include "defines.h"
|
||||
@ -116,22 +115,13 @@
|
||||
#include "lst.h"
|
||||
#include "node_int.h"
|
||||
#include "nodehashconsts.h"
|
||||
#ifdef CLEANUP
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include "dump.h"
|
||||
|
||||
static struct ohash targets; /* hash table of targets */
|
||||
struct ohash_info gnode_info = {
|
||||
offsetof(GNode, name), NULL, hash_alloc, hash_free, element_alloc
|
||||
};
|
||||
|
||||
static void TargPrintOnlySrc(GNode *);
|
||||
static void TargPrintName(void *);
|
||||
static void TargPrintNode(GNode *, int);
|
||||
#ifdef CLEANUP
|
||||
static LIST allTargets;
|
||||
static void TargFreeGN(void *);
|
||||
#endif
|
||||
#define Targ_FindConstantNode(n, f) Targ_FindNodeh(n, sizeof(n), K_##n, f)
|
||||
|
||||
|
||||
@ -142,9 +132,6 @@ Targ_Init(void)
|
||||
{
|
||||
/* A small make file already creates 200 targets. */
|
||||
ohash_init(&targets, 10, &gnode_info);
|
||||
#ifdef CLEANUP
|
||||
Lst_Init(&allTargets);
|
||||
#endif
|
||||
begin_node = Targ_FindConstantNode(NODE_BEGIN, TARG_CREATE);
|
||||
begin_node->type |= OP_DUMMY | OP_NOTMAIN | OP_NODEFAULT;
|
||||
end_node = Targ_FindConstantNode(NODE_END, TARG_CREATE);
|
||||
@ -156,15 +143,6 @@ Targ_Init(void)
|
||||
|
||||
}
|
||||
|
||||
#ifdef CLEANUP
|
||||
void
|
||||
Targ_End(void)
|
||||
{
|
||||
Lst_Every(&allTargets, TargFreeGN);
|
||||
ohash_delete(&targets);
|
||||
}
|
||||
#endif
|
||||
|
||||
GNode *
|
||||
Targ_NewGNi(const char *name, const char *ename)
|
||||
{
|
||||
@ -172,7 +150,8 @@ Targ_NewGNi(const char *name, const char *ename)
|
||||
|
||||
gn = ohash_create_entry(&gnode_info, name, &ename);
|
||||
gn->path = NULL;
|
||||
if (name[0] == '-' && name[1] == 'l')
|
||||
if ((name[0] == '-' && name[1] == 'l') ||
|
||||
(ename - name >=2 && ename[-1] == 'a' && ename[-2] == '.'))
|
||||
gn->type = OP_LIB;
|
||||
else
|
||||
gn->type = 0;
|
||||
@ -191,8 +170,6 @@ Targ_NewGNi(const char *name, const char *ename)
|
||||
Lst_Init(&gn->successors);
|
||||
Lst_Init(&gn->preds);
|
||||
SymTable_Init(&gn->context);
|
||||
gn->origin.lineno = 0;
|
||||
gn->origin.fname = NULL;
|
||||
gn->impliedsrc = NULL;
|
||||
Lst_Init(&gn->commands);
|
||||
gn->suffix = NULL;
|
||||
@ -205,30 +182,9 @@ Targ_NewGNi(const char *name, const char *ename)
|
||||
STAT_GN_COUNT++;
|
||||
#endif
|
||||
|
||||
#ifdef CLEANUP
|
||||
Lst_AtEnd(&allTargets, gn);
|
||||
#endif
|
||||
return gn;
|
||||
}
|
||||
|
||||
#ifdef CLEANUP
|
||||
static void
|
||||
TargFreeGN(void *gnp)
|
||||
{
|
||||
GNode *gn = (GNode *)gnp;
|
||||
|
||||
efree(gn->path);
|
||||
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->commands, NOFREE);
|
||||
SymTable_Destroy(&gn->context);
|
||||
free(gn);
|
||||
}
|
||||
#endif
|
||||
|
||||
GNode *
|
||||
Targ_FindNodei(const char *name, const char *ename, int flags)
|
||||
{
|
||||
@ -302,14 +258,6 @@ Targ_Precious(GNode *gn)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
TargPrintName(void *gnp)
|
||||
{
|
||||
GNode *gn = (GNode *)gnp;
|
||||
printf("%s ", gn->name);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Targ_PrintCmd(void *p)
|
||||
{
|
||||
@ -352,6 +300,7 @@ Targ_PrintType(int type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
status_to_string(GNode *gn)
|
||||
{
|
||||
@ -371,91 +320,6 @@ status_to_string(GNode *gn)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
TargPrintNode(GNode *gn, int pass)
|
||||
{
|
||||
if (OP_NOP(gn->type))
|
||||
return;
|
||||
printf("#\n");
|
||||
if (pass == 2) {
|
||||
printf("# %d unmade children\n", gn->unmade);
|
||||
if (! (gn->type & (OP_JOIN|OP_USE|OP_EXEC))) {
|
||||
if (!is_out_of_date(gn->mtime)) {
|
||||
printf("# last modified %s: %s\n",
|
||||
time_to_string(gn->mtime),
|
||||
status_to_string(gn));
|
||||
} else if (gn->built_status != UNKNOWN) {
|
||||
printf("# non-existent (maybe): %s\n",
|
||||
status_to_string(gn));
|
||||
} else {
|
||||
printf("# unmade\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Lst_IsEmpty(&gn->parents)) {
|
||||
printf("# parents: ");
|
||||
Lst_Every(&gn->parents, TargPrintName);
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
if (gn->impliedsrc)
|
||||
printf("# implied source: %s\n", gn->impliedsrc->name);
|
||||
|
||||
printf("%-16s", gn->name);
|
||||
switch (gn->type & OP_OPMASK) {
|
||||
case OP_DEPENDS:
|
||||
printf(": "); break;
|
||||
case OP_FORCE:
|
||||
printf("! "); break;
|
||||
case OP_DOUBLEDEP:
|
||||
printf(":: "); break;
|
||||
}
|
||||
Targ_PrintType(gn->type);
|
||||
Lst_Every(&gn->children, TargPrintName);
|
||||
fputc('\n', stdout);
|
||||
Lst_Every(&gn->commands, Targ_PrintCmd);
|
||||
printf("\n\n");
|
||||
if (gn->type & OP_DOUBLEDEP) {
|
||||
LstNode ln;
|
||||
|
||||
for (ln = Lst_First(&gn->cohorts); ln != NULL; ln = Lst_Adv(ln))
|
||||
TargPrintNode((GNode *)Lst_Datum(ln), pass);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
TargPrintOnlySrc(GNode *gn)
|
||||
{
|
||||
if (OP_NOP(gn->type) && gn->special == SPECIAL_NONE &&
|
||||
!(gn->type & OP_DUMMY))
|
||||
printf("#\t%s [%s]\n", gn->name,
|
||||
gn->path != NULL ? gn->path : gn->name);
|
||||
}
|
||||
|
||||
void
|
||||
Targ_PrintGraph(int pass) /* Which pass this is. 1 => no processing
|
||||
* 2 => processing done */
|
||||
{
|
||||
GNode *gn;
|
||||
unsigned int i;
|
||||
|
||||
printf("#*** Input graph:\n");
|
||||
for (gn = ohash_first(&targets, &i); gn != NULL;
|
||||
gn = ohash_next(&targets, &i))
|
||||
TargPrintNode(gn, pass);
|
||||
printf("\n\n");
|
||||
printf("#\n# Files that are only sources:\n");
|
||||
for (gn = ohash_first(&targets, &i); gn != NULL;
|
||||
gn = ohash_next(&targets, &i))
|
||||
TargPrintOnlySrc(gn);
|
||||
Var_Dump();
|
||||
printf("\n");
|
||||
#ifdef DEBUG_DIRECTORY_CACHE
|
||||
Dir_PrintDirectories();
|
||||
printf("\n");
|
||||
#endif
|
||||
Suff_PrintAll();
|
||||
}
|
||||
|
||||
struct ohash *
|
||||
targets_hash()
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef TARG_H
|
||||
#define TARG_H
|
||||
/* $OpenBSD: targ.h,v 1.10 2012/08/20 09:51:05 jsg Exp $ */
|
||||
/* $OpenBSD: targ.h,v 1.11 2012/10/02 10:29:31 espie Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Marc Espie.
|
||||
@ -41,11 +41,6 @@
|
||||
#define TARG_NOCREATE 0x00 /* don't create it */
|
||||
|
||||
extern void Targ_Init(void);
|
||||
#ifdef CLEANUP
|
||||
extern void Targ_End(void);
|
||||
#else
|
||||
#define Targ_End()
|
||||
#endif
|
||||
extern GNode *Targ_NewGNi(const char *, const char *);
|
||||
#define Targ_NewGN(n) Targ_NewGNi(n, NULL);
|
||||
extern GNode *Targ_FindNodei(const char *, const char *, int);
|
||||
@ -56,6 +51,9 @@ extern GNode *Targ_FindNodei(const char *, const char *, int);
|
||||
/* set of helpers for constant nodes */
|
||||
extern GNode *Targ_FindNodeih(const char *, const char *, uint32_t, int);
|
||||
|
||||
__only_inline GNode *
|
||||
Targ_FindNodeh(const char *, size_t, uint32_t, int);
|
||||
|
||||
__only_inline GNode *
|
||||
Targ_FindNodeh(const char *name, size_t n, uint32_t hv, int flags)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: targequiv.c,v 1.2 2010/04/25 13:59:53 espie Exp $ */
|
||||
/* $OpenBSD: targequiv.c,v 1.3 2012/10/02 10:29:31 espie Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2007-2008 Marc Espie.
|
||||
*
|
||||
@ -129,13 +129,9 @@ build_equivalence()
|
||||
e = ohash_next(&equiv, &i)) {
|
||||
if (e->last != e->first)
|
||||
e->last->next = e->first;
|
||||
#ifdef CLEANUP
|
||||
free(e);
|
||||
#endif
|
||||
}
|
||||
#ifdef CLEANUP
|
||||
ohash_delete(&equiv);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const char *curdir, *objdir;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: var.c,v 1.90 2012/08/25 08:12:56 espie Exp $ */
|
||||
/* $OpenBSD: var.c,v 1.91 2012/10/02 10:29:31 espie Exp $ */
|
||||
/* $NetBSD: var.c,v 1.18 1997/03/18 19:24:46 christos Exp $ */
|
||||
|
||||
/*
|
||||
@ -83,6 +83,8 @@
|
||||
#include "memory.h"
|
||||
#include "symtable.h"
|
||||
#include "gnode.h"
|
||||
#include "dump.h"
|
||||
#include "lowparse.h"
|
||||
|
||||
/*
|
||||
* This is a harmless return value for Var_Parse that can be used by Var_Subst
|
||||
@ -439,20 +441,6 @@ SymTable_Init(SymTable *ctxt)
|
||||
memcpy(ctxt, &sym_template, sizeof(*ctxt));
|
||||
}
|
||||
|
||||
/* free symtable.
|
||||
*/
|
||||
#ifdef CLEANUP
|
||||
void
|
||||
SymTable_Destroy(SymTable *ctxt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < LOCAL_SIZE; i++)
|
||||
if (ctxt->locals[i] != NULL)
|
||||
delete_var(ctxt->locals[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***
|
||||
*** Global variable handling.
|
||||
***/
|
||||
@ -948,25 +936,22 @@ Var_Parse(const char *str, /* The string to parse */
|
||||
*freePtr = true;
|
||||
val = Str_dupi(str, tstr);
|
||||
} else {
|
||||
/* somehow, this should have been expanded already. */
|
||||
GNode *n;
|
||||
Location origin;
|
||||
|
||||
/* XXX */
|
||||
n = (GNode *)(((char *)ctxt) -
|
||||
offsetof(GNode, context));
|
||||
Parse_FillLocation(&origin);
|
||||
if (idx >= LOCAL_SIZE)
|
||||
idx = EXTENDED2SIMPLE(idx);
|
||||
switch(idx) {
|
||||
case IMPSRC_INDEX:
|
||||
Fatal(
|
||||
"Using $< in a non-suffix rule context is a GNUmake idiom (line %lu of %s)",
|
||||
n->origin.lineno, n->origin.fname);
|
||||
origin.lineno, origin.fname);
|
||||
break;
|
||||
default:
|
||||
Error(
|
||||
"Using undefined dynamic variable $%s (line %lu of %s)",
|
||||
varnames[idx], n->origin.lineno,
|
||||
n->origin.fname);
|
||||
varnames[idx], origin.lineno,
|
||||
origin.fname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1233,19 +1218,6 @@ Var_Init(void)
|
||||
}
|
||||
|
||||
|
||||
#ifdef CLEANUP
|
||||
void
|
||||
Var_End(void)
|
||||
{
|
||||
Var *v;
|
||||
unsigned int i;
|
||||
|
||||
for (v = ohash_first(&global_variables, &i); v != NULL;
|
||||
v = ohash_next(&global_variables, &i))
|
||||
delete_var(v);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *interpret(int);
|
||||
|
||||
static const char *
|
||||
@ -1264,17 +1236,65 @@ print_var(Var *v)
|
||||
(v->flags & VAR_DUMMY) == 0 ? var_get_value(v) : "(none)");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Var_Dump(void)
|
||||
{
|
||||
Var *v;
|
||||
Var **t;
|
||||
|
||||
unsigned int i;
|
||||
const char *banner;
|
||||
bool first = true;
|
||||
|
||||
printf("#*** Global Variables:\n");
|
||||
t = sort_ohash_by_name(&global_variables);
|
||||
/* somewhat dirty, but does the trick */
|
||||
|
||||
for (v = ohash_first(&global_variables, &i); v != NULL;
|
||||
v = ohash_next(&global_variables, &i))
|
||||
print_var(v);
|
||||
#define LOOP(mask, value, do_stuff) \
|
||||
for (i = 0; t[i] != NULL; i++) \
|
||||
if ((t[i]->flags & (mask)) == (value)) { \
|
||||
if (banner) { \
|
||||
if (first) \
|
||||
first = false; \
|
||||
else \
|
||||
putchar('\n'); \
|
||||
fputs(banner, stdout); \
|
||||
banner = NULL; \
|
||||
} \
|
||||
do_stuff; \
|
||||
}
|
||||
|
||||
banner = "#variables from command line:\n";
|
||||
LOOP(VAR_FROM_CMD | VAR_DUMMY, VAR_FROM_CMD, print_var(t[i]));
|
||||
|
||||
banner = "#global variables:\n";
|
||||
LOOP(VAR_FROM_ENV| VAR_FROM_CMD | VAR_DUMMY, 0, print_var(t[i]));
|
||||
|
||||
banner = "#variables from env:\n";
|
||||
LOOP(VAR_FROM_ENV|VAR_DUMMY, VAR_FROM_ENV, print_var(t[i]));
|
||||
|
||||
banner = "#variable name seen, but not defined:";
|
||||
LOOP(VAR_DUMMY|POISONS, VAR_DUMMY, printf(" %s", t[i]->name));
|
||||
|
||||
#undef LOOP
|
||||
|
||||
printf("\n\n");
|
||||
|
||||
for (i = 0; t[i] != NULL; i++)
|
||||
switch(t[i]->flags & POISONS) {
|
||||
case POISON_NORMAL:
|
||||
printf(".poison %s\n", t[i]->name);
|
||||
break;
|
||||
case POISON_EMPTY:
|
||||
printf(".poison empty(%s)\n", t[i]->name);
|
||||
break;
|
||||
case POISON_NOT_DEFINED:
|
||||
printf(".poison !defined(%s)\n", t[i]->name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
free(t);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static const char *quotable = " \t\n\\'\"";
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef VAR_H
|
||||
#define VAR_H
|
||||
/* $OpenBSD: var.h,v 1.14 2010/07/19 19:46:44 espie Exp $ */
|
||||
/* $OpenBSD: var.h,v 1.15 2012/10/02 10:29:31 espie Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Marc Espie.
|
||||
*
|
||||
@ -27,12 +27,6 @@
|
||||
*/
|
||||
|
||||
extern void Var_Init(void);
|
||||
#ifdef CLEANUP
|
||||
extern void Var_End(void);
|
||||
#else
|
||||
#define Var_End()
|
||||
#endif
|
||||
|
||||
extern void Var_setCheckEnvFirst(bool);
|
||||
|
||||
/* Global variable handling. */
|
||||
|
Loading…
Reference in New Issue
Block a user