/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1984-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Glenn Fowler
* AT&T Research
*
* make - maintain and update programs
*
* history
*
* 1970's pre-make (research)
* .
* .
* 1976 make S. I. Feldman
* . .
* . .
* . .
* . .
* 1978 augmented-make . E. G. Bradford
* . . . .
* . . . .
* . . . .
* . . . .
* 1979 build . . . V. B. Erickson, J. F. Pellegrin
* . . . .
* . . . .
* 1984 . . V8-make S. I. Feldman
* . . . .
* . . . .
* . . . .
* . . . .
* . . . .
* . . . .
* . . . .
* 1985 . nmake . G. S. Fowler
* . . . .
* . . . .
* . . . .
* 1986 LC-nmake . . J. E. Shopiro, M. S. Freeland
* . . . .
* . . . mk A. G. Hume
* . . . . .
* 1987 . nmake . . G. S. Fowler
* . . . .
* (1.4) . . .
* . . . .
* . . . .
* . . . .
* 1988 nmake . G. S. Fowler
* . .
* (2.0) .
* . .
* 1990 (2.1) .
* . .
* 1991 (2.2) .
* . .
* 1992 (2.3) .
* . .
* 1993 (3.0) .
* . .
* 1994 (3.1) .
* . .
* 1995 (3.2) . AT&T Bell Labs
* . .
* 1996 (3.3) . AT&T Research (Lucent split)
* . .
* 1997 (3.4) . AT&T Research
* . .
* 1998 (3.5) . AT&T Research
* . .
* 1999 (3.6) . AT&T Research
* . .
* 2000 (4.0) . AT&T Research
* . .
* 2001 (4.1) . AT&T Research
* 2002 (4.2) . AT&T Research
* 2003 (4.3) . AT&T Research
* 2004 (4.4) . AT&T Research
* 2005 (5.0) . AT&T Research
* 2006 (5.1) . AT&T Research
* 2007 (5.2) . AT&T Research
* 2008 (5.3) . AT&T Research
* 2009 (5.4) . AT&T Research
* 2010 (5.5) . AT&T Research
* 2011 (5.6) . AT&T Research
* 2012 (5.7) . AT&T Research
*
* command line arguments are of three types
*
* make [ [ option ] [ script ] [ target ] ... ]
*
* options are described in options.h
*
* debug trace levels are controlled by error_info.trace
* debug level n enables tracing for all levels less than or equal to n
* levels 4 and higher are conditionally compiled with DEBUG!=0
* if debug level < 20 then all levels are disabled during early bootstrap
* if debug level = 1 then all levels are disabled until after .INIT is made
*
* level trace
* 0 no trace
* 1 basic make trace
* 2 major actions
* 3 option settings, make object files
* 4 state variables
* 5 directory and archive scan, some OPT_explain'ations
* 6 coshell commands and messages
* 7 makefile input lines
* 8 lexical analyzer states
* 9 metarules applied
* 10 variable expansions
* 11 bindfile() trace
* 12 files added to hash
* 13 new atoms
* 14 hash table usage
* ...
* 20 bootstrap trace
*
* state.questionable registry (looks like it should go but not sure)
*
* 0x00000001 *temporary*
* 0x00000002 *temporary*
* 0x00000004 *temporary* disable bind_p "- ..." and "... ..." virtual logic
* 0x00000008 1996-10-11 meta rhs prefix dir check even if rhs has prefix
* 0x00000010 1994-01-01 old out of date if prereq in higher view
* 0x00000020 1994-01-01 old scan advance logic
* 0x00000040 2001-10-20 foiled alias still allows bind (!1994-08-11)
* 0x00000080 1994-08-11 don't catrule() ../.. dir prefixes in bindfile()
* 0x00000100 1994-10-01 metaclose() recursion even if rule.action!=0
* 0x00000200 1994-11-11 disable generate() % transformation check
* 0x00000400 1995-01-19 forceread even if global
* 0x00000800 1995-07-17 D_global if not P_target in bindfile()
* 0x00001000 1995-07-17 less agressive aliasing in bindfile()
* 0x00002000 1995-07-17 less agressive putbound() in bindalias()
* 0x00004000 1995-11-11 P_target && D_dynamic does not imply generated
* 0x00008000 1996-02-29 :P=D: returns at most one dir per item
* 0x00010000 1996-10-11 don't alias check path suffixes in bindfile()
* 0x00020000 1998-11-11 don't force require_p make() recheck
* 0x00040000 1999-09-07 generate() intermediates only if (sep & LT)
* 0x00080000 1999-11-19 disable touch steady state loop
* 0x00100000 2000-02-14 apply metarule even if dir on unbound lhs
* 0x00200000 2000-09-08 0x00100000 implied if !P_implicit
* 0x00400000 2001-02-14 allow P_archive to break job deadlock
* 0x00800000 2001-10-05 disable early r->status=FAILED when errors!=0
* 0x02000000 2002-12-04 don't inhibit .UNBIND of M_bind rules
* 0x04000000 2004-01-20 don't include triggered time==0 targets in :T=F:
* 0x08000000 2004-10-01 metaget does not assume % target for ... : % .NULL
* 0x10000000 2007-01-08 :P=D: alias check
* 0x20000000 2007-06-15 disable :W: . alias check
* 0x40000000 2007-06-20 don't include intermediate makefile dirs in :W:
* 0x80000000 2007-08-28 don't force reassoc bindalias()
*
* state.test registry (conditionally compiled with DEBUG!=0)
*
* 0x00000001 *temporary*
* 0x00000002 *temporary*
* 0x00000004 *temporary*
* 0x00000008 bindfile() directory prune trace
* 0x00000010 expand() trace
* 0x00000020 force external archive table of contents generation
* 0x00000040 bindalias() trace
* 0x00000080 scan state trace
* 0x00000100 statetime() trace
* 0x00000200 staterule() view trace
* 0x00000400 more staterule() view trace
* 0x00000800 mergestate() trace
* 0x00001000 job status trace
* 0x00002000 dump Vmheap stats on exit
* 0x00004000 dump atom address with name
* 0x00008000 force state file garbage collection
* 0x00010000 alarm status trace
* 0x00020000 close internal.openfd before job exec
* 0x00040000 set failed state|metarule event to staterule event
* 0x00080000 replace ' ' with '?' instead of FILE_SPACE
* 0x00100000 scan action trace
*/
#include "make.h"
#include "options.h"
#include <sig.h>
#include <stak.h>
#include <vecargs.h>
#include <vmalloc.h>
#ifndef PATHCHECK
#endif
/*
* global initialization -- external engine names are defined in initrule()
*/
/*
* user error message intercept
*/
static int
{
register Rule_t* r;
char* m;
char* s;
char* t;
char* e;
int n;
int i;
if ((state.mam.level = level) > 0 && !state.hold && (r = internal.error) && (r->property & (P_functional|P_target)) == (P_functional|P_target) && !state.compileonly && !state.interrupt && (m = stakptr(0)) && (n = staktell()) > 0)
{
/*
* make the error trap
*/
while (*m && *m != ':')
m++;
while (isspace(*++m));
/*
* return [ level | - ] [ message ]
* level is new level or - to retain old
* omitted message means it has been printed
*/
if (t = call(r, s))
{
i = strtol(t, &e, 0);
if (e > t)
{
t = e;
level = i;
}
else if (*t == '-')
t++;
while (isspace(*t))
t++;
}
if (!t || !*t)
{
level |= ERROR_OUTPUT;
}
}
return level;
}
/*
* make entry point
*/
int
{
register char* s;
register Rule_t* r;
register List_t* p;
int i;
int args;
int trace;
char* t;
char* buf;
char* tok;
Var_t* v;
/*
* initialize dynamic globals
*/
return 1;
settype(0, C_TERMINAL);
settypes("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_", C_ID1|C_ID2|C_VARIABLE1|C_VARIABLE2);
/*
* close garbage fd's -- we'll be tidy from this point on
* 0..9 for user redirection in shell
* 10..19 left open by bugs in some shells
* error_info.fd interited from parent
* any close-on-exec fd's must have been done on our behalf
*/
i = 3;
if (isatty(i))
i++;
for (; i < 20; i++)
close(i);
/*
* allocate the very temporary buffer streams
*/
/*
* initialize the code and hash tables
*/
initcode();
inithash();
/*
* set the default state
*/
#if DEBUG
#endif
#if BINDINDEX
#else
#endif
/*
* pwd initialization
*
* for project management, if . is group|other writeable
* then change umask() for similar write protections
*/
/*
* set some variable default values
*/
setvar(external.lib, strdup((s = pathpath(t, argv[0], PATH_EXECUTE, buf, SF_BUFSIZE)) ? s : t), V_import);
/*
* read the environment
*/
readenv();
{
if (!stat(v->value, &st) && !stat(internal.pwd, &ds) && st.st_ino == ds.st_ino && st.st_dev == ds.st_dev)
{
}
else
{
}
}
/*
* initialize the internal rule pointers
*/
initrule();
/*
* read the static initialization script
*/
/*
* check and read the args file
*/
{
i = fs3d(0);
break;
fs3d(i);
}
/*
* set the command line options
* read the command line assignments
* mark the command line scripts and targets
*/
return 1;
if (state.compileonly)
{
state.virtualdot = 0;
}
/*
* tone down the bootstrap noise
*/
error_info.trace = 0;
/*
* check explicit environment overrides
*/
{
{
if (i = *s == '!')
s++;
if (v = getvar(s))
{
if (i)
else
v->property |= V_readonly;
}
}
}
/*
* set up the traps
*/
inittrap();
/*
* announce the version
*/
if (error_info.trace < 0)
{
errno = 0;
}
/*
* initialize the views
*/
initview();
/*
* check for mam
*/
{
{
}
else
{
sfprintf(state.mam.out, "%sinfo mam %s %05d 1994-07-17 %s\n", state.mam.label, state.mam.type, state.mam.parent, version);
{
else
sfprintf(state.mam.out, "%sinfo pwd %s %s\n", state.mam.label, state.mam.root, mamname(makerule(internal.pwd)));
}
}
}
/*
* read the dynamic initialization script
*/
error_info.trace = 0;
error_info.trace = i;
/*
* read the explicit makefiles
* readfile() handles the base and global rules
*
* NOTE: internal.tmplist is used to handle the effects of
* load() on internal list pointers
*/
{
for (; p; p = p->next)
}
/*
* if no explicit makefiles then try external.{convert,files}
*/
{
int sep;
exp = 0;
sep = 0;
s = 0;
{
{
if (!exp)
{
t = tokopen(t, 0);
while (s = tokread(t))
{
break;
if (sep)
else
sep = 1;
}
tokclose(t);
if (s)
break;
}
break;
}
}
{
{
break;
if (sep)
else
sep = 1;
}
}
if (!s)
{
/*
* this readfile() pulls in the default base rules
* that might resolve any delayed self-documenting
* options in optcheck()
*/
optcheck(1);
else
}
if (exp)
}
/*
* validate external command line options
*/
optcheck(1);
/*
* check for listing of variable and rule definitions
*/
{
return 0;
}
/*
* check if makefiles to be compiled
*/
{
/*
* make the compinit trap
*/
{
}
{
}
/*
* make the compdone trap
*/
{
}
}
/*
* makefile read cleanup
*/
if (state.compileonly)
return 0;
{
}
/*
* read the state file
*/
readstate();
/*
* place the command line targets in internal.args
*/
{
List_t* q;
if (p)
p = p->next = q;
else
}
/*
* the engine bootstrap is complete -- start user activities
*/
/*
* make the makeinit trap
*/
/*
* read the command line scripts
*/
{
}
/*
* freeze the parameter files and candidate state variables
*/
candidates();
/*
* make the init trap
*/
/*
* internal.args default to internal.main
*/
/*
* turn up the volume again
*/
if (!error_info.trace)
/*
* make the prerequisites of internal.args
*/
{
/*
* we explicitly allow internal.args modifications
*/
}
/*
* finish up
*/
finish(0);
return 0;
}
/*
* clean up and exit
*/
void
finish(int n)
{
Rule_t* r;
int i;
/*
* old error intercept
*/
{
{
{
return;
}
}
}
/*
* children exit without cleanup
*/
_exit(n);
unparse(0);
{
case 0:
/*
* disable listing and wait for any jobs to finish
*/
alarm(0);
/*FALLTHROUGH*/
case 1:
/*
* make the done trap
*/
/*FALLTHROUGH*/
case 2:
/*
* make the makedone trap
*/
/*FALLTHROUGH*/
case 3:
/*
* wait for any job(s) to finish
*/
/*FALLTHROUGH*/
case 4:
/*
* put all jobs in foreground and save state
*/
savestate();
/*FALLTHROUGH*/
case 5:
/*
* clean up temporaries
*/
remtmp(1);
/*FALLTHROUGH*/
case 6:
/*
* drop the coshell
*/
drop();
/*FALLTHROUGH*/
case 7:
/*
* dump
*/
{
error(0, "vm region %lu segments %lu busy %lu:%lu:%lu free %lu:%lu:%lu", vs.extent, vs.n_seg, vs.n_busy, vs.s_busy, vs.m_busy, vs.n_free, vs.s_free, vs.m_free);
}
/*FALLTHROUGH*/
case 8:
/*
* final output
*/
n = 1;
{
}
break;
}
{
n = 3;
pause();
}
exit(n);
}