1
0
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:
espie 2012-10-02 10:29:30 +00:00
parent 613b479708
commit 1bae8e1fd6
26 changed files with 673 additions and 942 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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. */

View File

@ -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 --

View File

@ -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.

View File

@ -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);
}

View File

@ -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

View File

@ -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:

View File

@ -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 */
}

View File

@ -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

View File

@ -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

View File

@ -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);
}
/*

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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(&gtargets, 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(&gtargets, 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 */
{

View File

@ -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;

View File

@ -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

View File

@ -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) \

View File

@ -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()
{

View File

@ -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)
{

View File

@ -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;

View File

@ -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\\'\"";

View File

@ -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. */