diff options
120 files changed, 0 insertions, 54382 deletions
diff --git a/20120831/ChangeLog b/20120831/ChangeLog deleted file mode 100644 index 3f82c8d..0000000 --- a/20120831/ChangeLog +++ /dev/null @@ -1,1383 +0,0 @@ -2012-07-04 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20120704 - Merge with NetBSD make, pick up - o Job_ParseShell should call Shell_Init if it has been - previously called. - * Makefile.in: set USE_META based on configure result. - also .PARSEDIR is safer indicator of bmake. - -2012-06-26 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in: bump version to 20120626 - ensure CPPFLAGS is in CFLAGS - * meta.c: avoid nested externs - * bsd.after-import.mk: avoid ${.CURDIR}/Makefile as target - -2012-06-20 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20120620 - Merge with NetBSD make, pick up - o make_malloc.c: avoid including make_malloc.h again - - * Makefile.in: avoid bmake only syntax or protect with - .if defined(.MAKE.LEVEL) - * bsd.after-import.mk: replace .-include with .sinclude - ensure? SRCTOP gets a value - * configure.in: look for filemon.h in /usr/include/dev/filemon first. - -2012-06-19 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20120612 - Merge with NetBSD make, pick up - o use MAKE_ATTR_* rather than those defined by cdefs.h or compiler - for greater portability. - o unit-tests/forloop: check that .for works as expected wrt - number of times and with "quoted strings". - -2012-06-06 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20120606 - Merge with NetBSD make, pick up - o compat.c: use kill(2) rather than raise(3). - * configure.in: look for sys/dev/filemon - * bsd.after-import.mk: add a .-include "Makefile.inc" to Makefile - and pass BOOTSTRAP_XTRAS to boot-strap. - -2012-06-04 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20120604 - Merge with NetBSD make, pick up - o util.c and var.c share same var for tracking if environ - has been reallocated. - o util.c provide getenv with setenv. - * Add MAKE_LEVEL_SAFE as an alternate means of passing MAKE_LEVEL - when the shell actively strips .MAKE.* from the environment. - We still refer to the variable always as .MAKE.LEVEL - * util.c fix bug in findenv() was finding prefix of name. - * compat.c: re-raising SIGINT etc after running .INTERRUPT - results in more reliable termination of all activity on many - platforms. - -2012-06-02 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20120602 - Merge with NetBSD make, pick up - o for.c: handle quoted items in .for list - -2012-05-30 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20120530 - Merge with NetBSD make, pick up - o compat.c: ignore empty command. - -2012-05-24 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20120524 - * FILES: add bsd.after-import.mk: - A simple means of integrating bmake into a BSD build system. - -2012-05-20 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20120520 - Merge with NetBSD make, pick up - o increased limit for nested conditionals. - -2012-05-18 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20120518 - Merge with NetBSD make, pick up - o use _exit(2) in signal hanlder - o Don't use the [dir] cache when building nodes that might have - changed since the last exec. - o Avoid nested extern declaration warnings. - -2012-04-27 Simon J. Gerraty <sjg@bad.crufty.net> - - * meta.c (fgetLine): avoid %z - not portable. - * parse.c: Since we moved include of sys/mman.h - and def's of MAP_COPY etc. we got dups from a merge. - -2012-04-24 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20120420 - Merge with NetBSD make, pick up - o restore duplicate supression in .MAKE.MAKEFILES - runtime saving can be significant. - o Var_Subst() uses Buf_DestroyCompact() to reduce memory - consumption up to 20%. - -2012-04-20 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20120420 - Merge with NetBSD make, pick up - o remove duplicate supression in .MAKE.MAKEFILES - o improved dir cache behavior - o gmake'ish export command - -2012-03-25 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20120325 - Merge with NetBSD make, pick up - o fix parsing of :[#] in conditionals. - -2012-02-10 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in: replace use of .Nx in bmake.1 with NetBSD - since some systems cannot cope with .Nx <version> - -2011-11-14 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20111111 - Merge with NetBSD make, pick up - o debug output for .PARSEDIR and .PARSEFILE - -2011-10-10 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20111010 - -2011-10-09 Simon J. Gerraty <sjg@bad.crufty.net> - - * boot-strap: check for an expected file in the dirs we look for. - * make-bootstrap.sh: pass on LDSTATIC - -2011-10-01 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20111001 - Merge with NetBSD make, pick up - o ensure .PREFIX is set for .PHONY - and .TARGET set for .PHONY run via .END - o __dead used consistently - -2011-09-10 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): 20110909 is a better number ;-) - -2011-09-05 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110905 - Merge with NetBSD make, pick up - o meta_oodate: ignore makeDependfile - -2011-08-28 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110828 - Merge with NetBSD make, pick up - o silent=yes in .MAKE.MODE causes meta mode to mark targets - as SILENT if a .meta file is created - -2011-08-18 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110818 - Merge with NetBSD make, pick up - o in meta mode, if target flagged .META a missing .meta file - means target is out-of-date - o fixes for gcc 4.5 warnings - o simplify job printing code - -2011-08-09 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110808 - Merge with NetBSD make, pick up - o do not touch OP_SPECIAL targets when doing make -t - -2011-06-22 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110622 - Merge with NetBSD make, pick up - o meta_oodate detect corrupted .meta file and declare oodate. - * configure.in: add check for setsid - -2011-06-07 Simon J. Gerraty <sjg@bad.crufty.net> - - * Merge with NetBSD make, pick up - o unit-tests/modts now works on MirBSD - -2011-06-04 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110606 - Merge with NetBSD make, pick up - o ApplyModifiers: when we parse a variable which is not - the entire modifier string, or not followed by ':', do not - consider it as containing modifiers. - o loadfile: ensure newline at end of mapped file. - -2011-05-05 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110505 - Merge with NetBSD make, pick up - o .MAKE.META.BAILIWICK - list of prefixes which define the scope - of make's control. In meta mode, any generated file within - said bailiwick, which is found to be missing, causes current - target to be out-of-date. - -2011-04-11 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110411 - Merge with NetBSD make, pick up - o when long modifiers fail to match, check sysV style. - - add a test case - -2011-04-10 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110410 - Merge with NetBSD make, pick up - o :hash - cheap 32bit hash of value - o :localtime, :gmtime - use value as format string for strftime. - -2011-03-30 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110330 - mostly because its a cooler version. - Merge with NetBSD make, pick up - o NetBSD tags for meta.[ch] - o job.c call meta_job_finish() after meta_job_error(). - o meta_job_error() should call meta_job_finish() to ensure - .meta file is closed, and safe to copy - if .ERROR target wants. - meta_job_finish() is safe to call repeatedly. - -2011-03-29 Simon J. Gerraty <sjg@bad.crufty.net> - - * unit-tests/modts: use printf if it is a builtin, - to save us from MirBSD - - * Makefile.in (MAKE_VERSION): bump version to 20110329 - Merge with NetBSD make, pick up - o fix for use after free() in CondDoExists(). - o meta_oodate() report extra commands and return earlier. - -2011-03-27 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110327 - Merge with NetBSD make, pick up - o meta.c, if .MAKE.MODE contains curdirOk=yes - allow creating .meta files in .CURDIR - * boot-strap (TOOL_DIFF): aparently at least on linux distro - formats the output of 'type' differently - so eat any "()" - -2011-03-06 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110306 - Merge with NetBSD make, pick up - o meta.c, only do getcwd() once - -2011-03-05 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110305 - Merge with NetBSD make, pick up - o correct sysV substitution handling of empty lhs and variable - o correct exists() check for dir with trailing / - o correct handling of modifiers for non-existant variables - during evaluation of conditionals. - o ensure MAP_FILE is defined. - o meta.c use curdir[] now exported by main.c - -2011-02-25 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110225 - Merge with NetBSD make, pick up - o fix for incorrect .PARSEDIR when .OBJDIR is re-computed after - makefiles have been read. - o fix example of :? modifier in man page. - -2011-02-13 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110214 - Merge with NetBSD make, pick up - o meta.c handle realpath() failing when generating meta file - name. - - * sigcompat.c: convert to ansi so we can use higher warning levels. - - -2011-02-07 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110207 - Merge with NetBSD make, pick up - o fix for bug in meta mode. - -2011-01-03 Simon J. Gerraty <sjg@bad.crufty.net> - - * parse.c: SunOS 5.8 at least does not have MAP_FILE - -2011-01-01 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20110101 - Merge with NetBSD make, pick up - o use mmap(2) if available, for reading makefiles - -2010-12-15 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20101215 - Merge with NetBSD make, pick up - o ensure meta_job_error() does not report a previous .meta file - as being culprit. - -2010-12-10 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20101210 - Merge with NetBSD make, pick up - o meta_oodate: track cwd per process, and only consider target - out-of-date if missing file is outside make's CWD. - Ignore files in /tmp/ etc. - o to ensure unit-tests results match, need to control LC_ALL - as well as LANG. - o fix for parsing bug in var.c - -2010-11-26 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20101126 - Merge with NetBSD make, pick up - o if stale dependency is an IMPSRC, search via .PATH - o meta_oodate: if a referenced file is missing, target is - out-of-date. - o meta_oodate: if a target uses .OODATE in its commands, - it (.OODATE) needs to be recomputed. - o keep a pointer to youngest child node, rather than just its - mtime. - -2010-11-02 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20101101 - -2010-10-16 Simon J. Gerraty <sjg@bad.crufty.net> - - * machine.sh: like os.sh, - allow for uname -p producing useless drivel - -2010-09-13 Simon J. Gerraty <sjg@bad.crufty.net> - - * boot-strap: document configure knobs for meta and filemon. - - * Makefile.in (MAKE_VERSION): bump version to 20100911 - Merge with NetBSD make, pick up - o meta.c - meta mode - - * make-bootstrap.sh.in: handle meta.c - * configure.in: add knobs for use_meta and filemon_h - also, look for dirname, str[e]sep and strlcpy - * util.c: add simple err[x] and warn[x] - -2010-08-08 Simon J. Gerraty <sjg@bad.crufty.net> - - * boot-strap (TOOL_DIFF): set this to ensure tests use - the same version of diff that configure tested - - * Makefile.in (MAKE_VERSION): bump version to 20100808 - Merge with NetBSD make, pick up - o in jobs mode, when we discover we cannot make something, - call PrintOnError before exit. - -2010-08-06 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100806 - Merge with NetBSD make, pick up - o formatting fixes for ignored errors - o ensure jobs are cleaned up regardless of where wait() was called. - -2010-06-28 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100618 - * os.sh (MACHINE_ARCH): watch out for drivel from uname -p - -2010-06-16 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100616 - Merge with NetBSD make, pick up - o man page update - o call PrintOnError from JobFinish when we detect an error we - are not ignoring. - -2010-06-06 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100606 - Merge with NetBSD make, pick up - o man page update - -2010-06-05 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100605 - Merge with NetBSD make, pick up - o use bmake_signal() which is a wrapper around sigaction() - in place of signal() - o add .export-env to allow exporting variables to environment - without tracking (so no re-export when the internal value is - changed). - -2010-05-24 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100524 - Merge with NetBSD make, pick up - o fix for .info et al being greedy. - -2010-05-23 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100520 - Merge with NetBSD make, pick up - o back to using realpath on argv[0] - but only if contains '/' and does not start with '/'. - -2010-05-10 Simon J. Gerraty <sjg@bad.crufty.net> - - * boot-strap: use absolute path for bmake when running tests. - - * Makefile.in (MAKE_VERSION): bump version to 20100510 - Merge with NetBSD make, pick up - o revert use of realpath on argv[0] - too many corner cases. - o print MAKE_PRINT_VAR_ON_ERROR before running .ERROR target. - -2010-05-05 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100505 - Merge with NetBSD make, pick up - o fix for missed SIGCHLD when compiled with SunPRO - actually for bmake, defining FORCE_POSIX_SIGNALS would have - done the job. - -2010-04-30 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100430 - Merge with NetBSD make, pick up - o fflush stdout before writing to stdout - -2010-04-23 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100423 - Merge with NetBSD make, pick up - o updated unit tests for Haiku (this time for sure). - * boot-strap: based on patch from joerg - honor --with-default-sys-path better. - * boot-strap: remove mention of --with-prefix-sys-path - -2010-04-22 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100422 - * Merge with NetBSD make, pick up - o fix for vfork() on Darwin. - o fix for bogus $TMPDIR. - o set .MAKE.MODE=compat for -B - o set .MAKE.JOBS=max_jobs for -j max_jobs - o allow unit-tests to run without any *.mk - o unit-tests/modmisc be more conservative in dirs presumed to exist. - * boot-strap: ignore /usr/share/mk except on NetBSD. - * unit-tests/Makefile.in: set LANG=C when running unit-tests to - ensure sort(1) behaves as expected. - -2010-04-21 Simon J. Gerraty <sjg@bad.crufty.net> - - * boot-strap: add FindHereOrAbove so we can use -m .../mk - -2010-04-20 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100420 - * Merge with NetBSD make, pick up - o fix for variable realpath() behavior. - we have to stat(2) the result to be sure. - o fix for .export (all) when nested vars use :sh - -2010-04-14 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100414 - * Merge with NetBSD make, pick up - o use realpath to resolve argv[0] (for .MAKE) if needed. - o add realpath from libc. - o add :tA to resolve variable via realpath(3) if possible. - -2010-04-08 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100408 - * Merge with NetBSD make, pick up - o unit tests for .ERROR, .error - o fix for .ERROR to ensure it cannot be default target. - -2010-04-06 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100406 - * Merge with NetBSD make, pick up - o fix for compat mode "Error code" going to debug_file. - o fix for .ALLSRC being populated twice. - o support for .info, .warning and .error directives - o .MAKE.MODE to control make's operational mode - o .MAKE.MAKEFILE_PREFERENCE to control the preferred makefile - name(s). - o .MAKE.DEPENDFILE to control the name of the depend file - o .ERROR target - run on failure. - -2010-03-18 Simon J. Gerraty <sjg@bad.crufty.net> - - * make-bootstrap.sh.in: extract MAKE_VERSION from Makefile - - * os.sh,arch.c: patch for Haiku from joerg at netbsd - -2010-03-17 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100222 - * Merge with NetBSD make, pick up - o better error msg for .for with mutiple inter vars - - * boot-strap: - o use make-bootstrap.sh from joerg at netbsd - to avoid the need for a native make when bootstrapping. - o add "" everywhere ;-) - o if /usr/share/tmac/andoc.tmac exists install nroff bmake.1 - otherwise the pre-formated version. - -2010-01-04 Simon J. Gerraty <sjg@bad.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20100102 - * Merge with NetBSD make, pick up: - o fix for -m .../ - -2009-11-18 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20091118 - * Merge with NetBSD make, pick up: - o .unexport - o report lines that start with '.' and should have ':' - (catch typo's of .el*if). - -2009-10-30 Simon J. Gerraty <sjg@void.crufty.net> - - * configure.in: Ensure that srcdir and mksrc are absolute paths. - -2009-10-09 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (MAKE_VERSION): fix version to 20091007 - -2009-10-07 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 200910007 - * Merge with NetBSD make, pick up: - o fix for parsing of :S;...;...; applied to .for loop iterator - appearing in a dependency line. - -2009-09-09 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20090909 - * Merge with NetBSD make, pick up: - o fix for -C, .CURDIR and .OBJDIR - * boot-strap: - o allow share_dir to be set independent of prefix. - o select default share_dir better when prefix ends in $HOST_TARGET - o if FORCE_BSD_MK etc were set, include them in the suggested - install-mk command. - -2009-09-08 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20090908 - * Merge with NetBSD make, pick up: - o .MAKE.LEVEL for recursion tracking - o fix for :M scanning \: - -2009-09-03 Simon J. Gerraty <sjg@void.crufty.net> - - * configure.in: Don't -D__EXTENSIONS__ if - AC_USE_SYSTEM_EXTENSIONS says "no". - -2009-08-26 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (MAKE_VERSION): bump version to 20090826 - Simplify MAKE_VERSION to just the bare date. - * Merge with NetBSD make, pick up: - o -C directory support. - o support for SIGINFO - o use $TMPDIR for temp files. - o child of vfork should be careful about modifying parent's state. - - -2009-03-26 Simon J. Gerraty <sjg@void.crufty.net> - - * Appy some patches for MiNT from David Brownlee - -2009-02-26 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20090222 - * Merge with NetBSD make, pick up: - o Possible null pointer de-ref in Var_Set. - -2009-02-08 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20090204 - * Merge with NetBSD make, pick up: - o bmake_malloc et al moved to their own .c - o Count both () and {} when looking for the end of a :M pattern - o Change 'Buffer' so that it is the actual struct, not a pointer to it. - o strlist.c - functions for processing extendable arrays of pointers to strings. - o ClientData replaced with void *, so const void * can be used. - o New debug flag C for DEBUG_CWD - -2008-11-11 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20081111 - Apply patch from Joerg Sonnenberge to - configure.in: - o remove some redundant checks - o check for emlloc etc only in libutil and require the whole family. - util.c: - o remove [v]asprintf which is no longer used. - -2008-11-04 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20081101 - * Merge with NetBSD make, pick up: - o util.c: avoid use of putenv() - christos - -2008-10-30 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20081030 - pick up man page tweaks. - -2008-10-29 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in: move processing of LIBOBJS to after is definition! - thus we'll have getenv.c in SRCS only if needed. - - * make.1: add examples of how to use :? - - * Makefile.in (BMAKE_VERSION): bump version to 20081029 - * Merge with NetBSD make, pick up: - o fix for .END processing with -j - o segfault from Parse_Error when no makefile is open - o handle numeric expressions in any variable expansion - o debug output now defaults to stderr, -dF to change it - apb - o make now uses bmake_malloc etc so that it can build natively - on A/UX - wasn't an issue for bmake, but we want to keep in sync. - -2008-09-27 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20080808 - * Merge with NetBSD make, pick up: - o fix for PR/38840: Pierre Pronchery: make crashes while parsing - long lines in Makefiles - o optimizations for VarQuote by joerg - o fix for PR/38756: dominik: make dumps core on invalid makefile - -2008-05-15 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20080515 - * Merge with NetBSD make, pick up: - o fix skip setting vars in VAR_GLOBAL context, to handle - cases where VAR_CMD is used for other than command line vars. - -2008-05-14 Simon J. Gerraty <sjg@void.crufty.net> - - * boot-strap (make_version): we may need to look in - $prefix/share/mk for sys.mk - - * Makefile.in (BMAKE_VERSION): bump version to 20080514 - * Merge with NetBSD make, pick up: - o skip setting vars in VAR_GLOBAL context, when already set in - VAR_CMD which takes precedence. - -2008-03-30 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20080330 - * Merge with NetBSD make, pick up: - o fix for ?= when LHS contains variable reference. - -2008-02-15 Simon J. Gerraty <sjg@void.crufty.net> - - * merge some patches from NetBSD pkgsrc. - - * makefile.boot.in (BOOTSTRAP_SYS_PATH): Allow better control of - the MAKSYSPATH used during bootstrap. - - * Makefile.in (BMAKE_VERSION): bump version to 20080215 - * Merge with NetBSD make, pick up: - o warn if non-space chars follow 'empty' in a conditional. - -2008-01-18 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20080118 - * Merge with NetBSD make, pick up: - o consider dependencies read from .depend as optional - dsl - o remember when buffer for reading makefile grows - dsl - o add -dl (aka LOUD) - David O'Brien - -2007-10-22 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20071022 - * Merge with NetBSD make, pick up: - o Allow .PATH<suffix> to be used for .include "" - - * boot-strap: source default settings from .bmake-boot-strap.rc - -2007-10-16 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in: fix maninstall on various systems - provided that our man.mk is used. - For non-BSD systems we install the preformatted page - into $MANDIR/cat1 - -2007-10-15 Simon J. Gerraty <sjg@void.crufty.net> - - * boot-strap: make bmake.1 too, so maninstall works. - -2007-10-14 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20071014 - * Merge with NetBSD make, pick up: - o revamped handling of defshell - configure no longer needs to - know the content of the shells array - apb - o stop Var_Subst modifying its input - apb - o avoid calling ParseTrackInput too often - dsl - -2007-10-11 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20071011 - * Merge with NetBSD make, pick up: - o fix Shell_Init for case that _BASENAME_DEFSHELL is absolute path. - - * sigcompat.c: some tweaks for HP-UX 11.x based on - patch from Tobias Nygren - - * configure.in: update handling of --with-defshell to match - new make behavior. --with-defshell=/usr/xpg4/bin/sh - will now do what one might hope - provided the chosen shell - behaves enough like sh. - -2007-10-08 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20071008 - * Merge with NetBSD make, pick up: - o .MAKE.JOB.PREFIX - control the token output before jobs - sjg - o .export/.MAKE.EXPORTED - export of variables - sjg - o .MAKE.MAKEFILES - track all makefiles read - sjg - o performance improvements - dsl - o revamp parallel job scheduling - dsl - -2006-07-28 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20060728 - * Merge with NetBSD make, pick up: - o extra debug info during variable and cond processing - sjg - o shell definition now covers newline - rillig - o minor mem leak in PrintOnError - sjg - -2006-05-11 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20060511 - * Merge with NetBSD make, pick up: - o more memory leaks - coverity - o possible overflow in ArchFindMember - coverity - o extract variable modifier code out of Var_Parse() - so it can be called recursively - sjg - o unit-tests/moderrs - sjg - -2006-04-12 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20060412 - * Merge with NetBSD make, pick up: - o fixes for some memory leaks - coverity - o only read first sys.mk etc when searching sysIncPath - sjg - - * main.c (ReadMakefile): remove hack for __INTERIX that prevented - setting ${MAKEFILE} - OBATA Akio - -2006-03-18 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20060318 - * Merge with NetBSD make, pick up: - o cleanup of job.c to remove remote handling, distcc is more - useful and this code was likely bit-rotting - dsl - o fix for :P modifier - sjg - * boot-strap: set default prefix to something reasonable - (for me anyway). - -2006-03-01 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20060301 - * Merge with NetBSD make, pick up: - o make .WAIT apply recursively, document and test case - apb - o allow variable modifiers in a variable appear anywhere in - modifier list, document and test case - sjg - -2006-02-22 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20060222 - * Merge with NetBSD make, pick up: - o improved job token handling - dsl - o SIG_DFL the correct signal before exec - dsl - o more debug info during parsing - dsl - o allow variable modifiers to be specified via variable - sjg - * boot-strap: explain why we died if no mksrc - -2005-11-05 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20051105 - * configure.in: always set default_sys_path - default is ${prefix}/share/mk - - remove prefix_sys_path, anyone wanting more than above - needs to set it manually. - -2005-11-04 Simon J. Gerraty <sjg@void.crufty.net> - - * boot-strap: make this a bit easier for pkgsrc folk. - bootstrap still fails on IRIX64 since MACHINE_ARCH gets set to - 'mips' while pkgsrc wants 'mipseb' or 'mipsel' - -2005-11-02 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20051102 - * job.c (JobFinish): fix likely ancient merge lossage - fix from Todd Vierling. - * boot-strap (srcdir): allow setting mksrc=none - -2005-10-31 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20051031 - * ranlib.h: skip on OSF too. - (NetBSD PR 31864) - -2005-10-10 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20051002 - fix a silly typo - -2005-10-09 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20051001 - support for UnixWare and some other systems, - based on patches from pkgsrc/bootstrap - -2005-09-03 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20050901 - * Merge with NetBSD make, pick up: - o possible parse error causing us to wander off. - -2005-06-06 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20050606 - * Merge with NetBSD make, pick up: - o :0x modifier for randomizing a list - o fixes for a number of -Wuninitialized issues. - -2005-05-30 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20050530 - * Merge with NetBSD make, pick up: - o Handle dependencies for .BEGIN, .END and .INTERRUPT - - * README: was seriously out of date. - -2005-03-22 Simon J. Gerraty <sjg@void.crufty.net> - - * Important to use .MAKE rather than MAKE. - -2005-03-15 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20050315 - * Merge with NetBSD make, pick up: - o don't mistake .elsefoo for .else - o use suffix-specific search path correctly - o bunch of style nits - -2004-05-11 Simon J. Gerraty <sjg@void.crufty.net> - - * boot-strap: - o ensure that args to --src and --with-mksrc - are resolved before giving them to configure. - o add -o "objdir" so that builder can control it, - default is $OS as determined by os.sh - o add -q to suppress all the install instructions. - -2004-05-08 Simon J. Gerraty <sjg@void.crufty.net> - - * Remove __IDSTRING() - - * Makefile.in (BMAKE_VERSION): bump to 20040508 - * Merge with NetBSD make, pick up: - o posix fixes - - remove '-e' from compat mode - - add support for '+' command-line prefix. - o fix for handling '--' on command-line. - o fix include in lst.lib/lstInt.h to simplify '-I's - o we also picked up replacement of MAKE_BOOTSTRAP - with !MAKE_NATIVE which is a noop, but possibly confusing. - -2004-04-14 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20040414 - * Merge with NetBSD make, pick up: - o allow quoted strings on lhs of conditionals - o issue warning when extra .else is seen - o print line numer when errors encountered during parsing from - string. - -2004-02-20 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20040220 - * Merge with NetBSD make, pick up: - o fix for old :M parsing bug. - o re-jigged unit-tests - -2004-02-15 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (accept test): use ${.MAKE:S,^./,${.CURDIR}/,} - so that './bmake -f Makefile test' works. - -2004-02-14 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in: (BMAKE_VERSION): bump to 20040214 - * Merge with NetBSD make, pick up: - o search upwards for *.mk - o fix for double free of var substitution buffers - o use of getopt replaced with custom code, since the usage - (re-scanning) isn't posix compatible. - -2004-02-12 Simon J. Gerraty <sjg@void.crufty.net> - - * arch.c: don't include ranlib.h on ELF systems - (thanks to Chuck Cranor <chuck@ece.cmu.edu>). - -2004-01-18 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump to 20040118 - - * boot-strap (while): export vars we assign to on cmdline - * unit-test/Makefile.in: ternary is .PHONY - -2004-01-08 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20040108 - * Merge with NetBSD make, pick up: - o fix for ternary modifier - -2004-01-06 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20040105 - * Merge with NetBSD make, pick up: - o fix for cond.c to handle compound expressions better - o variable expansion within sysV style replacements - -2003-12-22 Simon J. Gerraty <sjg@void.crufty.net> - - * Make portable snprintf safer - output to /dev/null first to - check space needed. - - * Makefile.in (BMAKE_VERSION): bump version to 20031222 - * Merge with NetBSD make, pick up: - o -dg3 to show input graph when things go wrong. - o explicitly look for makefiles in objdir if not found in curdir so - that errors in .depend etc will be reported accurarely. - o avoid use of -e in shell scripts in jobs mode, use '|| exit $?' - instead as it more accurately reflects the expected behavior and - is more consistently implemented. - o avoid use of asprintf. - -2003-09-28 Simon J. Gerraty <sjg@void.crufty.net> - - * util.c: Add asprintf and vasprintf. - - * Makefile.in (BMAKE_VERSION): bump version to 20030928 - * Merge with NetBSD make, pick up: - :[] modifier - allows picking words from a variable. - :tW modifier - allows treating value as one big word. - W flag for :C and :S - allows treating value as one big word. - -2003-09-12 Simon J. Gerraty <sjg@void.crufty.net> - - * Merge with NetBSD make - pick up -de flag to enable printing failed command. - don't skip 1st two dir entries (normally . and ..) since - coda does not have them. - -2003-09-09 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20030909 - * Merge with NetBSD make, pick up: - - changes for -V '${VAR}' to print fully expanded value - cf. -V VAR - - CompatRunCommand now prints the command that failed. - - several files got updated 3 clause Berkeley license. - -2003-08-02 Simon J. Gerraty <sjg@void.crufty.net> - - * boot-strap: Allow setting configure args on command line. - -2003-07-31 Simon J. Gerraty <sjg@void.crufty.net> - - * configure.in: add --with-defshell to allow sh or ksh - to be selected as default shell. - - * Makefile.in: bump version to 20030731 - - * Merge with NetBSD make - Pick up .SHELL spec for ksh and associate man page changes. - Also compat mode now uses the same shell specs. - -2003-07-29 Simon J. Gerraty <sjg@void.crufty.net> - - * var.c (Var_Parse): ensure delim is initialized. - - * unit-tests/Makefile.in: use single quotes to avoid problems from - some shells. - - * makefile.boot.in: - Run the unit-tests as part of the bootstrap procedure. - -2003-07-28 Simon J. Gerraty <sjg@void.crufty.net> - - * unit-tests/Makefile.in: always force complaints from - ${TEST_MAKE} to be from 'make'. - - * configure.in: add check for 'diff -u' - also fix some old autoconf'isms - - * Makefile.in (BMAKE_VERSION): bump version to 20030728. - if using GCC add -Wno-cast-qual to CFLAGS for var.o - - * Merge with NetBSD make - Pick up fix for :ts parsing error in some cases. - Pick unit-tests. - -2003-07-23 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in (BMAKE_VERSION): bump version to 20030723. - - * var.c (Var_Parse): fix bug in :ts modifier, after const - correctness fixes, must pass nstr to VarModify. - -2003-07-14 Simon J. Gerraty <sjg@void.crufty.net> - - * Makefile.in: BMAKE_VERSION switch to a date based version. - We'll generally use the date of last import from NetBSD. - - * Merge with NetBSD make - Pick up fixes for const-correctness, now passes WARNS=3 on - NetBSD. - Pick up :ts modifier, allows controlling the separator used - between words in variable expansion. - -2003-07-11 Simon J. Gerraty <sjg@void.crufty.net> - - * FILES: include boot-strap and os.sh - - * Makefile.in: only set WARNS if we are NetBSD, the effect on - FreeBSD is known to be bad. - - * makefile.boot.in (bootstrap): make this the default target. - - * Makefile.in: bump version to 3.1.19 - - * machine.sh: avoid A-Z with tr as it is bound to lose. - -2003-07-10 Simon J. Gerraty <sjg@void.crufty.net> - - * Merge with NetBSD make - Pick up fix for PR/19781 - unhelpful error msg on unclosed ${var:foo - Plus some doc fixes. - -2003-04-27 Simon J. Gerraty <sjg@void.crufty.net> - - * Merge with NetBSD make - Pick up fix for PR/1523 - don't count a library as built, if there - is no way to build it - - * Bump version to 3.1.18 - -2003-03-23 Simon J. Gerraty <sjg@void.crufty.net> - - * Merge with NetBSD make - Pick up fix for ParseDoSpecialSrc - we only use it if .WAIT - appears in src list. - -2003-03-21 Simon J. Gerraty <sjg@void.crufty.net> - - * Merge with NetBSD make (mmm 10th anniversary!) - pick up fix for .WAIT in srcs that refer to $@ or $* (PR#20828) - pick up -X which tells us to not export VAR=val via setenv if - we are already doing so via MAKEFLAGS. This saves valuable env - space on systems like Darwin. - set MAKE_VERSION to 3.1.17 - - * parse.c: pix up fix for suffix rules - -2003-03-06 Simon J. Gerraty <sjg@void.crufty.net> - - * Merge with NetBSD make. - pick up fix for propagating -B via MAKEFLAGS. - set MAKE_VERSION to 3.1.16 - - * Apply some patches from pkgsrc-bootstrap/bmake - Originally by Grant Beattie <grant@netbsd.org> - I may have missed some - since they are based on bmake-3.1.12 - -2002-12-03 Simon J. Gerraty <sjg@void.crufty.net> - - * makefile.boot.in (bmake): update install targets for those that - use them, also clear MAKEFLAGS when invoking bmake.boot to avoid - havoc from gmake -w. Thanks to Harlan Stenn <hstenn@cisco.com>. - - * bmake.cat1: update the pre-formatted man page! - -2002-11-30 Simon J. Gerraty <sjg@void.crufty.net> - - * Merge with NetBSD make. - pick up fix for premature free of pointer used in call - to Dir_InitCur(). - set MAKE_VERSION to 3.1.15 - -2002-11-26 Simon J. Gerraty <sjg@void.crufty.net> - - * configure.in: determine suitable value for MKSRC. - override using --with-mksrc=PATH. - - * machine.sh: use `uname -p` for MACHINE_ARCH on modern SunOS systems. - configs(8) will use 'sun4' as an alias for 'sparc'. - -2002-11-25 Simon J. Gerraty <sjg@void.crufty.net> - - * Merge with NetBSD make. - pick up ${.PATH} - pick up fix for finding ../cat.c via .PATH when .CURDIR=.. - set MAKE_VERSION to 3.1.14 - add configure checks for killpg and sys/socket.h - -2002-09-16 Simon J. Gerraty <sjg@void.crufty.net> - - * tag bmake-3-1-13 - - * makefile.boot.in (bmake): use install-mk - Also setup ./mk before trying to invoke bmake.boot incase we - needed install-mk to create a sys.mk for us. - - * configure.in: If we need to add -I${srcdir}/missing, make it an - absolute path so that it works for lst.lib too. - - * make.h: always include sys/cdefs.h since we provide one if the - host does not. - - * Makefile.in (install-mk): - use MKSRC/install-mk which will do the right thing. - use uname -p for ARCH if possible. - since install-mk will setup links bsd.prog.mk -> prog.mk if - needed, just .include bsd.prog.mk - - * Merge with NetBSD make (NetBSD-1.6) - Code is ansi-C only now. - Bug in handling of dotLast is fixed. - Can now assign .OBJDIR and make will reset its notions of life. - New modifiers :tu :tl for toUpper and toLower. - -Tue Oct 16 12:18:42 2001 Simon J. Gerraty <sjg@zen.crufty.net> - - * Merge with NetBSD make - pick up fix for .END failure in compat mode. - pick up fix for extra va_end() in ParseVErrorInternal. - -Thu Oct 11 13:20:06 2001 Simon J. Gerraty <sjg@zen.crufty.net> - - * configure.in: for systems that have sys/cdefs.h check if it is - compatible. If not, include the one under missing, but tell it to - include the native one too - necessary on Linux. - - * missing/sys/cdefs.h: if NEED_HOST_CDEFS_H is defined, use - include_next (for gcc) to get the native sys/cdefs.h - -Tue Aug 21 02:29:34 2001 Simon J. Gerraty <sjg@zen.quick.com.au> - - * job.c (JobFinish): Fix an earlier merge bug that resulted in - leaking descriptors when using -jN. - - * job.c (JobPrintCommand): See if "curdir" exists before - attempting to chdir(). Doing the chdir directly in make (when in - compat mode) fails silently, so let the -jN version do the same. - This can happen when building kernels in an object tree and - playing clever games to reset .CURDIR. - - * Merged with NetBSD make - pick up .USEBEFORE - -Tue Jun 26 23:45:11 2001 Simon J. Gerraty <sjg@zen.quick.com.au> - - * makefile.boot.in: Give bmake.boot a MAKESYSPATH that might work. - -Tue Jun 12 16:48:57 2001 Simon J. Gerraty <sjg@zen.quick.com.au> - - * var.c (Var_Set): Add 4th (flags) arg so VarLoopExpand can tell - us not to export the iterator variable when using VAR_CMD context. - -Sun Jun 10 21:55:21 2001 Simon J. Gerraty <sjg@zen.quick.com.au> - - * job.c (Job_CatchChildren): don't call Job_CatchOutput() here, - its the wrong "fix". - -Sat Jun 9 00:11:24 2001 Simon J. Gerraty <sjg@zen.quick.com.au> - - * Redesigned export of VAR_CMD's via MAKEFLAGS. - We now simply append the variable names to .MAKEOVERRIDES, and - handle duplicate suppression and quoting in ExportMAKEFLAGS using: - ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@} - Apart from fixing quoting bugs in previous version, this allows us - to export vars to the environment by simply doing: - .MAKEOVERRIDES+= PATH - Merged again with NetBSD make, but the above is the only change. - - * configure.in: added - --disable-pwd-override disable $PWD overriding getcwd() - --disable-check-make-chdir disable make trying to guess - when it should automatically cd ${.CURDIR} - - * Merge with NetBSD make, changes include: - parse.c (ParseDoDependency): Spot that the syntax error is - caused by an unresolved cvs/rcs conflict and say so. - var.c: most of Var* functions now take a ctxt as 1st arg. - now does variable substituion on rhs of sysv style modifiers. - - * var.c (Var_Set): exporting of command line variables (VAR_CMD) - is now done here. We append the name='value' to .MAKEOVERRIDES - rather than directly into MAKEFLAGS as this allows a Makefile to - use .MAKEOVERRIDES= to disable this behaviour. GNU make uses a - very similar mechanism. Note that in adding name='value' to - .MAKEOVERRIDES we do the moral equivalent of: - .MAKEOVERRIDES:= ${.MAKEOVERRIDES:Nname=*} name='val' - -Fri Jun 1 14:08:02 2001 Simon J. Gerraty <sjg@zen.quick.com.au> - - * make-conf.h (USE_IOVEC): make it conditional on HAVE_SYS_UIO_H - - * Merged with NetBSD make - make -dx can now be used to run commands via sh -x - better error messages on exec failures. - -Thu May 31 01:44:54 2001 Simon J. Gerraty <sjg@zen.quick.com.au> - - * Makefile.in (main.o): depends on ${SRCS} ${MAKEFILE} so that - MAKE_VERSION gets updated. Also don't use ?= for MAKE_VERSION, - MACHINE etc otherwise they propagate from the previous bmake. - - * configure.in (machine): allow --with-machine=generic to make - configure use machine.sh to set MACHINE. - - * job.c (JobInterrupt): convert to using WAIT_T and friends. - - * Makefile.in: mention in bmake.1 that we use autoconf. - - * make.1: mention MAKE_PRINT_VAR_ON_ERROR. - -Wed May 30 23:17:18 2001 Simon J. Gerraty <sjg@zen.quick.com.au> - - * main.c (ReadMakefile): don't set MAKEFILE if reading ".depend" - as that rather defeats the usefulness of ${MAKEFILE}. - - * main.c (MainParseArgs): append command line variable assignments - to MAKEFLAGS so that they get propagated to child make's. - Apparently this is required POSIX behaviour? Its useful anyway. - -Tue May 29 02:20:07 2001 Simon J. Gerraty <sjg@zen.quick.com.au> - - * compat.c (CompatRunCommand): don't use perror() since stdio may - cause problems in child of vfork(). - - * compat.c, main.c: Call PrintOnError() when we are going to bail. - This routine prints out the .curdir where we stopped and will also - display any vars listed in ${MAKE_PRINT_VAR_ON_ERROR}. - - * main.c: add ${.newline} to hold a "\n" - sometimes handy in - :@ expansion. - - * var.c: VarLoopExpand: ignore addSpace if a \n is present. - - * Added RCSid's for the files we've touched. - -Thu May 24 15:41:37 2001 Simon J. Gerraty <sjg@zen.quick.com.au> - - * configure.in: Thanks to some clues from mdb@juniper.net, - added autoconf magic to control setting of MACHINE, MACHINE_ARCH - as well as what ends up in _PATH_DEFSYSPATH. We now have: - - --with-machine=MACHINE explicitly set MACHINE - --with-force-machine=MACHINE set FORCE_MACHINE - --with-machine_arch=MACHINE_ARCH explicitly set MACHINE_ARCH - --with-default-sys-path=PATH:DIR:LIST use an explicit _PATH_DEFSYSPATH - --with-prefix-sys-path=PATH:DIR:LIST prefix _PATH_PREFIX_SYSPATH - --with-path-objdirprefix=PATH override _PATH_OBJDIRPREFIX - - If _PATH_OBJDIRPREFIX is set to "no" we won't define it. - - * makefile: added a pathetically simple makefile to drive - bootstrapping. Running configure by hand is more useful. - - * Makefile.in: added MAKE_VERSION, and reworked things to be less - dependent on NetBSD bsd.*.mk - - * pathnames.h: allow NO_PATH_OBJDIRPREFIX to stop us defining - _PATH_OBJDIRPREFIX for those that don't want a default. - construct _PATH_DEFSYSPATH from the info we get from configure. - - * main.c: allow for no _PATH_OBJDIRPREFIX, set ${MAKE_VERSION} - if MAKE_VERSION is defined. - - * compat.c: when we bail, print out the .CURDIR we were in. - -Sat May 12 00:34:12 2001 Simon J. Gerraty <sjg@zen.quick.com.au> - - * Merged with NetBSD make - - * var.c: fixed a bug in the handling of the modifier :P - if the node as found but the path was null, we segfault trying to - duplicate it. - -Mon Mar 5 16:20:33 2001 Simon J. Gerraty <sjg@zen.quick.com.au> - - * Merged with NetBSD make - - * make.c: Make_OODate's test for a library out of date was using - cmtime where it should have used mtime (my bug). - - * compat.c: Use perror() to tell us what really went wrong when we - cannot exec a command. - -Fri Dec 15 10:11:08 2000 Simon J. Gerraty <sjg@zen.quick.com.au> - - * Merged with NetBSD make - -Sat Jun 10 10:11:08 2000 Simon J. Gerraty <sjg@zen.quick.com.au> - - * Merged with NetBSD make - -Thu Jun 1 10:11:08 2000 Simon J. Gerraty <sjg@zen.quick.com.au> - - * Merged with NetBSD make - -Tue May 30 10:11:08 2000 Simon J. Gerraty <sjg@zen.quick.com.au> - - * Merged with NetBSD make - -Thu Apr 27 00:07:47 2000 Simon J. Gerraty <sjg@zen.quick.com.au> - - * util.c: don't provide signal() since we use sigcompat.c - - * Makefile.in: added a build target. - - * var.c (Var_Parse): added ODE modifiers :U, :D, :L, :P, :@ and :! - These allow some quite clever magic. - - * main.c (main): added support for getenv(MAKESYSPATH). - -Mon Apr 2 16:25:13 2000 Simon J. Gerraty <sjg@zen.quick.com.au> - - * Disable $PWD overriding getcwd() if MAKEOBJDIRPREFIX is set. - This avoids objdir having a different value depending on how a - directory was reached (via command line, or subdir.mk). - - * If FORCE_MACHINE is defined, ignore getenv("MACHINE"). - -Mon Apr 2 23:15:31 2000 Simon J. Gerraty <sjg@zen.quick.com.au> - - * Do a chdir(${.CURDIR}) before invoking ${.MAKE} or ${.MAKE:T} if - MAKEOBJDIRPREFIX is set and NOCHECKMAKECHDIR is not. - I've been testing this in NetBSD's make for some weeks. - - * Turn Makefile into Makefile.in and make it useful. - -Tue Feb 29 22:08:00 2000 Simon J. Gerraty <sjg@zen.quick.com.au> - - * Imported NetBSD's -current make(1) and resolve conflicts. - - * Applied autoconf patches from bmake v2 - - * Imported clean code base from NetBSD-1.0 diff --git a/20120831/FILES b/20120831/FILES deleted file mode 100644 index 397d3a2..0000000 --- a/20120831/FILES +++ /dev/null @@ -1,121 +0,0 @@ -FILES -ChangeLog -bmake.cat1 -boot-strap -bsd.after-import.mk -os.sh -Makefile.in -PSD.doc/Makefile -PSD.doc/tutorial.ms -README -arch.c -buf.c -buf.h -compat.c -cond.c -make-conf.h -make_malloc.c -make_malloc.h -config.h.in -configure -aclocal.m4 -configure.in -dir.c -dir.h -find_lib.sh -for.c -getopt.c -hash.c -hash.h -install-sh -job.c -job.h -meta.c -meta.h -dirname.c -realpath.c -strlcpy.c -strlist.c -strlist.h -stresep.c -trace.c -trace.h -lst.h -lst.lib/Makefile -lst.lib/lstAppend.c -lst.lib/lstAtEnd.c -lst.lib/lstAtFront.c -lst.lib/lstClose.c -lst.lib/lstConcat.c -lst.lib/lstDatum.c -lst.lib/lstDeQueue.c -lst.lib/lstDestroy.c -lst.lib/lstDupl.c -lst.lib/lstEnQueue.c -lst.lib/lstFind.c -lst.lib/lstFindFrom.c -lst.lib/lstFirst.c -lst.lib/lstForEach.c -lst.lib/lstForEachFrom.c -lst.lib/lstInit.c -lst.lib/lstInsert.c -lst.lib/lstInt.h -lst.lib/lstIsAtEnd.c -lst.lib/lstIsEmpty.c -lst.lib/lstLast.c -lst.lib/lstMember.c -lst.lib/lstNext.c -lst.lib/lstOpen.c -lst.lib/lstPrev.c -lst.lib/lstRemove.c -lst.lib/lstReplace.c -lst.lib/lstSucc.c -machine.sh -main.c -make.1 -bmake.1 -make.c -make.h -make-bootstrap.sh.in -missing/sys/cdefs.h -mkdeps.sh -nonints.h -parse.c -pathnames.h -ranlib.h -setenv.c -sigcompat.c -sprite.h -str.c -suff.c -targ.c -util.c -var.c -wait.h -unit-tests/Makefile.in -unit-tests/comment -unit-tests/cond1 -unit-tests/doterror -unit-tests/dotwait -unit-tests/error -unit-tests/export -unit-tests/export-all -unit-tests/forloop -unit-tests/forsubst -unit-tests/hash -unit-tests/misc -unit-tests/moderrs -unit-tests/modmatch -unit-tests/modmisc -unit-tests/modorder -unit-tests/modts -unit-tests/modword -unit-tests/phony-end -unit-tests/posix -unit-tests/qequals -unit-tests/sysv -unit-tests/ternary -unit-tests/test.exp -unit-tests/unexport -unit-tests/unexport-env -unit-tests/varcmd diff --git a/20120831/Makefile.in b/20120831/Makefile.in deleted file mode 100644 index 5a1f004..0000000 --- a/20120831/Makefile.in +++ /dev/null @@ -1,187 +0,0 @@ -# $NetBSD: Makefile,v 1.56 2012/05/30 21:54:23 sjg Exp $ -# @(#)Makefile 5.2 (Berkeley) 12/28/90 - -# $Id: Makefile.in,v 1.168 2012/07/05 04:10:23 sjg Exp $ - -PROG= bmake -SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \ - make.c parse.c str.c suff.c targ.c trace.c var.c util.c -SRCS+= strlist.c -SRCS+= make_malloc.c -SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \ - lstDatum.c lstDeQueue.c lstDestroy.c lstDupl.c lstEnQueue.c \ - lstFind.c lstFindFrom.c lstFirst.c lstForEach.c lstForEachFrom.c \ - lstInit.c lstInsert.c lstIsAtEnd.c lstIsEmpty.c lstLast.c \ - lstMember.c lstNext.c lstOpen.c lstRemove.c lstReplace.c lstSucc.c -SRCS += lstPrev.c - -# you can use this Makefile if you have an earlier version of bmake. -prefix= @prefix@ -srcdir= @srcdir@ -CC?= @CC@ - -# Base version on src date -MAKE_VERSION= 20120704 -MACHINE=@machine@ -MACHINE_ARCH=@machine_arch@ -DEFAULT_SYS_PATH = @default_sys_path@ - -CPPFLAGS+= @CPPFLAGS@ -CFLAGS+= ${CPPFLAGS} -CFLAGS+= -D_PATH_DEFSYSPATH=\"${DEFAULT_SYS_PATH}\" -CFLAGS+= -I. -I${srcdir} @DEFS@ ${XDEFS} -DMAKE_NATIVE -CFLAGS+= ${CFLAGS_${.TARGET:T}} -CFLAGS+= ${COPTS.${.ALLSRC:M*.c:T:u}} -COPTS.main.c+= "-DMAKE_VERSION=\"${MAKE_VERSION}\"" -LDFLAGS= @LDFLAGS@ -LIBOBJS= @LIBOBJS@ -LDADD= @LIBS@ - -.if !empty(LIBOBJS) -SRCS+= ${LIBOBJS:T:.o=.c} -.endif - -USE_META = @use_meta@ -.if ${USE_META} != "no" -SRCS+= meta.c -CPPFLAGS+= -DUSE_META -FILEMON_H ?= @filemon_h@ -.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h" -COPTS.meta.c += -DHAVE_FILEMON_H -I${FILEMON_H:H} -.endif -.endif - -.PATH: ${srcdir} -.PATH: ${srcdir}/lst.lib - -OS!= uname -s -ARCH!= uname -p 2>/dev/null || uname -m - -# list of OS's which are derrived from BSD4.4 -isBSD44= NetBSD FreeBSD OpenBSD DragonFly - -.if ${OS} == "NetBSD" -# Don't set these for anyone else since we don't know what the effect may be. -# On FreeBSD WARNS=2 sets a bunch of -W flags that make does not handle. -WFORMAT= 1 -WARNS=4 -.NOPATH: bmake.cat1 -.if make(install) && exists(${DESTDIR}/usr/share/doc) -SUBDIR= PSD.doc -.endif -.endif - -.if empty(isBSD44:M${OS}) -# XXX not sure if we still want this given that configure -# lets us force or not the definition of MACHINE. -CFLAGS_main.o+= "-DFORCE_MACHINE=\"${MACHINE}\"" -MANTARGET=cat -INSTALL?=${srcdir}/install-sh -.if (${MACHINE} == "sun386") -# even I don't have one of these anymore :-) -CFLAGS+= -DPORTAR -.elif (${MACHINE} != "sunos") -SRCS+= sigcompat.c -CFLAGS+= -DSIGNAL_FLAGS=SA_RESTART -.endif -.endif -.if defined(.PARSEDIR) -.if make(obj) || make(clean) -SUBDIR+= unit-tests -.endif -.endif - -# many systems use gcc these days -CC_IS_GCC=@GCC@ -.if ${CC_IS_GCC} == "yes" -# problem with gcc3 -CFLAGS_var.o+= -Wno-cast-qual -.endif - -CFLAGS_main.o+= "-D@force_machine@MACHINE=\"${MACHINE}\"" "-DMACHINE_ARCH=\"${MACHINE_ARCH}\"" - -EXTRACT_MAN=no - -MAN=${PROG}.1 -.if (${PROG} != "make") -${MAN}: make.1 - @echo making ${PROG}.1 - @sed -e 's/^.Nx/NetBSD/' -e '/^.Nm/s/make/${PROG}/' -e '/^.Sh HISTORY/,$$d' ${srcdir}/make.1 > $@ - @(echo ".Sh HISTORY"; \ - echo ".Nm"; \ - echo "is derived from NetBSD"; \ - echo ".Xr make 1 ."; \ - echo It uses autoconf to facilitate portability to other platforms.) >> $@ - -.endif - -.if !empty(isBSD44:M${OS}) -.if "${OS}" != "NetBSD" -MAN1=${MAN} -.endif -MANTARGET?=man -.endif - -MANTARGET?= cat -MANDEST?= ${MANDIR}/${MANTARGET}1 - -.if ${MANTARGET} == "cat" -_mfromdir=${srcdir} -.endif - -.if exists(${srcdir}/../Makefile.inc) -.include "${srcdir}/../Makefile.inc" -.endif -.-include <bsd.prog.mk> -# sigh, FreeBSD at least includes bsd.subdir.mk via bsd.obj.mk -# so the inclusion below, results in complaints about re-defined -# targets. For NetBSD though we need to explicitly include it. -.if defined(.PARSEDIR) -.if defined(SUBDIR) && !target(${SUBDIR:[1]}) -.-include <bsd.subdir.mk> -.endif -.endif - -CPPFLAGS+= -DMAKE_NATIVE -COPTS.var.c += -Wno-cast-qual -COPTS.job.c += -Wno-format-nonliteral -COPTS.parse.c += -Wno-format-nonliteral -COPTS.var.c += -Wno-format-nonliteral - -# Force these -BINDIR= ${prefix}/bin -MANDIR= ${prefix}/man - -arch.o: config.h -# make sure that MAKE_VERSION gets updated. -main.o: ${SRCS} ${MAKEFILE} - -MK?=${prefix}/share/mk -MKSRC?=@mksrc@ -INSTALL?=${srcdir}/install-sh - -beforeinstall: - test -d ${DESTDIR}${BINDIR} || ${INSTALL} -m 775 -d ${DESTDIR}${BINDIR} - test -d ${DESTDIR}${MANDEST} || ${INSTALL} -m 775 -d ${DESTDIR}${MANDEST} - -# latest version of *.mk includes an installer. -# you should not need to set USE_OS -install-mk: -.if exists(${MKSRC}/install-mk) - test -d ${DESTDIR}${MK} || ${INSTALL} -m 775 -d ${DESTDIR}${MK} - ${MKSRC}/install-mk -v -m 644 ${DESTDIR}${MK} ${USE_OS} -.else - @echo need to unpack mk.tar.gz under ${srcdir} or set MKSRC; false -.endif - -.ifdef TOOLDIR -# this is a native netbsd build, -# use libutil rather than the local emalloc etc. -CPPFLAGS+= -DUSE_EMALLOC -LDADD+=-lutil -DPADD+=${LIBUTIL} -.endif - -# A simple unit-test driver to help catch regressions -accept test: - cd ${.CURDIR}/unit-tests && MAKEFLAGS= ${.MAKE} -r -m / TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET} diff --git a/20120831/PSD.doc/Makefile b/20120831/PSD.doc/Makefile deleted file mode 100644 index 8e1f1fa..0000000 --- a/20120831/PSD.doc/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $NetBSD: Makefile,v 1.2 1995/06/14 15:20:23 christos Exp $ -# @(#)Makefile 8.1 (Berkeley) 8/14/93 - -DIR= psd/12.make -SRCS= tutorial.ms -MACROS= -ms - -.include <bsd.doc.mk> diff --git a/20120831/PSD.doc/tutorial.ms b/20120831/PSD.doc/tutorial.ms deleted file mode 100644 index c1a6444..0000000 --- a/20120831/PSD.doc/tutorial.ms +++ /dev/null @@ -1,3773 +0,0 @@ -.\" $NetBSD: tutorial.ms,v 1.11 2011/08/18 15:19:30 sjg Exp $ -.\" Copyright (c) 1988, 1989, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Adam de Boor. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" Copyright (c) 1988, 1989 by Adam de Boor -.\" Copyright (c) 1989 by Berkeley Softworks -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Adam de Boor. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)tutorial.ms 8.1 (Berkeley) 8/18/93 -.\" -.EH 'PSD:12-%''PMake \*- A Tutorial' -.OH 'PMake \*- A Tutorial''PSD:12-%' -.\" xH is a macro to provide numbered headers that are automatically stuffed -.\" into a table-of-contents, properly indented, etc. If the first argument -.\" is numeric, it is taken as the depth for numbering (as for .NH), else -.\" the default (1) is assumed. -.\" -.\" @P The initial paragraph distance. -.\" @Q The piece of section number to increment (or 0 if none given) -.\" @R Section header. -.\" @S Indent for toc entry -.\" @T Argument to NH (can't use @Q b/c giving 0 to NH resets the counter) -.de xH -.NH \\$1 -\\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 -.nr PD .1v -.XS \\n% -.ta 0.6i -\\*(SN \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 -.XE -.nr PD .3v -.. -.\" CW is used to place a string in fixed-width or switch to a -.\" fixed-width font. -.\" C is a typewriter font for a laserwriter. Use something else if -.\" you don't have one... -.de CW -.ie !\\n(.$ .ft C -.el \&\\$3\fC\\$1\fP\\$2 -.. -.\" Anything I put in a display I want to be in fixed-width -.am DS -.CW -.. -.\" The stuff in .No produces a little stop sign in the left margin -.\" that says NOTE in it. Unfortunately, it does cause a break, but -.\" hey. Can't have everything. In case you're wondering how I came -.\" up with such weird commands, they came from running grn on a -.\" gremlin file... -.de No -.br -.ne 0.5i -.po -0.5i -.br -.mk -.nr g3 \\n(.f -.nr g4 \\n(.s -.sp -1 -.\" .st cf -\D't 5u' -.sp -1 -\h'50u' -.sp -1 -\D't 3u' -.sp -1 -.sp 7u -\h'53u' -\d\D'p -0.19i 0.0i 0.0i -0.13i 0.30i 0.0i 0.0i 0.13i' -.sp -1 -.ft R -.ps 6 -.nr g8 \\n(.d -.ds g9 "NOTE -.sp 74u -\h'85u'\v'0.85n'\h-\w\\*(g9u/2u\&\\*(g9 -.sp |\\n(g8u -.sp 166u -\D't 3u' -.br -.po -.rt -.ft \\n(g3 -.ps \\n(g4 -.. -.de Bp -.ie !\\n(.$ .IP \(bu 2 -.el .IP "\&" 2 -.. -.po +.3i -.TL -PMake \*- A Tutorial -.AU -Adam de Boor -.AI -Berkeley Softworks -2150 Shattuck Ave, Penthouse -Berkeley, CA 94704 -adam@bsw.uu.net -\&...!uunet!bsw!adam -.FS -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appears in all copies. -The University of California, Berkeley Softworks, and Adam de Boor make no -representations about the suitability of this software for any -purpose. It is provided "as is" without express or implied warranty. -.FE -.PP -.xH 1 Introduction -.LP -PMake is a program for creating other programs, or anything else you -can think of for it to do. The basic idea behind PMake is that, for -any given system, be it a program or a document or whatever, there -will be some files that depend on the state of other files (on when -they were last modified). PMake takes these dependencies, which you -must specify, and uses them to build whatever it is you want it to -build. -.LP -PMake is almost fully-compatible with Make, with which you may already -be familiar. PMake's most important feature is its ability to run -several different jobs at once, making the creation of systems -considerably faster. It also has a great deal more functionality than -Make. Throughout the text, whenever something is mentioned that is an -important difference between PMake and Make (i.e. something that will -cause a makefile to fail if you don't do something about it), or is -simply important, it will be flagged with a little sign in the left -margin, like this: -.No -.LP -This tutorial is divided into three main sections corresponding to basic, -intermediate and advanced PMake usage. If you already know Make well, -you will only need to skim chapter 2 (there are some aspects of -PMake that I consider basic to its use that didn't exist in Make). -Things in chapter 3 make life much easier, while those in chapter 4 -are strictly for those who know what they are doing. Chapter 5 has -definitions for the jargon I use and chapter 6 contains possible -solutions to the problems presented throughout the tutorial. -.xH 1 The Basics of PMake -.LP -PMake takes as input a file that tells a) which files depend on which -other files to be complete and b) what to do about files that are -``out-of-date.'' This file is known as a ``makefile'' and is usually -.Ix 0 def makefile -kept in the top-most directory of the system to be built. While you -can call the makefile anything you want, PMake will look for -.CW Makefile -and -.CW makefile -(in that order) in the current directory if you don't tell it -otherwise. -.Ix 0 def makefile default -To specify a different makefile, use the -.B \-f -flag (e.g. -.CW "pmake -f program.mk" ''). `` -.Ix 0 ref flags -f -.Ix 0 ref makefile other -.LP -A makefile has four different types of lines in it: -.RS -.IP \(bu 2 -File dependency specifications -.IP \(bu 2 -Creation commands -.IP \(bu 2 -Variable assignments -.IP \(bu 2 -Comments, include statements and conditional directives -.RE -.LP -Any line may be continued over multiple lines by ending it with a -backslash. -.Ix 0 def "continuation line" -The backslash, following newline and any initial whitespace -on the following line are compressed into a single space before the -input line is examined by PMake. -.xH 2 Dependency Lines -.LP -As mentioned in the introduction, in any system, there are -dependencies between the files that make up the system. For instance, -in a program made up of several C source files and one header file, -the C files will need to be re-compiled should the header file be -changed. For a document of several chapters and one macro file, the -chapters will need to be reprocessed if any of the macros changes. -.Ix 0 def "dependency" -These are dependencies and are specified by means of dependency lines in -the makefile. -.LP -.Ix 0 def "dependency line" -On a dependency line, there are targets and sources, separated by a -one- or two-character operator. -The targets ``depend'' on the sources and are usually created from -them. -.Ix 0 def target -.Ix 0 def source -.Ix 0 ref operator -Any number of targets and sources may be specified on a dependency line. -All the targets in the line are made to depend on all the sources. -Targets and sources need not be actual files, but every source must be -either an actual file or another target in the makefile. -If you run out of room, use a backslash at the end of the line to continue onto -the next one. -.LP -Any file may be a target and any file may be a source, but the -relationship between the two (or however many) is determined by the -``operator'' that separates them. -.Ix 0 def operator -Three types of operators exist: one specifies that the datedness of a -target is determined by the state of its sources, while another -specifies other files (the sources) that need to be dealt with before -the target can be re-created. The third operator is very similar to -the first, with the additional condition that the target is -out-of-date if it has no sources. These operations are represented by -the colon, the exclamation point and the double-colon, respectively, and are -mutually exclusive. Their exact semantics are as follows: -.IP ":" -.Ix 0 def operator colon -.Ix 0 def : -If a colon is used, a target on the line is considered to be -``out-of-date'' (and in need of creation) if -.RS -.IP \(bu 2 -any of the sources has been modified more recently than the target, or -.IP \(bu 2 -the target doesn't exist. -.RE -.Ix 0 def out-of-date -.IP "\&" -Under this operation, steps will be taken to re-create the target only -if it is found to be out-of-date by using these two rules. -.IP "!" -.Ix 0 def operator force -.Ix 0 def ! -If an exclamation point is used, the target will always be re-created, -but this will not happen until all of its sources have been examined -and re-created, if necessary. -.IP "::" -.Ix 0 def operator double-colon -.Ix 0 def :: -If a double-colon is used, a target is out-of-date if: -.RS -.IP \(bu 2 -any of the sources has been modified more recently than the target, or -.IP \(bu 2 -the target doesn't exist, or -.IP \(bu 2 -the target has no sources. -.RE -.IP "\&" -If the target is out-of-date according to these rules, it will be re-created. -This operator also does something else to the targets, but I'll go -into that in the next section (``Shell Commands''). -.LP -Enough words, now for an example. Take that C program I mentioned -earlier. Say there are three C files -.CW a.c , ( -.CW b.c -and -.CW c.c ) -each of which -includes the file -.CW defs.h . -The dependencies between the files could then be expressed as follows: -.DS -program : a.o b.o c.o -a.o b.o c.o : defs.h -a.o : a.c -b.o : b.c -c.o : c.c -.DE -.LP -You may be wondering at this point, where -.CW a.o , -.CW b.o -and -.CW c.o -came in and why -.I they -depend on -.CW defs.h -and the C files don't. The reason is quite simple: -.CW program -cannot be made by linking together .c files \*- it must be -made from .o files. Likewise, if you change -.CW defs.h , -it isn't the .c files that need to be re-created, it's the .o files. -If you think of dependencies in these terms \*- which files (targets) -need to be created from which files (sources) \*- you should have no problems. -.LP -An important thing to notice about the above example, is that all the -\&.o files appear as targets on more than one line. This is perfectly -all right: the target is made to depend on all the sources mentioned -on all the dependency lines. E.g. -.CW a.o -depends on both -.CW defs.h -and -.CW a.c . -.Ix 0 ref dependency -.No -.LP -The order of the dependency lines in the makefile is -important: the first target on the first dependency line in the -makefile will be the one that gets made if you don't say otherwise. -That's why -.CW program -comes first in the example makefile, above. -.LP -Both targets and sources may contain the standard C-Shell wildcard -characters -.CW { , ( -.CW } , -.CW * , -.CW ? , -.CW [ , -and -.CW ] ), -but the non-curly-brace ones may only appear in the final component -(the file portion) of the target or source. The characters mean the -following things: -.IP \fB{}\fP -These enclose a comma-separated list of options and cause the pattern -to be expanded once for each element of the list. Each expansion -contains a different element. For example, -.CW src/{whiffle,beep,fish}.c -expands to the three words -.CW src/whiffle.c , -.CW src/beep.c , -and -.CW src/fish.c . -These braces may be nested and, unlike the other wildcard characters, -the resulting words need not be actual files. All other wildcard -characters are expanded using the files that exist when PMake is -started. -.IP \fB*\fP -This matches zero or more characters of any sort. -.CW src/*.c -will expand to the same three words as above as long as -.CW src -contains those three files (and no other files that end in -.CW .c ). -.IP \fB?\fP -Matches any single character. -.IP \fB[]\fP -This is known as a character class and contains either a list of -single characters, or a series of character ranges -.CW a-z , ( -for example means all characters between a and z), or both. It matches -any single character contained in the list. E.g. -.CW [A-Za-z] -will match all letters, while -.CW [0123456789] -will match all numbers. -.xH 2 Shell Commands -.LP -``Isn't that nice,'' you say to yourself, ``but how are files -actually `re-created,' as he likes to spell it?'' -The re-creation is accomplished by commands you place in the makefile. -These commands are passed to the Bourne shell (better known as -``/bin/sh'') to be executed and are -.Ix 0 ref shell -.Ix 0 ref re-creation -.Ix 0 ref update -expected to do what's necessary to update the target file (PMake -doesn't actually check to see if the target was created. It just -assumes it's there). -.Ix 0 ref target -.LP -Shell commands in a makefile look a lot like shell commands you would -type at a terminal, with one important exception: each command in a -makefile -.I must -be preceded by at least one tab. -.LP -Each target has associated with it a shell script made up of -one or more of these shell commands. The creation script for a target -should immediately follow the dependency line for that target. While -any given target may appear on more than one dependency line, only one -of these dependency lines may be followed by a creation script, unless -the `::' operator was used on the dependency line. -.Ix 0 ref operator double-colon -.Ix 0 ref :: -.No -.LP -If the double-colon was used, each dependency line for the target -may be followed by a shell script. That script will only be executed -if the target on the associated dependency line is out-of-date with -respect to the sources on that line, according to the rules I gave -earlier. -I'll give you a good example of this later on. -.LP -To expand on the earlier makefile, you might add commands as follows: -.DS -program : a.o b.o c.o - cc a.o b.o c.o \-o program -a.o b.o c.o : defs.h -a.o : a.c - cc \-c a.c -b.o : b.c - cc \-c b.c -c.o : c.c - cc \-c c.c -.DE -.LP -Something you should remember when writing a makefile is, the -commands will be executed if the -.I target -on the dependency line is out-of-date, not the sources. -.Ix 0 ref target -.Ix 0 ref source -.Ix 0 ref out-of-date -In this example, the command -.CW "cc \-c a.c" '' `` -will be executed if -.CW a.o -is out-of-date. Because of the `:' operator, -.Ix 0 ref : -.Ix 0 ref operator colon -this means that should -.CW a.c -.I or -.CW defs.h -have been modified more recently than -.CW a.o , -the command will be executed -.CW a.o "\&" ( -will be considered out-of-date). -.Ix 0 ref out-of-date -.LP -Remember how I said the only difference between a makefile shell -command and a regular shell command was the leading tab? I lied. There -is another way in which makefile commands differ from regular ones. -The first two characters after the initial whitespace are treated -specially. -If they are any combination of `@' and `\-', they cause PMake to do -different things. -.LP -In most cases, shell commands are printed before they're -actually executed. This is to keep you informed of what's going on. If -an `@' appears, however, this echoing is suppressed. In the case of an -.CW echo -command, say -.CW "echo Linking index" ,'' `` -it would be -rather silly to see -.DS -echo Linking index -Linking index -.DE -.LP -so PMake allows you to place an `@' before the command -.CW "@echo Linking index" '') (`` -to prevent the command from being printed. -.LP -The other special character is the `\-'. In case you didn't know, -shell commands finish with a certain ``exit status.'' This status is -made available by the operating system to whatever program invoked the -command. Normally this status will be 0 if everything went ok and -non-zero if something went wrong. For this reason, PMake will consider -an error to have occurred if one of the shells it invokes returns a non-zero -status. When it detects an error, PMake's usual action is to abort -whatever it's doing and exit with a non-zero status itself (any other -targets that were being created will continue being made, but nothing -new will be started. PMake will exit after the last job finishes). -This behavior can be altered, however, by placing a `\-' at the front -of a command -.CW "\-mv index index.old" ''), (`` -certain command-line arguments, -or doing other things, to be detailed later. In such -a case, the non-zero status is simply ignored and PMake keeps chugging -along. -.No -.LP -Because all the commands are given to a single shell to execute, such -things as setting shell variables, changing directories, etc., last -beyond the command in which they are found. This also allows shell -compound commands (like -.CW for -loops) to be entered in a natural manner. -Since this could cause problems for some makefiles that depend on -each command being executed by a single shell, PMake has a -.B \-B -.Ix 0 ref compatibility -.Ix 0 ref flags -B -flag (it stands for backwards-compatible) that forces each command to -be given to a separate shell. It also does several other things, all -of which I discourage since they are now old-fashioned.\|.\|.\|. -.No -.LP -A target's shell script is fed to the shell on its (the shell's) input stream. -This means that any commands, such as -.CW ci -that need to get input from the terminal won't work right \*- they'll -get the shell's input, something they probably won't find to their -liking. A simple way around this is to give a command like this: -.DS -ci $(SRCS) < /dev/tty -.DE -This would force the program's input to come from the terminal. If you -can't do this for some reason, your only other alternative is to use -PMake in its fullest compatibility mode. See -.B Compatibility -in chapter 4. -.Ix 0 ref compatibility -.LP -.xH 2 Variables -.LP -PMake, like Make before it, has the ability to save text in variables -to be recalled later at your convenience. Variables in PMake are used -much like variables in the shell and, by tradition, consist of -all upper-case letters (you don't -.I have -to use all upper-case letters. -In fact there's nothing to stop you from calling a variable -.CW @^&$%$ . -Just tradition). Variables are assigned-to using lines of the form -.Ix 0 def variable assignment -.DS -VARIABLE = value -.DE -.Ix 0 def variable assignment -appended-to by -.DS -VARIABLE += value -.DE -.Ix 0 def variable appending -.Ix 0 def variable assignment appended -.Ix 0 def += -conditionally assigned-to (if the variable isn't already defined) by -.DS -VARIABLE ?= value -.DE -.Ix 0 def variable assignment conditional -.Ix 0 def ?= -and assigned-to with expansion (i.e. the value is expanded (see below) -before being assigned to the variable\*-useful for placing a value at -the beginning of a variable, or other things) by -.DS -VARIABLE := value -.DE -.Ix 0 def variable assignment expanded -.Ix 0 def := -.LP -Any whitespace before -.I value -is stripped off. When appending, a space is placed between the old -value and the stuff being appended. -.LP -The final way a variable may be assigned to is using -.DS -VARIABLE != shell-command -.DE -.Ix 0 def variable assignment shell-output -.Ix 0 def != -In this case, -.I shell-command -has all its variables expanded (see below) and is passed off to a -shell to execute. The output of the shell is then placed in the -variable. Any newlines (other than the final one) are replaced by -spaces before the assignment is made. This is typically used to find -the current directory via a line like: -.DS -CWD != pwd -.DE -.LP -.B Note: -this is intended to be used to execute commands that produce small amounts -of output (e.g. ``pwd''). The implementation is less than intelligent and will -likely freeze if you execute something that produces thousands of -bytes of output (8 Kb is the limit on many UNIX systems). -.LP -The value of a variable may be retrieved by enclosing the variable -name in parentheses or curly braces and preceding the whole thing -with a dollar sign. -.LP -For example, to set the variable CFLAGS to the string -.CW "\-I/sprite/src/lib/libc \-O" ,'' `` -you would place a line -.DS -CFLAGS = \-I/sprite/src/lib/libc \-O -.DE -in the makefile and use the word -.CW "$(CFLAGS)" -wherever you would like the string -.CW "\-I/sprite/src/lib/libc \-O" -to appear. This is called variable expansion. -.Ix 0 def variable expansion -.No -.LP -Unlike Make, PMake will not expand a variable unless it knows -the variable exists. E.g. if you have a -.CW "${i}" -in a shell command and you have not assigned a value to the variable -.CW i -(the empty string is considered a value, by the way), where Make would have -substituted the empty string, PMake will leave the -.CW "${i}" -alone. -To keep PMake from substituting for a variable it knows, precede the -dollar sign with another dollar sign. -(e.g. to pass -.CW "${HOME}" -to the shell, use -.CW "$${HOME}" ). -This causes PMake, in effect, to expand the -.CW $ -macro, which expands to a single -.CW $ . -For compatibility, Make's style of variable expansion will be used -if you invoke PMake with any of the compatibility flags (\c -.B \-V , -.B \-B -or -.B \-M . -The -.B \-V -flag alters just the variable expansion). -.Ix 0 ref flags -V -.Ix 0 ref flags -B -.Ix 0 ref flags -M -.Ix 0 ref compatibility -.LP -.Ix 0 ref variable expansion -There are two different times at which variable expansion occurs: -When parsing a dependency line, the expansion occurs immediately -upon reading the line. If any variable used on a dependency line is -undefined, PMake will print a message and exit. -Variables in shell commands are expanded when the command is -executed. -Variables used inside another variable are expanded whenever the outer -variable is expanded (the expansion of an inner variable has no effect -on the outer variable. I.e. if the outer variable is used on a dependency -line and in a shell command, and the inner variable changes value -between when the dependency line is read and the shell command is -executed, two different values will be substituted for the outer -variable). -.Ix 0 def variable types -.LP -Variables come in four flavors, though they are all expanded the same -and all look about the same. They are (in order of expanding scope): -.RS -.IP \(bu 2 -Local variables. -.Ix 0 ref variable local -.IP \(bu 2 -Command-line variables. -.Ix 0 ref variable command-line -.IP \(bu 2 -Global variables. -.Ix 0 ref variable global -.IP \(bu 2 -Environment variables. -.Ix 0 ref variable environment -.RE -.LP -The classification of variables doesn't matter much, except that the -classes are searched from the top (local) to the bottom (environment) -when looking up a variable. The first one found wins. -.xH 3 Local Variables -.LP -.Ix 0 def variable local -Each target can have as many as seven local variables. These are -variables that are only ``visible'' within that target's shell script -and contain such things as the target's name, all of its sources (from -all its dependency lines), those sources that were out-of-date, etc. -Four local variables are defined for all targets. They are: -.RS -.IP ".TARGET" -.Ix 0 def variable local .TARGET -.Ix 0 def .TARGET -The name of the target. -.IP ".OODATE" -.Ix 0 def variable local .OODATE -.Ix 0 def .OODATE -The list of the sources for the target that were considered out-of-date. -The order in the list is not guaranteed to be the same as the order in -which the dependencies were given. -.IP ".ALLSRC" -.Ix 0 def variable local .ALLSRC -.Ix 0 def .ALLSRC -The list of all sources for this target in the order in which they -were given. -.IP ".PREFIX" -.Ix 0 def variable local .PREFIX -.Ix 0 def .PREFIX -The target without its suffix and without any leading path. E.g. for -the target -.CW ../../lib/compat/fsRead.c , -this variable would contain -.CW fsRead . -.RE -.LP -Three other local variables are set only for certain targets under -special circumstances. These are the ``.IMPSRC,'' -.Ix 0 ref variable local .IMPSRC -.Ix 0 ref .IMPSRC -``.ARCHIVE,'' -.Ix 0 ref variable local .ARCHIVE -.Ix 0 ref .ARCHIVE -and ``.MEMBER'' -.Ix 0 ref variable local .MEMBER -.Ix 0 ref .MEMBER -variables. When they are set and how they are used is described later. -.LP -Four of these variables may be used in sources as well as in shell -scripts. -.Ix 0 def "dynamic source" -.Ix 0 def source dynamic -These are ``.TARGET'', ``.PREFIX'', ``.ARCHIVE'' and ``.MEMBER''. The -variables in the sources are expanded once for each target on the -dependency line, providing what is known as a ``dynamic source,'' -.Rd 0 -allowing you to specify several dependency lines at once. For example, -.DS -$(OBJS) : $(.PREFIX).c -.DE -will create a dependency between each object file and its -corresponding C source file. -.xH 3 Command-line Variables -.LP -.Ix 0 def variable command-line -Command-line variables are set when PMake is first invoked by giving a -variable assignment as one of the arguments. For example, -.DS -pmake "CFLAGS = -I/sprite/src/lib/libc -O" -.DE -would make -.CW CFLAGS -be a command-line variable with the given value. Any assignments to -.CW CFLAGS -in the makefile will have no effect, because once it -is set, there is (almost) nothing you can do to change a command-line -variable (the search order, you see). Command-line variables may be -set using any of the four assignment operators, though only -.CW = -and -.CW ?= -behave as you would expect them to, mostly because assignments to -command-line variables are performed before the makefile is read, thus -the values set in the makefile are unavailable at the time. -.CW += -.Ix 0 ref += -.Ix 0 ref variable assignment appended -is the same as -.CW = , -because the old value of the variable is sought only in the scope in -which the assignment is taking place (for reasons of efficiency that I -won't get into here). -.CW := -and -.CW ?= -.Ix 0 ref := -.Ix 0 ref ?= -.Ix 0 ref variable assignment expanded -.Ix 0 ref variable assignment conditional -will work if the only variables used are in the environment. -.CW != -is sort of pointless to use from the command line, since the same -effect can no doubt be accomplished using the shell's own command -substitution mechanisms (backquotes and all that). -.xH 3 Global Variables -.LP -.Ix 0 def variable global -Global variables are those set or appended-to in the makefile. -There are two classes of global variables: those you set and those PMake sets. -As I said before, the ones you set can have any name you want them to have, -except they may not contain a colon or an exclamation point. -The variables PMake sets (almost) always begin with a -period and always contain upper-case letters, only. The variables are -as follows: -.RS -.IP .PMAKE -.Ix 0 def variable global .PMAKE -.Ix 0 def .PMAKE -.Ix 0 def variable global MAKE -.Ix 0 def MAKE -The name by which PMake was invoked is stored in this variable. For -compatibility, the name is also stored in the MAKE variable. -.IP .MAKEFLAGS -.Ix 0 def variable global .MAKEFLAGS -.Ix 0 def .MAKEFLAGS variable -.Ix 0 def variable global MFLAGS -.Ix 0 def MFLAGS -All the relevant flags with which PMake was invoked. This does not -include such things as -.B \-f -or variable assignments. Again for compatibility, this value is stored -in the MFLAGS variable as well. -.RE -.LP -Two other variables, ``.INCLUDES'' and ``.LIBS,'' are covered in the -section on special targets in chapter 3. -.Ix 0 ref variable global .INCLUDES -.Ix 0 ref variable global .LIBS -.LP -Global variables may be deleted using lines of the form: -.Ix 0 def #undef -.Ix 0 def variable deletion -.DS -#undef \fIvariable\fP -.DE -The -.CW # ' ` -must be the first character on the line. Note that this may only be -done on global variables. -.xH 3 Environment Variables -.LP -.Ix 0 def variable environment -Environment variables are passed by the shell that invoked PMake and -are given by PMake to each shell it invokes. They are expanded like -any other variable, but they cannot be altered in any way. -.LP -One special environment variable, -.CW PMAKE , -.Ix 0 def variable environment PMAKE -is examined by PMake for command-line flags, variable assignments, -etc., it should always use. This variable is examined before the -actual arguments to PMake are. In addition, all flags given to PMake, -either through the -.CW PMAKE -variable or on the command line, are placed in this environment -variable and exported to each shell PMake executes. Thus recursive -invocations of PMake automatically receive the same flags as the -top-most one. -.LP -Using all these variables, you can compress the sample makefile even more: -.DS -OBJS = a.o b.o c.o -program : $(OBJS) - cc $(.ALLSRC) \-o $(.TARGET) -$(OBJS) : defs.h -a.o : a.c - cc \-c a.c -b.o : b.c - cc \-c b.c -c.o : c.c - cc \-c c.c -.DE -.Ix 0 ref variable local .ALLSRC -.Ix 0 ref .ALLSRC -.Ix 0 ref variable local .TARGET -.Ix 0 ref .TARGET -.Rd 3 -.xH 2 Comments -.LP -.Ix 0 def comments -Comments in a makefile start with a `#' character and extend to the -end of the line. They may appear -anywhere you want them, except in a shell command (though the shell -will treat it as a comment, too). If, for some reason, you need to use the `#' -in a variable or on a dependency line, put a backslash in front of it. -PMake will compress the two into a single `#' (Note: this isn't true -if PMake is operating in full-compatibility mode). -.Ix 0 ref flags -M -.Ix 0 ref compatibility -.xH 2 Parallelism -.No -.LP -PMake was specifically designed to re-create several targets at once, -when possible. You do not have to do anything special to cause this to -happen (unless PMake was configured to not act in parallel, in which -case you will have to make use of the -.B \-L -and -.B \-J -flags (see below)), -.Ix 0 ref flags -L -.Ix 0 ref flags -J -but you do have to be careful at times. -.LP -There are several problems you are likely to encounter. One is -that some makefiles (and programs) are written in such a way that it is -impossible for two targets to be made at once. The program -.CW xstr , -for example, -always modifies the files -.CW strings -and -.CW x.c . -There is no way to change it. Thus you cannot run two of them at once -without something being trashed. Similarly, if you have commands -in the makefile that always send output to the same file, you will not -be able to make more than one target at once unless you change the -file you use. You can, for instance, add a -.CW $$$$ -to the end of the file name to tack on the process ID of the shell -executing the command (each -.CW $$ -expands to a single -.CW $ , -thus giving you the shell variable -.CW $$ ). -Since only one shell is used for all the -commands, you'll get the same file name for each command in the -script. -.LP -The other problem comes from improperly-specified dependencies that -worked in Make because of its sequential, depth-first way of examining -them. While I don't want to go into depth on how PMake -works (look in chapter 4 if you're interested), I will warn you that -files in two different ``levels'' of the dependency tree may be -examined in a different order in PMake than they were in Make. For -example, given the makefile -.DS -a : b c -b : d -.DE -PMake will examine the targets in the order -.CW c , -.CW d , -.CW b , -.CW a . -If the makefile's author expected PMake to abort before making -.CW c -if an error occurred while making -.CW b , -or if -.CW b -needed to exist before -.CW c -was made, -s/he will be sorely disappointed. The dependencies are -incomplete, since in both these cases, -.CW c -would depend on -.CW b . -So watch out. -.LP -Another problem you may face is that, while PMake is set up to handle the -output from multiple jobs in a graceful fashion, the same is not so for input. -It has no way to regulate input to different jobs, -so if you use the redirection from -.CW /dev/tty -I mentioned earlier, you must be careful not to run two of the jobs at once. -.xH 2 Writing and Debugging a Makefile -.LP -Now you know most of what's in a makefile, what do you do next? There -are two choices: (1) use one of the uncommonly-available makefile -generators or (2) write your own makefile (I leave out the third choice of -ignoring PMake and doing everything by hand as being beyond the bounds -of common sense). -.LP -When faced with the writing of a makefile, it is usually best to start -from first principles: just what -.I are -you trying to do? What do you want the makefile finally to produce? -.LP -To begin with a somewhat traditional example, let's say you need to -write a makefile to create a program, -.CW expr , -that takes standard infix expressions and converts them to prefix form (for -no readily apparent reason). You've got three source files, in C, that -make up the program: -.CW main.c , -.CW parse.c , -and -.CW output.c . -Harking back to my pithy advice about dependency lines, you write the -first line of the file: -.DS -expr : main.o parse.o output.o -.DE -because you remember -.CW expr -is made from -.CW .o -files, not -.CW .c -files. Similarly for the -.CW .o -files you produce the lines: -.DS -main.o : main.c -parse.o : parse.c -output.o : output.c -main.o parse.o output.o : defs.h -.DE -.LP -Great. You've now got the dependencies specified. What you need now is -commands. These commands, remember, must produce the target on the -dependency line, usually by using the sources you've listed. -You remember about local variables? Good, so it should come -to you as no surprise when you write -.DS -expr : main.o parse.o output.o - cc -o $(.TARGET) $(.ALLSRC) -.DE -Why use the variables? If your program grows to produce postfix -expressions too (which, of course, requires a name change or two), it -is one fewer place you have to change the file. You cannot do this for -the object files, however, because they depend on their corresponding -source files -.I and -.CW defs.h , -thus if you said -.DS - cc -c $(.ALLSRC) -.DE -you'd get (for -.CW main.o ): -.DS - cc -c main.c defs.h -.DE -which is wrong. So you round out the makefile with these lines: -.DS -main.o : main.c - cc -c main.c -parse.o : parse.c - cc -c parse.c -output.o : output.c - cc -c output.c -.DE -.LP -The makefile is now complete and will, in fact, create the program you -want it to without unnecessary compilations or excessive typing on -your part. There are two things wrong with it, however (aside from it -being altogether too long, something I'll address in chapter 3): -.IP 1) -The string -.CW "main.o parse.o output.o" '' `` -is repeated twice, necessitating two changes when you add postfix -(you were planning on that, weren't you?). This is in direct violation -of de Boor's First Rule of writing makefiles: -.QP -.I -Anything that needs to be written more than once -should be placed in a variable. -.IP "\&" -I cannot emphasize this enough as being very important to the -maintenance of a makefile and its program. -.IP 2) -There is no way to alter the way compilations are performed short of -editing the makefile and making the change in all places. This is evil -and violates de Boor's Second Rule, which follows directly from the -first: -.QP -.I -Any flags or programs used inside a makefile should be placed in a variable so -they may be changed, temporarily or permanently, with the greatest ease. -.LP -The makefile should more properly read: -.DS -OBJS = main.o parse.o output.o -expr : $(OBJS) - $(CC) $(CFLAGS) -o $(.TARGET) $(.ALLSRC) -main.o : main.c - $(CC) $(CFLAGS) -c main.c -parse.o : parse.c - $(CC) $(CFLAGS) -c parse.c -output.o : output.c - $(CC) $(CFLAGS) -c output.c -$(OBJS) : defs.h -.DE -Alternatively, if you like the idea of dynamic sources mentioned in -section 2.3.1, -.Rm 0 2.3.1 -.Rd 4 -.Ix 0 ref "dynamic source" -.Ix 0 ref source dynamic -you could write it like this: -.DS -OBJS = main.o parse.o output.o -expr : $(OBJS) - $(CC) $(CFLAGS) -o $(.TARGET) $(.ALLSRC) -$(OBJS) : $(.PREFIX).c defs.h - $(CC) $(CFLAGS) -c $(.PREFIX).c -.DE -These two rules and examples lead to de Boor's First Corollary: -.QP -.I -Variables are your friends. -.LP -Once you've written the makefile comes the sometimes-difficult task of -.Ix 0 ref debugging -making sure the darn thing works. Your most helpful tool to make sure -the makefile is at least syntactically correct is the -.B \-n -.Ix 0 ref flags -n -flag, which allows you to see if PMake will choke on the makefile. The -second thing the -.B \-n -flag lets you do is see what PMake would do without it actually doing -it, thus you can make sure the right commands would be executed were -you to give PMake its head. -.LP -When you find your makefile isn't behaving as you hoped, the first -question that comes to mind (after ``What time is it, anyway?'') is -``Why not?'' In answering this, two flags will serve you well: -.CW "-d m" '' `` -.Ix 0 ref flags -d -and -.CW "-p 2" .'' `` -.Ix 0 ref flags -p -The first causes PMake to tell you as it examines each target in the -makefile and indicate why it is deciding whatever it is deciding. You -can then use the information printed for other targets to see where -you went wrong. The -.CW "-p 2" '' `` -flag makes PMake print out its internal state when it is done, -allowing you to see that you forgot to make that one chapter depend on -that file of macros you just got a new version of. The output from -.CW "-p 2" '' `` -is intended to resemble closely a real makefile, but with additional -information provided and with variables expanded in those commands -PMake actually printed or executed. -.LP -Something to be especially careful about is circular dependencies. -.Ix 0 def dependency circular -E.g. -.DS -a : b -b : c d -d : a -.DE -In this case, because of how PMake works, -.CW c -is the only thing PMake will examine, because -.CW d -and -.CW a -will effectively fall off the edge of the universe, making it -impossible to examine -.CW b -(or them, for that matter). -PMake will tell you (if run in its normal mode) all the targets -involved in any cycle it looked at (i.e. if you have two cycles in the -graph (naughty, naughty), but only try to make a target in one of -them, PMake will only tell you about that one. You'll have to try to -make the other to find the second cycle). When run as Make, it will -only print the first target in the cycle. -.xH 2 Invoking PMake -.LP -.Ix 0 ref flags -.Ix 0 ref arguments -.Ix 0 ref usage -PMake comes with a wide variety of flags to choose from. -They may appear in any order, interspersed with command-line variable -assignments and targets to create. -The flags are as follows: -.IP "\fB\-d\fP \fIwhat\fP" -.Ix 0 def flags -d -.Ix 0 ref debugging -This causes PMake to spew out debugging information that -may prove useful to you. If you can't -figure out why PMake is doing what it's doing, you might try using -this flag. The -.I what -parameter is a string of single characters that tell PMake what -aspects you are interested in. Most of what I describe will make -little sense to you, unless you've dealt with Make before. Just -remember where this table is and come back to it as you read on. -The characters and the information they produce are as follows: -.RS -.IP a -Archive searching and caching. -.IP c -Conditional evaluation. -.IP d -The searching and caching of directories. -.IP j -Various snippets of information related to the running of the multiple -shells. Not particularly interesting. -.IP m -The making of each target: what target is being examined; when it was -last modified; whether it is out-of-date; etc. -.IP p -Makefile parsing. -.IP r -Remote execution. -.IP s -The application of suffix-transformation rules. (See chapter 3) -.IP t -The maintenance of the list of targets. -.IP v -Variable assignment. -.RE -.IP "\&" -Of these all, the -.CW m -and -.CW s -letters will be most useful to you. -If the -.B \-d -is the final argument or the argument from which it would get these -key letters (see below for a note about which argument would be used) -begins with a -.B \- , -all of these debugging flags will be set, resulting in massive amounts -of output. -.IP "\fB\-f\fP \fImakefile\fP" -.Ix 0 def flags -f -Specify a makefile to read different from the standard makefiles -.CW Makefile "\&" ( -or -.CW makefile ). -.Ix 0 ref makefile default -.Ix 0 ref makefile other -If -.I makefile -is ``\-'', PMake uses the standard input. This is useful for making -quick and dirty makefiles.\|.\|. -.Ix 0 ref makefile "quick and dirty" -.IP \fB\-h\fP -.Ix 0 def flags -h -Prints out a summary of the various flags PMake accepts. It can also -be used to find out what level of concurrency was compiled into the -version of PMake you are using (look at -.B \-J -and -.B \-L ) -and various other information on how PMake was configured. -.Ix 0 ref configuration -.Ix 0 ref makefile system -.IP \fB\-i\fP -.Ix 0 def flags -i -If you give this flag, PMake will ignore non-zero status returned -by any of its shells. It's like placing a `\-' before all the commands -in the makefile. -.IP \fB\-k\fP -.Ix 0 def flags -k -This is similar to -.B \-i -in that it allows PMake to continue when it sees an error, but unlike -.B \-i , -where PMake continues blithely as if nothing went wrong, -.B \-k -causes it to recognize the error and only continue work on those -things that don't depend on the target, either directly or indirectly (through -depending on something that depends on it), whose creation returned the error. -The `k' is for ``keep going''.\|.\|. -.Ix 0 ref target -.IP \fB\-l\fP -.Ix 0 def flags -l -PMake has the ability to lock a directory against other -people executing it in the same directory (by means of a file called -``LOCK.make'' that it creates and checks for in the directory). This -is a Good Thing because two people doing the same thing in the same place -can be disastrous for the final product (too many cooks and all that). -Whether this locking is the default is up to your system -administrator. If locking is on, -.B \-l -will turn it off, and vice versa. Note that this locking will not -prevent \fIyou\fP from invoking PMake twice in the same place \*- if -you own the lock file, PMake will warn you about it but continue to execute. -.IP "\fB\-m\fP \fIdirectory\fP" -.Ix 0 def flags -m -Tells PMake another place to search for included makefiles via the <...> -style. Several -.B \-m -options can be given to form a search path. If this construct is used the -default system makefile search path is completely overridden. -To be explained in chapter 3, section 3.2. -.Rm 2 3.2 -.IP \fB\-n\fP -.Ix 0 def flags -n -This flag tells PMake not to execute the commands needed to update the -out-of-date targets in the makefile. Rather, PMake will simply print -the commands it would have executed and exit. This is particularly -useful for checking the correctness of a makefile. If PMake doesn't do -what you expect it to, it's a good chance the makefile is wrong. -.IP "\fB\-p\fP \fInumber\fP" -.Ix 0 def flags -p -.Ix 0 ref debugging -This causes PMake to print its input in a reasonable form, though -not necessarily one that would make immediate sense to anyone but me. The -.I number -is a bitwise-or of 1 and 2 where 1 means it should print the input -before doing any processing and 2 says it should print it after -everything has been re-created. Thus -.CW "\-p 3" -would print it twice\*-once before processing and once after (you -might find the difference between the two interesting). This is mostly -useful to me, but you may find it informative in some bizarre circumstances. -.IP \fB\-q\fP -.Ix 0 def flags -q -If you give PMake this flag, it will not try to re-create anything. It -will just see if anything is out-of-date and exit non-zero if so. -.IP \fB\-r\fP -.Ix 0 def flags -r -When PMake starts up, it reads a default makefile that tells it what -sort of system it's on and gives it some idea of what to do if you -don't tell it anything. I'll tell you about it in chapter 3. If you -give this flag, PMake won't read the default makefile. -.IP \fB\-s\fP -.Ix 0 def flags -s -This causes PMake to not print commands before they're executed. It -is the equivalent of putting an `@' before every command in the -makefile. -.IP \fB\-t\fP -.Ix 0 def flags -t -Rather than try to re-create a target, PMake will simply ``touch'' it -so as to make it appear up-to-date. If the target didn't exist before, -it will when PMake finishes, but if the target did exist, it will -appear to have been updated. -.IP \fB\-v\fP -.Ix 0 def flags -v -This is a mixed-compatibility flag intended to mimic the System V -version of Make. It is the same as giving -.B \-B , -and -.B \-V -as well as turning off directory locking. Targets can still be created -in parallel, however. This is the mode PMake will enter if it is -invoked either as -.CW smake '' `` -or -.CW vmake ''. `` -.IP \fB\-x\fP -.Ix 0 def flags -x -This tells PMake it's ok to export jobs to other machines, if they're -available. It is used when running in Make mode, as exporting in this -mode tends to make things run slower than if the commands were just -executed locally. -.IP \fB\-B\fP -.Ix 0 ref compatibility -.Ix 0 def flags -B -Forces PMake to be as backwards-compatible with Make as possible while -still being itself. -This includes: -.RS -.IP \(bu 2 -Executing one shell per shell command -.IP \(bu 2 -Expanding anything that looks even vaguely like a variable, with the -empty string replacing any variable PMake doesn't know. -.IP \(bu 2 -Refusing to allow you to escape a `#' with a backslash. -.IP \(bu 2 -Permitting undefined variables on dependency lines and conditionals -(see below). Normally this causes PMake to abort. -.RE -.IP \fB\-C\fP -.Ix 0 def flags -C -This nullifies any and all compatibility mode flags you may have given -or implied up to the time the -.B \-C -is encountered. It is useful mostly in a makefile that you wrote for PMake -to avoid bad things happening when someone runs PMake as -.CW make '' `` -or has things set in the environment that tell it to be compatible. -.B \-C -is -.I not -placed in the -.CW PMAKE -environment variable or the -.CW .MAKEFLAGS -or -.CW MFLAGS -global variables. -.Ix 0 ref variable environment PMAKE -.Ix 0 ref variable global .MAKEFLAGS -.Ix 0 ref variable global MFLAGS -.Ix 0 ref .MAKEFLAGS variable -.Ix 0 ref MFLAGS -.IP "\fB\-D\fP \fIvariable\fP" -.Ix 0 def flags -D -Allows you to define a variable to have -.CW 1 '' `` -as its value. The variable is a global variable, not a command-line -variable. This is useful mostly for people who are used to the C -compiler arguments and those using conditionals, which I'll get into -in section 4.3 -.Rm 1 4.3 -.IP "\fB\-I\fP \fIdirectory\fP" -.Ix 0 def flags -I -Tells PMake another place to search for included makefiles. Yet -another thing to be explained in chapter 3 (section 3.2, to be -precise). -.Rm 2 3.2 -.IP "\fB\-J\fP \fInumber\fP" -.Ix 0 def flags -J -Gives the absolute maximum number of targets to create at once on both -local and remote machines. -.IP "\fB\-L\fP \fInumber\fP" -.Ix 0 def flags -L -This specifies the maximum number of targets to create on the local -machine at once. This may be 0, though you should be wary of doing -this, as PMake may hang until a remote machine becomes available, if -one is not available when it is started. -.IP \fB\-M\fP -.Ix 0 ref compatibility -.Ix 0 def flags -M -This is the flag that provides absolute, complete, full compatibility -with Make. It still allows you to use all but a few of the features of -PMake, but it is non-parallel. This is the mode PMake enters if you -call it -.CW make .'' `` -.IP \fB\-P\fP -.Ix 0 def flags -P -.Ix 0 ref "output control" -When creating targets in parallel, several shells are executing at -once, each wanting to write its own two cent's-worth to the screen. -This output must be captured by PMake in some way in order to prevent -the screen from being filled with garbage even more indecipherable -than you usually see. PMake has two ways of doing this, one of which -provides for much cleaner output and a clear separation between the -output of different jobs, the other of which provides a more immediate -response so one can tell what is really happening. The former is done -by notifying you when the creation of a target starts, capturing the -output and transferring it to the screen all at once when the job -finishes. The latter is done by catching the output of the shell (and -its children) and buffering it until an entire line is received, then -printing that line preceded by an indication of which job produced -the output. Since I prefer this second method, it is the one used by -default. The first method will be used if you give the -.B \-P -flag to PMake. -.IP \fB\-V\fP -.Ix 0 def flags -V -As mentioned before, the -.B \-V -flag tells PMake to use Make's style of expanding variables, -substituting the empty string for any variable it doesn't know. -.IP \fB\-W\fP -.Ix 0 def flags -W -There are several times when PMake will print a message at you that is -only a warning, i.e. it can continue to work in spite of your having -done something silly (such as forgotten a leading tab for a shell -command). Sometimes you are well aware of silly things you have done -and would like PMake to stop bothering you. This flag tells it to shut -up about anything non-fatal. -.IP \fB\-X\fP -.Ix 0 def flags -X -This flag causes PMake to not attempt to export any jobs to another -machine. -.LP -Several flags may follow a single `\-'. Those flags that require -arguments take them from successive parameters. E.g. -.DS -pmake -fDnI server.mk DEBUG /chip2/X/server/include -.DE -will cause PMake to read -.CW server.mk -as the input makefile, define the variable -.CW DEBUG -as a global variable and look for included makefiles in the directory -.CW /chip2/X/server/include . -.xH 2 Summary -.LP -A makefile is made of four types of lines: -.RS -.IP \(bu 2 -Dependency lines -.IP \(bu 2 -Creation commands -.IP \(bu 2 -Variable assignments -.IP \(bu 2 -Comments, include statements and conditional directives -.RE -.LP -A dependency line is a list of one or more targets, an operator -.CW : ', (` -.CW :: ', ` -or -.CW ! '), ` -and a list of zero or more sources. Sources may contain wildcards and -certain local variables. -.LP -A creation command is a regular shell command preceded by a tab. In -addition, if the first two characters after the tab (and other -whitespace) are a combination of -.CW @ ' ` -or -.CW - ', ` -PMake will cause the command to not be printed (if the character is -.CW @ ') ` -or errors from it to be ignored (if -.CW - '). ` -A blank line, dependency line or variable assignment terminates a -creation script. There may be only one creation script for each target -with a -.CW : ' ` -or -.CW ! ' ` -operator. -.LP -Variables are places to store text. They may be unconditionally -assigned-to using the -.CW = ' ` -.Ix 0 ref = -.Ix 0 ref variable assignment -operator, appended-to using the -.CW += ' ` -.Ix 0 ref += -.Ix 0 ref variable assignment appended -operator, conditionally (if the variable is undefined) assigned-to -with the -.CW ?= ' ` -.Ix 0 ref ?= -.Ix 0 ref variable assignment conditional -operator, and assigned-to with variable expansion with the -.CW := ' ` -.Ix 0 ref := -.Ix 0 ref variable assignment expanded -operator. The output of a shell command may be assigned to a variable -using the -.CW != ' ` -.Ix 0 ref != -.Ix 0 ref variable assignment shell-output -operator. Variables may be expanded (their value inserted) by enclosing -their name in parentheses or curly braces, preceded by a dollar sign. -A dollar sign may be escaped with another dollar sign. Variables are -not expanded if PMake doesn't know about them. There are seven local -variables: -.CW .TARGET , -.CW .ALLSRC , -.CW .OODATE , -.CW .PREFIX , -.CW .IMPSRC , -.CW .ARCHIVE , -and -.CW .MEMBER . -Four of them -.CW .TARGET , ( -.CW .PREFIX , -.CW .ARCHIVE , -and -.CW .MEMBER ) -may be used to specify ``dynamic sources.'' -.Ix 0 ref "dynamic source" -.Ix 0 ref source dynamic -Variables are good. Know them. Love them. Live them. -.LP -Debugging of makefiles is best accomplished using the -.B \-n , -.B "\-d m" , -and -.B "\-p 2" -flags. -.xH 2 Exercises -.ce -\s+4\fBTBA\fP\s0 -.xH 1 Short-cuts and Other Nice Things -.LP -Based on what I've told you so far, you may have gotten the impression -that PMake is just a way of storing away commands and making sure you -don't forget to compile something. Good. That's just what it is. -However, the ways I've described have been inelegant, at best, and -painful, at worst. -This chapter contains things that make the -writing of makefiles easier and the makefiles themselves shorter and -easier to modify (and, occasionally, simpler). In this chapter, I -assume you are somewhat more -familiar with Sprite (or UNIX, if that's what you're using) than I did -in chapter 2, just so you're on your toes. -So without further ado... -.xH 2 Transformation Rules -.LP -As you know, a file's name consists of two parts: a base name, which -gives some hint as to the contents of the file, and a suffix, which -usually indicates the format of the file. -Over the years, as -.UX -has developed, -naming conventions, with regard to suffixes, have also developed that have -become almost as incontrovertible as Law. E.g. a file ending in -.CW .c -is assumed to contain C source code; one with a -.CW .o -suffix is assumed to be a compiled, relocatable object file that may -be linked into any program; a file with a -.CW .ms -suffix is usually a text file to be processed by Troff with the \-ms -macro package, and so on. -One of the best aspects of both Make and PMake comes from their -understanding of how the suffix of a file pertains to its contents and -their ability to do things with a file based solely on its suffix. This -ability comes from something known as a transformation rule. A -transformation rule specifies how to change a file with one suffix -into a file with another suffix. -.LP -A transformation rule looks much like a dependency line, except the -target is made of two known suffixes stuck together. Suffixes are made -known to PMake by placing them as sources on a dependency line whose -target is the special target -.CW .SUFFIXES . -E.g. -.DS -\&.SUFFIXES : .o .c -\&.c.o : - $(CC) $(CFLAGS) -c $(.IMPSRC) -.DE -The creation script attached to the target is used to transform a file with -the first suffix (in this case, -.CW .c ) -into a file with the second suffix (here, -.CW .o ). -In addition, the target inherits whatever attributes have been applied -to the transformation rule. -The simple rule given above says that to transform a C source file -into an object file, you compile it using -.CW cc -with the -.CW \-c -flag. -This rule is taken straight from the system makefile. Many -transformation rules (and suffixes) are defined there, and I refer you -to it for more examples (type -.CW "pmake -h" '' `` -to find out where it is). -.LP -There are several things to note about the transformation rule given -above: -.RS -.IP 1) -The -.CW .IMPSRC -variable. -.Ix 0 def variable local .IMPSRC -.Ix 0 def .IMPSRC -This variable is set to the ``implied source'' (the file from which -the target is being created; the one with the first suffix), which, in this -case, is the .c file. -.IP 2) -The -.CW CFLAGS -variable. Almost all of the transformation rules in the system -makefile are set up using variables that you can alter in your -makefile to tailor the rule to your needs. In this case, if you want -all your C files to be compiled with the -.B \-g -flag, to provide information for -.CW dbx , -you would set the -.CW CFLAGS -variable to contain -.CW -g -.CW "CFLAGS = -g" '') (`` -and PMake would take care of the rest. -.RE -.LP -To give you a quick example, the makefile in 2.3.4 -.Rm 3 2.3.4 -could be changed to this: -.DS -OBJS = a.o b.o c.o -program : $(OBJS) - $(CC) -o $(.TARGET) $(.ALLSRC) -$(OBJS) : defs.h -.DE -The transformation rule I gave above takes the place of the 6 lines\** -.FS -This is also somewhat cleaner, I think, than the dynamic source -solution presented in 2.6 -.FE -.Rm 4 2.6 -.DS -a.o : a.c - cc -c a.c -b.o : b.c - cc -c b.c -c.o : c.c - cc -c c.c -.DE -.LP -Now you may be wondering about the dependency between the -.CW .o -and -.CW .c -files \*- it's not mentioned anywhere in the new makefile. This is -because it isn't needed: one of the effects of applying a -transformation rule is the target comes to depend on the implied -source. That's why it's called the implied -.I source . -.LP -For a more detailed example. Say you have a makefile like this: -.DS -a.out : a.o b.o - $(CC) $(.ALLSRC) -.DE -and a directory set up like this: -.DS -total 4 --rw-rw-r-- 1 deboor 34 Sep 7 00:43 Makefile --rw-rw-r-- 1 deboor 119 Oct 3 19:39 a.c --rw-rw-r-- 1 deboor 201 Sep 7 00:43 a.o --rw-rw-r-- 1 deboor 69 Sep 7 00:43 b.c -.DE -While just typing -.CW pmake '' `` -will do the right thing, it's much more informative to type -.CW "pmake -d s" ''. `` -This will show you what PMake is up to as it processes the files. In -this case, PMake prints the following: -.DS -Suff_FindDeps (a.out) - using existing source a.o - applying .o -> .out to "a.o" -Suff_FindDeps (a.o) - trying a.c...got it - applying .c -> .o to "a.c" -Suff_FindDeps (b.o) - trying b.c...got it - applying .c -> .o to "b.c" -Suff_FindDeps (a.c) - trying a.y...not there - trying a.l...not there - trying a.c,v...not there - trying a.y,v...not there - trying a.l,v...not there -Suff_FindDeps (b.c) - trying b.y...not there - trying b.l...not there - trying b.c,v...not there - trying b.y,v...not there - trying b.l,v...not there ---- a.o --- -cc -c a.c ---- b.o --- -cc -c b.c ---- a.out --- -cc a.o b.o -.DE -.LP -.CW Suff_FindDeps -is the name of a function in PMake that is called to check for implied -sources for a target using transformation rules. -The transformations it tries are, naturally -enough, limited to the ones that have been defined (a transformation -may be defined multiple times, by the way, but only the most recent -one will be used). You will notice, however, that there is a definite -order to the suffixes that are tried. This order is set by the -relative positions of the suffixes on the -.CW .SUFFIXES -line \*- the earlier a suffix appears, the earlier it is checked as -the source of a transformation. Once a suffix has been defined, the -only way to change its position in the pecking order is to remove all -the suffixes (by having a -.CW .SUFFIXES -dependency line with no sources) and redefine them in the order you -want. (Previously-defined transformation rules will be automatically -redefined as the suffixes they involve are re-entered.) -.LP -Another way to affect the search order is to make the dependency -explicit. In the above example, -.CW a.out -depends on -.CW a.o -and -.CW b.o . -Since a transformation exists from -.CW .o -to -.CW .out , -PMake uses that, as indicated by the -.CW "using existing source a.o" '' `` -message. -.LP -The search for a transformation starts from the suffix of the target -and continues through all the defined transformations, in the order -dictated by the suffix ranking, until an existing file with the same -base (the target name minus the suffix and any leading directories) is -found. At that point, one or more transformation rules will have been -found to change the one existing file into the target. -.LP -For example, ignoring what's in the system makefile for now, say you -have a makefile like this: -.DS -\&.SUFFIXES : .out .o .c .y .l -\&.l.c : - lex $(.IMPSRC) - mv lex.yy.c $(.TARGET) -\&.y.c : - yacc $(.IMPSRC) - mv y.tab.c $(.TARGET) -\&.c.o : - cc -c $(.IMPSRC) -\&.o.out : - cc -o $(.TARGET) $(.IMPSRC) -.DE -and the single file -.CW jive.l . -If you were to type -.CW "pmake -rd ms jive.out" ,'' `` -you would get the following output for -.CW jive.out : -.DS -Suff_FindDeps (jive.out) - trying jive.o...not there - trying jive.c...not there - trying jive.y...not there - trying jive.l...got it - applying .l -> .c to "jive.l" - applying .c -> .o to "jive.c" - applying .o -> .out to "jive.o" -.DE -and this is why: PMake starts with the target -.CW jive.out , -figures out its suffix -.CW .out ) ( -and looks for things it can transform to a -.CW .out -file. In this case, it only finds -.CW .o , -so it looks for the file -.CW jive.o . -It fails to find it, so it looks for transformations into a -.CW .o -file. Again it has only one choice: -.CW .c . -So it looks for -.CW jive.c -and, as you know, fails to find it. At this point it has two choices: -it can create the -.CW .c -file from either a -.CW .y -file or a -.CW .l -file. Since -.CW .y -came first on the -.CW .SUFFIXES -line, it checks for -.CW jive.y -first, but can't find it, so it looks for -.CW jive.l -and, lo and behold, there it is. -At this point, it has defined a transformation path as follows: -.CW .l -\(-> -.CW .c -\(-> -.CW .o -\(-> -.CW .out -and applies the transformation rules accordingly. For completeness, -and to give you a better idea of what PMake actually did with this -three-step transformation, this is what PMake printed for the rest of -the process: -.DS -Suff_FindDeps (jive.o) - using existing source jive.c - applying .c -> .o to "jive.c" -Suff_FindDeps (jive.c) - using existing source jive.l - applying .l -> .c to "jive.l" -Suff_FindDeps (jive.l) -Examining jive.l...modified 17:16:01 Oct 4, 1987...up-to-date -Examining jive.c...non-existent...out-of-date ---- jive.c --- -lex jive.l -\&.\|.\|. meaningless lex output deleted .\|.\|. -mv lex.yy.c jive.c -Examining jive.o...non-existent...out-of-date ---- jive.o --- -cc -c jive.c -Examining jive.out...non-existent...out-of-date ---- jive.out --- -cc -o jive.out jive.o -.DE -.LP -One final question remains: what does PMake do with targets that have -no known suffix? PMake simply pretends it actually has a known suffix -and searches for transformations accordingly. -The suffix it chooses is the source for the -.CW .NULL -.Ix 0 ref .NULL -target mentioned later. In the system makefile, -.CW .out -is chosen as the ``null suffix'' -.Ix 0 def suffix null -.Ix 0 def "null suffix" -because most people use PMake to create programs. You are, however, -free and welcome to change it to a suffix of your own choosing. -The null suffix is ignored, however, when PMake is in compatibility -mode (see chapter 4). -.xH 2 Including Other Makefiles -.Ix 0 def makefile inclusion -.Rd 2 -.LP -Just as for programs, it is often useful to extract certain parts of a -makefile into another file and just include it in other makefiles -somehow. Many compilers allow you say something like -.DS -#include "defs.h" -.DE -to include the contents of -.CW defs.h -in the source file. PMake allows you to do the same thing for -makefiles, with the added ability to use variables in the filenames. -An include directive in a makefile looks either like this: -.DS -#include <file> -.DE -or this -.DS -#include "file" -.DE -The difference between the two is where PMake searches for the file: -the first way, PMake will look for -the file only in the system makefile directory (or directories) -(to find out what that directory is, give PMake the -.B \-h -flag). -.Ix 0 ref flags -h -The system makefile directory search path can be overridden via the -.B \-m -option. -.Ix 0 ref flags -m -For files in double-quotes, the search is more complex: -.RS -.IP 1) -The directory of the makefile that's including the file. -.IP 2) -The current directory (the one in which you invoked PMake). -.IP 3) -The directories given by you using -.B \-I -flags, in the order in which you gave them. -.IP 4) -Directories given by -.CW .PATH -dependency lines (see chapter 4). -.IP 5) -The system makefile directory. -.RE -.LP -in that order. -.LP -You are free to use PMake variables in the filename\*-PMake will -expand them before searching for the file. You must specify the -searching method with either angle brackets or double-quotes -.I outside -of a variable expansion. I.e. the following -.DS -SYSTEM = <command.mk> - -#include $(SYSTEM) -.DE -won't work. -.xH 2 Saving Commands -.LP -.Ix 0 def ... -There may come a time when you will want to save certain commands to -be executed when everything else is done. For instance: you're -making several different libraries at one time and you want to create the -members in parallel. Problem is, -.CW ranlib -is another one of those programs that can't be run more than once in -the same directory at the same time (each one creates a file called -.CW __.SYMDEF -into which it stuffs information for the linker to use. Two of them -running at once will overwrite each other's file and the result will -be garbage for both parties). You might want a way to save the ranlib -commands til the end so they can be run one after the other, thus -keeping them from trashing each other's file. PMake allows you to do -this by inserting an ellipsis (``.\|.\|.'') as a command between -commands to be run at once and those to be run later. -.LP -So for the -.CW ranlib -case above, you might do this: -.Rd 5 -.DS -lib1.a : $(LIB1OBJS) - rm -f $(.TARGET) - ar cr $(.TARGET) $(.ALLSRC) - ... - ranlib $(.TARGET) - -lib2.a : $(LIB2OBJS) - rm -f $(.TARGET) - ar cr $(.TARGET) $(.ALLSRC) - ... - ranlib $(.TARGET) -.DE -.Ix 0 ref variable local .TARGET -.Ix 0 ref variable local .ALLSRC -This would save both -.DS -ranlib $(.TARGET) -.DE -commands until the end, when they would run one after the other -(using the correct value for the -.CW .TARGET -variable, of course). -.LP -Commands saved in this manner are only executed if PMake manages to -re-create everything without an error. -.xH 2 Target Attributes -.LP -PMake allows you to give attributes to targets by means of special -sources. Like everything else PMake uses, these sources begin with a -period and are made up of all upper-case letters. There are various -reasons for using them, and I will try to give examples for most of -them. Others you'll have to find uses for yourself. Think of it as ``an -exercise for the reader.'' By placing one (or more) of these as a source on a -dependency line, you are ``marking the target(s) with that -attribute.'' That's just the way I phrase it, so you know. -.LP -Any attributes given as sources for a transformation rule are applied -to the target of the transformation rule when the rule is applied. -.Ix 0 def attributes -.Ix 0 ref source -.Ix 0 ref target -.nr pw 12 -.IP .DONTCARE \n(pw -.Ix 0 def attributes .DONTCARE -.Ix 0 def .DONTCARE -If a target is marked with this attribute and PMake can't figure out -how to create it, it will ignore this fact and assume the file isn't -really needed or actually exists and PMake just can't find it. This may prove -wrong, but the error will be noted later on, not when PMake tries to create -the target so marked. This attribute also prevents PMake from -attempting to touch the target if it is given the -.B \-t -flag. -.Ix 0 ref flags -t -.IP .EXEC \n(pw -.Ix 0 def attributes .EXEC -.Ix 0 def .EXEC -This attribute causes its shell script to be executed while having no -effect on targets that depend on it. This makes the target into a sort -of subroutine. An example. Say you have some LISP files that need to -be compiled and loaded into a LISP process. To do this, you echo LISP -commands into a file and execute a LISP with this file as its input -when everything's done. Say also that you have to load other files -from another system before you can compile your files and further, -that you don't want to go through the loading and dumping unless one -of -.I your -files has changed. Your makefile might look a little bit -like this (remember, this is an educational example, and don't worry -about the -.CW COMPILE -rule, all will soon become clear, grasshopper): -.DS -system : init a.fasl b.fasl c.fasl - for i in $(.ALLSRC); - do - echo -n '(load "' >> input - echo -n ${i} >> input - echo '")' >> input - done - echo '(dump "$(.TARGET)")' >> input - lisp < input - -a.fasl : a.l init COMPILE -b.fasl : b.l init COMPILE -c.fasl : c.l init COMPILE -COMPILE : .USE - echo '(compile "$(.ALLSRC)")' >> input -init : .EXEC - echo '(load-system)' > input -.DE -.Ix 0 ref .USE -.Ix 0 ref attributes .USE -.Ix 0 ref variable local .ALLSRC -.IP "\&" -.CW .EXEC -sources, don't appear in the local variables of targets that depend on -them (nor are they touched if PMake is given the -.B \-t -flag). -.Ix 0 ref flags -t -Note that all the rules, not just that for -.CW system , -include -.CW init -as a source. This is because none of the other targets can be made -until -.CW init -has been made, thus they depend on it. -.IP .EXPORT \n(pw -.Ix 0 def attributes .EXPORT -.Ix 0 def .EXPORT -This is used to mark those targets whose creation should be sent to -another machine if at all possible. This may be used by some -exportation schemes if the exportation is expensive. You should ask -your system administrator if it is necessary. -.IP .EXPORTSAME \n(pw -.Ix 0 def attributes .EXPORTSAME -.Ix 0 def .EXPORTSAME -Tells the export system that the job should be exported to a machine -of the same architecture as the current one. Certain operations (e.g. -running text through -.CW nroff ) -can be performed the same on any architecture (CPU and -operating system type), while others (e.g. compiling a program with -.CW cc ) -must be performed on a machine with the same architecture. Not all -export systems will support this attribute. -.IP .IGNORE \n(pw -.Ix 0 def attributes .IGNORE -.Ix 0 def .IGNORE attribute -Giving a target the -.CW .IGNORE -attribute causes PMake to ignore errors from any of the target's commands, as -if they all had `\-' before them. -.IP .INVISIBLE \n(pw -.Ix 0 def attributes .INVISIBLE -.Ix 0 def .INVISIBLE -This allows you to specify one target as a source for another without -the one affecting the other's local variables. Useful if, say, you -have a makefile that creates two programs, one of which is used to -create the other, so it must exist before the other is created. You -could say -.DS -prog1 : $(PROG1OBJS) prog2 MAKEINSTALL -prog2 : $(PROG2OBJS) .INVISIBLE MAKEINSTALL -.DE -where -.CW MAKEINSTALL -is some complex .USE rule (see below) that depends on the -.Ix 0 ref .USE -.CW .ALLSRC -variable containing the right things. Without the -.CW .INVISIBLE -attribute for -.CW prog2 , -the -.CW MAKEINSTALL -rule couldn't be applied. This is not as useful as it should be, and -the semantics may change (or the whole thing go away) in the -not-too-distant future. -.IP .JOIN \n(pw -.Ix 0 def attributes .JOIN -.Ix 0 def .JOIN -This is another way to avoid performing some operations in parallel -while permitting everything else to be done so. Specifically it -forces the target's shell script to be executed only if one or more of the -sources was out-of-date. In addition, the target's name, -in both its -.CW .TARGET -variable and all the local variables of any target that depends on it, -is replaced by the value of its -.CW .ALLSRC -variable. -As an example, suppose you have a program that has four libraries that -compile in the same directory along with, and at the same time as, the -program. You again have the problem with -.CW ranlib -that I mentioned earlier, only this time it's more severe: you -can't just put the ranlib off to the end since the program -will need those libraries before it can be re-created. You can do -something like this: -.DS -program : $(OBJS) libraries - cc -o $(.TARGET) $(.ALLSRC) - -libraries : lib1.a lib2.a lib3.a lib4.a .JOIN - ranlib $(.OODATE) -.DE -.Ix 0 ref variable local .TARGET -.Ix 0 ref variable local .ALLSRC -.Ix 0 ref variable local .OODATE -.Ix 0 ref .TARGET -.Ix 0 ref .ALLSRC -.Ix 0 ref .OODATE -In this case, PMake will re-create the -.CW $(OBJS) -as necessary, along with -.CW lib1.a , -.CW lib2.a , -.CW lib3.a -and -.CW lib4.a . -It will then execute -.CW ranlib -on any library that was changed and set -.CW program 's -.CW .ALLSRC -variable to contain what's in -.CW $(OBJS) -followed by -.CW "lib1.a lib2.a lib3.a lib4.a" .'' `` -In case you're wondering, it's called -.CW .JOIN -because it joins together different threads of the ``input graph'' at -the target marked with the attribute. -Another aspect of the .JOIN attribute is it keeps the target from -being created if the -.B \-t -flag was given. -.Ix 0 ref flags -t -.IP .MAKE \n(pw -.Ix 0 def attributes .MAKE -.Ix 0 def .MAKE -The -.CW .MAKE -attribute marks its target as being a recursive invocation of PMake. -This forces PMake to execute the script associated with the target (if -it's out-of-date) even if you gave the -.B \-n -or -.B \-t -flag. By doing this, you can start at the top of a system and type -.DS -pmake -n -.DE -and have it descend the directory tree (if your makefiles are set up -correctly), printing what it would have executed if you hadn't -included the -.B \-n -flag. -.IP .NOEXPORT \n(pw -.Ix 0 def attributes .NOEXPORT -.Ix 0 def .NOEXPORT attribute -If possible, PMake will attempt to export the creation of all targets to -another machine (this depends on how PMake was configured). Sometimes, -the creation is so simple, it is pointless to send it to another -machine. If you give the target the -.CW .NOEXPORT -attribute, it will be run locally, even if you've given PMake the -.B "\-L 0" -flag. -.IP .NOTMAIN \n(pw -.Ix 0 def attributes .NOTMAIN -.Ix 0 def .NOTMAIN -Normally, if you do not specify a target to make in any other way, -PMake will take the first target on the first dependency line of a -makefile as the target to create. That target is known as the ``Main -Target'' and is labeled as such if you print the dependencies out -using the -.B \-p -flag. -.Ix 0 ref flags -p -Giving a target this attribute tells PMake that the target is -definitely -.I not -the Main Target. -This allows you to place targets in an included makefile and -have PMake create something else by default. -.IP .PRECIOUS \n(pw -.Ix 0 def attributes .PRECIOUS -.Ix 0 def .PRECIOUS attribute -When PMake is interrupted (you type control-C at the keyboard), it -will attempt to clean up after itself by removing any half-made -targets. If a target has the -.CW .PRECIOUS -attribute, however, PMake will leave it alone. An additional side -effect of the `::' operator is to mark the targets as -.CW .PRECIOUS . -.Ix 0 ref operator double-colon -.Ix 0 ref :: -.IP .SILENT \n(pw -.Ix 0 def attributes .SILENT -.Ix 0 def .SILENT attribute -Marking a target with this attribute keeps its commands from being -printed when they're executed, just as if they had an `@' in front of them. -.IP .USE \n(pw -.Ix 0 def attributes .USE -.Ix 0 def .USE -By giving a target this attribute, you turn it into PMake's equivalent -of a macro. When the target is used as a source for another target, -the other target acquires the commands, sources and attributes (except -.CW .USE ) -of the source. -If the target already has commands, the -.CW .USE -target's commands are added to the end. If more than one .USE-marked -source is given to a target, the rules are applied sequentially. -.IP "\&" \n(pw -The typical .USE rule (as I call them) will use the sources of the -target to which it is applied (as stored in the -.CW .ALLSRC -variable for the target) as its ``arguments,'' if you will. -For example, you probably noticed that the commands for creating -.CW lib1.a -and -.CW lib2.a -in the example in section 3.3 -.Rm 5 3.3 -were exactly the same. You can use the -.CW .USE -attribute to eliminate the repetition, like so: -.DS -lib1.a : $(LIB1OBJS) MAKELIB -lib2.a : $(LIB2OBJS) MAKELIB - -MAKELIB : .USE - rm -f $(.TARGET) - ar cr $(.TARGET) $(.ALLSRC) - ... - ranlib $(.TARGET) -.DE -.Ix 0 ref variable local .TARGET -.Ix 0 ref variable local .ALLSRC -.IP "\&" \n(pw -Several system makefiles (not to be confused with The System Makefile) -make use of these .USE rules to make your -life easier (they're in the default, system makefile directory...take a look). -Note that the .USE rule source itself -.CW MAKELIB ) ( -does not appear in any of the targets's local variables. -There is no limit to the number of times I could use the -.CW MAKELIB -rule. If there were more libraries, I could continue with -.CW "lib3.a : $(LIB3OBJS) MAKELIB" '' `` -and so on and so forth. -.xH 2 Special Targets -.LP -As there were in Make, so there are certain targets that have special -meaning to PMake. When you use one on a dependency line, it is the -only target that may appear on the left-hand-side of the operator. -.Ix 0 ref target -.Ix 0 ref operator -As for the attributes and variables, all the special targets -begin with a period and consist of upper-case letters only. -I won't describe them all in detail because some of them are rather -complex and I'll describe them in more detail than you'll want in -chapter 4. -The targets are as follows: -.nr pw 10 -.IP .BEGIN \n(pw -.Ix 0 def .BEGIN -Any commands attached to this target are executed before anything else -is done. You can use it for any initialization that needs doing. -.IP .DEFAULT \n(pw -.Ix 0 def .DEFAULT -This is sort of a .USE rule for any target (that was used only as a -source) that PMake can't figure out any other way to create. It's only -``sort of'' a .USE rule because only the shell script attached to the -.CW .DEFAULT -target is used. The -.CW .IMPSRC -variable of a target that inherits -.CW .DEFAULT 's -commands is set to the target's own name. -.Ix 0 ref .IMPSRC -.Ix 0 ref variable local .IMPSRC -.IP .END \n(pw -.Ix 0 def .END -This serves a function similar to -.CW .BEGIN , -in that commands attached to it are executed once everything has been -re-created (so long as no errors occurred). It also serves the extra -function of being a place on which PMake can hang commands you put off -to the end. Thus the script for this target will be executed before -any of the commands you save with the ``.\|.\|.''. -.Ix 0 ref ... -.IP .EXPORT \n(pw -The sources for this target are passed to the exportation system compiled -into PMake. Some systems will use these sources to configure -themselves. You should ask your system administrator about this. -.IP .IGNORE \n(pw -.Ix 0 def .IGNORE target -.Ix 0 ref .IGNORE attribute -.Ix 0 ref attributes .IGNORE -This target marks each of its sources with the -.CW .IGNORE -attribute. If you don't give it any sources, then it is like -giving the -.B \-i -flag when you invoke PMake \*- errors are ignored for all commands. -.Ix 0 ref flags -i -.IP .INCLUDES \n(pw -.Ix 0 def .INCLUDES target -.Ix 0 def variable global .INCLUDES -.Ix 0 def .INCLUDES variable -The sources for this target are taken to be suffixes that indicate a -file that can be included in a program source file. -The suffix must have already been declared with -.CW .SUFFIXES -(see below). -Any suffix so marked will have the directories on its search path -(see -.CW .PATH , -below) placed in the -.CW .INCLUDES -variable, each preceded by a -.B \-I -flag. This variable can then be used as an argument for the compiler -in the normal fashion. The -.CW .h -suffix is already marked in this way in the system makefile. -.Ix 0 ref makefile system -E.g. if you have -.DS -\&.SUFFIXES : .bitmap -\&.PATH.bitmap : /usr/local/X/lib/bitmaps -\&.INCLUDES : .bitmap -.DE -PMake will place -.CW "-I/usr/local/X/lib/bitmaps" '' `` -in the -.CW .INCLUDES -variable and you can then say -.DS -cc $(.INCLUDES) -c xprogram.c -.DE -(Note: the -.CW .INCLUDES -variable is not actually filled in until the entire makefile has been read.) -.IP .INTERRUPT \n(pw -.Ix 0 def .INTERRUPT -When PMake is interrupted, -it will execute the commands in the script for this target, if it -exists. -.IP .LIBS \n(pw -.Ix 0 def .LIBS target -.Ix 0 def .LIBS variable -.Ix 0 def variable global .LIBS -This does for libraries what -.CW .INCLUDES -does for include files, except the flag used is -.B \-L , -as required by those linkers that allow you to tell them where to find -libraries. The variable used is -.CW .LIBS . -Be forewarned that PMake may not have been compiled to do this if the -linker on your system doesn't accept the -.B \-L -flag, though the -.CW .LIBS -variable will always be defined once the makefile has been read. -.IP .MAIN \n(pw -.Ix 0 def .MAIN -If you didn't give a target (or targets) to create when you invoked -PMake, it will take the sources of this target as the targets to -create. -.IP .MAKEFLAGS \n(pw -.Ix 0 def .MAKEFLAGS target -This target provides a way for you to always specify flags for PMake -when the makefile is used. The flags are just as they would be typed -to the shell (except you can't use shell variables unless they're in -the environment), -though the -.B \-f -and -.B \-r -flags have no effect. -.IP .NULL \n(pw -.Ix 0 def .NULL -.Ix 0 ref suffix null -.Ix 0 ref "null suffix" -This allows you to specify what suffix PMake should pretend a file has -if, in fact, it has no known suffix. Only one suffix may be so -designated. The last source on the dependency line is the suffix that -is used (you should, however, only give one suffix.\|.\|.). -.IP .PATH \n(pw -.Ix 0 def .PATH -If you give sources for this target, PMake will take them as -directories in which to search for files it cannot find in the current -directory. If you give no sources, it will clear out any directories -added to the search path before. Since the effects of this all get -very complex, I'll leave it til chapter four to give you a complete -explanation. -.IP .PATH\fIsuffix\fP \n(pw -.Ix 0 ref .PATH -This does a similar thing to -.CW .PATH , -but it does it only for files with the given suffix. The suffix must -have been defined already. Look at -.B "Search Paths" -(section 4.1) -.Rm 6 4.1 -for more information. -.IP .PRECIOUS \n(pw -.Ix 0 def .PRECIOUS target -.Ix 0 ref .PRECIOUS attribute -.Ix 0 ref attributes .PRECIOUS -Similar to -.CW .IGNORE , -this gives the -.CW .PRECIOUS -attribute to each source on the dependency line, unless there are no -sources, in which case the -.CW .PRECIOUS -attribute is given to every target in the file. -.IP .RECURSIVE \n(pw -.Ix 0 def .RECURSIVE -.Ix 0 ref attributes .MAKE -.Ix 0 ref .MAKE -This target applies the -.CW .MAKE -attribute to all its sources. It does nothing if you don't give it any sources. -.IP .SHELL \n(pw -.Ix 0 def .SHELL -PMake is not constrained to only using the Bourne shell to execute -the commands you put in the makefile. You can tell it some other shell -to use with this target. Check out -.B "A Shell is a Shell is a Shell" -(section 4.4) -.Rm 7 4.4 -for more information. -.IP .SILENT \n(pw -.Ix 0 def .SILENT target -.Ix 0 ref .SILENT attribute -.Ix 0 ref attributes .SILENT -When you use -.CW .SILENT -as a target, it applies the -.CW .SILENT -attribute to each of its sources. If there are no sources on the -dependency line, then it is as if you gave PMake the -.B \-s -flag and no commands will be echoed. -.IP .SUFFIXES \n(pw -.Ix 0 def .SUFFIXES -This is used to give new file suffixes for PMake to handle. Each -source is a suffix PMake should recognize. If you give a -.CW .SUFFIXES -dependency line with no sources, PMake will forget about all the -suffixes it knew (this also nukes the null suffix). -For those targets that need to have suffixes defined, this is how you do it. -.LP -In addition to these targets, a line of the form -.DS -\fIattribute\fP : \fIsources\fP -.DE -applies the -.I attribute -to all the targets listed as -.I sources . -.xH 2 Modifying Variable Expansion -.LP -.Ix 0 def variable expansion modified -.Ix 0 ref variable expansion -.Ix 0 def variable modifiers -Variables need not always be expanded verbatim. PMake defines several -modifiers that may be applied to a variable's value before it is -expanded. You apply a modifier by placing it after the variable name -with a colon between the two, like so: -.DS -${\fIVARIABLE\fP:\fImodifier\fP} -.DE -Each modifier is a single character followed by something specific to -the modifier itself. -You may apply as many modifiers as you want \*- each one is applied to -the result of the previous and is separated from the previous by -another colon. -.LP -There are seven ways to modify a variable's expansion, most of which -come from the C shell variable modification characters: -.RS -.IP "M\fIpattern\fP" -.Ix 0 def :M -.Ix 0 def modifier match -This is used to select only those words (a word is a series of -characters that are neither spaces nor tabs) that match the given -.I pattern . -The pattern is a wildcard pattern like that used by the shell, where -.CW * -means 0 or more characters of any sort; -.CW ? -is any single character; -.CW [abcd] -matches any single character that is either `a', `b', `c' or `d' -(there may be any number of characters between the brackets); -.CW [0-9] -matches any single character that is between `0' and `9' (i.e. any -digit. This form may be freely mixed with the other bracket form), and -`\\' is used to escape any of the characters `*', `?', `[' or `:', -leaving them as regular characters to match themselves in a word. -For example, the system makefile -.CW <makedepend.mk> -uses -.CW "$(CFLAGS:M-[ID]*)" '' `` -to extract all the -.CW \-I -and -.CW \-D -flags that would be passed to the C compiler. This allows it to -properly locate include files and generate the correct dependencies. -.IP "N\fIpattern\fP" -.Ix 0 def :N -.Ix 0 def modifier nomatch -This is identical to -.CW :M -except it substitutes all words that don't match the given pattern. -.IP "S/\fIsearch-string\fP/\fIreplacement-string\fP/[g]" -.Ix 0 def :S -.Ix 0 def modifier substitute -Causes the first occurrence of -.I search-string -in the variable to be replaced by -.I replacement-string , -unless the -.CW g -flag is given at the end, in which case all occurrences of the string -are replaced. The substitution is performed on each word in the -variable in turn. If -.I search-string -begins with a -.CW ^ , -the string must match starting at the beginning of the word. If -.I search-string -ends with a -.CW $ , -the string must match to the end of the word (these two may be -combined to force an exact match). If a backslash precedes these two -characters, however, they lose their special meaning. Variable -expansion also occurs in the normal fashion inside both the -.I search-string -and the -.I replacement-string , -.B except -that a backslash is used to prevent the expansion of a -.CW $ , -not another dollar sign, as is usual. -Note that -.I search-string -is just a string, not a pattern, so none of the usual -regular-expression/wildcard characters have any special meaning save -.CW ^ -and -.CW $ . -In the replacement string, -the -.CW & -character is replaced by the -.I search-string -unless it is preceded by a backslash. -You are allowed to use any character except -colon or exclamation point to separate the two strings. This so-called -delimiter character may be placed in either string by preceding it -with a backslash. -.IP T -.Ix 0 def :T -.Ix 0 def modifier tail -Replaces each word in the variable expansion by its last -component (its ``tail''). For example, given -.DS -OBJS = ../lib/a.o b /usr/lib/libm.a -TAILS = $(OBJS:T) -.DE -the variable -.CW TAILS -would expand to -.CW "a.o b libm.a" .'' `` -.IP H -.Ix 0 def :H -.Ix 0 def modifier head -This is similar to -.CW :T , -except that every word is replaced by everything but the tail (the -``head''). Using the same definition of -.CW OBJS , -the string -.CW "$(OBJS:H)" '' `` -would expand to -.CW "../lib /usr/lib" .'' `` -Note that the final slash on the heads is removed and -anything without a head is replaced by the empty string. -.IP E -.Ix 0 def :E -.Ix 0 def modifier extension -.Ix 0 def modifier suffix -.Ix 0 ref suffix "variable modifier" -.CW :E -replaces each word by its suffix (``extension''). So -.CW "$(OBJS:E)" '' `` -would give you -.CW ".o .a" .'' `` -.IP R -.Ix 0 def :R -.Ix 0 def modifier root -.Ix 0 def modifier base -This replaces each word by everything but the suffix (the ``root'' of -the word). -.CW "$(OBJS:R)" '' `` -expands to `` -.CW "../lib/a b /usr/lib/libm" .'' -.RE -.LP -In addition, the System V style of substitution is also supported. -This looks like: -.DS -$(\fIVARIABLE\fP:\fIsearch-string\fP=\fIreplacement\fP) -.DE -It must be the last modifier in the chain. The search is anchored at -the end of each word, so only suffixes or whole words may be replaced. -.xH 2 More on Debugging -.xH 2 More Exercises -.IP (3.1) -You've got a set programs, each of which is created from its own -assembly-language source file (suffix -.CW .asm ). -Each program can be assembled into two versions, one with error-checking -code assembled in and one without. You could assemble them into files -with different suffixes -.CW .eobj \& ( -and -.CW .obj , -for instance), but your linker only understands files that end in -.CW .obj . -To top it all off, the final executables -.I must -have the suffix -.CW .exe . -How can you still use transformation rules to make your life easier -(Hint: assume the error-checking versions have -.CW ec -tacked onto their prefix)? -.IP (3.2) -Assume, for a moment or two, you want to perform a sort of -``indirection'' by placing the name of a variable into another one, -then you want to get the value of the first by expanding the second -somehow. Unfortunately, PMake doesn't allow constructs like -.DS I -$($(FOO)) -.DE -What do you do? Hint: no further variable expansion is performed after -modifiers are applied, thus if you cause a $ to occur in the -expansion, that's what will be in the result. -.xH 1 PMake for Gods -.LP -This chapter is devoted to those facilities in PMake that allow you to -do a great deal in a makefile with very little work, as well as do -some things you couldn't do in Make without a great deal of work (and -perhaps the use of other programs). The problem with these features, -is they must be handled with care, or you will end up with a mess. -.LP -Once more, I assume a greater familiarity with -.UX -or Sprite than I did in the previous two chapters. -.xH 2 Search Paths -.Rd 6 -.LP -PMake supports the dispersal of files into multiple directories by -allowing you to specify places to look for sources with -.CW .PATH -targets in the makefile. The directories you give as sources for these -targets make up a ``search path.'' Only those files used exclusively -as sources are actually sought on a search path, the assumption being -that anything listed as a target in the makefile can be created by the -makefile and thus should be in the current directory. -.LP -There are two types of search paths -in PMake: one is used for all types of files (including included -makefiles) and is specified with a plain -.CW .PATH -target (e.g. -.CW ".PATH : RCS" ''), `` -while the other is specific to a certain type of file, as indicated by -the file's suffix. A specific search path is indicated by immediately following -the -.CW .PATH -with the suffix of the file. For instance -.DS -\&.PATH.h : /sprite/lib/include /sprite/att/lib/include -.DE -would tell PMake to look in the directories -.CW /sprite/lib/include -and -.CW /sprite/att/lib/include -for any files whose suffix is -.CW .h . -.LP -The current directory is always consulted first to see if a file -exists. Only if it cannot be found there are the directories in the -specific search path, followed by those in the general search path, -consulted. -.LP -A search path is also used when expanding wildcard characters. If the -pattern has a recognizable suffix on it, the path for that suffix will -be used for the expansion. Otherwise the default search path is employed. -.LP -When a file is found in some directory other than the current one, all -local variables that would have contained the target's name -.CW .ALLSRC , ( -and -.CW .IMPSRC ) -will instead contain the path to the file, as found by PMake. -Thus if you have a file -.CW ../lib/mumble.c -and a makefile -.DS -\&.PATH.c : ../lib -mumble : mumble.c - $(CC) -o $(.TARGET) $(.ALLSRC) -.DE -the command executed to create -.CW mumble -would be -.CW "cc -o mumble ../lib/mumble.c" .'' `` -(As an aside, the command in this case isn't strictly necessary, since -it will be found using transformation rules if it isn't given. This is because -.CW .out -is the null suffix by default and a transformation exists from -.CW .c -to -.CW .out . -Just thought I'd throw that in.) -.LP -If a file exists in two directories on the same search path, the file -in the first directory on the path will be the one PMake uses. So if -you have a large system spread over many directories, it would behoove -you to follow a naming convention that avoids such conflicts. -.LP -Something you should know about the way search paths are implemented -is that each directory is read, and its contents cached, exactly once -\&\*- when it is first encountered \*- so any changes to the -directories while PMake is running will not be noted when searching -for implicit sources, nor will they be found when PMake attempts to -discover when the file was last modified, unless the file was created in the -current directory. While people have suggested that PMake should read -the directories each time, my experience suggests that the caching seldom -causes problems. In addition, not caching the directories slows things -down enormously because of PMake's attempts to apply transformation -rules through non-existent files \*- the number of extra file-system -searches is truly staggering, especially if many files without -suffixes are used and the null suffix isn't changed from -.CW .out . -.xH 2 Archives and Libraries -.LP -.UX -and Sprite allow you to merge files into an archive using the -.CW ar -command. Further, if the files are relocatable object files, you can -run -.CW ranlib -on the archive and get yourself a library that you can link into any -program you want. The main problem with archives is they double the -space you need to store the archived files, since there's one copy in -the archive and one copy out by itself. The problem with libraries is -you usually think of them as -.CW -lm -rather than -.CW /usr/lib/libm.a -and the linker thinks they're out-of-date if you so much as look at -them. -.LP -PMake solves the problem with archives by allowing you to tell it to -examine the files in the archives (so you can remove the individual -files without having to regenerate them later). To handle the problem -with libraries, PMake adds an additional way of deciding if a library -is out-of-date: -.IP \(bu 2 -If the table of contents is older than the library, or is missing, the -library is out-of-date. -.LP -A library is any target that looks like -.CW \-l name'' `` -or that ends in a suffix that was marked as a library using the -.CW .LIBS -target. -.CW .a -is so marked in the system makefile. -.LP -Members of an archive are specified as -``\fIarchive\fP(\fImember\fP[ \fImember\fP...])''. -Thus -.CW libdix.a(window.o) '' ``' -specifies the file -.CW window.o -in the archive -.CW libdix.a . -You may also use wildcards to specify the members of the archive. Just -remember that most the wildcard characters will only find -.I existing -files. -.LP -A file that is a member of an archive is treated specially. If the -file doesn't exist, but it is in the archive, the modification time -recorded in the archive is used for the file when determining if the -file is out-of-date. When figuring out how to make an archived member target -(not the file itself, but the file in the archive \*- the -\fIarchive\fP(\fImember\fP) target), special care is -taken with the transformation rules, as follows: -.IP \(bu 2 -\&\fIarchive\fP(\fImember\fP) is made to depend on \fImember\fP. -.IP \(bu 2 -The transformation from the \fImember\fP's suffix to the -\fIarchive\fP's suffix is applied to the \fIarchive\fP(\fImember\fP) target. -.IP \(bu 2 -The \fIarchive\fP(\fImember\fP)'s -.CW .TARGET -variable is set to the name of the \fImember\fP if \fImember\fP is -actually a target, or the path to the member file if \fImember\fP is -only a source. -.IP \(bu 2 -The -.CW .ARCHIVE -variable for the \fIarchive\fP(\fImember\fP) target is set to the name -of the \fIarchive\fP. -.Ix 0 def variable local .ARCHIVE -.Ix 0 def .ARCHIVE -.IP \(bu 2 -The -.CW .MEMBER -variable is set to the actual string inside the parentheses. In most -cases, this will be the same as the -.CW .TARGET -variable. -.Ix 0 def variable local .MEMBER -.Ix 0 def .MEMBER -.IP \(bu 2 -The \fIarchive\fP(\fImember\fP)'s place in the local variables of the -targets that depend on it is taken by the value of its -.CW .TARGET -variable. -.LP -Thus, a program library could be created with the following makefile: -.DS -\&.o.a : - ... - rm -f $(.TARGET:T) -OBJS = obj1.o obj2.o obj3.o -libprog.a : libprog.a($(OBJS)) - ar cru $(.TARGET) $(.OODATE) - ranlib $(.TARGET) -.DE -This will cause the three object files to be compiled (if the -corresponding source files were modified after the object file or, if -that doesn't exist, the archived object file), the out-of-date ones -archived in -.CW libprog.a , -a table of contents placed in the archive and the newly-archived -object files to be removed. -.LP -All this is used in the -.CW makelib.mk -system makefile to create a single library with ease. This makefile -looks like this: -.DS -.SM -# -# Rules for making libraries. The object files that make up the library -# are removed once they are archived. -# -# To make several libraries in parallel, you should define the variable -# "many_libraries". This will serialize the invocations of ranlib. -# -# To use, do something like this: -# -# OBJECTS = <files in the library> -# -# fish.a: fish.a($(OBJECTS)) MAKELIB -# -# - -#ifndef _MAKELIB_MK -_MAKELIB_MK = - -#include <po.mk> - -\&.po.a .o.a : - ... - rm -f $(.MEMBER) - -ARFLAGS ?= crl - -# -# Re-archive the out-of-date members and recreate the library's table of -# contents using ranlib. If many_libraries is defined, put the ranlib -# off til the end so many libraries can be made at once. -# -MAKELIB : .USE .PRECIOUS - ar $(ARFLAGS) $(.TARGET) $(.OODATE) -#ifndef no_ranlib -# ifdef many_libraries - ... -# endif /* many_libraries */ - ranlib $(.TARGET) -#endif /* no_ranlib */ - -#endif /* _MAKELIB_MK */ -.DE -.xH 2 On the Condition... -.Rd 1 -.LP -Like the C compiler before it, PMake allows you to configure the makefile, -based on the current environment, using conditional statements. A -conditional looks like this: -.DS -#if \fIboolean expression\fP -\fIlines\fP -#elif \fIanother boolean expression\fP -\fImore lines\fP -#else -\fIstill more lines\fP -#endif -.DE -They may be nested to a maximum depth of 30 and may occur anywhere -(except in a comment, of course). The -.CW # '' `` -must the very first character on the line. -.LP -Each -.I "boolean expression" -is made up of terms that look like function calls, the standard C -boolean operators -.CW && , -.CW || , -and -.CW ! , -and the standard relational operators -.CW == , -.CW != , -.CW > , -.CW >= , -.CW < , -and -.CW <= , -with -.CW == -and -.CW != -being overloaded to allow string comparisons as well. -.CW && -represents logical AND; -.CW || -is logical OR and -.CW ! -is logical NOT. The arithmetic and string operators take precedence -over all three of these operators, while NOT takes precedence over -AND, which takes precedence over OR. This precedence may be -overridden with parentheses, and an expression may be parenthesized to -your heart's content. Each term looks like a call on one of four -functions: -.nr pw 9 -.Ix 0 def make -.Ix 0 def conditional make -.Ix 0 def if make -.IP make \n(pw -The syntax is -.CW make( \fItarget\fP\c -.CW ) -where -.I target -is a target in the makefile. This is true if the given target was -specified on the command line, or as the source for a -.CW .MAIN -target (note that the sources for -.CW .MAIN -are only used if no targets were given on the command line). -.IP defined \n(pw -.Ix 0 def defined -.Ix 0 def conditional defined -.Ix 0 def if defined -The syntax is -.CW defined( \fIvariable\fP\c -.CW ) -and is true if -.I variable -is defined. Certain variables are defined in the system makefile that -identify the system on which PMake is being run. -.IP exists \n(pw -.Ix 0 def exists -.Ix 0 def conditional exists -.Ix 0 def if exists -The syntax is -.CW exists( \fIfile\fP\c -.CW ) -and is true if the file can be found on the global search path -(i.e. that defined by -.CW .PATH -targets, not by -.CW .PATH \fIsuffix\fP -targets). -.IP empty \n(pw -.Ix 0 def empty -.Ix 0 def conditional empty -.Ix 0 def if empty -This syntax is much like the others, except the string inside the -parentheses is of the same form as you would put between parentheses -when expanding a variable, complete with modifiers and everything. The -function returns true if the resulting string is empty (NOTE: an undefined -variable in this context will cause at the very least a warning -message about a malformed conditional, and at the worst will cause the -process to stop once it has read the makefile. If you want to check -for a variable being defined or empty, use the expression -.CW !defined( \fIvar\fP\c `` -.CW ") || empty(" \fIvar\fP\c -.CW ) '' -as the definition of -.CW || -will prevent the -.CW empty() -from being evaluated and causing an error, if the variable is -undefined). This can be used to see if a variable contains a given -word, for example: -.DS -#if !empty(\fIvar\fP:M\fIword\fP) -.DE -.LP -The arithmetic and string operators may only be used to test the value -of a variable. The lefthand side must contain the variable expansion, -while the righthand side contains either a string, enclosed in -double-quotes, or a number. The standard C numeric conventions (except -for specifying an octal number) apply to both sides. E.g. -.DS -#if $(OS) == 4.3 - -#if $(MACHINE) == "sun3" - -#if $(LOAD_ADDR) < 0xc000 -.DE -are all valid conditionals. In addition, the numeric value of a -variable can be tested as a boolean as follows: -.DS -#if $(LOAD) -.DE -would see if -.CW LOAD -contains a non-zero value and -.DS -#if !$(LOAD) -.DE -would test if -.CW LOAD -contains a zero value. -.LP -In addition to the bare -.CW #if ,'' `` -there are other forms that apply one of the first two functions to each -term. They are as follows: -.DS - ifdef \fRdefined\fP - ifndef \fR!defined\fP - ifmake \fRmake\fP - ifnmake \fR!make\fP -.DE -There are also the ``else if'' forms: -.CW elif , -.CW elifdef , -.CW elifndef , -.CW elifmake , -and -.CW elifnmake . -.LP -For instance, if you wish to create two versions of a program, one of which -is optimized (the production version) and the other of which is for debugging -(has symbols for dbx), you have two choices: you can create two -makefiles, one of which uses the -.CW \-g -flag for the compilation, while the other uses the -.CW \-O -flag, or you can use another target (call it -.CW debug ) -to create the debug version. The construct below will take care of -this for you. I have also made it so defining the variable -.CW DEBUG -(say with -.CW "pmake -D DEBUG" ) -will also cause the debug version to be made. -.DS -#if defined(DEBUG) || make(debug) -CFLAGS += -g -#else -CFLAGS += -O -#endif -.DE -There are, of course, problems with this approach. The most glaring -annoyance is that if you want to go from making a debug version to -making a production version, you have to remove all the object files, -or you will get some optimized and some debug versions in the same -program. Another annoyance is you have to be careful not to make two -targets that ``conflict'' because of some conditionals in the -makefile. For instance -.DS -#if make(print) -FORMATTER = ditroff -Plaser_printer -#endif -#if make(draft) -FORMATTER = nroff -Pdot_matrix_printer -#endif -.DE -would wreak havoc if you tried -.CW "pmake draft print" '' `` -since you would use the same formatter for each target. As I said, -this all gets somewhat complicated. -.xH 2 A Shell is a Shell is a Shell -.Rd 7 -.LP -In normal operation, the Bourne Shell (better known as -.CW sh '') `` -is used to execute the commands to re-create targets. PMake also allows you -to specify a different shell for it to use when executing these -commands. There are several things PMake must know about the shell you -wish to use. These things are specified as the sources for the -.CW .SHELL -.Ix 0 ref .SHELL -.Ix 0 ref target .SHELL -target by keyword, as follows: -.IP "\fBpath=\fP\fIpath\fP" -PMake needs to know where the shell actually resides, so it can -execute it. If you specify this and nothing else, PMake will use the -last component of the path and look in its table of the shells it -knows and use the specification it finds, if any. Use this if you just -want to use a different version of the Bourne or C Shell (yes, PMake knows -how to use the C Shell too). -.IP "\fBname=\fP\fIname\fP" -This is the name by which the shell is to be known. It is a single -word and, if no other keywords are specified (other than -.B path ), -it is the name by which PMake attempts to find a specification for -it (as mentioned above). You can use this if you would just rather use -the C Shell than the Bourne Shell -.CW ".SHELL: name=csh" '' (`` -will do it). -.IP "\fBquiet=\fP\fIecho-off command\fP" -As mentioned before, PMake actually controls whether commands are -printed by introducing commands into the shell's input stream. This -keyword, and the next two, control what those commands are. The -.B quiet -keyword is the command used to turn echoing off. Once it is turned -off, echoing is expected to remain off until the echo-on command is given. -.IP "\fBecho=\fP\fIecho-on command\fP" -The command PMake should give to turn echoing back on again. -.IP "\fBfilter=\fP\fIprinted echo-off command\fP" -Many shells will echo the echo-off command when it is given. This -keyword tells PMake in what format the shell actually prints the -echo-off command. Wherever PMake sees this string in the shell's -output, it will delete it and any following whitespace, up to and -including the next newline. See the example at the end of this section -for more details. -.IP "\fBechoFlag=\fP\fIflag to turn echoing on\fP" -Unless a target has been marked -.CW .SILENT , -PMake wants to start the shell running with echoing on. To do this, it -passes this flag to the shell as one of its arguments. If either this -or the next flag begins with a `\-', the flags will be passed to the -shell as separate arguments. Otherwise, the two will be concatenated -(if they are used at the same time, of course). -.IP "\fBerrFlag=\fP\fIflag to turn error checking on\fP" -Likewise, unless a target is marked -.CW .IGNORE , -PMake wishes error-checking to be on from the very start. To this end, -it will pass this flag to the shell as an argument. The same rules for -an initial `\-' apply as for the -.B echoFlag . -.IP "\fBcheck=\fP\fIcommand to turn error checking on\fP" -Just as for echo-control, error-control is achieved by inserting -commands into the shell's input stream. This is the command to make -the shell check for errors. It also serves another purpose if the -shell doesn't have error-control as commands, but I'll get into that -in a minute. Again, once error checking has been turned on, it is -expected to remain on until it is turned off again. -.IP "\fBignore=\fP\fIcommand to turn error checking off\fP" -This is the command PMake uses to turn error checking off. It has -another use if the shell doesn't do error-control, but I'll tell you -about that.\|.\|.\|now. -.IP "\fBhasErrCtl=\fP\fIyes or no\fP" -This takes a value that is either -.B yes -or -.B no . -Now you might think that the existence of the -.B check -and -.B ignore -keywords would be enough to tell PMake if the shell can do -error-control, but you'd be wrong. If -.B hasErrCtl -is -.B yes , -PMake uses the check and ignore commands in a straight-forward manner. -If this is -.B no , -however, their use is rather different. In this case, the check -command is used as a template, in which the string -.B %s -is replaced by the command that's about to be executed, to produce a -command for the shell that will echo the command to be executed. The -ignore command is also used as a template, again with -.B %s -replaced by the command to be executed, to produce a command that will -execute the command to be executed and ignore any error it returns. -When these strings are used as templates, you must provide newline(s) -.CW \en '') (`` -in the appropriate place(s). -.LP -The strings that follow these keywords may be enclosed in single or -double quotes (the quotes will be stripped off) and may contain the -usual C backslash-characters (\en is newline, \er is return, \eb is -backspace, \e' escapes a single-quote inside single-quotes, \e" -escapes a double-quote inside double-quotes). Now for an example. -.LP -This is actually the contents of the -.CW <shx.mk> -system makefile, and causes PMake to use the Bourne Shell in such a -way that each command is printed as it is executed. That is, if more -than one command is given on a line, each will be printed separately. -Similarly, each time the body of a loop is executed, the commands -within that loop will be printed, etc. The specification runs like -this: -.DS -# -# This is a shell specification to have the Bourne shell echo -# the commands just before executing them, rather than when it reads -# them. Useful if you want to see how variables are being expanded, etc. -# -\&.SHELL : path=/bin/sh \e - quiet="set -" \e - echo="set -x" \e - filter="+ set - " \e - echoFlag=x \e - errFlag=e \e - hasErrCtl=yes \e - check="set -e" \e - ignore="set +e" -.DE -.LP -It tells PMake the following: -.Bp -The shell is located in the file -.CW /bin/sh . -It need not tell PMake that the name of the shell is -.CW sh -as PMake can figure that out for itself (it's the last component of -the path). -.Bp -The command to stop echoing is -.CW "set -" . -.Bp -The command to start echoing is -.CW "set -x" . -.Bp -When the echo off command is executed, the shell will print -.CW "+ set - " -(The `+' comes from using the -.CW \-x -flag (rather than the -.CW \-v -flag PMake usually uses)). PMake will remove all occurrences of this -string from the output, so you don't notice extra commands you didn't -put there. -.Bp -The flag the Bourne Shell will take to start echoing in this way is -the -.CW \-x -flag. The Bourne Shell will only take its flag arguments concatenated -as its first argument, so neither this nor the -.B errFlag -specification begins with a \-. -.Bp -The flag to use to turn error-checking on from the start is -.CW \-e . -.Bp -The shell can turn error-checking on and off, and the commands to do -so are -.CW "set +e" -and -.CW "set -e" , -respectively. -.LP -I should note that this specification is for Bourne Shells that are -not part of Berkeley -.UX , -as shells from Berkeley don't do error control. You can get a similar -effect, however, by changing the last three lines to be: -.DS - hasErrCtl=no \e - check="echo \e"+ %s\e"\en" \e - ignore="sh -c '%s || exit 0\en" -.DE -.LP -This will cause PMake to execute the two commands -.DS -echo "+ \fIcmd\fP" -sh -c '\fIcmd\fP || true' -.DE -for each command for which errors are to be ignored. (In case you are -wondering, the thing for -.CW ignore -tells the shell to execute another shell without error checking on and -always exit 0, since the -.B || -causes the -.CW "exit 0" -to be executed only if the first command exited non-zero, and if the -first command exited zero, the shell will also exit zero, since that's -the last command it executed). -.xH 2 Compatibility -.Ix 0 ref compatibility -.LP -There are three (well, 3 \(12) levels of backwards-compatibility built -into PMake. Most makefiles will need none at all. Some may need a -little bit of work to operate correctly when run in parallel. Each -level encompasses the previous levels (e.g. -.B \-B -(one shell per command) implies -.B \-V ) -The three levels are described in the following three sections. -.xH 3 DEFCON 3 \*- Variable Expansion -.Ix 0 ref compatibility -.LP -As noted before, PMake will not expand a variable unless it knows of a -value for it. This can cause problems for makefiles that expect to -leave variables undefined except in special circumstances (e.g. if -more flags need to be passed to the C compiler or the output from a -text processor should be sent to a different printer). If the -variables are enclosed in curly braces -.CW ${PRINTER} ''), (`` -the shell will let them pass. If they are enclosed in parentheses, -however, the shell will declare a syntax error and the make will come -to a grinding halt. -.LP -You have two choices: change the makefile to define the variables -(their values can be overridden on the command line, since that's -where they would have been set if you used Make, anyway) or always give the -.B \-V -flag (this can be done with the -.CW .MAKEFLAGS -target, if you want). -.xH 3 DEFCON 2 \*- The Number of the Beast -.Ix 0 ref compatibility -.LP -Then there are the makefiles that expect certain commands, such as -changing to a different directory, to not affect other commands in a -target's creation script. You can solve this is either by going -back to executing one shell per command (which is what the -.B \-B -flag forces PMake to do), which slows the process down a good bit and -requires you to use semicolons and escaped newlines for shell constructs, or -by changing the makefile to execute the offending command(s) in a subshell -(by placing the line inside parentheses), like so: -.DS -install :: .MAKE - (cd src; $(.PMAKE) install) - (cd lib; $(.PMAKE) install) - (cd man; $(.PMAKE) install) -.DE -.Ix 0 ref operator double-colon -.Ix 0 ref variable global .PMAKE -.Ix 0 ref .PMAKE -.Ix 0 ref .MAKE -.Ix 0 ref attribute .MAKE -This will always execute the three makes (even if the -.B \-n -flag was given) because of the combination of the ``::'' operator and -the -.CW .MAKE -attribute. Each command will change to the proper directory to perform -the install, leaving the main shell in the directory in which it started. -.xH 3 "DEFCON 1 \*- Imitation is the Not the Highest Form of Flattery" -.Ix 0 ref compatibility -.LP -The final category of makefile is the one where every command requires -input, the dependencies are incompletely specified, or you simply -cannot create more than one target at a time, as mentioned earlier. In -addition, you may not have the time or desire to upgrade the makefile -to run smoothly with PMake. If you are the conservative sort, this is -the compatibility mode for you. It is entered either by giving PMake -the -.B \-M -flag (for Make), or by executing PMake as -.CW make .'' `` -In either case, PMake performs things exactly like Make (while still -supporting most of the nice new features PMake provides). This -includes: -.IP \(bu 2 -No parallel execution. -.IP \(bu 2 -Targets are made in the exact order specified by the makefile. The -sources for each target are made in strict left-to-right order, etc. -.IP \(bu 2 -A single Bourne shell is used to execute each command, thus the -shell's -.CW $$ -variable is useless, changing directories doesn't work across command -lines, etc. -.IP \(bu 2 -If no special characters exist in a command line, PMake will break the -command into words itself and execute the command directly, without -executing a shell first. The characters that cause PMake to execute a -shell are: -.CW # , -.CW = , -.CW | , -.CW ^ , -.CW ( , -.CW ) , -.CW { , -.CW } , -.CW ; , -.CW & , -.CW < , -.CW > , -.CW * , -.CW ? , -.CW [ , -.CW ] , -.CW : , -.CW $ , -.CW ` , -and -.CW \e . -You should notice that these are all the characters that are given -special meaning by the shell (except -.CW ' -and -.CW " , -which PMake deals with all by its lonesome). -.IP \(bu 2 -The use of the null suffix is turned off. -.Ix 0 ref "null suffix" -.Ix 0 ref suffix null -.xH 2 The Way Things Work -.LP -When PMake reads the makefile, it parses sources and targets into -nodes in a graph. The graph is directed only in the sense that PMake -knows which way is up. Each node contains not only links to all its -parents and children (the nodes that depend on it and those on which -it depends, respectively), but also a count of the number of its -children that have already been processed. -.LP -The most important thing to know about how PMake uses this graph is -that the traversal is breadth-first and occurs in two passes. -.LP -After PMake has parsed the makefile, it begins with the nodes the user -has told it to make (either on the command line, or via a -.CW .MAIN -target, or by the target being the first in the file not labeled with -the -.CW .NOTMAIN -attribute) placed in a queue. It continues to take the node off the -front of the queue, mark it as something that needs to be made, pass -the node to -.CW Suff_FindDeps -(mentioned earlier) to find any implicit sources for the node, and -place all the node's children that have yet to be marked at the end of -the queue. If any of the children is a -.CW .USE -rule, its attributes are applied to the parent, then its commands are -appended to the parent's list of commands and its children are linked -to its parent. The parent's unmade children counter is then decremented -(since the -.CW .USE -node has been processed). You will note that this allows a -.CW .USE -node to have children that are -.CW .USE -nodes and the rules will be applied in sequence. -If the node has no children, it is placed at the end of -another queue to be examined in the second pass. This process -continues until the first queue is empty. -.LP -At this point, all the leaves of the graph are in the examination -queue. PMake removes the node at the head of the queue and sees if it -is out-of-date. If it is, it is passed to a function that will execute -the commands for the node asynchronously. When the commands have -completed, all the node's parents have their unmade children counter -decremented and, if the counter is then 0, they are placed on the -examination queue. Likewise, if the node is up-to-date. Only those -parents that were marked on the downward pass are processed in this -way. Thus PMake traverses the graph back up to the nodes the user -instructed it to create. When the examination queue is empty and no -shells are running to create a target, PMake is finished. -.LP -Once all targets have been processed, PMake executes the commands -attached to the -.CW .END -target, either explicitly or through the use of an ellipsis in a shell -script. If there were no errors during the entire process but there -are still some targets unmade (PMake keeps a running count of how many -targets are left to be made), there is a cycle in the graph. PMake does -a depth-first traversal of the graph to find all the targets that -weren't made and prints them out one by one. -.xH 1 Answers to Exercises -.IP (3.1) -This is something of a trick question, for which I apologize. The -trick comes from the UNIX definition of a suffix, which PMake doesn't -necessarily share. You will have noticed that all the suffixes used in -this tutorial (and in UNIX in general) begin with a period -.CW .ms , ( -.CW .c , -etc.). Now, PMake's idea of a suffix is more like English's: it's the -characters at the end of a word. With this in mind, one possible -.Ix 0 def suffix -solution to this problem goes as follows: -.DS I -\&.SUFFIXES : ec.exe .exe ec.obj .obj .asm -ec.objec.exe .obj.exe : - link -o $(.TARGET) $(.IMPSRC) -\&.asmec.obj : - asm -o $(.TARGET) -DDO_ERROR_CHECKING $(.IMPSRC) -\&.asm.obj : - asm -o $(.TARGET) $(.IMPSRC) -.DE -.IP (3.2) -The trick to this one lies in the ``:='' variable-assignment operator -and the ``:S'' variable-expansion modifier. -.Ix 0 ref variable assignment expanded -.Ix 0 ref variable expansion modified -.Ix 0 ref modifier substitute -.Ix 0 ref :S -.Ix 0 ref := -Basically what you want is to take the pointer variable, so to speak, -and transform it into an invocation of the variable at which it -points. You might try something like -.DS I -$(PTR:S/^/\e$(/:S/$/)) -.DE -which places -.CW $( '' `` -at the front of the variable name and -.CW ) '' `` -at the end, thus transforming -.CW VAR ,'' `` -for example, into -.CW $(VAR) ,'' `` -which is just what we want. Unfortunately (as you know if you've tried -it), since, as it says in the hint, PMake does no further substitution -on the result of a modified expansion, that's \fIall\fP you get. The -solution is to make use of ``:='' to place that string into yet -another variable, then invoke the other variable directly: -.DS I -*PTR := $(PTR:S/^/\e$(/:S/$/)/) -.DE -You can then use -.CW $(*PTR) '' `` -to your heart's content. -.de Gp -.XP -\&\fB\\$1:\fP -.. -.xH 1 Glossary of Jargon -.Gp "attribute" -A property given to a target that causes PMake to treat it differently. -.Gp "command script" -The lines immediately following a dependency line that specify -commands to execute to create each of the targets on the dependency -line. Each line in the command script must begin with a tab. -.Gp "command-line variable" -A variable defined in an argument when PMake is first executed. -Overrides all assignments to the same variable name in the makefile. -.Gp "conditional" -A construct much like that used in C that allows a makefile to be -configured on the fly based on the local environment, or on what is being -made by that invocation of PMake. -.Gp "creation script" -Commands used to create a target. See ``command script.'' -.Gp "dependency" -The relationship between a source and a target. This comes in three -flavors, as indicated by the operator between the target and the -source. `:' gives a straight time-wise dependency (if the target is -older than the source, the target is out-of-date), while `!' provides -simply an ordering and always considers the target out-of-date. `::' -is much like `:', save it creates multiple instances of a target each -of which depends on its own list of sources. -.Gp "dynamic source" -This refers to a source that has a local variable invocation in it. It -allows a single dependency line to specify a different source for each -target on the line. -.Gp "global variable" -Any variable defined in a makefile. Takes precedence over variables -defined in the environment, but not over command-line or local variables. -.Gp "input graph" -What PMake constructs from a makefile. Consists of nodes made of the -targets in the makefile, and the links between them (the -dependencies). The links are directed (from source to target) and -there may not be any cycles (loops) in the graph. -.Gp "local variable" -A variable defined by PMake visible only in a target's shell script. -There are seven local variables, not all of which are defined for -every target: -.CW .TARGET , -.CW .ALLSRC , -.CW .OODATE , -.CW .PREFIX , -.CW .IMPSRC , -.CW .ARCHIVE , -and -.CW .MEMBER . -.CW .TARGET , -.CW .PREFIX , -.CW .ARCHIVE , -and -.CW .MEMBER -may be used on dependency lines to create ``dynamic sources.'' -.Gp "makefile" -A file that describes how a system is built. If you don't know what it -is after reading this tutorial.\|.\|.\|. -.Gp "modifier" -A letter, following a colon, used to alter how a variable is expanded. -It has no effect on the variable itself. -.Gp "operator" -What separates a source from a target (on a dependency line) and specifies -the relationship between the two. There are three: -.CW : ', ` -.CW :: ', ` -and -.CW ! '. ` -.Gp "search path" -A list of directories in which a file should be sought. PMake's view -of the contents of directories in a search path does not change once -the makefile has been read. A file is sought on a search path only if -it is exclusively a source. -.Gp "shell" -A program to which commands are passed in order to create targets. -.Gp "source" -Anything to the right of an operator on a dependency line. Targets on -the dependency line are usually created from the sources. -.Gp "special target" -A target that causes PMake to do special things when it's encountered. -.Gp "suffix" -The tail end of a file name. Usually begins with a period, -.CW .c -or -.CW .ms , -e.g. -.Gp "target" -A word to the left of the operator on a dependency line. More -generally, any file that PMake might create. A file may be (and often -is) both a target and a source (what it is depends on how PMake is -looking at it at the time \*- sort of like the wave/particle duality -of light, you know). -.Gp "transformation rule" -A special construct in a makefile that specifies how to create a file -of one type from a file of another, as indicated by their suffixes. -.Gp "variable expansion" -The process of substituting the value of a variable for a reference to -it. Expansion may be altered by means of modifiers. -.Gp "variable" -A place in which to store text that may be retrieved later. Also used -to define the local environment. Conditionals exist that test whether -a variable is defined or not. -.bp -.\" Output table of contents last, with an entry for the index, making -.\" sure to save and restore the last real page number for the index... -.nr @n \n(PN+1 -.\" We are not generating an index -.\" .XS \n(@n -.\" Index -.\" .XE -.nr %% \n% -.PX -.nr % \n(%% diff --git a/20120831/README b/20120831/README deleted file mode 100644 index fb688a3..0000000 --- a/20120831/README +++ /dev/null @@ -1,47 +0,0 @@ - bmake - -This directory contains a port of the BSD make tool (from NetBSD) -I have run it on SunOS,Solaris,HP-UX,AIX,IRIX,FreeBSD and Linux. - -Version 3 was re-worked from scratch to better facilitate -importing newer make(1) versions from NetBSD. The original code base -was NetBSD-1.0, so version 3 was built by doing a fresh import of the -NetBSD-1.0 usr.bin/make, adding the autoconf and other portability -patches to sync it with bmake v2, and then NetBSD's make -of Feb 20, 2000 was imported and conflicts dealt with. -NetBSD's make was again imported on June 6 and December 15, 2000. - -In 2003 bmake switched to a date based version (first was 20030714) -which generally represents the date it was last merged with NetBSD's -make. Since then, NetBSD's make is imported within a week of any -interesting changes, so that bmake tracks it very closely. - -Building: - -The prefered way to bootstrap bmake is: - -./bmake/boot-strap - -there are a number of args - most of which get passed to configure, -eg. - -./bmake/boot-strap --prefix=/opt - -see the boot-strap script for details. - -To make much use of bmake you will need the bsd.*.mk macros or my -portable *.mk macros. See -http://www.crufty.net/ftp/pub/sjg/mk.tar.gz -which will be links to the latest versions. - -On a non-BSD system, you would want to unpack mk[-YYYYmmdd].tar.gz in -the same directory as bmake (so ./mk and ./bmake exist), and -./bmake/boot-strap will do the rest. - -If you want to do it all by hand then read boot-strap first to get the -idea. - -Even if you have an earlier version of bmake installed, use boot-strap -to ensure that all goes well. - ---sjg diff --git a/20120831/aclocal.m4 b/20120831/aclocal.m4 deleted file mode 100644 index 2adafba..0000000 --- a/20120831/aclocal.m4 +++ /dev/null @@ -1,77 +0,0 @@ -dnl RCSid: -dnl $Id: aclocal.m4,v 1.5 2003/03/06 21:21:30 sjg Exp $ -dnl - -dnl -dnl AC_CHECK_HEADER_HAS(HEADER, PATTERN, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])) - -AC_DEFUN(AC_CHECK_HEADER_HAS, -[dnl first check if header exists and if so, see if it contains PATTERN -ac_has_hdr=`echo "ac_cv_header_$1" | sed 'y%./+-%__p_%'` -ac_has_it=`echo "ac_cv_header_$1"_$2 | sed 'y%./+-%__p_%'` -if eval "test \"`echo x'$'$ac_has_hdr`\" = x"; then - AC_CHECK_HEADER($1) -fi -if eval "test \"`echo '$'$ac_has_hdr`\" = yes"; then - ac_x=HAVE_`echo "$1" | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` - AC_DEFINE_UNQUOTED($ac_x) - AC_MSG_CHECKING([if $1 has $2]) - AC_CACHE_VAL($ac_has_it, - [eval $ac_has_it=no - AC_EGREP_HEADER($2, $1, eval "$ac_has_it=yes")]) - - if eval "test \"`echo '$'$ac_has_it`\" = yes"; then - AC_MSG_RESULT(yes) - ac_x=HAVE_`echo "$1"_$2 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` - AC_DEFINE_UNQUOTED($ac_x) - ifelse([$3], , :, [$3]) - else - AC_MSG_RESULT(no) - ifelse([$4], , , [$4 -])dnl - fi -fi -]) - -dnl AC_EGREP(PATTERN, FILE, ACTION-IF-FOUND [, -dnl ACTION-IF-NOT-FOUND]) -AC_DEFUN(AC_EGREP, -[ -dnl Prevent m4 from eating character classes: -changequote(, )dnl -if egrep "$1" $2 >/dev/null 2>&1; then -changequote([, ])dnl - ifelse([$3], , :, [$3]) -ifelse([$4], , , [else - $4 -])dnl -fi -]) - -dnl -dnl Test for __attribute__ -dnl - -AC_DEFUN(AC_C___ATTRIBUTE__, [ -AC_MSG_CHECKING(for __attribute__) -AC_CACHE_VAL(ac_cv___attribute__, [ -AC_TRY_COMPILE([ -#include <stdlib.h> -], -[ -static void foo(void) __attribute__ ((noreturn)); - -static void -foo(void) -{ - exit(1); -} -], -ac_cv___attribute__=yes, -ac_cv___attribute__=no)]) -if test "$ac_cv___attribute__" = "yes"; then - AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__]) -fi -AC_MSG_RESULT($ac_cv___attribute__) -]) - diff --git a/20120831/arch.c b/20120831/arch.c deleted file mode 100644 index 943f41e..0000000 --- a/20120831/arch.c +++ /dev/null @@ -1,1403 +0,0 @@ -/* $NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94"; -#else -__RCSID("$NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * arch.c -- - * Functions to manipulate libraries, archives and their members. - * - * Once again, cacheing/hashing comes into play in the manipulation - * of archives. The first time an archive is referenced, all of its members' - * headers are read and hashed and the archive closed again. All hashed - * archives are kept on a list which is searched each time an archive member - * is referenced. - * - * The interface to this module is: - * Arch_ParseArchive Given an archive specification, return a list - * of GNode's, one for each member in the spec. - * FAILURE is returned if the specification is - * invalid for some reason. - * - * Arch_Touch Alter the modification time of the archive - * member described by the given node to be - * the current time. - * - * Arch_TouchLib Update the modification time of the library - * described by the given node. This is special - * because it also updates the modification time - * of the library's table of contents. - * - * Arch_MTime Find the modification time of a member of - * an archive *in the archive*. The time is also - * placed in the member's GNode. Returns the - * modification time. - * - * Arch_MemTime Find the modification time of a member of - * an archive. Called when the member doesn't - * already exist. Looks in the archive for the - * modification time. Returns the modification - * time. - * - * Arch_FindLib Search for a library along a path. The - * library name in the GNode should be in - * -l<name> format. - * - * Arch_LibOODate Special function to decide if a library node - * is out-of-date. - * - * Arch_Init Initialize this module. - * - * Arch_End Cleanup this module. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/param.h> -#include <ctype.h> -#ifdef HAVE_AR_H -#include <ar.h> -#else -struct ar_hdr { - char ar_name[16]; /* name */ - char ar_date[12]; /* modification time */ - char ar_uid[6]; /* user id */ - char ar_gid[6]; /* group id */ - char ar_mode[8]; /* octal file permissions */ - char ar_size[10]; /* size in bytes */ -#ifndef ARFMAG -#define ARFMAG "`\n" -#endif - char ar_fmag[2]; /* consistency check */ -}; -#endif -#if defined(HAVE_RANLIB_H) && !(defined(__ELF__) || defined(NO_RANLIB)) -#include <ranlib.h> -#endif -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#ifdef HAVE_UTIME_H -#include <utime.h> -#endif - -#include "make.h" -#include "hash.h" -#include "dir.h" - -#ifdef TARGET_MACHINE -#undef MAKE_MACHINE -#define MAKE_MACHINE TARGET_MACHINE -#endif -#ifdef TARGET_MACHINE_ARCH -#undef MAKE_MACHINE_ARCH -#define MAKE_MACHINE_ARCH TARGET_MACHINE_ARCH -#endif - -static Lst archives; /* Lst of archives we've already examined */ - -typedef struct Arch { - char *name; /* Name of archive */ - Hash_Table members; /* All the members of the archive described - * by <name, struct ar_hdr *> key/value pairs */ - char *fnametab; /* Extended name table strings */ - size_t fnamesize; /* Size of the string table */ -} Arch; - -static int ArchFindArchive(const void *, const void *); -#ifdef CLEANUP -static void ArchFree(void *); -#endif -static struct ar_hdr *ArchStatMember(char *, char *, Boolean); -static FILE *ArchFindMember(char *, char *, struct ar_hdr *, const char *); -#if defined(__svr4__) || defined(__SVR4) || defined(__ELF__) -#define SVR4ARCHIVES -static int ArchSVR4Entry(Arch *, char *, size_t, FILE *); -#endif - - -#if defined(_AIX) -# define AR_NAME _ar_name.ar_name -# define AR_FMAG _ar_name.ar_fmag -# define SARMAG SAIAMAG -# define ARMAG AIAMAG -# define ARFMAG AIAFMAG -#endif -#ifndef AR_NAME -# define AR_NAME ar_name -#endif -#ifndef AR_DATE -# define AR_DATE ar_date -#endif -#ifndef AR_SIZE -# define AR_SIZE ar_size -#endif -#ifndef AR_FMAG -# define AR_FMAG ar_fmag -#endif -#ifndef ARMAG -# define ARMAG "!<arch>\n" -#endif -#ifndef SARMAG -# define SARMAG 8 -#endif - -#define AR_MAX_NAME_LEN (sizeof(arh.AR_NAME)-1) - -#ifdef CLEANUP -/*- - *----------------------------------------------------------------------- - * ArchFree -- - * Free memory used by an archive - * - * Results: - * None. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static void -ArchFree(void *ap) -{ - Arch *a = (Arch *)ap; - Hash_Search search; - Hash_Entry *entry; - - /* Free memory from hash entries */ - for (entry = Hash_EnumFirst(&a->members, &search); - entry != NULL; - entry = Hash_EnumNext(&search)) - free(Hash_GetValue(entry)); - - free(a->name); - if (a->fnametab) - free(a->fnametab); - Hash_DeleteTable(&a->members); - free(a); -} -#endif - - -/*- - *----------------------------------------------------------------------- - * Arch_ParseArchive -- - * Parse the archive specification in the given line and find/create - * the nodes for the specified archive members, placing their nodes - * on the given list. - * - * Input: - * linePtr Pointer to start of specification - * nodeLst Lst on which to place the nodes - * ctxt Context in which to expand variables - * - * Results: - * SUCCESS if it was a valid specification. The linePtr is updated - * to point to the first non-space after the archive spec. The - * nodes for the members are placed on the given list. - * - * Side Effects: - * Some nodes may be created. The given list is extended. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt) -{ - char *cp; /* Pointer into line */ - GNode *gn; /* New node */ - char *libName; /* Library-part of specification */ - char *memName; /* Member-part of specification */ - char *nameBuf; /* temporary place for node name */ - char saveChar; /* Ending delimiter of member-name */ - Boolean subLibName; /* TRUE if libName should have/had - * variable substitution performed on it */ - - libName = *linePtr; - - subLibName = FALSE; - - for (cp = libName; *cp != '(' && *cp != '\0'; cp++) { - if (*cp == '$') { - /* - * Variable spec, so call the Var module to parse the puppy - * so we can safely advance beyond it... - */ - int length; - void *freeIt; - char *result; - - result = Var_Parse(cp, ctxt, TRUE, &length, &freeIt); - if (freeIt) - free(freeIt); - if (result == var_Error) { - return(FAILURE); - } else { - subLibName = TRUE; - } - - cp += length-1; - } - } - - *cp++ = '\0'; - if (subLibName) { - libName = Var_Subst(NULL, libName, ctxt, TRUE); - } - - - for (;;) { - /* - * First skip to the start of the member's name, mark that - * place and skip to the end of it (either white-space or - * a close paren). - */ - Boolean doSubst = FALSE; /* TRUE if need to substitute in memName */ - - while (*cp != '\0' && *cp != ')' && isspace ((unsigned char)*cp)) { - cp++; - } - memName = cp; - while (*cp != '\0' && *cp != ')' && !isspace ((unsigned char)*cp)) { - if (*cp == '$') { - /* - * Variable spec, so call the Var module to parse the puppy - * so we can safely advance beyond it... - */ - int length; - void *freeIt; - char *result; - - result = Var_Parse(cp, ctxt, TRUE, &length, &freeIt); - if (freeIt) - free(freeIt); - if (result == var_Error) { - return(FAILURE); - } else { - doSubst = TRUE; - } - - cp += length; - } else { - cp++; - } - } - - /* - * If the specification ends without a closing parenthesis, - * chances are there's something wrong (like a missing backslash), - * so it's better to return failure than allow such things to happen - */ - if (*cp == '\0') { - printf("No closing parenthesis in archive specification\n"); - return (FAILURE); - } - - /* - * If we didn't move anywhere, we must be done - */ - if (cp == memName) { - break; - } - - saveChar = *cp; - *cp = '\0'; - - /* - * XXX: This should be taken care of intelligently by - * SuffExpandChildren, both for the archive and the member portions. - */ - /* - * If member contains variables, try and substitute for them. - * This will slow down archive specs with dynamic sources, of course, - * since we'll be (non-)substituting them three times, but them's - * the breaks -- we need to do this since SuffExpandChildren calls - * us, otherwise we could assume the thing would be taken care of - * later. - */ - if (doSubst) { - char *buf; - char *sacrifice; - char *oldMemName = memName; - size_t sz; - - memName = Var_Subst(NULL, memName, ctxt, TRUE); - - /* - * Now form an archive spec and recurse to deal with nested - * variables and multi-word variable values.... The results - * are just placed at the end of the nodeLst we're returning. - */ - sz = strlen(memName)+strlen(libName)+3; - buf = sacrifice = bmake_malloc(sz); - - snprintf(buf, sz, "%s(%s)", libName, memName); - - if (strchr(memName, '$') && strcmp(memName, oldMemName) == 0) { - /* - * Must contain dynamic sources, so we can't deal with it now. - * Just create an ARCHV node for the thing and let - * SuffExpandChildren handle it... - */ - gn = Targ_FindNode(buf, TARG_CREATE); - - if (gn == NULL) { - free(buf); - return(FAILURE); - } else { - gn->type |= OP_ARCHV; - (void)Lst_AtEnd(nodeLst, gn); - } - } else if (Arch_ParseArchive(&sacrifice, nodeLst, ctxt)!=SUCCESS) { - /* - * Error in nested call -- free buffer and return FAILURE - * ourselves. - */ - free(buf); - return(FAILURE); - } - /* - * Free buffer and continue with our work. - */ - free(buf); - } else if (Dir_HasWildcards(memName)) { - Lst members = Lst_Init(FALSE); - char *member; - size_t sz = MAXPATHLEN, nsz; - nameBuf = bmake_malloc(sz); - - Dir_Expand(memName, dirSearchPath, members); - while (!Lst_IsEmpty(members)) { - member = (char *)Lst_DeQueue(members); - nsz = strlen(libName) + strlen(member) + 3; - if (sz > nsz) - nameBuf = bmake_realloc(nameBuf, sz = nsz * 2); - - snprintf(nameBuf, sz, "%s(%s)", libName, member); - free(member); - gn = Targ_FindNode(nameBuf, TARG_CREATE); - if (gn == NULL) { - free(nameBuf); - return (FAILURE); - } else { - /* - * We've found the node, but have to make sure the rest of - * the world knows it's an archive member, without having - * to constantly check for parentheses, so we type the - * thing with the OP_ARCHV bit before we place it on the - * end of the provided list. - */ - gn->type |= OP_ARCHV; - (void)Lst_AtEnd(nodeLst, gn); - } - } - Lst_Destroy(members, NULL); - free(nameBuf); - } else { - size_t sz = strlen(libName) + strlen(memName) + 3; - nameBuf = bmake_malloc(sz); - snprintf(nameBuf, sz, "%s(%s)", libName, memName); - gn = Targ_FindNode(nameBuf, TARG_CREATE); - free(nameBuf); - if (gn == NULL) { - return (FAILURE); - } else { - /* - * We've found the node, but have to make sure the rest of the - * world knows it's an archive member, without having to - * constantly check for parentheses, so we type the thing with - * the OP_ARCHV bit before we place it on the end of the - * provided list. - */ - gn->type |= OP_ARCHV; - (void)Lst_AtEnd(nodeLst, gn); - } - } - if (doSubst) { - free(memName); - } - - *cp = saveChar; - } - - /* - * If substituted libName, free it now, since we need it no longer. - */ - if (subLibName) { - free(libName); - } - - /* - * We promised the pointer would be set up at the next non-space, so - * we must advance cp there before setting *linePtr... (note that on - * entrance to the loop, cp is guaranteed to point at a ')') - */ - do { - cp++; - } while (*cp != '\0' && isspace ((unsigned char)*cp)); - - *linePtr = cp; - return (SUCCESS); -} - -/*- - *----------------------------------------------------------------------- - * ArchFindArchive -- - * See if the given archive is the one we are looking for. Called - * From ArchStatMember and ArchFindMember via Lst_Find. - * - * Input: - * ar Current list element - * archName Name we want - * - * Results: - * 0 if it is, non-zero if it isn't. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static int -ArchFindArchive(const void *ar, const void *archName) -{ - return (strcmp(archName, ((const Arch *)ar)->name)); -} - -/*- - *----------------------------------------------------------------------- - * ArchStatMember -- - * Locate a member of an archive, given the path of the archive and - * the path of the desired member. - * - * Input: - * archive Path to the archive - * member Name of member. If it is a path, only the last - * component is used. - * hash TRUE if archive should be hashed if not already so. - * - * Results: - * A pointer to the current struct ar_hdr structure for the member. Note - * That no position is returned, so this is not useful for touching - * archive members. This is mostly because we have no assurances that - * The archive will remain constant after we read all the headers, so - * there's not much point in remembering the position... - * - * Side Effects: - * - *----------------------------------------------------------------------- - */ -static struct ar_hdr * -ArchStatMember(char *archive, char *member, Boolean hash) -{ - FILE * arch; /* Stream to archive */ - int size; /* Size of archive member */ - char *cp; /* Useful character pointer */ - char magic[SARMAG]; - LstNode ln; /* Lst member containing archive descriptor */ - Arch *ar; /* Archive descriptor */ - Hash_Entry *he; /* Entry containing member's description */ - struct ar_hdr arh; /* archive-member header for reading archive */ - char memName[MAXPATHLEN+1]; - /* Current member name while hashing. */ - - /* - * Because of space constraints and similar things, files are archived - * using their final path components, not the entire thing, so we need - * to point 'member' to the final component, if there is one, to make - * the comparisons easier... - */ - cp = strrchr(member, '/'); - if (cp != NULL) { - member = cp + 1; - } - - ln = Lst_Find(archives, archive, ArchFindArchive); - if (ln != NULL) { - ar = (Arch *)Lst_Datum(ln); - - he = Hash_FindEntry(&ar->members, member); - - if (he != NULL) { - return ((struct ar_hdr *)Hash_GetValue(he)); - } else { - /* Try truncated name */ - char copy[AR_MAX_NAME_LEN+1]; - size_t len = strlen(member); - - if (len > AR_MAX_NAME_LEN) { - len = AR_MAX_NAME_LEN; - strncpy(copy, member, AR_MAX_NAME_LEN); - copy[AR_MAX_NAME_LEN] = '\0'; - } - if ((he = Hash_FindEntry(&ar->members, copy)) != NULL) - return ((struct ar_hdr *)Hash_GetValue(he)); - return NULL; - } - } - - if (!hash) { - /* - * Caller doesn't want the thing hashed, just use ArchFindMember - * to read the header for the member out and close down the stream - * again. Since the archive is not to be hashed, we assume there's - * no need to allocate extra room for the header we're returning, - * so just declare it static. - */ - static struct ar_hdr sarh; - - arch = ArchFindMember(archive, member, &sarh, "r"); - - if (arch == NULL) { - return NULL; - } else { - fclose(arch); - return (&sarh); - } - } - - /* - * We don't have this archive on the list yet, so we want to find out - * everything that's in it and cache it so we can get at it quickly. - */ - arch = fopen(archive, "r"); - if (arch == NULL) { - return NULL; - } - - /* - * We use the ARMAG string to make sure this is an archive we - * can handle... - */ - if ((fread(magic, SARMAG, 1, arch) != 1) || - (strncmp(magic, ARMAG, SARMAG) != 0)) { - fclose(arch); - return NULL; - } - - ar = bmake_malloc(sizeof(Arch)); - ar->name = bmake_strdup(archive); - ar->fnametab = NULL; - ar->fnamesize = 0; - Hash_InitTable(&ar->members, -1); - memName[AR_MAX_NAME_LEN] = '\0'; - - while (fread((char *)&arh, sizeof(struct ar_hdr), 1, arch) == 1) { - if (strncmp( arh.AR_FMAG, ARFMAG, sizeof(arh.AR_FMAG)) != 0) { - /* - * The header is bogus, so the archive is bad - * and there's no way we can recover... - */ - goto badarch; - } else { - /* - * We need to advance the stream's pointer to the start of the - * next header. Files are padded with newlines to an even-byte - * boundary, so we need to extract the size of the file from the - * 'size' field of the header and round it up during the seek. - */ - arh.AR_SIZE[sizeof(arh.AR_SIZE)-1] = '\0'; - size = (int)strtol(arh.AR_SIZE, NULL, 10); - - (void)strncpy(memName, arh.AR_NAME, sizeof(arh.AR_NAME)); - for (cp = &memName[AR_MAX_NAME_LEN]; *cp == ' '; cp--) { - continue; - } - cp[1] = '\0'; - -#ifdef SVR4ARCHIVES - /* - * svr4 names are slash terminated. Also svr4 extended AR format. - */ - if (memName[0] == '/') { - /* - * svr4 magic mode; handle it - */ - switch (ArchSVR4Entry(ar, memName, size, arch)) { - case -1: /* Invalid data */ - goto badarch; - case 0: /* List of files entry */ - continue; - default: /* Got the entry */ - break; - } - } - else { - if (cp[0] == '/') - cp[0] = '\0'; - } -#endif - -#ifdef AR_EFMT1 - /* - * BSD 4.4 extended AR format: #1/<namelen>, with name as the - * first <namelen> bytes of the file - */ - if (strncmp(memName, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 && - isdigit((unsigned char)memName[sizeof(AR_EFMT1) - 1])) { - - unsigned int elen = atoi(&memName[sizeof(AR_EFMT1)-1]); - - if (elen > MAXPATHLEN) - goto badarch; - if (fread(memName, elen, 1, arch) != 1) - goto badarch; - memName[elen] = '\0'; - fseek(arch, -elen, SEEK_CUR); - if (DEBUG(ARCH) || DEBUG(MAKE)) { - fprintf(debug_file, "ArchStat: Extended format entry for %s\n", memName); - } - } -#endif - - he = Hash_CreateEntry(&ar->members, memName, NULL); - Hash_SetValue(he, bmake_malloc(sizeof(struct ar_hdr))); - memcpy(Hash_GetValue(he), &arh, sizeof(struct ar_hdr)); - } - fseek(arch, (size + 1) & ~1, SEEK_CUR); - } - - fclose(arch); - - (void)Lst_AtEnd(archives, ar); - - /* - * Now that the archive has been read and cached, we can look into - * the hash table to find the desired member's header. - */ - he = Hash_FindEntry(&ar->members, member); - - if (he != NULL) { - return ((struct ar_hdr *)Hash_GetValue(he)); - } else { - return NULL; - } - -badarch: - fclose(arch); - Hash_DeleteTable(&ar->members); - if (ar->fnametab) - free(ar->fnametab); - free(ar); - return NULL; -} - -#ifdef SVR4ARCHIVES -/*- - *----------------------------------------------------------------------- - * ArchSVR4Entry -- - * Parse an SVR4 style entry that begins with a slash. - * If it is "//", then load the table of filenames - * If it is "/<offset>", then try to substitute the long file name - * from offset of a table previously read. - * - * Results: - * -1: Bad data in archive - * 0: A table was loaded from the file - * 1: Name was successfully substituted from table - * 2: Name was not successfully substituted from table - * - * Side Effects: - * If a table is read, the file pointer is moved to the next archive - * member - * - *----------------------------------------------------------------------- - */ -static int -ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch) -{ -#define ARLONGNAMES1 "//" -#define ARLONGNAMES2 "/ARFILENAMES" - size_t entry; - char *ptr, *eptr; - - if (strncmp(name, ARLONGNAMES1, sizeof(ARLONGNAMES1) - 1) == 0 || - strncmp(name, ARLONGNAMES2, sizeof(ARLONGNAMES2) - 1) == 0) { - - if (ar->fnametab != NULL) { - if (DEBUG(ARCH)) { - fprintf(debug_file, "Attempted to redefine an SVR4 name table\n"); - } - return -1; - } - - /* - * This is a table of archive names, so we build one for - * ourselves - */ - ar->fnametab = bmake_malloc(size); - ar->fnamesize = size; - - if (fread(ar->fnametab, size, 1, arch) != 1) { - if (DEBUG(ARCH)) { - fprintf(debug_file, "Reading an SVR4 name table failed\n"); - } - return -1; - } - eptr = ar->fnametab + size; - for (entry = 0, ptr = ar->fnametab; ptr < eptr; ptr++) - switch (*ptr) { - case '/': - entry++; - *ptr = '\0'; - break; - - case '\n': - break; - - default: - break; - } - if (DEBUG(ARCH)) { - fprintf(debug_file, "Found svr4 archive name table with %lu entries\n", - (u_long)entry); - } - return 0; - } - - if (name[1] == ' ' || name[1] == '\0') - return 2; - - entry = (size_t)strtol(&name[1], &eptr, 0); - if ((*eptr != ' ' && *eptr != '\0') || eptr == &name[1]) { - if (DEBUG(ARCH)) { - fprintf(debug_file, "Could not parse SVR4 name %s\n", name); - } - return 2; - } - if (entry >= ar->fnamesize) { - if (DEBUG(ARCH)) { - fprintf(debug_file, "SVR4 entry offset %s is greater than %lu\n", - name, (u_long)ar->fnamesize); - } - return 2; - } - - if (DEBUG(ARCH)) { - fprintf(debug_file, "Replaced %s with %s\n", name, &ar->fnametab[entry]); - } - - (void)strncpy(name, &ar->fnametab[entry], MAXPATHLEN); - name[MAXPATHLEN] = '\0'; - return 1; -} -#endif - - -/*- - *----------------------------------------------------------------------- - * ArchFindMember -- - * Locate a member of an archive, given the path of the archive and - * the path of the desired member. If the archive is to be modified, - * the mode should be "r+", if not, it should be "r". - * - * Input: - * archive Path to the archive - * member Name of member. If it is a path, only the last - * component is used. - * arhPtr Pointer to header structure to be filled in - * mode The mode for opening the stream - * - * Results: - * An FILE *, opened for reading and writing, positioned at the - * start of the member's struct ar_hdr, or NULL if the member was - * nonexistent. The current struct ar_hdr for member. - * - * Side Effects: - * The passed struct ar_hdr structure is filled in. - * - *----------------------------------------------------------------------- - */ -static FILE * -ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr, - const char *mode) -{ - FILE * arch; /* Stream to archive */ - int size; /* Size of archive member */ - char *cp; /* Useful character pointer */ - char magic[SARMAG]; - size_t len, tlen; - - arch = fopen(archive, mode); - if (arch == NULL) { - return NULL; - } - - /* - * We use the ARMAG string to make sure this is an archive we - * can handle... - */ - if ((fread(magic, SARMAG, 1, arch) != 1) || - (strncmp(magic, ARMAG, SARMAG) != 0)) { - fclose(arch); - return NULL; - } - - /* - * Because of space constraints and similar things, files are archived - * using their final path components, not the entire thing, so we need - * to point 'member' to the final component, if there is one, to make - * the comparisons easier... - */ - cp = strrchr(member, '/'); - if (cp != NULL) { - member = cp + 1; - } - len = tlen = strlen(member); - if (len > sizeof(arhPtr->AR_NAME)) { - tlen = sizeof(arhPtr->AR_NAME); - } - - while (fread((char *)arhPtr, sizeof(struct ar_hdr), 1, arch) == 1) { - if (strncmp(arhPtr->AR_FMAG, ARFMAG, sizeof(arhPtr->AR_FMAG) ) != 0) { - /* - * The header is bogus, so the archive is bad - * and there's no way we can recover... - */ - fclose(arch); - return NULL; - } else if (strncmp(member, arhPtr->AR_NAME, tlen) == 0) { - /* - * If the member's name doesn't take up the entire 'name' field, - * we have to be careful of matching prefixes. Names are space- - * padded to the right, so if the character in 'name' at the end - * of the matched string is anything but a space, this isn't the - * member we sought. - */ - if (tlen != sizeof(arhPtr->AR_NAME) && arhPtr->AR_NAME[tlen] != ' '){ - goto skip; - } else { - /* - * To make life easier, we reposition the file at the start - * of the header we just read before we return the stream. - * In a more general situation, it might be better to leave - * the file at the actual member, rather than its header, but - * not here... - */ - fseek(arch, -sizeof(struct ar_hdr), SEEK_CUR); - return (arch); - } - } else -#ifdef AR_EFMT1 - /* - * BSD 4.4 extended AR format: #1/<namelen>, with name as the - * first <namelen> bytes of the file - */ - if (strncmp(arhPtr->AR_NAME, AR_EFMT1, - sizeof(AR_EFMT1) - 1) == 0 && - isdigit((unsigned char)arhPtr->AR_NAME[sizeof(AR_EFMT1) - 1])) { - - unsigned int elen = atoi(&arhPtr->AR_NAME[sizeof(AR_EFMT1)-1]); - char ename[MAXPATHLEN + 1]; - - if (elen > MAXPATHLEN) { - fclose(arch); - return NULL; - } - if (fread(ename, elen, 1, arch) != 1) { - fclose(arch); - return NULL; - } - ename[elen] = '\0'; - if (DEBUG(ARCH) || DEBUG(MAKE)) { - fprintf(debug_file, "ArchFind: Extended format entry for %s\n", ename); - } - if (strncmp(ename, member, len) == 0) { - /* Found as extended name */ - fseek(arch, -sizeof(struct ar_hdr) - elen, SEEK_CUR); - return (arch); - } - fseek(arch, -elen, SEEK_CUR); - goto skip; - } else -#endif - { -skip: - /* - * This isn't the member we're after, so we need to advance the - * stream's pointer to the start of the next header. Files are - * padded with newlines to an even-byte boundary, so we need to - * extract the size of the file from the 'size' field of the - * header and round it up during the seek. - */ - arhPtr->ar_size[sizeof(arhPtr->AR_SIZE)-1] = '\0'; - size = (int)strtol(arhPtr->AR_SIZE, NULL, 10); - fseek(arch, (size + 1) & ~1, SEEK_CUR); - } - } - - /* - * We've looked everywhere, but the member is not to be found. Close the - * archive and return NULL -- an error. - */ - fclose(arch); - return NULL; -} - -/*- - *----------------------------------------------------------------------- - * Arch_Touch -- - * Touch a member of an archive. - * - * Input: - * gn Node of member to touch - * - * Results: - * The 'time' field of the member's header is updated. - * - * Side Effects: - * The modification time of the entire archive is also changed. - * For a library, this could necessitate the re-ranlib'ing of the - * whole thing. - * - *----------------------------------------------------------------------- - */ -void -Arch_Touch(GNode *gn) -{ - FILE * arch; /* Stream open to archive, positioned properly */ - struct ar_hdr arh; /* Current header describing member */ - char *p1, *p2; - - arch = ArchFindMember(Var_Value(ARCHIVE, gn, &p1), - Var_Value(MEMBER, gn, &p2), - &arh, "r+"); - if (p1) - free(p1); - if (p2) - free(p2); - snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now); - - if (arch != NULL) { - (void)fwrite((char *)&arh, sizeof(struct ar_hdr), 1, arch); - fclose(arch); - } -} - -/*- - *----------------------------------------------------------------------- - * Arch_TouchLib -- - * Given a node which represents a library, touch the thing, making - * sure that the table of contents also is touched. - * - * Input: - * gn The node of the library to touch - * - * Results: - * None. - * - * Side Effects: - * Both the modification time of the library and of the RANLIBMAG - * member are set to 'now'. - * - *----------------------------------------------------------------------- - */ -void -#if !defined(RANLIBMAG) -Arch_TouchLib(GNode *gn MAKE_ATTR_UNUSED) -#else -Arch_TouchLib(GNode *gn) -#endif -{ -#ifdef RANLIBMAG - FILE * arch; /* Stream open to archive */ - struct ar_hdr arh; /* Header describing table of contents */ - struct utimbuf times; /* Times for utime() call */ - - arch = ArchFindMember(gn->path, UNCONST(RANLIBMAG), &arh, "r+"); - snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now); - - if (arch != NULL) { - (void)fwrite((char *)&arh, sizeof(struct ar_hdr), 1, arch); - fclose(arch); - - times.actime = times.modtime = now; - utime(gn->path, ×); - } -#endif -} - -/*- - *----------------------------------------------------------------------- - * Arch_MTime -- - * Return the modification time of a member of an archive. - * - * Input: - * gn Node describing archive member - * - * Results: - * The modification time(seconds). - * - * Side Effects: - * The mtime field of the given node is filled in with the value - * returned by the function. - * - *----------------------------------------------------------------------- - */ -time_t -Arch_MTime(GNode *gn) -{ - struct ar_hdr *arhPtr; /* Header of desired member */ - time_t modTime; /* Modification time as an integer */ - char *p1, *p2; - - arhPtr = ArchStatMember(Var_Value(ARCHIVE, gn, &p1), - Var_Value(MEMBER, gn, &p2), - TRUE); - if (p1) - free(p1); - if (p2) - free(p2); - - if (arhPtr != NULL) { - modTime = (time_t)strtol(arhPtr->AR_DATE, NULL, 10); - } else { - modTime = 0; - } - - gn->mtime = modTime; - return (modTime); -} - -/*- - *----------------------------------------------------------------------- - * Arch_MemMTime -- - * Given a non-existent archive member's node, get its modification - * time from its archived form, if it exists. - * - * Results: - * The modification time. - * - * Side Effects: - * The mtime field is filled in. - * - *----------------------------------------------------------------------- - */ -time_t -Arch_MemMTime(GNode *gn) -{ - LstNode ln; - GNode *pgn; - char *nameStart, - *nameEnd; - - if (Lst_Open(gn->parents) != SUCCESS) { - gn->mtime = 0; - return (0); - } - while ((ln = Lst_Next(gn->parents)) != NULL) { - pgn = (GNode *)Lst_Datum(ln); - - if (pgn->type & OP_ARCHV) { - /* - * If the parent is an archive specification and is being made - * and its member's name matches the name of the node we were - * given, record the modification time of the parent in the - * child. We keep searching its parents in case some other - * parent requires this child to exist... - */ - nameStart = strchr(pgn->name, '(') + 1; - nameEnd = strchr(nameStart, ')'); - - if ((pgn->flags & REMAKE) && - strncmp(nameStart, gn->name, nameEnd - nameStart) == 0) { - gn->mtime = Arch_MTime(pgn); - } - } else if (pgn->flags & REMAKE) { - /* - * Something which isn't a library depends on the existence of - * this target, so it needs to exist. - */ - gn->mtime = 0; - break; - } - } - - Lst_Close(gn->parents); - - return (gn->mtime); -} - -/*- - *----------------------------------------------------------------------- - * Arch_FindLib -- - * Search for a library along the given search path. - * - * Input: - * gn Node of library to find - * path Search path - * - * Results: - * None. - * - * Side Effects: - * The node's 'path' field is set to the found path (including the - * actual file name, not -l...). If the system can handle the -L - * flag when linking (or we cannot find the library), we assume that - * the user has placed the .LIBRARIES variable in the final linking - * command (or the linker will know where to find it) and set the - * TARGET variable for this node to be the node's name. Otherwise, - * we set the TARGET variable to be the full path of the library, - * as returned by Dir_FindFile. - * - *----------------------------------------------------------------------- - */ -void -Arch_FindLib(GNode *gn, Lst path) -{ - char *libName; /* file name for archive */ - size_t sz = strlen(gn->name) + 6 - 2; - - libName = bmake_malloc(sz); - snprintf(libName, sz, "lib%s.a", &gn->name[2]); - - gn->path = Dir_FindFile(libName, path); - - free(libName); - -#ifdef LIBRARIES - Var_Set(TARGET, gn->name, gn, 0); -#else - Var_Set(TARGET, gn->path == NULL ? gn->name : gn->path, gn, 0); -#endif /* LIBRARIES */ -} - -/*- - *----------------------------------------------------------------------- - * 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->cmgn->mtime). - * Its modification time is greater than the time at which the - * make began (i.e. it's been modified in the course - * of the make, probably 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. - * - * Input: - * gn The library's graph node - * - * Results: - * TRUE if the library is out-of-date. FALSE otherwise. - * - * Side Effects: - * The library will be hashed if it hasn't been already. - * - *----------------------------------------------------------------------- - */ -Boolean -Arch_LibOODate(GNode *gn) -{ - Boolean oodate; - - if (gn->type & OP_PHONY) { - oodate = TRUE; - } else if (OP_NOP(gn->type) && Lst_IsEmpty(gn->children)) { - oodate = FALSE; - } else if ((!Lst_IsEmpty(gn->children) && gn->cmgn == NULL) || - (gn->mtime > now) || - (gn->cmgn != NULL && gn->mtime < gn->cmgn->mtime)) { - oodate = TRUE; - } else { -#ifdef RANLIBMAG - struct ar_hdr *arhPtr; /* Header for __.SYMDEF */ - int modTimeTOC; /* The table-of-contents's mod time */ - - arhPtr = ArchStatMember(gn->path, UNCONST(RANLIBMAG), FALSE); - - if (arhPtr != NULL) { - modTimeTOC = (int)strtol(arhPtr->AR_DATE, NULL, 10); - - if (DEBUG(ARCH) || DEBUG(MAKE)) { - fprintf(debug_file, "%s modified %s...", RANLIBMAG, Targ_FmtTime(modTimeTOC)); - } - oodate = (gn->cmgn == NULL || gn->cmgn->mtime > modTimeTOC); - } else { - /* - * A library w/o a table of contents is out-of-date - */ - if (DEBUG(ARCH) || DEBUG(MAKE)) { - fprintf(debug_file, "No t.o.c...."); - } - oodate = TRUE; - } -#else - oodate = FALSE; -#endif - } - return (oodate); -} - -/*- - *----------------------------------------------------------------------- - * Arch_Init -- - * Initialize things for this module. - * - * Results: - * None. - * - * Side Effects: - * The 'archives' list is initialized. - * - *----------------------------------------------------------------------- - */ -void -Arch_Init(void) -{ - archives = Lst_Init(FALSE); -} - - - -/*- - *----------------------------------------------------------------------- - * Arch_End -- - * Cleanup things for this module. - * - * Results: - * None. - * - * Side Effects: - * The 'archives' list is freed - * - *----------------------------------------------------------------------- - */ -void -Arch_End(void) -{ -#ifdef CLEANUP - Lst_Destroy(archives, ArchFree); -#endif -} - -/*- - *----------------------------------------------------------------------- - * Arch_IsLib -- - * Check if the node is a library - * - * Results: - * True or False. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -int -Arch_IsLib(GNode *gn) -{ - static const char armag[] = "!<arch>\n"; - char buf[sizeof(armag)-1]; - int fd; - - if ((fd = open(gn->path, O_RDONLY)) == -1) - return FALSE; - - if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { - (void)close(fd); - return FALSE; - } - - (void)close(fd); - - return memcmp(buf, armag, sizeof(buf)) == 0; -} diff --git a/20120831/bmake.1 b/20120831/bmake.1 deleted file mode 100644 index 0bb377a..0000000 --- a/20120831/bmake.1 +++ /dev/null @@ -1,2043 +0,0 @@ -.\" $NetBSD: make.1,v 1.204 2012/04/24 20:12:16 sjg Exp $ -.\" -.\" Copyright (c) 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 -.\" -.Dd April 24, 2012 -.Dt MAKE 1 -.Os -.Sh NAME -.Nm bmake -.Nd maintain program dependencies -.Sh SYNOPSIS -.Nm -.Op Fl BeikNnqrstWX -.Op Fl C Ar directory -.Op Fl D Ar variable -.Op Fl d Ar flags -.Op Fl f Ar makefile -.Op Fl I Ar directory -.Op Fl J Ar private -.Op Fl j Ar max_jobs -.Op Fl m Ar directory -.Op Fl T Ar file -.Op Fl V Ar variable -.Op Ar variable=value -.Op Ar target ... -.Sh DESCRIPTION -.Nm -is a program designed to simplify the maintenance of other programs. -Its input is a list of specifications as to the files upon which programs -and other files depend. -If no -.Fl f Ar makefile -makefile option is given, -.Nm -will try to open -.Ql Pa makefile -then -.Ql Pa Makefile -in order to find the specifications. -If the file -.Ql Pa .depend -exists, it is read (see -.Xr mkdep 1 ) . -.Pp -This manual page is intended as a reference document only. -For a more thorough description of -.Nm -and makefiles, please refer to -.%T "PMake \- A Tutorial" . -.Pp -.Nm -will prepend the contents of the -.Va MAKEFLAGS -environment variable to the command line arguments before parsing them. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl B -Try to be backwards compatible by executing a single shell per command and -by executing the commands to make the sources of a dependency line in sequence. -.It Fl C Ar directory -Change to -.Ar directory -before reading the makefiles or doing anything else. -If multiple -.Fl C -options are specified, each is interpreted relative to the previous one: -.Fl C Pa / Fl C Pa etc -is equivalent to -.Fl C Pa /etc . -.It Fl D Ar variable -Define -.Ar variable -to be 1, in the global context. -.It Fl d Ar [-]flags -Turn on debugging, and specify which portions of -.Nm -are to print debugging information. -Unless the flags are preceded by -.Ql \- -they are added to the -.Va MAKEFLAGS -environment variable and will be processed by any child make processes. -By default, debugging information is printed to standard error, -but this can be changed using the -.Ar F -debugging flag. -The debugging output is always unbuffered; in addition, if debugging -is enabled but debugging output is not directed to standard output, -then the standard output is line buffered. -.Ar Flags -is one or more of the following: -.Bl -tag -width Ds -.It Ar A -Print all possible debugging information; -equivalent to specifying all of the debugging flags. -.It Ar a -Print debugging information about archive searching and caching. -.It Ar C -Print debugging information about current working directory. -.It Ar c -Print debugging information about conditional evaluation. -.It Ar d -Print debugging information about directory searching and caching. -.It Ar e -Print debugging information about failed commands and targets. -.It Ar F Ns Oo Sy \&+ Oc Ns Ar filename -Specify where debugging output is written. -This must be the last flag, because it consumes the remainder of -the argument. -If the character immediately after the -.Ql F -flag is -.Ql \&+ , -then the file will be opened in append mode; -otherwise the file will be overwritten. -If the file name is -.Ql stdout -or -.Ql stderr -then debugging output will be written to the -standard output or standard error output file descriptors respectively -(and the -.Ql \&+ -option has no effect). -Otherwise, the output will be written to the named file. -If the file name ends -.Ql .%d -then the -.Ql %d -is replaced by the pid. -.It Ar f -Print debugging information about loop evaluation. -.It Ar "g1" -Print the input graph before making anything. -.It Ar "g2" -Print the input graph after making everything, or before exiting -on error. -.It Ar "g3" -Print the input graph before exiting on error. -.It Ar j -Print debugging information about running multiple shells. -.It Ar l -Print commands in Makefiles regardless of whether or not they are prefixed by -.Ql @ -or other "quiet" flags. -Also known as "loud" behavior. -.It Ar M -Print debugging information about "meta" mode decisions about targets. -.It Ar m -Print debugging information about making targets, including modification -dates. -.It Ar n -Don't delete the temporary command scripts created when running commands. -These temporary scripts are created in the directory -referred to by the -.Ev TMPDIR -environment variable, or in -.Pa /tmp -if -.Ev TMPDIR -is unset or set to the empty string. -The temporary scripts are created by -.Xr mkstemp 3 , -and have names of the form -.Pa makeXXXXXX . -.Em NOTE : -This can create many files in -.Ev TMPDIR -or -.Pa /tmp , -so use with care. -.It Ar p -Print debugging information about makefile parsing. -.It Ar s -Print debugging information about suffix-transformation rules. -.It Ar t -Print debugging information about target list maintenance. -.It Ar v -Print debugging information about variable assignment. -.It Ar x -Run shell commands with -.Fl x -so the actual commands are printed as they are executed. -.El -.It Fl e -Specify that environment variables override macro assignments within -makefiles. -.It Fl f Ar makefile -Specify a makefile to read instead of the default -.Ql Pa makefile . -If -.Ar makefile -is -.Ql Fl , -standard input is read. -Multiple makefiles may be specified, and are read in the order specified. -.It Fl I Ar directory -Specify a directory in which to search for makefiles and included makefiles. -The system makefile directory (or directories, see the -.Fl m -option) is automatically included as part of this list. -.It Fl i -Ignore non-zero exit of shell commands in the makefile. -Equivalent to specifying -.Ql Fl -before each command line in the makefile. -.It Fl J Ar private -This option should -.Em not -be specified by the user. -.Pp -When the -.Ar j -option is in use in a recursive build, this option is passed by a make -to child makes to allow all the make processes in the build to -cooperate to avoid overloading the system. -.It Fl j Ar max_jobs -Specify the maximum number of jobs that -.Nm -may have running at any one time. -The value is saved in -.Va .MAKE.JOBS . -Turns compatibility mode off, unless the -.Ar B -flag is also specified. -When compatibility mode is off, all commands associated with a -target are executed in a single shell invocation as opposed to the -traditional one shell invocation per line. -This can break traditional scripts which change directories on each -command invocation and then expect to start with a fresh environment -on the next line. -It is more efficient to correct the scripts rather than turn backwards -compatibility on. -.It Fl k -Continue processing after errors are encountered, but only on those targets -that do not depend on the target whose creation caused the error. -.It Fl m Ar directory -Specify a directory in which to search for sys.mk and makefiles included -via the -.Ao Ar file Ac Ns -style -include statement. -The -.Fl m -option can be used multiple times to form a search path. -This path will override the default system include path: /usr/share/mk. -Furthermore the system include path will be appended to the search path used -for -.Qo Ar file Qc Ns -style -include statements (see the -.Fl I -option). -.Pp -If a file or directory name in the -.Fl m -argument (or the -.Ev MAKESYSPATH -environment variable) starts with the string -.Qq \&.../ -then -.Nm -will search for the specified file or directory named in the remaining part -of the argument string. -The search starts with the current directory of -the Makefile and then works upward towards the root of the filesystem. -If the search is successful, then the resulting directory replaces the -.Qq \&.../ -specification in the -.Fl m -argument. -If used, this feature allows -.Nm -to easily search in the current source tree for customized sys.mk files -(e.g., by using -.Qq \&.../mk/sys.mk -as an argument). -.It Fl n -Display the commands that would have been executed, but do not -actually execute them unless the target depends on the .MAKE special -source (see below). -.It Fl N -Display the commands which would have been executed, but do not -actually execute any of them; useful for debugging top-level makefiles -without descending into subdirectories. -.It Fl q -Do not execute any commands, but exit 0 if the specified targets are -up-to-date and 1, otherwise. -.It Fl r -Do not use the built-in rules specified in the system makefile. -.It Fl s -Do not echo any commands as they are executed. -Equivalent to specifying -.Ql Ic @ -before each command line in the makefile. -.It Fl T Ar tracefile -When used with the -.Fl j -flag, -append a trace record to -.Ar tracefile -for each job started and completed. -.It Fl t -Rather than re-building a target as specified in the makefile, create it -or update its modification time to make it appear up-to-date. -.It Fl V Ar variable -Print -.Nm Ns 's -idea of the value of -.Ar variable , -in the global context. -Do not build any targets. -Multiple instances of this option may be specified; -the variables will be printed one per line, -with a blank line for each null or undefined variable. -If -.Ar variable -contains a -.Ql \&$ -then the value will be expanded before printing. -.It Fl W -Treat any warnings during makefile parsing as errors. -.It Fl X -Don't export variables passed on the command line to the environment -individually. -Variables passed on the command line are still exported -via the -.Va MAKEFLAGS -environment variable. -This option may be useful on systems which have a small limit on the -size of command arguments. -.It Ar variable=value -Set the value of the variable -.Ar variable -to -.Ar value . -Normally, all values passed on the command line are also exported to -sub-makes in the environment. -The -.Fl X -flag disables this behavior. -Variable assignments should follow options for POSIX compatibility -but no ordering is enforced. -.El -.Pp -There are seven different types of lines in a makefile: file dependency -specifications, shell commands, variable assignments, include statements, -conditional directives, for loops, and comments. -.Pp -In general, lines may be continued from one line to the next by ending -them with a backslash -.Pq Ql \e . -The trailing newline character and initial whitespace on the following -line are compressed into a single space. -.Sh FILE DEPENDENCY SPECIFICATIONS -Dependency lines consist of one or more targets, an operator, and zero -or more sources. -This creates a relationship where the targets -.Dq depend -on the sources -and are usually created from them. -The exact relationship between the target and the source is determined -by the operator that separates them. -The three operators are as follows: -.Bl -tag -width flag -.It Ic \&: -A target is considered out-of-date if its modification time is less than -those of any of its sources. -Sources for a target accumulate over dependency lines when this operator -is used. -The target is removed if -.Nm -is interrupted. -.It Ic \&! -Targets are always re-created, but not until all sources have been -examined and re-created as necessary. -Sources for a target accumulate over dependency lines when this operator -is used. -The target is removed if -.Nm -is interrupted. -.It Ic \&:: -If no sources are specified, the target is always re-created. -Otherwise, a target is considered out-of-date if any of its sources has -been modified more recently than the target. -Sources for a target do not accumulate over dependency lines when this -operator is used. -The target will not be removed if -.Nm -is interrupted. -.El -.Pp -Targets and sources may contain the shell wildcard values -.Ql \&? , -.Ql * , -.Ql [] , -and -.Ql {} . -The values -.Ql \&? , -.Ql * , -and -.Ql [] -may only be used as part of the final -component of the target or source, and must be used to describe existing -files. -The value -.Ql {} -need not necessarily be used to describe existing files. -Expansion is in directory order, not alphabetically as done in the shell. -.Sh SHELL COMMANDS -Each target may have associated with it a series of shell commands, normally -used to create the target. -Each of the commands in this script -.Em must -be preceded by a tab. -While any target may appear on a dependency line, only one of these -dependencies may be followed by a creation script, unless the -.Ql Ic \&:: -operator is used. -.Pp -If the first characters of the command line are any combination of -.Ql Ic @ , -.Ql Ic + , -or -.Ql Ic \- , -the command is treated specially. -A -.Ql Ic @ -causes the command not to be echoed before it is executed. -A -.Ql Ic + -causes the command to be executed even when -.Fl n -is given. -This is similar to the effect of the .MAKE special source, -except that the effect can be limited to a single line of a script. -A -.Ql Ic \- -causes any non-zero exit status of the command line to be ignored. -.Sh VARIABLE ASSIGNMENTS -Variables in make are much like variables in the shell, and, by tradition, -consist of all upper-case letters. -.Ss Variable assignment modifiers -The five operators that can be used to assign values to variables are as -follows: -.Bl -tag -width Ds -.It Ic \&= -Assign the value to the variable. -Any previous value is overridden. -.It Ic \&+= -Append the value to the current value of the variable. -.It Ic \&?= -Assign the value to the variable if it is not already defined. -.It Ic \&:= -Assign with expansion, i.e. expand the value before assigning it -to the variable. -Normally, expansion is not done until the variable is referenced. -.Em NOTE : -References to undefined variables are -.Em not -expanded. -This can cause problems when variable modifiers are used. -.It Ic \&!= -Expand the value and pass it to the shell for execution and assign -the result to the variable. -Any newlines in the result are replaced with spaces. -.El -.Pp -Any white-space before the assigned -.Ar value -is removed; if the value is being appended, a single space is inserted -between the previous contents of the variable and the appended value. -.Pp -Variables are expanded by surrounding the variable name with either -curly braces -.Pq Ql {} -or parentheses -.Pq Ql () -and preceding it with -a dollar sign -.Pq Ql \&$ . -If the variable name contains only a single letter, the surrounding -braces or parentheses are not required. -This shorter form is not recommended. -.Pp -If the variable name contains a dollar, then the name itself is expanded first. -This allows almost arbitrary variable names, however names containing dollar, -braces, parenthesis, or whitespace are really best avoided! -.Pp -If the result of expanding a variable contains a dollar sign -.Pq Ql \&$ -the string is expanded again. -.Pp -Variable substitution occurs at three distinct times, depending on where -the variable is being used. -.Bl -enum -.It -Variables in dependency lines are expanded as the line is read. -.It -Variables in shell commands are expanded when the shell command is -executed. -.It -.Dq .for -loop index variables are expanded on each loop iteration. -Note that other variables are not expanded inside loops so -the following example code: -.Bd -literal -offset indent - -.Dv .for i in 1 2 3 -a+= ${i} -j= ${i} -b+= ${j} -.Dv .endfor - -all: - @echo ${a} - @echo ${b} - -.Ed -will print: -.Bd -literal -offset indent -1 2 3 -3 3 3 - -.Ed -Because while ${a} contains -.Dq 1 2 3 -after the loop is executed, ${b} -contains -.Dq ${j} ${j} ${j} -which expands to -.Dq 3 3 3 -since after the loop completes ${j} contains -.Dq 3 . -.El -.Ss Variable classes -The four different classes of variables (in order of increasing precedence) -are: -.Bl -tag -width Ds -.It Environment variables -Variables defined as part of -.Nm Ns 's -environment. -.It Global variables -Variables defined in the makefile or in included makefiles. -.It Command line variables -Variables defined as part of the command line. -.It Local variables -Variables that are defined specific to a certain target. -The seven local variables are as follows: -.Bl -tag -width ".ARCHIVE" -.It Va .ALLSRC -The list of all sources for this target; also known as -.Ql Va \&\*[Gt] . -.It Va .ARCHIVE -The name of the archive file. -.It Va .IMPSRC -In suffix-transformation rules, the name/path of the source from which the -target is to be transformed (the -.Dq implied -source); also known as -.Ql Va \&\*[Lt] . -It is not defined in explicit rules. -.It Va .MEMBER -The name of the archive member. -.It Va .OODATE -The list of sources for this target that were deemed out-of-date; also -known as -.Ql Va \&? . -.It Va .PREFIX -The file prefix of the target, containing only the file portion, no suffix -or preceding directory components; also known as -.Ql Va * . -.It Va .TARGET -The name of the target; also known as -.Ql Va @ . -.El -.Pp -The shorter forms -.Ql Va @ , -.Ql Va \&? , -.Ql Va \&\*[Lt] , -.Ql Va \&\*[Gt] , -and -.Ql Va * -are permitted for backward -compatibility with historical makefiles and are not recommended. -The six variables -.Ql Va "@F" , -.Ql Va "@D" , -.Ql Va "\*[Lt]F" , -.Ql Va "\*[Lt]D" , -.Ql Va "*F" , -and -.Ql Va "*D" -are permitted for compatibility with -.At V -makefiles and are not recommended. -.Pp -Four of the local variables may be used in sources on dependency lines -because they expand to the proper value for each target on the line. -These variables are -.Ql Va .TARGET , -.Ql Va .PREFIX , -.Ql Va .ARCHIVE , -and -.Ql Va .MEMBER . -.El -.Ss Additional built-in variables -In addition, -.Nm -sets or knows about the following variables: -.Bl -tag -width .MAKEOVERRIDES -.It Va \&$ -A single dollar sign -.Ql \&$ , -i.e. -.Ql \&$$ -expands to a single dollar -sign. -.It Va .ALLTARGETS -The list of all targets encountered in the Makefile. -If evaluated during -Makefile parsing, lists only those targets encountered thus far. -.It Va .CURDIR -A path to the directory where -.Nm -was executed. -Refer to the description of -.Ql Ev PWD -for more details. -.It Ev MAKE -The name that -.Nm -was executed with -.Pq Va argv[0] . -For compatibility -.Nm -also sets -.Va .MAKE -with the same value. -The preferred variable to use is the environment variable -.Ev MAKE -because it is more compatible with other versions of -.Nm -and cannot be confused with the special target with the same name. -.It Va .MAKE.DEPENDFILE -Names the makefile (default -.Ql Pa .depend ) -from which generated dependencies are read. -.It Va .MAKE.EXPORTED -The list of variables exported by -.Nm . -.It Va .MAKE.JOBS -The argument to the -.Fl j -option. -.It Va .MAKE.JOB.PREFIX -If -.Nm -is run with -.Ar j -then output for each target is prefixed with a token -.Ql --- target --- -the first part of which can be controlled via -.Va .MAKE.JOB.PREFIX . -.br -For example: -.Li .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}] -would produce tokens like -.Ql ---make[1234] target --- -making it easier to track the degree of parallelism being achieved. -.It Ev MAKEFLAGS -The environment variable -.Ql Ev MAKEFLAGS -may contain anything that -may be specified on -.Nm Ns 's -command line. -Anything specified on -.Nm Ns 's -command line is appended to the -.Ql Ev MAKEFLAGS -variable which is then -entered into the environment for all programs which -.Nm -executes. -.It Va .MAKE.LEVEL -The recursion depth of -.Nm . -The initial instance of -.Nm -will be 0, and an incremented value is put into the environment -to be seen by the next generation. -This allows tests like: -.Li .if ${.MAKE.LEVEL} == 0 -to protect things which should only be evaluated in the initial instance of -.Nm . -.It Va .MAKE.MAKEFILE_PREFERENCE -The ordered list of makefile names -(default -.Ql Pa makefile , -.Ql Pa Makefile ) -that -.Nm -will look for. -.It Va .MAKE.MAKEFILES -The list of makefiles read by -.Nm , -which is useful for tracking dependencies. -Each makefile is recorded only once, regardless of the number of times read. -.It Va .MAKE.MODE -Processed after reading all makefiles. -Can affect the mode that -.Nm -runs in. -It can contain a number of keywords: -.Bl -hang -width ignore-cmd -.It Pa compat -Like -.Fl B , -puts -.Nm -into "compat" mode. -.It Pa meta -Puts -.Nm -into "meta" mode, where meta files are created for each target -to capture the command run, the output generated and if -.Xr filemon 4 -is available, the system calls which are of interest to -.Nm . -The captured output can be very useful when diagnosing errors. -.It Pa curdirOk= Ar bf -Normally -.Nm -will not create .meta files in -.Ql Va .CURDIR . -This can be overridden by setting -.Va bf -to a value which represents True. -.It Pa env -For debugging, it can be useful to inlcude the environment -in the .meta file. -.It Pa verbose -If in "meta" mode, print a clue about the target being built. -This is useful if the build is otherwise running silently. -The message printed the value of: -.Va .MAKE.META.PREFIX . -.It Pa ignore-cmd -Some makefiles have commands which are simply not stable. -This keyword causes them to be ignored for -determining whether a target is out of date in "meta" mode. -See also -.Ic .NOMETA_CMP . -.It Pa silent= Ar bf -If -.Va bf -is True, when a .meta file is created, mark the target -.Ic .SILENT . -.El -.It Va .MAKE.META.BAILIWICK -In "meta" mode, provides a list of prefixes which -match the directories controlled by -.Nm . -If a file that was generated outside of -.Va .OBJDIR -but within said bailiwick is missing, -the current target is considered out-of-date. -.It Va .MAKE.META.CREATED -In "meta" mode, this variable contains a list of all the meta files -updated. -If not empty, it can be used to trigger processing of -.Va .MAKE.META.FILES . -.It Va .MAKE.META.FILES -In "meta" mode, this variable contains a list of all the meta files -used (updated or not). -This list can be used to process the meta files to extract dependency -information. -.It Va .MAKE.META.PREFIX -Defines the message printed for each meta file updated in "meta verbose" mode. -The default value is: -.Dl Building ${.TARGET:H:tA}/${.TARGET:T} -.It Va .MAKEOVERRIDES -This variable is used to record the names of variables assigned to -on the command line, so that they may be exported as part of -.Ql Ev MAKEFLAGS . -This behaviour can be disabled by assigning an empty value to -.Ql Va .MAKEOVERRIDES -within a makefile. -Extra variables can be exported from a makefile -by appending their names to -.Ql Va .MAKEOVERRIDES . -.Ql Ev MAKEFLAGS -is re-exported whenever -.Ql Va .MAKEOVERRIDES -is modified. -.It Va .MAKE.PID -The process-id of -.Nm . -.It Va .MAKE.PPID -The parent process-id of -.Nm . -.It Va MAKE_PRINT_VAR_ON_ERROR -When -.Nm -stops due to an error, it prints its name and the value of -.Ql Va .CURDIR -as well as the value of any variables named in -.Ql Va MAKE_PRINT_VAR_ON_ERROR . -.It Va .newline -This variable is simply assigned a newline character as its value. -This allows expansions using the -.Cm \&:@ -modifier to put a newline between -iterations of the loop rather than a space. -For example, the printing of -.Ql Va MAKE_PRINT_VAR_ON_ERROR -could be done as ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}. -.It Va .OBJDIR -A path to the directory where the targets are built. -Its value is determined by trying to -.Xr chdir 2 -to the following directories in order and using the first match: -.Bl -enum -.It -.Ev ${MAKEOBJDIRPREFIX}${.CURDIR} -.Pp -(Only if -.Ql Ev MAKEOBJDIRPREFIX -is set in the environment or on the command line.) -.It -.Ev ${MAKEOBJDIR} -.Pp -(Only if -.Ql Ev MAKEOBJDIR -is set in the environment or on the command line.) -.It -.Ev ${.CURDIR} Ns Pa /obj. Ns Ev ${MACHINE} -.It -.Ev ${.CURDIR} Ns Pa /obj -.It -.Pa /usr/obj/ Ns Ev ${.CURDIR} -.It -.Ev ${.CURDIR} -.El -.Pp -Variable expansion is performed on the value before it's used, -so expressions such as -.Dl ${.CURDIR:S,^/usr/src,/var/obj,} -may be used. -This is especially useful with -.Ql Ev MAKEOBJDIR . -.Pp -.Ql Va .OBJDIR -may be modified in the makefile as a global variable. -In all cases, -.Nm -will -.Xr chdir 2 -to -.Ql Va .OBJDIR -and set -.Ql Ev PWD -to that directory before executing any targets. -. -.It Va .PARSEDIR -A path to the directory of the current -.Ql Pa Makefile -being parsed. -.It Va .PARSEFILE -The basename of the current -.Ql Pa Makefile -being parsed. -This variable and -.Ql Va .PARSEDIR -are both set only while the -.Ql Pa Makefiles -are being parsed. -If you want to retain their current values, assign them to a variable -using assignment with expansion: -.Pq Ql Cm \&:= . -.It Va .PATH -A variable that represents the list of directories that -.Nm -will search for files. -The search list should be updated using the target -.Ql Va .PATH -rather than the variable. -.It Ev PWD -Alternate path to the current directory. -.Nm -normally sets -.Ql Va .CURDIR -to the canonical path given by -.Xr getcwd 3 . -However, if the environment variable -.Ql Ev PWD -is set and gives a path to the current directory, then -.Nm -sets -.Ql Va .CURDIR -to the value of -.Ql Ev PWD -instead. -This behaviour is disabled if -.Ql Ev MAKEOBJDIRPREFIX -is set or -.Ql Ev MAKEOBJDIR -contains a variable transform. -.Ql Ev PWD -is set to the value of -.Ql Va .OBJDIR -for all programs which -.Nm -executes. -.It Ev .TARGETS -The list of targets explicitly specified on the command line, if any. -.It Ev VPATH -Colon-separated -.Pq Dq \&: -lists of directories that -.Nm -will search for files. -The variable is supported for compatibility with old make programs only, -use -.Ql Va .PATH -instead. -.El -.Ss Variable modifiers -Variable expansion may be modified to select or modify each word of the -variable (where a -.Dq word -is white-space delimited sequence of characters). -The general format of a variable expansion is as follows: -.Pp -.Dl ${variable[:modifier[:...]]} -.Pp -Each modifier begins with a colon, -which may be escaped with a backslash -.Pq Ql \e . -.Pp -A set of modifiers can be specified via a variable, as follows: -.Pp -.Dl modifier_variable=modifier[:...] -.Dl ${variable:${modifier_variable}[:...]} -.Pp -In this case the first modifier in the modifier_variable does not -start with a colon, since that must appear in the referencing -variable. -If any of the modifiers in the modifier_variable contain a dollar sign -.Pq Ql $ , -these must be doubled to avoid early expansion. -.Pp -The supported modifiers are: -.Bl -tag -width EEE -.It Cm \&:E -Replaces each word in the variable with its suffix. -.It Cm \&:H -Replaces each word in the variable with everything but the last component. -.It Cm \&:M Ns Ar pattern -Select only those words that match -.Ar pattern . -The standard shell wildcard characters -.Pf ( Ql * , -.Ql \&? , -and -.Ql Oo Oc ) -may -be used. -The wildcard characters may be escaped with a backslash -.Pq Ql \e . -.It Cm \&:N Ns Ar pattern -This is identical to -.Ql Cm \&:M , -but selects all words which do not match -.Ar pattern . -.It Cm \&:O -Order every word in variable alphabetically. -To sort words in -reverse order use the -.Ql Cm \&:O:[-1..1] -combination of modifiers. -.It Cm \&:Ox -Randomize words in variable. -The results will be different each time you are referring to the -modified variable; use the assignment with expansion -.Pq Ql Cm \&:= -to prevent such behaviour. -For example, -.Bd -literal -offset indent -LIST= uno due tre quattro -RANDOM_LIST= ${LIST:Ox} -STATIC_RANDOM_LIST:= ${LIST:Ox} - -all: - @echo "${RANDOM_LIST}" - @echo "${RANDOM_LIST}" - @echo "${STATIC_RANDOM_LIST}" - @echo "${STATIC_RANDOM_LIST}" -.Ed -may produce output similar to: -.Bd -literal -offset indent -quattro due tre uno -tre due quattro uno -due uno quattro tre -due uno quattro tre -.Ed -.It Cm \&:Q -Quotes every shell meta-character in the variable, so that it can be passed -safely through recursive invocations of -.Nm . -.It Cm \&:R -Replaces each word in the variable with everything but its suffix. -.It Cm \&:gmtime -The value is a format string for -.Xr strftime 3 , -using the current -.Xr gmtime 3 . -.It Cm \&:hash -Compute a 32bit hash of the value and encode it as hex digits. -.It Cm \&:localtime -The value is a format string for -.Xr strftime 3 , -using the current -.Xr localtime 3 . -.It Cm \&:tA -Attempt to convert variable to an absolute path using -.Xr realpath 3 , -if that fails, the value is unchanged. -.It Cm \&:tl -Converts variable to lower-case letters. -.It Cm \&:ts Ns Ar c -Words in the variable are normally separated by a space on expansion. -This modifier sets the separator to the character -.Ar c . -If -.Ar c -is omitted, then no separator is used. -The common escapes (including octal numeric codes), work as expected. -.It Cm \&:tu -Converts variable to upper-case letters. -.It Cm \&:tW -Causes the value to be treated as a single word -(possibly containing embedded white space). -See also -.Ql Cm \&:[*] . -.It Cm \&:tw -Causes the value to be treated as a sequence of -words delimited by white space. -See also -.Ql Cm \&:[@] . -.Sm off -.It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW -.Sm on -Modify the first occurrence of -.Ar old_string -in the variable's value, replacing it with -.Ar new_string . -If a -.Ql g -is appended to the last slash of the pattern, all occurrences -in each word are replaced. -If a -.Ql 1 -is appended to the last slash of the pattern, only the first word -is affected. -If a -.Ql W -is appended to the last slash of the pattern, -then the value is treated as a single word -(possibly containing embedded white space). -If -.Ar old_string -begins with a caret -.Pq Ql ^ , -.Ar old_string -is anchored at the beginning of each word. -If -.Ar old_string -ends with a dollar sign -.Pq Ql \&$ , -it is anchored at the end of each word. -Inside -.Ar new_string , -an ampersand -.Pq Ql \*[Am] -is replaced by -.Ar old_string -(without any -.Ql ^ -or -.Ql \&$ ) . -Any character may be used as a delimiter for the parts of the modifier -string. -The anchoring, ampersand and delimiter characters may be escaped with a -backslash -.Pq Ql \e . -.Pp -Variable expansion occurs in the normal fashion inside both -.Ar old_string -and -.Ar new_string -with the single exception that a backslash is used to prevent the expansion -of a dollar sign -.Pq Ql \&$ , -not a preceding dollar sign as is usual. -.Sm off -.It Cm \&:C No \&/ Ar pattern No \&/ Ar replacement No \&/ Op Cm 1gW -.Sm on -The -.Cm \&:C -modifier is just like the -.Cm \&:S -modifier except that the old and new strings, instead of being -simple strings, are a regular expression (see -.Xr regex 3 ) -string -.Ar pattern -and an -.Xr ed 1 Ns \-style -string -.Ar replacement . -Normally, the first occurrence of the pattern -.Ar pattern -in each word of the value is substituted with -.Ar replacement . -The -.Ql 1 -modifier causes the substitution to apply to at most one word; the -.Ql g -modifier causes the substitution to apply to as many instances of the -search pattern -.Ar pattern -as occur in the word or words it is found in; the -.Ql W -modifier causes the value to be treated as a single word -(possibly containing embedded white space). -Note that -.Ql 1 -and -.Ql g -are orthogonal; the former specifies whether multiple words are -potentially affected, the latter whether multiple substitutions can -potentially occur within each affected word. -.It Cm \&:T -Replaces each word in the variable with its last component. -.It Cm \&:u -Remove adjacent duplicate words (like -.Xr uniq 1 ) . -.Sm off -.It Cm \&:\&? Ar true_string Cm \&: Ar false_string -.Sm on -If the variable name (not its value), when parsed as a .if conditional -expression, evaluates to true, return as its value the -.Ar true_string , -otherwise return the -.Ar false_string . -Since the variable name is used as the expression, \&:\&? must be the -first modifier after the variable name itself - which will, of course, -usually contain variable expansions. -A common error is trying to use expressions like -.Dl ${NUMBERS:M42:?match:no} -which actually tests defined(NUMBERS), -to determine is any words match "42" you need to use something like: -.Dl ${"${NUMBERS:M42}" != \&"\&":?match:no} . -.It Ar :old_string=new_string -This is the -.At V -style variable substitution. -It must be the last modifier specified. -If -.Ar old_string -or -.Ar new_string -do not contain the pattern matching character -.Ar % -then it is assumed that they are -anchored at the end of each word, so only suffixes or entire -words may be replaced. -Otherwise -.Ar % -is the substring of -.Ar old_string -to be replaced in -.Ar new_string . -.Pp -Variable expansion occurs in the normal fashion inside both -.Ar old_string -and -.Ar new_string -with the single exception that a backslash is used to prevent the -expansion of a dollar sign -.Pq Ql \&$ , -not a preceding dollar sign as is usual. -.Sm off -.It Cm \&:@ Ar temp Cm @ Ar string Cm @ -.Sm on -This is the loop expansion mechanism from the OSF Development -Environment (ODE) make. -Unlike -.Cm \&.for -loops expansion occurs at the time of -reference. -Assign -.Ar temp -to each word in the variable and evaluate -.Ar string . -The ODE convention is that -.Ar temp -should start and end with a period. -For example. -.Dl ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@} -.Pp -However a single character varaiable is often more readable: -.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@} -.It Cm \&:U Ns Ar newval -If the variable is undefined -.Ar newval -is the value. -If the variable is defined, the existing value is returned. -This is another ODE make feature. -It is handy for setting per-target CFLAGS for instance: -.Dl ${_${.TARGET:T}_CFLAGS:U${DEF_CFLAGS}} -If a value is only required if the variable is undefined, use: -.Dl ${VAR:D:Unewval} -.It Cm \&:D Ns Ar newval -If the variable is defined -.Ar newval -is the value. -.It Cm \&:L -The name of the variable is the value. -.It Cm \&:P -The path of the node which has the same name as the variable -is the value. -If no such node exists or its path is null, then the -name of the variable is used. -In order for this modifier to work, the name (node) must at least have -appeared on the rhs of a dependency. -.Sm off -.It Cm \&:\&! Ar cmd Cm \&! -.Sm on -The output of running -.Ar cmd -is the value. -.It Cm \&:sh -If the variable is non-empty it is run as a command and the output -becomes the new value. -.It Cm \&::= Ns Ar str -The variable is assigned the value -.Ar str -after substitution. -This modifier and its variations are useful in -obscure situations such as wanting to set a variable when shell commands -are being parsed. -These assignment modifiers always expand to -nothing, so if appearing in a rule line by themselves should be -preceded with something to keep -.Nm -happy. -.Pp -The -.Ql Cm \&:: -helps avoid false matches with the -.At V -style -.Cm \&:= -modifier and since substitution always occurs the -.Cm \&::= -form is vaguely appropriate. -.It Cm \&::?= Ns Ar str -As for -.Cm \&::= -but only if the variable does not already have a value. -.It Cm \&::+= Ns Ar str -Append -.Ar str -to the variable. -.It Cm \&::!= Ns Ar cmd -Assign the output of -.Ar cmd -to the variable. -.It Cm \&:\&[ Ns Ar range Ns Cm \&] -Selects one or more words from the value, -or performs other operations related to the way in which the -value is divided into words. -.Pp -Ordinarily, a value is treated as a sequence of words -delimited by white space. -Some modifiers suppress this behaviour, -causing a value to be treated as a single word -(possibly containing embedded white space). -An empty value, or a value that consists entirely of white-space, -is treated as a single word. -For the purposes of the -.Ql Cm \&:[] -modifier, the words are indexed both forwards using positive integers -(where index 1 represents the first word), -and backwards using negative integers -(where index \-1 represents the last word). -.Pp -The -.Ar range -is subjected to variable expansion, and the expanded result is -then interpreted as follows: -.Bl -tag -width index -.\" :[n] -.It Ar index -Selects a single word from the value. -.\" :[start..end] -.It Ar start Ns Cm \&.. Ns Ar end -Selects all words from -.Ar start -to -.Ar end , -inclusive. -For example, -.Ql Cm \&:[2..-1] -selects all words from the second word to the last word. -If -.Ar start -is greater than -.Ar end , -then the words are output in reverse order. -For example, -.Ql Cm \&:[-1..1] -selects all the words from last to first. -.\" :[*] -.It Cm \&* -Causes subsequent modifiers to treat the value as a single word -(possibly containing embedded white space). -Analogous to the effect of -\&"$*\&" -in Bourne shell. -.\" :[0] -.It 0 -Means the same as -.Ql Cm \&:[*] . -.\" :[*] -.It Cm \&@ -Causes subsequent modifiers to treat the value as a sequence of words -delimited by white space. -Analogous to the effect of -\&"$@\&" -in Bourne shell. -.\" :[#] -.It Cm \&# -Returns the number of words in the value. -.El \" :[range] -.El -.Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS -Makefile inclusion, conditional structures and for loops reminiscent -of the C programming language are provided in -.Nm . -All such structures are identified by a line beginning with a single -dot -.Pq Ql \&. -character. -Files are included with either -.Cm \&.include Aq Ar file -or -.Cm \&.include Pf \*q Ar file Ns \*q . -Variables between the angle brackets or double quotes are expanded -to form the file name. -If angle brackets are used, the included makefile is expected to be in -the system makefile directory. -If double quotes are used, the including makefile's directory and any -directories specified using the -.Fl I -option are searched before the system -makefile directory. -For compatibility with other versions of -.Nm -.Ql include file ... -is also accepted. -If the include statement is written as -.Cm .-include -or as -.Cm .sinclude -then errors locating and/or opening include files are ignored. -.Pp -Conditional expressions are also preceded by a single dot as the first -character of a line. -The possible conditionals are as follows: -.Bl -tag -width Ds -.It Ic .error Ar message -The message is printed along with the name of the makefile and line number, -then -.Nm -will exit. -.It Ic .export Ar variable ... -Export the specified global variable. -If no variable list is provided, all globals are exported -except for internal variables (those that start with -.Ql \&. ) . -This is not affected by the -.Fl X -flag, so should be used with caution. -For compatibility with other -.Nm -programs -.Ql export variable=value -is also accepted. -.Pp -Appending a variable name to -.Va .MAKE.EXPORTED -is equivalent to exporting a variable. -.It Ic .export-env Ar variable ... -The same as -.Ql .export , -except that the variable is not appended to -.Va .MAKE.EXPORTED . -This allows exporting a value to the environment which is different from that -used by -.Nm -internally. -.It Ic .info Ar message -The message is printed along with the name of the makefile and line number. -.It Ic .undef Ar variable -Un-define the specified global variable. -Only global variables may be un-defined. -.It Ic .unexport Ar variable ... -The opposite of -.Ql .export . -The specified global -.Va variable -will be removed from -.Va .MAKE.EXPORTED . -If no variable list is provided, all globals are unexported, -and -.Va .MAKE.EXPORTED -deleted. -.It Ic .unexport-env -Unexport all globals previously exported and -clear the environment inherited from the parent. -This operation will cause a memory leak of the original environment, -so should be used sparingly. -Testing for -.Va .MAKE.LEVEL -being 0, would make sense. -Also note that any variables which originated in the parent environment -should be explicitly preserved if desired. -For example: -.Bd -literal -offset indent -.Li .if ${.MAKE.LEVEL} == 0 -PATH := ${PATH} -.Li .unexport-env -.Li .export PATH -.Li .endif -.Pp -.Ed -Would result in an environment containing only -.Ql Ev PATH , -which is the minimal useful environment. -Actually -.Ql Ev .MAKE.LEVEL -will also be pushed into the new environment. -.It Ic .warning Ar message -The message prefixed by -.Ql Pa warning: -is printed along with the name of the makefile and line number. -.It Ic \&.if Oo \&! Oc Ns Ar expression Op Ar operator expression ... -Test the value of an expression. -.It Ic .ifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -Test the value of a variable. -.It Ic .ifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -Test the value of a variable. -.It Ic .ifmake Oo \&! Oc Ns Ar target Op Ar operator target ... -Test the target being built. -.It Ic .ifnmake Oo \&! Ns Oc Ar target Op Ar operator target ... -Test the target being built. -.It Ic .else -Reverse the sense of the last conditional. -.It Ic .elif Oo \&! Ns Oc Ar expression Op Ar operator expression ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .if . -.It Ic .elifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifdef . -.It Ic .elifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifndef . -.It Ic .elifmake Oo \&! Oc Ns Ar target Op Ar operator target ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifmake . -.It Ic .elifnmake Oo \&! Oc Ns Ar target Op Ar operator target ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifnmake . -.It Ic .endif -End the body of the conditional. -.El -.Pp -The -.Ar operator -may be any one of the following: -.Bl -tag -width "Cm XX" -.It Cm \&|\&| -Logical OR. -.It Cm \&\*[Am]\*[Am] -Logical -.Tn AND ; -of higher precedence than -.Dq \&|\&| . -.El -.Pp -As in C, -.Nm -will only evaluate a conditional as far as is necessary to determine -its value. -Parentheses may be used to change the order of evaluation. -The boolean operator -.Ql Ic \&! -may be used to logically negate an entire -conditional. -It is of higher precedence than -.Ql Ic \&\*[Am]\*[Am] . -.Pp -The value of -.Ar expression -may be any of the following: -.Bl -tag -width defined -.It Ic defined -Takes a variable name as an argument and evaluates to true if the variable -has been defined. -.It Ic make -Takes a target name as an argument and evaluates to true if the target -was specified as part of -.Nm Ns 's -command line or was declared the default target (either implicitly or -explicitly, see -.Va .MAIN ) -before the line containing the conditional. -.It Ic empty -Takes a variable, with possible modifiers, and evaluates to true if -the expansion of the variable would result in an empty string. -.It Ic exists -Takes a file name as an argument and evaluates to true if the file exists. -The file is searched for on the system search path (see -.Va .PATH ) . -.It Ic target -Takes a target name as an argument and evaluates to true if the target -has been defined. -.It Ic commands -Takes a target name as an argument and evaluates to true if the target -has been defined and has commands associated with it. -.El -.Pp -.Ar Expression -may also be an arithmetic or string comparison. -Variable expansion is -performed on both sides of the comparison, after which the integral -values are compared. -A value is interpreted as hexadecimal if it is -preceded by 0x, otherwise it is decimal; octal numbers are not supported. -The standard C relational operators are all supported. -If after -variable expansion, either the left or right hand side of a -.Ql Ic == -or -.Ql Ic "!=" -operator is not an integral value, then -string comparison is performed between the expanded -variables. -If no relational operator is given, it is assumed that the expanded -variable is being compared against 0 or an empty string in the case -of a string comparison. -.Pp -When -.Nm -is evaluating one of these conditional expressions, and it encounters -a (white-space separated) word it doesn't recognize, either the -.Dq make -or -.Dq defined -expression is applied to it, depending on the form of the conditional. -If the form is -.Ql Ic .ifdef , -.Ql Ic .ifndef , -or -.Ql Ic .if -the -.Dq defined -expression is applied. -Similarly, if the form is -.Ql Ic .ifmake -or -.Ql Ic .ifnmake , the -.Dq make -expression is applied. -.Pp -If the conditional evaluates to true the parsing of the makefile continues -as before. -If it evaluates to false, the following lines are skipped. -In both cases this continues until a -.Ql Ic .else -or -.Ql Ic .endif -is found. -.Pp -For loops are typically used to apply a set of rules to a list of files. -The syntax of a for loop is: -.Pp -.Bl -tag -compact -width Ds -.It Ic \&.for Ar variable Oo Ar variable ... Oc Ic in Ar expression -.It Aq make-rules -.It Ic \&.endfor -.El -.Pp -After the for -.Ic expression -is evaluated, it is split into words. -On each iteration of the loop, one word is taken and assigned to each -.Ic variable , -in order, and these -.Ic variables -are substituted into the -.Ic make-rules -inside the body of the for loop. -The number of words must come out even; that is, if there are three -iteration variables, the number of words provided must be a multiple -of three. -.Sh COMMENTS -Comments begin with a hash -.Pq Ql \&# -character, anywhere but in a shell -command line, and continue to the end of an unescaped new line. -.Sh SPECIAL SOURCES (ATTRIBUTES) -.Bl -tag -width .IGNOREx -.It Ic .EXEC -Target is never out of date, but always execute commands anyway. -.It Ic .IGNORE -Ignore any errors from the commands associated with this target, exactly -as if they all were preceded by a dash -.Pq Ql \- . -.\" .It Ic .INVISIBLE -.\" XXX -.\" .It Ic .JOIN -.\" XXX -.It Ic .MADE -Mark all sources of this target as being up-to-date. -.It Ic .MAKE -Execute the commands associated with this target even if the -.Fl n -or -.Fl t -options were specified. -Normally used to mark recursive -.Nm Ns 's . -.It Ic .META -Create a meta file for the target, even if it is flagged as -.Ic .PHONY , -.Ic .MAKE , -or -.Ic .SPECIAL . -Usage in conjunction with -.Ic .MAKE -is the most likely case. -In "meta" mode, the target is out-of-date if the meta file is missing. -.It Ic .NOMETA -Do not create a meta file for the target. -Meta files are also not created for -.Ic .PHONY , -.Ic .MAKE , -or -.Ic .SPECIAL -targets. -.It Ic .NOMETA_CMP -Ignore differences in commands when deciding if target is out of date. -This is useful if the command contains a value which always changes. -If the number of commands change, though, the target will still be out of date. -.It Ic .NOPATH -Do not search for the target in the directories specified by -.Ic .PATH . -.It Ic .NOTMAIN -Normally -.Nm -selects the first target it encounters as the default target to be built -if no target was specified. -This source prevents this target from being selected. -.It Ic .OPTIONAL -If a target is marked with this attribute and -.Nm -can't figure out how to create it, it will ignore this fact and assume -the file isn't needed or already exists. -.It Ic .PHONY -The target does not -correspond to an actual file; it is always considered to be out of date, -and will not be created with the -.Fl t -option. -Suffix-transformation rules are not applied to -.Ic .PHONY -targets. -.It Ic .PRECIOUS -When -.Nm -is interrupted, it normally removes any partially made targets. -This source prevents the target from being removed. -.It Ic .RECURSIVE -Synonym for -.Ic .MAKE . -.It Ic .SILENT -Do not echo any of the commands associated with this target, exactly -as if they all were preceded by an at sign -.Pq Ql @ . -.It Ic .USE -Turn the target into -.Nm Ns 's -version of a macro. -When the target is used as a source for another target, the other target -acquires the commands, sources, and attributes (except for -.Ic .USE ) -of the -source. -If the target already has commands, the -.Ic .USE -target's commands are appended -to them. -.It Ic .USEBEFORE -Exactly like -.Ic .USE , -but prepend the -.Ic .USEBEFORE -target commands to the target. -.It Ic .WAIT -If -.Ic .WAIT -appears in a dependency line, the sources that precede it are -made before the sources that succeed it in the line. -Since the dependents of files are not made until the file itself -could be made, this also stops the dependents being built unless they -are needed for another branch of the dependency tree. -So given: -.Bd -literal -x: a .WAIT b - echo x -a: - echo a -b: b1 - echo b -b1: - echo b1 - -.Ed -the output is always -.Ql a , -.Ql b1 , -.Ql b , -.Ql x . -.br -The ordering imposed by -.Ic .WAIT -is only relevant for parallel makes. -.El -.Sh SPECIAL TARGETS -Special targets may not be included with other targets, i.e. they must be -the only target specified. -.Bl -tag -width .BEGINx -.It Ic .BEGIN -Any command lines attached to this target are executed before anything -else is done. -.It Ic .DEFAULT -This is sort of a -.Ic .USE -rule for any target (that was used only as a -source) that -.Nm -can't figure out any other way to create. -Only the shell script is used. -The -.Ic .IMPSRC -variable of a target that inherits -.Ic .DEFAULT Ns 's -commands is set -to the target's own name. -.It Ic .END -Any command lines attached to this target are executed after everything -else is done. -.It Ic .ERROR -Any command lines attached to this target are executed when another target fails. -The -.Ic .ERROR_TARGET -variable is set to the target that failed. -See also -.Ic MAKE_PRINT_VAR_ON_ERROR . -.It Ic .IGNORE -Mark each of the sources with the -.Ic .IGNORE -attribute. -If no sources are specified, this is the equivalent of specifying the -.Fl i -option. -.It Ic .INTERRUPT -If -.Nm -is interrupted, the commands for this target will be executed. -.It Ic .MAIN -If no target is specified when -.Nm -is invoked, this target will be built. -.It Ic .MAKEFLAGS -This target provides a way to specify flags for -.Nm -when the makefile is used. -The flags are as if typed to the shell, though the -.Fl f -option will have -no effect. -.\" XXX: NOT YET!!!! -.\" .It Ic .NOTPARALLEL -.\" The named targets are executed in non parallel mode. -.\" If no targets are -.\" specified, then all targets are executed in non parallel mode. -.It Ic .NOPATH -Apply the -.Ic .NOPATH -attribute to any specified sources. -.It Ic .NOTPARALLEL -Disable parallel mode. -.It Ic .NO_PARALLEL -Synonym for -.Ic .NOTPARALLEL , -for compatibility with other pmake variants. -.It Ic .ORDER -The named targets are made in sequence. -This ordering does not add targets to the list of targets to be made. -Since the dependents of a target do not get built until the target itself -could be built, unless -.Ql a -is built by another part of the dependency graph, -the following is a dependency loop: -.Bd -literal -\&.ORDER: b a -b: a -.Ed -.Pp -The ordering imposed by -.Ic .ORDER -is only relevant for parallel makes. -.\" XXX: NOT YET!!!! -.\" .It Ic .PARALLEL -.\" The named targets are executed in parallel mode. -.\" If no targets are -.\" specified, then all targets are executed in parallel mode. -.It Ic .PATH -The sources are directories which are to be searched for files not -found in the current directory. -If no sources are specified, any previously specified directories are -deleted. -If the source is the special -.Ic .DOTLAST -target, then the current working -directory is searched last. -.It Ic .PHONY -Apply the -.Ic .PHONY -attribute to any specified sources. -.It Ic .PRECIOUS -Apply the -.Ic .PRECIOUS -attribute to any specified sources. -If no sources are specified, the -.Ic .PRECIOUS -attribute is applied to every -target in the file. -.It Ic .SHELL -Sets the shell that -.Nm -will use to execute commands. -The sources are a set of -.Ar field=value -pairs. -.Bl -tag -width hasErrCtls -.It Ar name -This is the minimal specification, used to select one of the builtin -shell specs; -.Ar sh , -.Ar ksh , -and -.Ar csh . -.It Ar path -Specifies the path to the shell. -.It Ar hasErrCtl -Indicates whether the shell supports exit on error. -.It Ar check -The command to turn on error checking. -.It Ar ignore -The command to disable error checking. -.It Ar echo -The command to turn on echoing of commands executed. -.It Ar quiet -The command to turn off echoing of commands executed. -.It Ar filter -The output to filter after issuing the -.Ar quiet -command. -It is typically identical to -.Ar quiet . -.It Ar errFlag -The flag to pass the shell to enable error checking. -.It Ar echoFlag -The flag to pass the shell to enable command echoing. -.It Ar newline -The string literal to pass the shell that results in a single newline -character when used outside of any quoting characters. -.El -Example: -.Bd -literal -\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \e - check="set \-e" ignore="set +e" \e - echo="set \-v" quiet="set +v" filter="set +v" \e - echoFlag=v errFlag=e newline="'\en'" -.Ed -.It Ic .SILENT -Apply the -.Ic .SILENT -attribute to any specified sources. -If no sources are specified, the -.Ic .SILENT -attribute is applied to every -command in the file. -.It Ic .SUFFIXES -Each source specifies a suffix to -.Nm . -If no sources are specified, any previously specified suffixes are deleted. -It allows the creation of suffix-transformation rules. -.Pp -Example: -.Bd -literal -\&.SUFFIXES: .o -\&.c.o: - cc \-o ${.TARGET} \-c ${.IMPSRC} -.Ed -.El -.Sh ENVIRONMENT -.Nm -uses the following environment variables, if they exist: -.Ev MACHINE , -.Ev MACHINE_ARCH , -.Ev MAKE , -.Ev MAKEFLAGS , -.Ev MAKEOBJDIR , -.Ev MAKEOBJDIRPREFIX , -.Ev MAKESYSPATH , -.Ev PWD , -and -.Ev TMPDIR . -.Pp -.Ev MAKEOBJDIRPREFIX -and -.Ev MAKEOBJDIR -may only be set in the environment or on the command line to -.Nm -and not as makefile variables; -see the description of -.Ql Va .OBJDIR -for more details. -.Sh FILES -.Bl -tag -width /usr/share/mk -compact -.It .depend -list of dependencies -.It Makefile -list of dependencies -.It makefile -list of dependencies -.It sys.mk -system makefile -.It /usr/share/mk -system makefile directory -.El -.Sh COMPATIBILITY -The basic make syntax is compatible between different versions of make, -however the special variables, variable modifiers and conditionals are not. -.Pp -The way that parallel makes are scheduled changed in -NetBSD 4.0 -so that .ORDER and .WAIT apply recursively to the dependent nodes. -The algorithms used may change again in the future. -.Pp -The way that .for loop variables are substituted changed after -NetBSD 5.0 -so that they still appear to be variable expansions. -In particular this stops them being treated as syntax, and removes some -obscure problems using them in .if statements. -.Pp -Unlike other -.Nm -programs, this implementation by default executes all commands for a given -target using a single shell invocation. -This is done for both efficiency and to simplify error handling in remote -command invocations. -Typically this is transparent to the user, unless the target commands change -the current working directory using -.Dq cd -or -.Dq chdir . -To be compatible with Makefiles that do this, one can use -.Fl B -to disable this behavior. -.Sh SEE ALSO -.Xr mkdep 1 -.Sh HISTORY -.Nm -is derived from NetBSD -.Xr make 1 . -It uses autoconf to facilitate portability to other platforms. diff --git a/20120831/bmake.cat1 b/20120831/bmake.cat1 deleted file mode 100644 index 7624c43..0000000 --- a/20120831/bmake.cat1 +++ /dev/null @@ -1,1305 +0,0 @@ -MAKE(1) NetBSD General Commands Manual MAKE(1) - -NNAAMMEE - bbmmaakkee -- maintain program dependencies - -SSYYNNOOPPSSIISS - bbmmaakkee [--BBeeiikkNNnnqqrrssttWWXX] [--CC _d_i_r_e_c_t_o_r_y] [--DD _v_a_r_i_a_b_l_e] [--dd _f_l_a_g_s] - [--ff _m_a_k_e_f_i_l_e] [--II _d_i_r_e_c_t_o_r_y] [--JJ _p_r_i_v_a_t_e] [--jj _m_a_x___j_o_b_s] - [--mm _d_i_r_e_c_t_o_r_y] [--TT _f_i_l_e] [--VV _v_a_r_i_a_b_l_e] [_v_a_r_i_a_b_l_e_=_v_a_l_u_e] - [_t_a_r_g_e_t _._._.] - -DDEESSCCRRIIPPTTIIOONN - bbmmaakkee is a program designed to simplify the maintenance of other pro- - grams. Its input is a list of specifications as to the files upon which - programs and other files depend. If no --ff _m_a_k_e_f_i_l_e makefile option is - given, bbmmaakkee will try to open `_m_a_k_e_f_i_l_e' then `_M_a_k_e_f_i_l_e' in order to find - the specifications. If the file `_._d_e_p_e_n_d' exists, it is read (see - mkdep(1)). - - This manual page is intended as a reference document only. For a more - thorough description of bbmmaakkee and makefiles, please refer to _P_M_a_k_e _- _A - _T_u_t_o_r_i_a_l. - - bbmmaakkee will prepend the contents of the _M_A_K_E_F_L_A_G_S environment variable to - the command line arguments before parsing them. - - The options are as follows: - - --BB Try to be backwards compatible by executing a single shell per - command and by executing the commands to make the sources of a - dependency line in sequence. - - --CC _d_i_r_e_c_t_o_r_y - Change to _d_i_r_e_c_t_o_r_y before reading the makefiles or doing any- - thing else. If multiple --CC options are specified, each is inter- - preted relative to the previous one: --CC _/ --CC _e_t_c is equivalent to - --CC _/_e_t_c. - - --DD _v_a_r_i_a_b_l_e - Define _v_a_r_i_a_b_l_e to be 1, in the global context. - - --dd _[_-_]_f_l_a_g_s - Turn on debugging, and specify which portions of bbmmaakkee are to - print debugging information. Unless the flags are preceded by - `-' they are added to the _M_A_K_E_F_L_A_G_S environment variable and will - be processed by any child make processes. By default, debugging - information is printed to standard error, but this can be changed - using the _F debugging flag. The debugging output is always - unbuffered; in addition, if debugging is enabled but debugging - output is not directed to standard output, then the standard out- - put is line buffered. _F_l_a_g_s is one or more of the following: - - _A Print all possible debugging information; equivalent to - specifying all of the debugging flags. - - _a Print debugging information about archive searching and - caching. - - _C Print debugging information about current working direc- - tory. - - _c Print debugging information about conditional evaluation. - - _d Print debugging information about directory searching and - caching. - - _e Print debugging information about failed commands and - targets. - - _F[++]_f_i_l_e_n_a_m_e - Specify where debugging output is written. This must be - the last flag, because it consumes the remainder of the - argument. If the character immediately after the `F' - flag is `+', then the file will be opened in append mode; - otherwise the file will be overwritten. If the file name - is `stdout' or `stderr' then debugging output will be - written to the standard output or standard error output - file descriptors respectively (and the `+' option has no - effect). Otherwise, the output will be written to the - named file. If the file name ends `.%d' then the `%d' is - replaced by the pid. - - _f Print debugging information about loop evaluation. - - _g_1 Print the input graph before making anything. - - _g_2 Print the input graph after making everything, or before - exiting on error. - - _g_3 Print the input graph before exiting on error. - - _j Print debugging information about running multiple - shells. - - _l Print commands in Makefiles regardless of whether or not - they are prefixed by `@' or other "quiet" flags. Also - known as "loud" behavior. - - _M Print debugging information about "meta" mode decisions - about targets. - - _m Print debugging information about making targets, includ- - ing modification dates. - - _n Don't delete the temporary command scripts created when - running commands. These temporary scripts are created in - the directory referred to by the TMPDIR environment vari- - able, or in _/_t_m_p if TMPDIR is unset or set to the empty - string. The temporary scripts are created by mkstemp(3), - and have names of the form _m_a_k_e_X_X_X_X_X_X. _N_O_T_E: This can - create many files in TMPDIR or _/_t_m_p, so use with care. - - _p Print debugging information about makefile parsing. - - _s Print debugging information about suffix-transformation - rules. - - _t Print debugging information about target list mainte- - nance. - - _v Print debugging information about variable assignment. - - _x Run shell commands with --xx so the actual commands are - printed as they are executed. - - --ee Specify that environment variables override macro assignments - within makefiles. - - --ff _m_a_k_e_f_i_l_e - Specify a makefile to read instead of the default `_m_a_k_e_f_i_l_e'. If - _m_a_k_e_f_i_l_e is `--', standard input is read. Multiple makefiles may - be specified, and are read in the order specified. - - --II _d_i_r_e_c_t_o_r_y - Specify a directory in which to search for makefiles and included - makefiles. The system makefile directory (or directories, see - the --mm option) is automatically included as part of this list. - - --ii Ignore non-zero exit of shell commands in the makefile. Equiva- - lent to specifying `--' before each command line in the makefile. - - --JJ _p_r_i_v_a_t_e - This option should _n_o_t be specified by the user. - - When the _j option is in use in a recursive build, this option is - passed by a make to child makes to allow all the make processes - in the build to cooperate to avoid overloading the system. - - --jj _m_a_x___j_o_b_s - Specify the maximum number of jobs that bbmmaakkee may have running at - any one time. The value is saved in _._M_A_K_E_._J_O_B_S. Turns compati- - bility mode off, unless the _B flag is also specified. When com- - patibility mode is off, all commands associated with a target are - executed in a single shell invocation as opposed to the tradi- - tional one shell invocation per line. This can break traditional - scripts which change directories on each command invocation and - then expect to start with a fresh environment on the next line. - It is more efficient to correct the scripts rather than turn - backwards compatibility on. - - --kk Continue processing after errors are encountered, but only on - those targets that do not depend on the target whose creation - caused the error. - - --mm _d_i_r_e_c_t_o_r_y - Specify a directory in which to search for sys.mk and makefiles - included via the <_f_i_l_e>-style include statement. The --mm option - can be used multiple times to form a search path. This path will - override the default system include path: /usr/share/mk. Fur- - thermore the system include path will be appended to the search - path used for "_f_i_l_e"-style include statements (see the --II - option). - - If a file or directory name in the --mm argument (or the - MAKESYSPATH environment variable) starts with the string ".../" - then bbmmaakkee will search for the specified file or directory named - in the remaining part of the argument string. The search starts - with the current directory of the Makefile and then works upward - towards the root of the filesystem. If the search is successful, - then the resulting directory replaces the ".../" specification in - the --mm argument. If used, this feature allows bbmmaakkee to easily - search in the current source tree for customized sys.mk files - (e.g., by using ".../mk/sys.mk" as an argument). - - --nn Display the commands that would have been executed, but do not - actually execute them unless the target depends on the .MAKE spe- - cial source (see below). - - --NN Display the commands which would have been executed, but do not - actually execute any of them; useful for debugging top-level - makefiles without descending into subdirectories. - - --qq Do not execute any commands, but exit 0 if the specified targets - are up-to-date and 1, otherwise. - - --rr Do not use the built-in rules specified in the system makefile. - - --ss Do not echo any commands as they are executed. Equivalent to - specifying `@@' before each command line in the makefile. - - --TT _t_r_a_c_e_f_i_l_e - When used with the --jj flag, append a trace record to _t_r_a_c_e_f_i_l_e - for each job started and completed. - - --tt Rather than re-building a target as specified in the makefile, - create it or update its modification time to make it appear up- - to-date. - - --VV _v_a_r_i_a_b_l_e - Print bbmmaakkee's idea of the value of _v_a_r_i_a_b_l_e, in the global con- - text. Do not build any targets. Multiple instances of this - option may be specified; the variables will be printed one per - line, with a blank line for each null or undefined variable. If - _v_a_r_i_a_b_l_e contains a `$' then the value will be expanded before - printing. - - --WW Treat any warnings during makefile parsing as errors. - - --XX Don't export variables passed on the command line to the environ- - ment individually. Variables passed on the command line are - still exported via the _M_A_K_E_F_L_A_G_S environment variable. This - option may be useful on systems which have a small limit on the - size of command arguments. - - _v_a_r_i_a_b_l_e_=_v_a_l_u_e - Set the value of the variable _v_a_r_i_a_b_l_e to _v_a_l_u_e. Normally, all - values passed on the command line are also exported to sub-makes - in the environment. The --XX flag disables this behavior. Vari- - able assignments should follow options for POSIX compatibility - but no ordering is enforced. - - There are seven different types of lines in a makefile: file dependency - specifications, shell commands, variable assignments, include statements, - conditional directives, for loops, and comments. - - In general, lines may be continued from one line to the next by ending - them with a backslash (`\'). The trailing newline character and initial - whitespace on the following line are compressed into a single space. - -FFIILLEE DDEEPPEENNDDEENNCCYY SSPPEECCIIFFIICCAATTIIOONNSS - Dependency lines consist of one or more targets, an operator, and zero or - more sources. This creates a relationship where the targets ``depend'' - on the sources and are usually created from them. The exact relationship - between the target and the source is determined by the operator that sep- - arates them. The three operators are as follows: - - :: A target is considered out-of-date if its modification time is less - than those of any of its sources. Sources for a target accumulate - over dependency lines when this operator is used. The target is - removed if bbmmaakkee is interrupted. - - !! Targets are always re-created, but not until all sources have been - examined and re-created as necessary. Sources for a target accumu- - late over dependency lines when this operator is used. The target - is removed if bbmmaakkee is interrupted. - - :::: If no sources are specified, the target is always re-created. Oth- - erwise, a target is considered out-of-date if any of its sources - has been modified more recently than the target. Sources for a - target do not accumulate over dependency lines when this operator - is used. The target will not be removed if bbmmaakkee is interrupted. - - Targets and sources may contain the shell wildcard values `?', `*', `[]', - and `{}'. The values `?', `*', and `[]' may only be used as part of the - final component of the target or source, and must be used to describe - existing files. The value `{}' need not necessarily be used to describe - existing files. Expansion is in directory order, not alphabetically as - done in the shell. - -SSHHEELLLL CCOOMMMMAANNDDSS - Each target may have associated with it a series of shell commands, nor- - mally used to create the target. Each of the commands in this script - _m_u_s_t be preceded by a tab. While any target may appear on a dependency - line, only one of these dependencies may be followed by a creation - script, unless the `::::' operator is used. - - If the first characters of the command line are any combination of `@@', - `++', or `--', the command is treated specially. A `@@' causes the command - not to be echoed before it is executed. A `++' causes the command to be - executed even when --nn is given. This is similar to the effect of the - .MAKE special source, except that the effect can be limited to a single - line of a script. A `--' causes any non-zero exit status of the command - line to be ignored. - -VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS - Variables in make are much like variables in the shell, and, by tradi- - tion, consist of all upper-case letters. - - VVaarriiaabbllee aassssiiggnnmmeenntt mmooddiiffiieerrss - The five operators that can be used to assign values to variables are as - follows: - - == Assign the value to the variable. Any previous value is overrid- - den. - - ++== Append the value to the current value of the variable. - - ??== Assign the value to the variable if it is not already defined. - - ::== Assign with expansion, i.e. expand the value before assigning it - to the variable. Normally, expansion is not done until the vari- - able is referenced. _N_O_T_E: References to undefined variables are - _n_o_t expanded. This can cause problems when variable modifiers - are used. - - !!== Expand the value and pass it to the shell for execution and - assign the result to the variable. Any newlines in the result - are replaced with spaces. - - Any white-space before the assigned _v_a_l_u_e is removed; if the value is - being appended, a single space is inserted between the previous contents - of the variable and the appended value. - - Variables are expanded by surrounding the variable name with either curly - braces (`{}') or parentheses (`()') and preceding it with a dollar sign - (`$'). If the variable name contains only a single letter, the surround- - ing braces or parentheses are not required. This shorter form is not - recommended. - - If the variable name contains a dollar, then the name itself is expanded - first. This allows almost arbitrary variable names, however names con- - taining dollar, braces, parenthesis, or whitespace are really best - avoided! - - If the result of expanding a variable contains a dollar sign (`$') the - string is expanded again. - - Variable substitution occurs at three distinct times, depending on where - the variable is being used. - - 1. Variables in dependency lines are expanded as the line is read. - - 2. Variables in shell commands are expanded when the shell command is - executed. - - 3. ``.for'' loop index variables are expanded on each loop iteration. - Note that other variables are not expanded inside loops so the fol- - lowing example code: - - - .for i in 1 2 3 - a+= ${i} - j= ${i} - b+= ${j} - .endfor - - all: - @echo ${a} - @echo ${b} - - will print: - - 1 2 3 - 3 3 3 - - Because while ${a} contains ``1 2 3'' after the loop is executed, - ${b} contains ``${j} ${j} ${j}'' which expands to ``3 3 3'' since - after the loop completes ${j} contains ``3''. - - VVaarriiaabbllee ccllaasssseess - The four different classes of variables (in order of increasing prece- - dence) are: - - Environment variables - Variables defined as part of bbmmaakkee's environment. - - Global variables - Variables defined in the makefile or in included makefiles. - - Command line variables - Variables defined as part of the command line. - - Local variables - Variables that are defined specific to a certain target. The - seven local variables are as follows: - - _._A_L_L_S_R_C The list of all sources for this target; also known as - `_>'. - - _._A_R_C_H_I_V_E The name of the archive file. - - _._I_M_P_S_R_C In suffix-transformation rules, the name/path of the - source from which the target is to be transformed (the - ``implied'' source); also known as `_<'. It is not - defined in explicit rules. - - _._M_E_M_B_E_R The name of the archive member. - - _._O_O_D_A_T_E The list of sources for this target that were deemed - out-of-date; also known as `_?'. - - _._P_R_E_F_I_X The file prefix of the target, containing only the file - portion, no suffix or preceding directory components; - also known as `_*'. - - _._T_A_R_G_E_T The name of the target; also known as `_@'. - - The shorter forms `_@', `_?', `_<', `_>', and `_*' are permitted for - backward compatibility with historical makefiles and are not rec- - ommended. The six variables `_@_F', `_@_D', `_<_F', `_<_D', `_*_F', and - `_*_D' are permitted for compatibility with AT&T System V UNIX - makefiles and are not recommended. - - Four of the local variables may be used in sources on dependency - lines because they expand to the proper value for each target on - the line. These variables are `_._T_A_R_G_E_T', `_._P_R_E_F_I_X', `_._A_R_C_H_I_V_E', - and `_._M_E_M_B_E_R'. - - AAddddiittiioonnaall bbuuiilltt--iinn vvaarriiaabblleess - In addition, bbmmaakkee sets or knows about the following variables: - - _$ A single dollar sign `$', i.e. `$$' expands to a single - dollar sign. - - _._A_L_L_T_A_R_G_E_T_S The list of all targets encountered in the Makefile. If - evaluated during Makefile parsing, lists only those tar- - gets encountered thus far. - - _._C_U_R_D_I_R A path to the directory where bbmmaakkee was executed. Refer - to the description of `PWD' for more details. - - MAKE The name that bbmmaakkee was executed with (_a_r_g_v_[_0_]). For - compatibility bbmmaakkee also sets _._M_A_K_E with the same value. - The preferred variable to use is the environment variable - MAKE because it is more compatible with other versions of - bbmmaakkee and cannot be confused with the special target with - the same name. - - _._M_A_K_E_._D_E_P_E_N_D_F_I_L_E - Names the makefile (default `_._d_e_p_e_n_d') from which gener- - ated dependencies are read. - - _._M_A_K_E_._E_X_P_O_R_T_E_D The list of variables exported by bbmmaakkee. - - _._M_A_K_E_._J_O_B_S The argument to the --jj option. - - _._M_A_K_E_._J_O_B_._P_R_E_F_I_X - If bbmmaakkee is run with _j then output for each target is - prefixed with a token `--- target ---' the first part of - which can be controlled via _._M_A_K_E_._J_O_B_._P_R_E_F_I_X. - For example: - .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}] - would produce tokens like `---make[1234] target ---' mak- - ing it easier to track the degree of parallelism being - achieved. - - MAKEFLAGS The environment variable `MAKEFLAGS' may contain anything - that may be specified on bbmmaakkee's command line. Anything - specified on bbmmaakkee's command line is appended to the - `MAKEFLAGS' variable which is then entered into the envi- - ronment for all programs which bbmmaakkee executes. - - _._M_A_K_E_._L_E_V_E_L The recursion depth of bbmmaakkee. The initial instance of - bbmmaakkee will be 0, and an incremented value is put into the - environment to be seen by the next generation. This - allows tests like: .if ${.MAKE.LEVEL} == 0 to protect - things which should only be evaluated in the initial - instance of bbmmaakkee. - - _._M_A_K_E_._M_A_K_E_F_I_L_E___P_R_E_F_E_R_E_N_C_E - The ordered list of makefile names (default `_m_a_k_e_f_i_l_e', - `_M_a_k_e_f_i_l_e') that bbmmaakkee will look for. - - _._M_A_K_E_._M_A_K_E_F_I_L_E_S - The list of makefiles read by bbmmaakkee, which is useful for - tracking dependencies. Each makefile is recorded only - once, regardless of the number of times read. - - _._M_A_K_E_._M_O_D_E Processed after reading all makefiles. Can affect the - mode that bbmmaakkee runs in. It can contain a number of key- - words: - - _c_o_m_p_a_t Like --BB, puts bbmmaakkee into "compat" mode. - - _m_e_t_a Puts bbmmaakkee into "meta" mode, where meta files - are created for each target to capture the - command run, the output generated and if - filemon(4) is available, the system calls - which are of interest to bbmmaakkee. The captured - output can be very useful when diagnosing - errors. - - _c_u_r_d_i_r_O_k_= _b_f Normally bbmmaakkee will not create .meta files - in `_._C_U_R_D_I_R'. This can be overridden by set- - ting _b_f to a value which represents True. - - _e_n_v For debugging, it can be useful to inlcude - the environment in the .meta file. - - _v_e_r_b_o_s_e If in "meta" mode, print a clue about the - target being built. This is useful if the - build is otherwise running silently. The - message printed the value of: - _._M_A_K_E_._M_E_T_A_._P_R_E_F_I_X. - - _i_g_n_o_r_e_-_c_m_d Some makefiles have commands which are simply - not stable. This keyword causes them to be - ignored for determining whether a target is - out of date in "meta" mode. See also - ..NNOOMMEETTAA__CCMMPP. - - _s_i_l_e_n_t_= _b_f If _b_f is True, when a .meta file is created, - mark the target ..SSIILLEENNTT. - - _._M_A_K_E_._M_E_T_A_._B_A_I_L_I_W_I_C_K - In "meta" mode, provides a list of prefixes which match - the directories controlled by bbmmaakkee. If a file that was - generated outside of _._O_B_J_D_I_R but within said bailiwick is - missing, the current target is considered out-of-date. - - _._M_A_K_E_._M_E_T_A_._C_R_E_A_T_E_D - In "meta" mode, this variable contains a list of all the - meta files updated. If not empty, it can be used to - trigger processing of _._M_A_K_E_._M_E_T_A_._F_I_L_E_S. - - _._M_A_K_E_._M_E_T_A_._F_I_L_E_S - In "meta" mode, this variable contains a list of all the - meta files used (updated or not). This list can be used - to process the meta files to extract dependency informa- - tion. - - _._M_A_K_E_._M_E_T_A_._P_R_E_F_I_X - Defines the message printed for each meta file updated in - "meta verbose" mode. The default value is: - Building ${.TARGET:H:tA}/${.TARGET:T} - - _._M_A_K_E_O_V_E_R_R_I_D_E_S This variable is used to record the names of variables - assigned to on the command line, so that they may be - exported as part of `MAKEFLAGS'. This behaviour can be - disabled by assigning an empty value to `_._M_A_K_E_O_V_E_R_R_I_D_E_S' - within a makefile. Extra variables can be exported from - a makefile by appending their names to `_._M_A_K_E_O_V_E_R_R_I_D_E_S'. - `MAKEFLAGS' is re-exported whenever `_._M_A_K_E_O_V_E_R_R_I_D_E_S' is - modified. - - _._M_A_K_E_._P_I_D The process-id of bbmmaakkee. - - _._M_A_K_E_._P_P_I_D The parent process-id of bbmmaakkee. - - _M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R - When bbmmaakkee stops due to an error, it prints its name and - the value of `_._C_U_R_D_I_R' as well as the value of any vari- - ables named in `_M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R'. - - _._n_e_w_l_i_n_e This variable is simply assigned a newline character as - its value. This allows expansions using the ::@@ modifier - to put a newline between iterations of the loop rather - than a space. For example, the printing of - `_M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R' could be done as - ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}. - - _._O_B_J_D_I_R A path to the directory where the targets are built. Its - value is determined by trying to chdir(2) to the follow- - ing directories in order and using the first match: - - 1. ${MAKEOBJDIRPREFIX}${.CURDIR} - - (Only if `MAKEOBJDIRPREFIX' is set in the environ- - ment or on the command line.) - - 2. ${MAKEOBJDIR} - - (Only if `MAKEOBJDIR' is set in the environment or - on the command line.) - - 3. ${.CURDIR}_/_o_b_j_.${MACHINE} - - 4. ${.CURDIR}_/_o_b_j - - 5. _/_u_s_r_/_o_b_j_/${.CURDIR} - - 6. ${.CURDIR} - - Variable expansion is performed on the value before it's - used, so expressions such as - ${.CURDIR:S,^/usr/src,/var/obj,} - may be used. This is especially useful with - `MAKEOBJDIR'. - - `_._O_B_J_D_I_R' may be modified in the makefile as a global - variable. In all cases, bbmmaakkee will chdir(2) to `_._O_B_J_D_I_R' - and set `PWD' to that directory before executing any tar- - gets. - - _._P_A_R_S_E_D_I_R A path to the directory of the current `_M_a_k_e_f_i_l_e' being - parsed. - - _._P_A_R_S_E_F_I_L_E The basename of the current `_M_a_k_e_f_i_l_e' being parsed. - This variable and `_._P_A_R_S_E_D_I_R' are both set only while the - `_M_a_k_e_f_i_l_e_s' are being parsed. If you want to retain - their current values, assign them to a variable using - assignment with expansion: (`::=='). - - _._P_A_T_H A variable that represents the list of directories that - bbmmaakkee will search for files. The search list should be - updated using the target `_._P_A_T_H' rather than the vari- - able. - - PWD Alternate path to the current directory. bbmmaakkee normally - sets `_._C_U_R_D_I_R' to the canonical path given by getcwd(3). - However, if the environment variable `PWD' is set and - gives a path to the current directory, then bbmmaakkee sets - `_._C_U_R_D_I_R' to the value of `PWD' instead. This behaviour - is disabled if `MAKEOBJDIRPREFIX' is set or `MAKEOBJDIR' - contains a variable transform. `PWD' is set to the value - of `_._O_B_J_D_I_R' for all programs which bbmmaakkee executes. - - .TARGETS The list of targets explicitly specified on the command - line, if any. - - VPATH Colon-separated (``:'') lists of directories that bbmmaakkee - will search for files. The variable is supported for - compatibility with old make programs only, use `_._P_A_T_H' - instead. - - VVaarriiaabbllee mmooddiiffiieerrss - Variable expansion may be modified to select or modify each word of the - variable (where a ``word'' is white-space delimited sequence of charac- - ters). The general format of a variable expansion is as follows: - - ${variable[:modifier[:...]]} - - Each modifier begins with a colon, which may be escaped with a backslash - (`\'). - - A set of modifiers can be specified via a variable, as follows: - - modifier_variable=modifier[:...] - ${variable:${modifier_variable}[:...]} - - In this case the first modifier in the modifier_variable does not start - with a colon, since that must appear in the referencing variable. If any - of the modifiers in the modifier_variable contain a dollar sign (`$'), - these must be doubled to avoid early expansion. - - The supported modifiers are: - - ::EE Replaces each word in the variable with its suffix. - - ::HH Replaces each word in the variable with everything but the last com- - ponent. - - ::MM_p_a_t_t_e_r_n - Select only those words that match _p_a_t_t_e_r_n. The standard shell - wildcard characters (`*', `?', and `[]') may be used. The wildcard - characters may be escaped with a backslash (`\'). - - ::NN_p_a_t_t_e_r_n - This is identical to `::MM', but selects all words which do not match - _p_a_t_t_e_r_n. - - ::OO Order every word in variable alphabetically. To sort words in - reverse order use the `::OO::[[--11....11]]' combination of modifiers. - - ::OOxx Randomize words in variable. The results will be different each - time you are referring to the modified variable; use the assignment - with expansion (`::==') to prevent such behaviour. For example, - - LIST= uno due tre quattro - RANDOM_LIST= ${LIST:Ox} - STATIC_RANDOM_LIST:= ${LIST:Ox} - - all: - @echo "${RANDOM_LIST}" - @echo "${RANDOM_LIST}" - @echo "${STATIC_RANDOM_LIST}" - @echo "${STATIC_RANDOM_LIST}" - may produce output similar to: - - quattro due tre uno - tre due quattro uno - due uno quattro tre - due uno quattro tre - - ::QQ Quotes every shell meta-character in the variable, so that it can be - passed safely through recursive invocations of bbmmaakkee. - - ::RR Replaces each word in the variable with everything but its suffix. - - ::ggmmttiimmee - The value is a format string for strftime(3), using the current - gmtime(3). - - ::hhaasshh - Compute a 32bit hash of the value and encode it as hex digits. - - ::llooccaallttiimmee - The value is a format string for strftime(3), using the current - localtime(3). - - ::ttAA Attempt to convert variable to an absolute path using realpath(3), - if that fails, the value is unchanged. - - ::ttll Converts variable to lower-case letters. - - ::ttss_c - Words in the variable are normally separated by a space on expan- - sion. This modifier sets the separator to the character _c. If _c is - omitted, then no separator is used. The common escapes (including - octal numeric codes), work as expected. - - ::ttuu Converts variable to upper-case letters. - - ::ttWW Causes the value to be treated as a single word (possibly containing - embedded white space). See also `::[[**]]'. - - ::ttww Causes the value to be treated as a sequence of words delimited by - white space. See also `::[[@@]]'. - - ::SS/_o_l_d___s_t_r_i_n_g/_n_e_w___s_t_r_i_n_g/[11ggWW] - Modify the first occurrence of _o_l_d___s_t_r_i_n_g in the variable's value, - replacing it with _n_e_w___s_t_r_i_n_g. If a `g' is appended to the last - slash of the pattern, all occurrences in each word are replaced. If - a `1' is appended to the last slash of the pattern, only the first - word is affected. If a `W' is appended to the last slash of the - pattern, then the value is treated as a single word (possibly con- - taining embedded white space). If _o_l_d___s_t_r_i_n_g begins with a caret - (`^'), _o_l_d___s_t_r_i_n_g is anchored at the beginning of each word. If - _o_l_d___s_t_r_i_n_g ends with a dollar sign (`$'), it is anchored at the end - of each word. Inside _n_e_w___s_t_r_i_n_g, an ampersand (`&') is replaced by - _o_l_d___s_t_r_i_n_g (without any `^' or `$'). Any character may be used as a - delimiter for the parts of the modifier string. The anchoring, - ampersand and delimiter characters may be escaped with a backslash - (`\'). - - Variable expansion occurs in the normal fashion inside both - _o_l_d___s_t_r_i_n_g and _n_e_w___s_t_r_i_n_g with the single exception that a backslash - is used to prevent the expansion of a dollar sign (`$'), not a pre- - ceding dollar sign as is usual. - - ::CC/_p_a_t_t_e_r_n/_r_e_p_l_a_c_e_m_e_n_t/[11ggWW] - The ::CC modifier is just like the ::SS modifier except that the old and - new strings, instead of being simple strings, are a regular expres- - sion (see regex(3)) string _p_a_t_t_e_r_n and an ed(1)-style string - _r_e_p_l_a_c_e_m_e_n_t. Normally, the first occurrence of the pattern _p_a_t_t_e_r_n - in each word of the value is substituted with _r_e_p_l_a_c_e_m_e_n_t. The `1' - modifier causes the substitution to apply to at most one word; the - `g' modifier causes the substitution to apply to as many instances - of the search pattern _p_a_t_t_e_r_n as occur in the word or words it is - found in; the `W' modifier causes the value to be treated as a sin- - gle word (possibly containing embedded white space). Note that `1' - and `g' are orthogonal; the former specifies whether multiple words - are potentially affected, the latter whether multiple substitutions - can potentially occur within each affected word. - - ::TT Replaces each word in the variable with its last component. - - ::uu Remove adjacent duplicate words (like uniq(1)). - - ::??_t_r_u_e___s_t_r_i_n_g::_f_a_l_s_e___s_t_r_i_n_g - If the variable name (not its value), when parsed as a .if condi- - tional expression, evaluates to true, return as its value the - _t_r_u_e___s_t_r_i_n_g, otherwise return the _f_a_l_s_e___s_t_r_i_n_g. Since the variable - name is used as the expression, :? must be the first modifier after - the variable name itself - which will, of course, usually contain - variable expansions. A common error is trying to use expressions - like - ${NUMBERS:M42:?match:no} - which actually tests defined(NUMBERS), to determine is any words - match "42" you need to use something like: - ${"${NUMBERS:M42}" != "":?match:no}. - - _:_o_l_d___s_t_r_i_n_g_=_n_e_w___s_t_r_i_n_g - This is the AT&T System V UNIX style variable substitution. It must - be the last modifier specified. If _o_l_d___s_t_r_i_n_g or _n_e_w___s_t_r_i_n_g do not - contain the pattern matching character _% then it is assumed that - they are anchored at the end of each word, so only suffixes or - entire words may be replaced. Otherwise _% is the substring of - _o_l_d___s_t_r_i_n_g to be replaced in _n_e_w___s_t_r_i_n_g. - - Variable expansion occurs in the normal fashion inside both - _o_l_d___s_t_r_i_n_g and _n_e_w___s_t_r_i_n_g with the single exception that a backslash - is used to prevent the expansion of a dollar sign (`$'), not a pre- - ceding dollar sign as is usual. - - ::@@_t_e_m_p@@_s_t_r_i_n_g@@ - This is the loop expansion mechanism from the OSF Development Envi- - ronment (ODE) make. Unlike ..ffoorr loops expansion occurs at the time - of reference. Assign _t_e_m_p to each word in the variable and evaluate - _s_t_r_i_n_g. The ODE convention is that _t_e_m_p should start and end with a - period. For example. - ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@} - - However a single character varaiable is often more readable: - ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@} - - ::UU_n_e_w_v_a_l - If the variable is undefined _n_e_w_v_a_l is the value. If the variable - is defined, the existing value is returned. This is another ODE - make feature. It is handy for setting per-target CFLAGS for - instance: - ${_${.TARGET:T}_CFLAGS:U${DEF_CFLAGS}} - If a value is only required if the variable is undefined, use: - ${VAR:D:Unewval} - - ::DD_n_e_w_v_a_l - If the variable is defined _n_e_w_v_a_l is the value. - - ::LL The name of the variable is the value. - - ::PP The path of the node which has the same name as the variable is the - value. If no such node exists or its path is null, then the name of - the variable is used. In order for this modifier to work, the name - (node) must at least have appeared on the rhs of a dependency. - - ::!!_c_m_d!! - The output of running _c_m_d is the value. - - ::sshh If the variable is non-empty it is run as a command and the output - becomes the new value. - - ::::==_s_t_r - The variable is assigned the value _s_t_r after substitution. This - modifier and its variations are useful in obscure situations such as - wanting to set a variable when shell commands are being parsed. - These assignment modifiers always expand to nothing, so if appearing - in a rule line by themselves should be preceded with something to - keep bbmmaakkee happy. - - The `::::' helps avoid false matches with the AT&T System V UNIX style - ::== modifier and since substitution always occurs the ::::== form is - vaguely appropriate. - - ::::??==_s_t_r - As for ::::== but only if the variable does not already have a value. - - ::::++==_s_t_r - Append _s_t_r to the variable. - - ::::!!==_c_m_d - Assign the output of _c_m_d to the variable. - - ::[[_r_a_n_g_e]] - Selects one or more words from the value, or performs other opera- - tions related to the way in which the value is divided into words. - - Ordinarily, a value is treated as a sequence of words delimited by - white space. Some modifiers suppress this behaviour, causing a - value to be treated as a single word (possibly containing embedded - white space). An empty value, or a value that consists entirely of - white-space, is treated as a single word. For the purposes of the - `::[[]]' modifier, the words are indexed both forwards using positive - integers (where index 1 represents the first word), and backwards - using negative integers (where index -1 represents the last word). - - The _r_a_n_g_e is subjected to variable expansion, and the expanded - result is then interpreted as follows: - - _i_n_d_e_x Selects a single word from the value. - - _s_t_a_r_t...._e_n_d - Selects all words from _s_t_a_r_t to _e_n_d, inclusive. For example, - `::[[22....--11]]' selects all words from the second word to the last - word. If _s_t_a_r_t is greater than _e_n_d, then the words are out- - put in reverse order. For example, `::[[--11....11]]' selects all - the words from last to first. - - ** Causes subsequent modifiers to treat the value as a single - word (possibly containing embedded white space). Analogous - to the effect of "$*" in Bourne shell. - - 0 Means the same as `::[[**]]'. - - @@ Causes subsequent modifiers to treat the value as a sequence - of words delimited by white space. Analogous to the effect - of "$@" in Bourne shell. - - ## Returns the number of words in the value. - -IINNCCLLUUDDEE SSTTAATTEEMMEENNTTSS,, CCOONNDDIITTIIOONNAALLSS AANNDD FFOORR LLOOOOPPSS - Makefile inclusion, conditional structures and for loops reminiscent of - the C programming language are provided in bbmmaakkee. All such structures - are identified by a line beginning with a single dot (`.') character. - Files are included with either ..iinncclluuddee <_f_i_l_e> or ..iinncclluuddee "_f_i_l_e". Vari- - ables between the angle brackets or double quotes are expanded to form - the file name. If angle brackets are used, the included makefile is - expected to be in the system makefile directory. If double quotes are - used, the including makefile's directory and any directories specified - using the --II option are searched before the system makefile directory. - For compatibility with other versions of bbmmaakkee `include file ...' is also - accepted. If the include statement is written as ..--iinncclluuddee or as - ..ssiinncclluuddee then errors locating and/or opening include files are ignored. - - Conditional expressions are also preceded by a single dot as the first - character of a line. The possible conditionals are as follows: - - ..eerrrroorr _m_e_s_s_a_g_e - The message is printed along with the name of the makefile and - line number, then bbmmaakkee will exit. - - ..eexxppoorrtt _v_a_r_i_a_b_l_e _._._. - Export the specified global variable. If no variable list is - provided, all globals are exported except for internal variables - (those that start with `.'). This is not affected by the --XX - flag, so should be used with caution. For compatibility with - other bbmmaakkee programs `export variable=value' is also accepted. - - Appending a variable name to _._M_A_K_E_._E_X_P_O_R_T_E_D is equivalent to - exporting a variable. - - ..eexxppoorrtt--eennvv _v_a_r_i_a_b_l_e _._._. - The same as `.export', except that the variable is not appended - to _._M_A_K_E_._E_X_P_O_R_T_E_D. This allows exporting a value to the environ- - ment which is different from that used by bbmmaakkee internally. - - ..iinnffoo _m_e_s_s_a_g_e - The message is printed along with the name of the makefile and - line number. - - ..uunnddeeff _v_a_r_i_a_b_l_e - Un-define the specified global variable. Only global variables - may be un-defined. - - ..uunneexxppoorrtt _v_a_r_i_a_b_l_e _._._. - The opposite of `.export'. The specified global _v_a_r_i_a_b_l_e will be - removed from _._M_A_K_E_._E_X_P_O_R_T_E_D. If no variable list is provided, - all globals are unexported, and _._M_A_K_E_._E_X_P_O_R_T_E_D deleted. - - ..uunneexxppoorrtt--eennvv - Unexport all globals previously exported and clear the environ- - ment inherited from the parent. This operation will cause a mem- - ory leak of the original environment, so should be used spar- - ingly. Testing for _._M_A_K_E_._L_E_V_E_L being 0, would make sense. Also - note that any variables which originated in the parent environ- - ment should be explicitly preserved if desired. For example: - - .if ${.MAKE.LEVEL} == 0 - PATH := ${PATH} - .unexport-env - .export PATH - .endif - - Would result in an environment containing only `PATH', which is - the minimal useful environment. Actually `.MAKE.LEVEL' will also - be pushed into the new environment. - - ..wwaarrnniinngg _m_e_s_s_a_g_e - The message prefixed by `_w_a_r_n_i_n_g_:' is printed along with the name - of the makefile and line number. - - ..iiff [!]_e_x_p_r_e_s_s_i_o_n [_o_p_e_r_a_t_o_r _e_x_p_r_e_s_s_i_o_n _._._.] - Test the value of an expression. - - ..iiffddeeff [!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e _._._.] - Test the value of a variable. - - ..iiffnnddeeff [!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e _._._.] - Test the value of a variable. - - ..iiffmmaakkee [!]_t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t _._._.] - Test the target being built. - - ..iiffnnmmaakkee [!] _t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t _._._.] - Test the target being built. - - ..eellssee Reverse the sense of the last conditional. - - ..eelliiff [!] _e_x_p_r_e_s_s_i_o_n [_o_p_e_r_a_t_o_r _e_x_p_r_e_s_s_i_o_n _._._.] - A combination of `..eellssee' followed by `..iiff'. - - ..eelliiffddeeff [!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e _._._.] - A combination of `..eellssee' followed by `..iiffddeeff'. - - ..eelliiffnnddeeff [!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e _._._.] - A combination of `..eellssee' followed by `..iiffnnddeeff'. - - ..eelliiffmmaakkee [!]_t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t _._._.] - A combination of `..eellssee' followed by `..iiffmmaakkee'. - - ..eelliiffnnmmaakkee [!]_t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t _._._.] - A combination of `..eellssee' followed by `..iiffnnmmaakkee'. - - ..eennddiiff End the body of the conditional. - - The _o_p_e_r_a_t_o_r may be any one of the following: - - |||| Logical OR. - - &&&& Logical AND; of higher precedence than ``||''. - - As in C, bbmmaakkee will only evaluate a conditional as far as is necessary to - determine its value. Parentheses may be used to change the order of - evaluation. The boolean operator `!!' may be used to logically negate an - entire conditional. It is of higher precedence than `&&&&'. - - The value of _e_x_p_r_e_s_s_i_o_n may be any of the following: - - ddeeffiinneedd Takes a variable name as an argument and evaluates to true if - the variable has been defined. - - mmaakkee Takes a target name as an argument and evaluates to true if the - target was specified as part of bbmmaakkee's command line or was - declared the default target (either implicitly or explicitly, - see _._M_A_I_N) before the line containing the conditional. - - eemmppttyy Takes a variable, with possible modifiers, and evaluates to true - if the expansion of the variable would result in an empty - string. - - eexxiissttss Takes a file name as an argument and evaluates to true if the - file exists. The file is searched for on the system search path - (see _._P_A_T_H). - - ttaarrggeett Takes a target name as an argument and evaluates to true if the - target has been defined. - - ccoommmmaannddss - Takes a target name as an argument and evaluates to true if the - target has been defined and has commands associated with it. - - _E_x_p_r_e_s_s_i_o_n may also be an arithmetic or string comparison. Variable - expansion is performed on both sides of the comparison, after which the - integral values are compared. A value is interpreted as hexadecimal if - it is preceded by 0x, otherwise it is decimal; octal numbers are not sup- - ported. The standard C relational operators are all supported. If after - variable expansion, either the left or right hand side of a `====' or `!!==' - operator is not an integral value, then string comparison is performed - between the expanded variables. If no relational operator is given, it - is assumed that the expanded variable is being compared against 0 or an - empty string in the case of a string comparison. - - When bbmmaakkee is evaluating one of these conditional expressions, and it - encounters a (white-space separated) word it doesn't recognize, either - the ``make'' or ``defined'' expression is applied to it, depending on the - form of the conditional. If the form is `..iiffddeeff', `..iiffnnddeeff', or `..iiff' - the ``defined'' expression is applied. Similarly, if the form is - `..iiffmmaakkee' or `..iiffnnmmaakkee, tthhee' ``make'' expression is applied. - - If the conditional evaluates to true the parsing of the makefile contin- - ues as before. If it evaluates to false, the following lines are - skipped. In both cases this continues until a `..eellssee' or `..eennddiiff' is - found. - - For loops are typically used to apply a set of rules to a list of files. - The syntax of a for loop is: - - ..ffoorr _v_a_r_i_a_b_l_e [_v_a_r_i_a_b_l_e _._._.] iinn _e_x_p_r_e_s_s_i_o_n - <make-rules> - ..eennddffoorr - - After the for eexxpprreessssiioonn is evaluated, it is split into words. On each - iteration of the loop, one word is taken and assigned to each vvaarriiaabbllee, - in order, and these vvaarriiaabblleess are substituted into the mmaakkee--rruulleess inside - the body of the for loop. The number of words must come out even; that - is, if there are three iteration variables, the number of words provided - must be a multiple of three. - -CCOOMMMMEENNTTSS - Comments begin with a hash (`#') character, anywhere but in a shell com- - mand line, and continue to the end of an unescaped new line. - -SSPPEECCIIAALL SSOOUURRCCEESS ((AATTTTRRIIBBUUTTEESS)) - ..EEXXEECC Target is never out of date, but always execute commands any- - way. - - ..IIGGNNOORREE Ignore any errors from the commands associated with this tar- - get, exactly as if they all were preceded by a dash (`-'). - - ..MMAADDEE Mark all sources of this target as being up-to-date. - - ..MMAAKKEE Execute the commands associated with this target even if the --nn - or --tt options were specified. Normally used to mark recursive - bbmmaakkee's. - - ..MMEETTAA Create a meta file for the target, even if it is flagged as - ..PPHHOONNYY, ..MMAAKKEE, or ..SSPPEECCIIAALL. Usage in conjunction with ..MMAAKKEE is - the most likely case. In "meta" mode, the target is out-of- - date if the meta file is missing. - - ..NNOOMMEETTAA Do not create a meta file for the target. Meta files are also - not created for ..PPHHOONNYY, ..MMAAKKEE, or ..SSPPEECCIIAALL targets. - - ..NNOOMMEETTAA__CCMMPP - Ignore differences in commands when deciding if target is out - of date. This is useful if the command contains a value which - always changes. If the number of commands change, though, the - target will still be out of date. - - ..NNOOPPAATTHH Do not search for the target in the directories specified by - ..PPAATTHH. - - ..NNOOTTMMAAIINN Normally bbmmaakkee selects the first target it encounters as the - default target to be built if no target was specified. This - source prevents this target from being selected. - - ..OOPPTTIIOONNAALL - If a target is marked with this attribute and bbmmaakkee can't fig- - ure out how to create it, it will ignore this fact and assume - the file isn't needed or already exists. - - ..PPHHOONNYY The target does not correspond to an actual file; it is always - considered to be out of date, and will not be created with the - --tt option. Suffix-transformation rules are not applied to - ..PPHHOONNYY targets. - - ..PPRREECCIIOOUUSS - When bbmmaakkee is interrupted, it normally removes any partially - made targets. This source prevents the target from being - removed. - - ..RREECCUURRSSIIVVEE - Synonym for ..MMAAKKEE. - - ..SSIILLEENNTT Do not echo any of the commands associated with this target, - exactly as if they all were preceded by an at sign (`@'). - - ..UUSSEE Turn the target into bbmmaakkee's version of a macro. When the tar- - get is used as a source for another target, the other target - acquires the commands, sources, and attributes (except for - ..UUSSEE) of the source. If the target already has commands, the - ..UUSSEE target's commands are appended to them. - - ..UUSSEEBBEEFFOORREE - Exactly like ..UUSSEE, but prepend the ..UUSSEEBBEEFFOORREE target commands - to the target. - - ..WWAAIITT If ..WWAAIITT appears in a dependency line, the sources that precede - it are made before the sources that succeed it in the line. - Since the dependents of files are not made until the file - itself could be made, this also stops the dependents being - built unless they are needed for another branch of the depen- - dency tree. So given: - - x: a .WAIT b - echo x - a: - echo a - b: b1 - echo b - b1: - echo b1 - - the output is always `a', `b1', `b', `x'. - The ordering imposed by ..WWAAIITT is only relevant for parallel - makes. - -SSPPEECCIIAALL TTAARRGGEETTSS - Special targets may not be included with other targets, i.e. they must be - the only target specified. - - ..BBEEGGIINN Any command lines attached to this target are executed before - anything else is done. - - ..DDEEFFAAUULLTT - This is sort of a ..UUSSEE rule for any target (that was used only - as a source) that bbmmaakkee can't figure out any other way to cre- - ate. Only the shell script is used. The ..IIMMPPSSRRCC variable of a - target that inherits ..DDEEFFAAUULLTT's commands is set to the target's - own name. - - ..EENNDD Any command lines attached to this target are executed after - everything else is done. - - ..EERRRROORR Any command lines attached to this target are executed when - another target fails. The ..EERRRROORR__TTAARRGGEETT variable is set to the - target that failed. See also MMAAKKEE__PPRRIINNTT__VVAARR__OONN__EERRRROORR. - - ..IIGGNNOORREE Mark each of the sources with the ..IIGGNNOORREE attribute. If no - sources are specified, this is the equivalent of specifying the - --ii option. - - ..IINNTTEERRRRUUPPTT - If bbmmaakkee is interrupted, the commands for this target will be - executed. - - ..MMAAIINN If no target is specified when bbmmaakkee is invoked, this target - will be built. - - ..MMAAKKEEFFLLAAGGSS - This target provides a way to specify flags for bbmmaakkee when the - makefile is used. The flags are as if typed to the shell, - though the --ff option will have no effect. - - ..NNOOPPAATTHH Apply the ..NNOOPPAATTHH attribute to any specified sources. - - ..NNOOTTPPAARRAALLLLEELL - Disable parallel mode. - - ..NNOO__PPAARRAALLLLEELL - Synonym for ..NNOOTTPPAARRAALLLLEELL, for compatibility with other pmake - variants. - - ..OORRDDEERR The named targets are made in sequence. This ordering does not - add targets to the list of targets to be made. Since the depen- - dents of a target do not get built until the target itself could - be built, unless `a' is built by another part of the dependency - graph, the following is a dependency loop: - - .ORDER: b a - b: a - - The ordering imposed by ..OORRDDEERR is only relevant for parallel - makes. - - ..PPAATTHH The sources are directories which are to be searched for files - not found in the current directory. If no sources are speci- - fied, any previously specified directories are deleted. If the - source is the special ..DDOOTTLLAASSTT target, then the current working - directory is searched last. - - ..PPHHOONNYY Apply the ..PPHHOONNYY attribute to any specified sources. - - ..PPRREECCIIOOUUSS - Apply the ..PPRREECCIIOOUUSS attribute to any specified sources. If no - sources are specified, the ..PPRREECCIIOOUUSS attribute is applied to - every target in the file. - - ..SSHHEELLLL Sets the shell that bbmmaakkee will use to execute commands. The - sources are a set of _f_i_e_l_d_=_v_a_l_u_e pairs. - - _n_a_m_e This is the minimal specification, used to select - one of the builtin shell specs; _s_h, _k_s_h, and _c_s_h. - - _p_a_t_h Specifies the path to the shell. - - _h_a_s_E_r_r_C_t_l Indicates whether the shell supports exit on error. - - _c_h_e_c_k The command to turn on error checking. - - _i_g_n_o_r_e The command to disable error checking. - - _e_c_h_o The command to turn on echoing of commands executed. - - _q_u_i_e_t The command to turn off echoing of commands exe- - cuted. - - _f_i_l_t_e_r The output to filter after issuing the _q_u_i_e_t com- - mand. It is typically identical to _q_u_i_e_t. - - _e_r_r_F_l_a_g The flag to pass the shell to enable error checking. - - _e_c_h_o_F_l_a_g The flag to pass the shell to enable command echo- - ing. - - _n_e_w_l_i_n_e The string literal to pass the shell that results in - a single newline character when used outside of any - quoting characters. - Example: - - .SHELL: name=ksh path=/bin/ksh hasErrCtl=true \ - check="set -e" ignore="set +e" \ - echo="set -v" quiet="set +v" filter="set +v" \ - echoFlag=v errFlag=e newline="'\n'" - - ..SSIILLEENNTT Apply the ..SSIILLEENNTT attribute to any specified sources. If no - sources are specified, the ..SSIILLEENNTT attribute is applied to every - command in the file. - - ..SSUUFFFFIIXXEESS - Each source specifies a suffix to bbmmaakkee. If no sources are - specified, any previously specified suffixes are deleted. It - allows the creation of suffix-transformation rules. - - Example: - - .SUFFIXES: .o - .c.o: - cc -o ${.TARGET} -c ${.IMPSRC} - -EENNVVIIRROONNMMEENNTT - bbmmaakkee uses the following environment variables, if they exist: MACHINE, - MACHINE_ARCH, MAKE, MAKEFLAGS, MAKEOBJDIR, MAKEOBJDIRPREFIX, MAKESYSPATH, - PWD, and TMPDIR. - - MAKEOBJDIRPREFIX and MAKEOBJDIR may only be set in the environment or on - the command line to bbmmaakkee and not as makefile variables; see the descrip- - tion of `_._O_B_J_D_I_R' for more details. - -FFIILLEESS - .depend list of dependencies - Makefile list of dependencies - makefile list of dependencies - sys.mk system makefile - /usr/share/mk system makefile directory - -CCOOMMPPAATTIIBBIILLIITTYY - The basic make syntax is compatible between different versions of make, - however the special variables, variable modifiers and conditionals are - not. - - The way that parallel makes are scheduled changed in NetBSD 4.0 so that - .ORDER and .WAIT apply recursively to the dependent nodes. The algo- - rithms used may change again in the future. - - The way that .for loop variables are substituted changed after NetBSD 5.0 - so that they still appear to be variable expansions. In particular this - stops them being treated as syntax, and removes some obscure problems - using them in .if statements. - - Unlike other bbmmaakkee programs, this implementation by default executes all - commands for a given target using a single shell invocation. This is - done for both efficiency and to simplify error handling in remote command - invocations. Typically this is transparent to the user, unless the tar- - get commands change the current working directory using ``cd'' or - ``chdir''. To be compatible with Makefiles that do this, one can use --BB - to disable this behavior. - -SSEEEE AALLSSOO - mkdep(1) - -HHIISSTTOORRYY - bbmmaakkee is derived from NetBSD make(1). It uses autoconf to facilitate - portability to other platforms. - -NetBSD 5.1 April 24, 2012 NetBSD 5.1 diff --git a/20120831/boot-strap b/20120831/boot-strap deleted file mode 100755 index 660b766..0000000 --- a/20120831/boot-strap +++ /dev/null @@ -1,388 +0,0 @@ -: -# NAME: -# boot-strap -# -# SYNOPSIS: -# boot-strap [--"configure_arg" ... ][-s "srcdir"][-m "mksrc"]\\ -# ["prefix" ["bmakesrc" ["mksrc"]]] -# -# DESCRIPTION: -# This script is used to configure/build bmake it builds for -# each OS in a subdir to keep the src clean. -# On successful completion it echos commands to put the new -# bmake binary into the /configs tree (if it exists) -# (http://www.crufty.net/FreeWare/configs.html), $prefix/bin -# and a suitable ~/*bin directory. -# -# Options: -# -# -c "rc" -# Pick up settings from "rc". -# We look for '.bmake-boot-strap.rc' before processing -# options. -# -# --share "share_dir" -# Where to put man pages and mk files. -# If $prefix ends in $HOST_TARGET, and $prefix/../share -# exits, the default will be that rather than $prefix/share. -# -# --mksrc "mksrc" -# Indicate where the mk files can be found. -# Default is ./mk or ../mk, set to 'none' to force -# building without "mksrc" but in that case a sys.mk -# needs to exist in the default syspath ($share_dir/mk) -# -# Possibly useful configure_args: -# -# --without-meta -# disable use of meta mode. -# -# --without-filemon -# disable use of filemon(9) which is currently only -# available for NetBSD and FreeBSD. -# -# --with-filemon="path/to/filemon.h" -# enables use of filemon(9) by meta mode. -# -# --with-machine="machine" -# set "machine" to override that determined by -# machine.sh -# -# --with-force-machine="machine" -# force "machine" even if uname(3) provides a value. -# -# --with-machine_arch="machine_arch" -# set "machine_arch" to override that determined by -# machine.sh -# -# --with-default-sys-path="syspath" -# set an explicit default "syspath" which is where bmake -# will look for sys.mk and friends. -# -# AUTHOR: -# Simon J. Gerraty <sjg@crufty.net> - -# RCSid: -# $Id: boot-strap,v 1.39 2012/03/26 17:08:22 sjg Exp $ -# -# @(#) Copyright (c) 2001 Simon J. Gerraty -# -# This file is provided in the hope that it will -# be of use. There is absolutely NO WARRANTY. -# Permission to copy, redistribute or otherwise -# use this file is hereby granted provided that -# the above copyright notice and this notice are -# left intact. -# -# Please send copies of changes and bug-fixes to: -# sjg@crufty.net -# - -Mydir=`dirname $0` -. "$Mydir/os.sh" -case "$Mydir" in -/*) ;; -*) Mydir=`cd "$Mydir" && 'pwd'`;; -esac - - -Usage() { - [ "$1" ] && echo "ERROR: $@" >&2 - echo "Usage:" >&2 - echo "$0 [--<configure_arg> ...][-s <srcdir>][-m <mksrc>][<prefix> [[<srcdir>] [<mksrc>]]]" >&2 - exit 1 -} - -Error() { - echo "ERROR: $@" >&2 - exit 1 -} - -source_rc() { - rc="$1"; shift - for d in ${*:-""} - do - r="${d:+$d/}$rc" - [ -f "$r" -a -s "$r" ] || continue - echo "NOTE: reading $r" - . "$r" - break - done -} - -CONFIGURE_ARGS= -MAKESYSPATH= -# pick a useful default prefix (for me at least ;-) -for prefix in /opt/$HOST_TARGET "$HOME/$HOST_TARGET" /usr/pkg /usr/local "" -do - [ -d "${prefix:-.}" ] && break -done -srcdir= -mksrc= -objdir= -quiet=: - -source_rc .bmake-boot-strap.rc . "$Mydir/.." "$HOME" - -get_optarg() { - expr "x$1" : "x[^=]*=\\(.*\\)" -} - -while : -do - case "$1" in - --) shift; break;; - --prefix) prefix="$2"; shift;; - --prefix=*) prefix=`get_optarg "$1"`;; - --src=*) srcdir=`get_optarg "$1"`;; - --with-mksrc=*|--mksrc=*) mksrc=`get_optarg "$1"`;; - --share=*) share_dir=`get_optarg "$1"`;; - --share) share_dir="$2"; shift;; - --with-default-sys-path=*) - CONFIGURE_ARGS="$1" - MAKESYSPATH=`get_optarg "$1"`;; - --with-default-sys-path) - CONFIGURE_ARGS="$1 $2" - MAKESYSPATH="$2"; shift;; - -s|--src) srcdir="$2"; shift;; - -m|--mksrc) mksrc="$2"; shift;; - -o|--objdir) objdir="$2"; shift;; - -q) quiet=;; - -c) source_rc "$2"; shift;; - --*) CONFIGURE_ARGS="$CONFIGURE_ARGS $1";; - *=*) eval "$1"; export `expr "x$1" : "x\\(.[^=]*\\)=.*"`;; - *) break;; - esac - shift -done - -AddConfigure() { - case " $CONFIGURE_ARGS " in - *" $1"*) ;; - *) CONFIGURE_ARGS="$CONFIGURE_ARGS $1$2";; - esac -} - -GetDir() { - match="$1" - shift - fmatch="$1" - shift - for dir in $* - do - [ -d "$dir" ] || continue - case "/$dir/" in - *$match*) ;; - *) continue;; - esac - case "$fmatch" in - .) ;; - *) [ -s $dir/$fmatch ] || continue;; - esac - case "$dir/" in - *./*) cd "$dir" && 'pwd';; - /*) echo $dir;; - *) cd "$dir" && 'pwd';; - esac - break - done -} - -FindHereOrAbove() { - ( - _t=-s - while : - do - case "$1" in - -C) cd "$2"; shift; shift;; - -?) _t=$1; shift;; - *) break;; - esac - done - case "$1" in - /*) # we shouldn't be here - [ $_t "$1" ] && echo "$1" - return - ;; - .../*) want=`echo "$1" | sed 's,^.../*,,'`;; - *) want="$1";; - esac - here=`'pwd'` - while : - do - if [ $_t "./$want" ]; then - echo "$here/$want" - return - fi - cd .. - here=`'pwd'` - case "$here" in - /) return;; - esac - done - ) -} - -# is $1 missing from $2 (or PATH) ? -no_path() { - eval "__p=\$${2:-PATH}" - case ":$__p:" in *:"$1":*) return 1;; *) return 0;; esac -} - -# if $1 exists and is not in path, append it -add_path () { - case "$1" in - -?) t=$1; shift;; - *) t=-d;; - esac - case "$2,$1" in - MAKESYSPATH,.../*) ;; - *) [ $t ${1:-.} ] || return;; - esac - no_path $* && eval ${2:-PATH}="$__p${__p:+:}$1" -} - - -srcdir=`GetDir /bmake make-bootstrap.sh.in "$srcdir" "$2" "$Mydir" ./bmake* "$Mydir"/../bmake*` -[ -d "${srcdir:-/dev/null}" ] || Usage -case "$mksrc" in -none|-) # we don't want it - mksrc= - ;; -.../*) # find here or above - mksrc=`FindHereOrAbove -C "$Mydir" -s "$mksrc/sys.mk"` - # that found a file - mksrc=`dirname $mksrc` - ;; -*) # guess we want mksrc... - mksrc=`GetDir /mk sys.mk "$mksrc" "$3" ./mk* "$srcdir"/mk* "$srcdir"/../mk*` - [ -d "${mksrc:-/dev/null}" ] || Usage "Use '-m none' to build without mksrc" - ;; -esac - -# Ok, get to work... -objdir="${objdir:-$OS}" -[ -d "$objdir" ] || mkdir -p "$objdir" -[ -d "$objdir" ] || mkdir "$objdir" -cd "$objdir" || exit 1 -# make it absolute -objdir=`'pwd'` - -ShareDir() { - case "/$1" in - /) [ -d /share ] || return;; - */$HOST_TARGET) - if [ -d "$1/../share" ]; then - echo `dirname "$1"`/share - return - fi - ;; - esac - echo $1/share -} - -# make it easy to force prefix to use $HOST_TARGET -: looking at "$prefix" -case "$prefix" in -*/host?target) prefix=`echo "$prefix" | sed "s,host.target,${HOST_TARGET},"`;; -esac - -share_dir="${share_dir:-`ShareDir $prefix`}" - -AddConfigure --prefix= "$prefix" -case "$CONFIGURE_ARGS" in -*--with-*-sys-path*) ;; # skip -*) [ "$share_dir" ] && AddConfigure --with-default-sys-path= "$share_dir/mk";; -esac -if [ "$mksrc" ]; then - AddConfigure --with-mksrc= "$mksrc" - # not all cc's support this - CFLAGS_MF= CFLAGS_MD= - export CFLAGS_MF CFLAGS_MD -fi - -$srcdir/configure $CONFIGURE_ARGS || exit 1 -chmod 755 make-bootstrap.sh || exit 1 -./make-bootstrap.sh || exit 1 -if [ -z "$MAKESYSPATH" ]; then - add_path "${share_dir:-...}/mk" MAKESYSPATH - case "$HOST_TARGET" in - netbsd*) add_path /usr/share/mk MAKESYSPATH;; - esac -fi -if [ -s "${mksrc:-/dev/null}/install-mk" ]; then - sh "${mksrc}/install-mk" "$objdir/mk" - case "$MAKESYSPATH" in - .../mk*) ;; - *) MAKESYSPATH=".../mk:${MAKESYSPATH}";; - esac -fi -# make sure test below uses the same diff that configure did -TOOL_DIFF=`type diff | sed 's,[()],,g;s,^[^/][^/]*,,;q'` -export MAKESYSPATH TOOL_DIFF -if [ "$mksrc" ]; then - $objdir/bmake test || exit 1 -else - # assume nothing - $objdir/bmake -r -m / test || exit 1 -fi -# If -q given, we don't want all the install instructions -$quiet exit 0 - -make_version=`./bmake -r -m / -f ./Makefile -V MAKE_VERSION | ( read one two; echo $one )` -bmake_version=bmake-$make_version - -if [ -s /usr/share/tmac/andoc.tmac ]; then - # this should be ok - man_subdir=man1 - man_src=$srcdir/bmake.1 -else - # guess not - man_subdir=cat1 - man_src=$srcdir/bmake.cat1 -fi - -install_prefix() { - ( - bin_dir= - share_dir= - man_dir= - mk_dir= - while : - do - case "$1" in - *=*) eval "$1"; shift;; - *) break;; - esac - done - bin_dir=${bin_dir:-$1/bin} - share_dir=${share_dir:-`ShareDir "$1"`} - man_dir=${man_dir:-$share_dir/man} - mk_dir=${mk_dir:-$share_dir/mk} - echo - echo Commands to install into $1/ - echo - echo mkdir -p $bin_dir - echo cp $objdir/bmake $bin_dir/$bmake_version - echo rm -f $bin_dir/bmake - echo ln -s $bmake_version $bin_dir/bmake - echo mkdir -p $man_dir/$man_subdir - echo cp $man_src $man_dir/$man_subdir/bmake.1 - if [ "$mksrc" ]; then - ev=`env | grep '_MK='` - echo $ev sh $mksrc/install-mk $mk_dir - fi - ) -} - -case "$prefix/" in -"$HOME"/*) ;; -*) CONFIGS=${CONFIGS:-/configs} - [ -d $CONFIGS ] && - install_prefix mksrc= "$CONFIGS/$OS/$OSMAJOR.X/$MACHINE_ARCH$prefix" - # I like to keep a copy here... - install_prefix share_dir="$HOME/share" "$HOME/$HOST_TARGET" - ;; -esac - -install_prefix "$prefix" diff --git a/20120831/bsd.after-import.mk b/20120831/bsd.after-import.mk deleted file mode 100644 index e87026f..0000000 --- a/20120831/bsd.after-import.mk +++ /dev/null @@ -1,105 +0,0 @@ -# $Id: bsd.after-import.mk,v 1.6 2012/06/27 18:23:32 sjg Exp $ - -# This makefile is for use when integrating bmake into a BSD build -# system. Use this makefile after importing bmake. -# It will bootstrap the new version, -# capture the generated files we need, and add an after-import -# target to allow the process to be easily repeated. - -# The goal is to allow the benefits of autoconf without -# the overhead of running configure. - -all: _makefile -all: after-import - -# we rely on bmake -.if !defined(.MAKE.LEVEL) -.error this makefile requires bmake -.endif - -_this := ${MAKEFILE:tA} -BMAKE_SRC := ${.PARSEDIR} - -# it helps to know where the top of the tree is. -.if !defined(SRCTOP) -srctop := ${.MAKE.MAKEFILES:M*src/share/mk/sys.mk:H:H:H} -.if empty(srctop) -# likely locations? -.for d in contrib/bmake external/bsd/bmake/dist -.if ${BMAKE_SRC:M*/$d} != "" -srctop := ${BMAKE_SRC:tA:S,/$d,,} -.endif -.endfor -.endif -.if !empty(srctop) -SRCTOP := ${srctop} -.endif -.endif - -# This lets us match what boot-strap does -.if !defined(HOST_OS) -HOST_OS!= uname -.endif - -# .../share/mk will find ${SRCTOP}/share/mk -# if we are within ${SRCTOP} -DEFAULT_SYS_PATH= .../share/mk:/usr/share/mk - -BOOTSTRAP_ARGS = \ - --with-default-sys-path='${DEFAULT_SYS_PATH}' \ - --prefix /usr \ - --share /usr/share \ - --mksrc none - -# run boot-strap with minimal influence -bootstrap: ${BMAKE_SRC}/boot-strap ${MAKEFILE} - HOME=/ ${BMAKE_SRC}/boot-strap ${BOOTSTRAP_ARGS} ${BOOTSTRAP_XTRAS} - touch ${.TARGET} - -# Makefiles need a little more tweaking than say config.h -MAKEFILE_SED = sed -e '/^MACHINE/d' \ - -e '/^PROG/s,bmake,${.CURDIR:T},' \ - -e 's,^.-include,.sinclude,' \ - -e 's,${SRCTOP},$${SRCTOP},g' - -# These are the simple files we want to capture -configured_files= config.h unit-tests/Makefile - -after-import: bootstrap ${MAKEFILE} -.for f in ${configured_files:N*Makefile} - @echo Capturing $f - @mkdir -p ${${.CURDIR}/$f:L:H} - @cmp -s ${.CURDIR}/$f ${HOST_OS}/$f || \ - cp ${HOST_OS}/$f ${.CURDIR}/$f -.endfor -.for f in ${configured_files:M*Makefile} - @echo Capturing $f - @mkdir -p ${${.CURDIR}/$f:L:H} - @${MAKEFILE_SED} ${HOST_OS}/$f > ${.CURDIR}/$f -.endfor - -# this needs the most work -_makefile: bootstrap ${MAKEFILE} - @echo Generating ${.CURDIR}/Makefile - @(echo '# This is a generated file, do NOT edit!'; \ - echo '# See ${_this:S,${SRCTOP}/,,}'; \ - echo '#'; echo '# $$${OS}$$'; echo; \ - echo 'SRCTOP?= $${.CURDIR:${.CURDIR:S,${SRCTOP}/,,:C,[^/]+,H,g:S,/,:,g}}'; echo; \ - echo; echo '# look here first for config.h'; \ - echo 'CFLAGS+= -I$${.CURDIR}'; echo; \ - ${MAKEFILE_SED} ${HOST_OS}/Makefile; \ - echo; echo '# override some simple things'; \ - echo 'BINDIR= /usr/bin'; \ - echo 'MANDIR= /usr/share/man'; \ - echo; echo '# make sure we get this'; \ - echo 'CFLAGS+= $${COPTS.$${.IMPSRC:T}}'; \ - echo 'CLEANFILES+= bootstrap'; \ - echo; echo 'after-import: ${_this:S,${SRCTOP},\${SRCTOP},}'; \ - echo ' cd $${.CURDIR} && $${.MAKE} -f ${_this:S,${SRCTOP},\${SRCTOP},}'; \ - echo; echo '.sinclude "Makefile.inc"'; \ - echo ) > ${.TARGET} - @cmp -s ${.TARGET} ${.CURDIR}/Makefile || \ - mv ${.TARGET} ${.CURDIR}/Makefile - -.include <bsd.obj.mk> - diff --git a/20120831/buf.c b/20120831/buf.c deleted file mode 100644 index ac95c16..0000000 --- a/20120831/buf.c +++ /dev/null @@ -1,291 +0,0 @@ -/* $NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * buf.c -- - * Functions for automatically-expanded buffers. - */ - -#include "make.h" -#include "buf.h" - -#ifndef max -#define max(a,b) ((a) > (b) ? (a) : (b)) -#endif - -#define BUF_DEF_SIZE 256 /* Default buffer size */ - -/*- - *----------------------------------------------------------------------- - * Buf_Expand_1 -- - * Extend buffer for single byte add. - * - *----------------------------------------------------------------------- - */ -void -Buf_Expand_1(Buffer *bp) -{ - bp->size += max(bp->size, 16); - bp->buffer = bmake_realloc(bp->buffer, bp->size); -} - -/*- - *----------------------------------------------------------------------- - * Buf_AddBytes -- - * Add a number of bytes to the buffer. - * - * Results: - * None. - * - * Side Effects: - * Guess what? - * - *----------------------------------------------------------------------- - */ -void -Buf_AddBytes(Buffer *bp, int numBytes, const Byte *bytesPtr) -{ - int count = bp->count; - Byte *ptr; - - if (__predict_false(count + numBytes >= bp->size)) { - bp->size += max(bp->size, numBytes + 16); - bp->buffer = bmake_realloc(bp->buffer, bp->size); - } - - ptr = bp->buffer + count; - bp->count = count + numBytes; - ptr[numBytes] = 0; - memcpy(ptr, bytesPtr, numBytes); -} - -/*- - *----------------------------------------------------------------------- - * Buf_GetAll -- - * Get all the available data at once. - * - * Results: - * A pointer to the data and the number of bytes available. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -Byte * -Buf_GetAll(Buffer *bp, int *numBytesPtr) -{ - - if (numBytesPtr != NULL) - *numBytesPtr = bp->count; - - return (bp->buffer); -} - -/*- - *----------------------------------------------------------------------- - * Buf_Empty -- - * Throw away bytes in a buffer. - * - * Results: - * None. - * - * Side Effects: - * The bytes are discarded. - * - *----------------------------------------------------------------------- - */ -void -Buf_Empty(Buffer *bp) -{ - - bp->count = 0; - *bp->buffer = 0; -} - -/*- - *----------------------------------------------------------------------- - * Buf_Init -- - * Initialize a buffer. If no initial size is given, a reasonable - * default is used. - * - * Input: - * size Initial size for the buffer - * - * Results: - * A buffer to be given to other functions in this library. - * - * Side Effects: - * The buffer is created, the space allocated and pointers - * initialized. - * - *----------------------------------------------------------------------- - */ -void -Buf_Init(Buffer *bp, int size) -{ - if (size <= 0) { - size = BUF_DEF_SIZE; - } - bp->size = size; - bp->count = 0; - bp->buffer = bmake_malloc(size); - *bp->buffer = 0; -} - -/*- - *----------------------------------------------------------------------- - * Buf_Destroy -- - * Nuke a buffer and all its resources. - * - * Input: - * buf Buffer to destroy - * freeData TRUE if the data should be destroyed - * - * Results: - * Data buffer, NULL if freed - * - * Side Effects: - * The buffer is freed. - * - *----------------------------------------------------------------------- - */ -Byte * -Buf_Destroy(Buffer *buf, Boolean freeData) -{ - Byte *data; - - data = buf->buffer; - if (freeData) { - free(data); - data = NULL; - } - - buf->size = 0; - buf->count = 0; - buf->buffer = NULL; - - return data; -} - - -/*- - *----------------------------------------------------------------------- - * Buf_DestroyCompact -- - * Nuke a buffer and return its data. - * - * Input: - * buf Buffer to destroy - * - * Results: - * Data buffer - * - * Side Effects: - * If the buffer size is much greater than its content, - * a new buffer will be allocated and the old one freed. - * - *----------------------------------------------------------------------- - */ -#ifndef BUF_COMPACT_LIMIT -# define BUF_COMPACT_LIMIT 128 /* worthwhile saving */ -#endif - -Byte * -Buf_DestroyCompact(Buffer *buf) -{ -#if BUF_COMPACT_LIMIT > 0 - Byte *data; - - if (buf->size - buf->count >= BUF_COMPACT_LIMIT) { - /* We trust realloc to be smart */ - data = bmake_realloc(buf->buffer, buf->count + 1); - if (data) { - data[buf->count] = 0; - Buf_Destroy(buf, FALSE); - return data; - } - } -#endif - return Buf_Destroy(buf, FALSE); -} diff --git a/20120831/buf.h b/20120831/buf.h deleted file mode 100644 index 25be67d..0000000 --- a/20120831/buf.h +++ /dev/null @@ -1,119 +0,0 @@ -/* $NetBSD: buf.h,v 1.17 2012/04/24 20:26:58 sjg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)buf.h 8.1 (Berkeley) 6/6/93 - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)buf.h 8.1 (Berkeley) 6/6/93 - */ - -/*- - * buf.h -- - * Header for users of the buf library. - */ - -#ifndef _BUF_H -#define _BUF_H - -typedef char Byte; - -typedef struct Buffer { - int size; /* Current size of the buffer */ - int count; /* Number of bytes in buffer */ - Byte *buffer; /* The buffer itself (zero terminated) */ -} Buffer; - -/* If we aren't on netbsd, __predict_false() might not be defined. */ -#ifndef __predict_false -#define __predict_false(x) (x) -#endif - -/* Buf_AddByte adds a single byte to a buffer. */ -#define Buf_AddByte(bp, byte) do { \ - int _count = ++(bp)->count; \ - char *_ptr; \ - if (__predict_false(_count >= (bp)->size)) \ - Buf_Expand_1(bp); \ - _ptr = (bp)->buffer + _count; \ - _ptr[-1] = (byte); \ - _ptr[0] = 0; \ - } while (0) - -#define BUF_ERROR 256 - -#define Buf_Size(bp) ((bp)->count) - -void Buf_Expand_1(Buffer *); -void Buf_AddBytes(Buffer *, int, const Byte *); -Byte *Buf_GetAll(Buffer *, int *); -void Buf_Empty(Buffer *); -void Buf_Init(Buffer *, int); -Byte *Buf_Destroy(Buffer *, Boolean); -Byte *Buf_DestroyCompact(Buffer *); - -#endif /* _BUF_H */ diff --git a/20120831/compat.c b/20120831/compat.c deleted file mode 100644 index 7f715cc..0000000 --- a/20120831/compat.c +++ /dev/null @@ -1,764 +0,0 @@ -/* $NetBSD: compat.c,v 1.89 2012/06/10 21:44:01 wiz Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: compat.c,v 1.89 2012/06/10 21:44:01 wiz Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94"; -#else -__RCSID("$NetBSD: compat.c,v 1.89 2012/06/10 21:44:01 wiz Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * compat.c -- - * The routines in this file implement the full-compatibility - * mode of PMake. Most of the special functionality of PMake - * is available in this mode. Things not supported: - * - different shells. - * - friendly variable substitution. - * - * Interface: - * Compat_Run Initialize things for this module and recreate - * thems as need creatin' - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include <sys/types.h> -#include <sys/stat.h> -#include "wait.h" - -#include <ctype.h> -#include <errno.h> -#include <signal.h> -#include <stdio.h> - -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "job.h" -#include "pathnames.h" - -/* - * The following array is used to make a fast determination of which - * characters are interpreted specially by the shell. If a command - * contains any of these characters, it is executed by the shell, not - * directly by us. - */ - -static char meta[256]; - -static GNode *curTarg = NULL; -static GNode *ENDNode; -static void CompatInterrupt(int); - -static void -Compat_Init(void) -{ - const char *cp; - - Shell_Init(); /* setup default shell */ - - for (cp = "#=|^(){};&<>*?[]:$`\\\n"; *cp != '\0'; cp++) { - meta[(unsigned char) *cp] = 1; - } - /* - * The null character serves as a sentinel in the string. - */ - meta[0] = 1; -} - -/*- - *----------------------------------------------------------------------- - * CompatInterrupt -- - * Interrupt the creation of the current target and remove it if - * it ain't precious. - * - * Results: - * None. - * - * Side Effects: - * The target is removed and the process exits. If .INTERRUPT exists, - * its commands are run first WITH INTERRUPTS IGNORED.. - * - *----------------------------------------------------------------------- - */ -static void -CompatInterrupt(int signo) -{ - GNode *gn; - - if ((curTarg != NULL) && !Targ_Precious (curTarg)) { - char *p1; - char *file = Var_Value(TARGET, curTarg, &p1); - - if (!noExecute && eunlink(file) != -1) { - Error("*** %s removed", file); - } - if (p1) - free(p1); - - /* - * Run .INTERRUPT only if hit with interrupt signal - */ - if (signo == SIGINT) { - gn = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); - if (gn != NULL) { - Compat_Make(gn, gn); - } - } - - } - if (signo == SIGQUIT) - _exit(signo); - bmake_signal(signo, SIG_DFL); - kill(myPid, signo); -} - -/*- - *----------------------------------------------------------------------- - * CompatRunCommand -- - * Execute the next command for a target. If the command returns an - * error, the node's made field is set to ERROR and creation stops. - * - * Input: - * cmdp Command to execute - * gnp Node from which the command came - * - * Results: - * 0 if the command succeeded, 1 if an error occurred. - * - * Side Effects: - * The node's 'made' field may be set to ERROR. - * - *----------------------------------------------------------------------- - */ -int -CompatRunCommand(void *cmdp, void *gnp) -{ - char *cmdStart; /* Start of expanded command */ - char *cp, *bp; - Boolean silent, /* Don't print command */ - doIt; /* Execute even if -n */ - volatile Boolean errCheck; /* Check errors */ - WAIT_T reason; /* Reason for child's death */ - int status; /* Description of child's death */ - pid_t cpid; /* Child actually found */ - pid_t retstat; /* Result of wait */ - LstNode cmdNode; /* Node where current command is located */ - const char ** volatile av; /* Argument vector for thing to exec */ - char ** volatile mav;/* Copy of the argument vector for freeing */ - int argc; /* Number of arguments in av or 0 if not - * dynamically allocated */ - Boolean local; /* TRUE if command should be executed - * locally */ - Boolean useShell; /* TRUE if command should be executed - * using a shell */ - char * volatile cmd = (char *)cmdp; - GNode *gn = (GNode *)gnp; - - silent = gn->type & OP_SILENT; - errCheck = !(gn->type & OP_IGNORE); - doIt = FALSE; - - cmdNode = Lst_Member(gn->commands, cmd); - cmdStart = Var_Subst(NULL, cmd, gn, FALSE); - - /* - * brk_string will return an argv with a NULL in av[0], thus causing - * execvp to choke and die horribly. Besides, how can we execute a null - * command? In any case, we warn the user that the command expanded to - * nothing (is this the right thing to do?). - */ - - if (*cmdStart == '\0') { - free(cmdStart); - Error("%s expands to empty string", cmd); - return(0); - } - cmd = cmdStart; - Lst_Replace(cmdNode, cmdStart); - - if ((gn->type & OP_SAVE_CMDS) && (gn != ENDNode)) { - (void)Lst_AtEnd(ENDNode->commands, cmdStart); - return(0); - } - if (strcmp(cmdStart, "...") == 0) { - gn->type |= OP_SAVE_CMDS; - return(0); - } - - while ((*cmd == '@') || (*cmd == '-') || (*cmd == '+')) { - switch (*cmd) { - case '@': - silent = DEBUG(LOUD) ? FALSE : TRUE; - break; - case '-': - errCheck = FALSE; - break; - case '+': - doIt = TRUE; - if (!meta[0]) /* we came here from jobs */ - Compat_Init(); - break; - } - cmd++; - } - - while (isspace((unsigned char)*cmd)) - cmd++; - - /* - * If we did not end up with a command, just skip it. - */ - if (!*cmd) - return (0); - -#if !defined(MAKE_NATIVE) - /* - * In a non-native build, the host environment might be weird enough - * that it's necessary to go through a shell to get the correct - * behaviour. Or perhaps the shell has been replaced with something - * that does extra logging, and that should not be bypassed. - */ - useShell = TRUE; -#else - /* - * Search for meta characters in the command. If there are no meta - * characters, there's no need to execute a shell to execute the - * command. - */ - for (cp = cmd; !meta[(unsigned char)*cp]; cp++) { - continue; - } - useShell = (*cp != '\0'); -#endif - - /* - * Print the command before echoing if we're not supposed to be quiet for - * this one. We also print the command if -n given. - */ - if (!silent || NoExecute(gn)) { - printf("%s\n", cmd); - fflush(stdout); - } - - /* - * If we're not supposed to execute any commands, this is as far as - * we go... - */ - if (!doIt && NoExecute(gn)) { - return (0); - } - if (DEBUG(JOB)) - fprintf(debug_file, "Execute: '%s'\n", cmd); - -again: - if (useShell) { - /* - * We need to pass the command off to the shell, typically - * because the command contains a "meta" character. - */ - static const char *shargv[4]; - - shargv[0] = shellPath; - /* - * The following work for any of the builtin shell specs. - */ - if (DEBUG(SHELL)) - shargv[1] = "-xc"; - else - shargv[1] = "-c"; - shargv[2] = cmd; - shargv[3] = NULL; - av = shargv; - argc = 0; - bp = NULL; - mav = NULL; - } else { - /* - * No meta-characters, so no need to exec a shell. Break the command - * into words to form an argument vector we can execute. - */ - mav = brk_string(cmd, &argc, TRUE, &bp); - if (mav == NULL) { - useShell = 1; - goto again; - } - av = (void *)mav; - } - - local = TRUE; - -#ifdef USE_META - if (useMeta) { - meta_compat_start(); - } -#endif - - /* - * Fork and execute the single command. If the fork fails, we abort. - */ - cpid = vFork(); - if (cpid < 0) { - Fatal("Could not fork"); - } - if (cpid == 0) { - Check_Cwd(av); - Var_ExportVars(); -#ifdef USE_META - if (useMeta) { - meta_compat_child(); - } -#endif - if (local) - (void)execvp(av[0], (char *const *)UNCONST(av)); - else - (void)execv(av[0], (char *const *)UNCONST(av)); - execError("exec", av[0]); - _exit(1); - } - if (mav) - free(mav); - if (bp) - free(bp); - Lst_Replace(cmdNode, NULL); - -#ifdef USE_META - if (useMeta) { - meta_compat_parent(); - } -#endif - - /* - * The child is off and running. Now all we can do is wait... - */ - while (1) { - - while ((retstat = wait(&reason)) != cpid) { - if (retstat > 0) - JobReapChild(retstat, reason, FALSE); /* not ours? */ - if (retstat == -1 && errno != EINTR) { - break; - } - } - - if (retstat > -1) { - if (WIFSTOPPED(reason)) { - status = WSTOPSIG(reason); /* stopped */ - } else if (WIFEXITED(reason)) { - status = WEXITSTATUS(reason); /* exited */ -#if defined(USE_META) && defined(USE_FILEMON_ONCE) - if (useMeta) { - meta_cmd_finish(NULL); - } -#endif - if (status != 0) { - if (DEBUG(ERROR)) { - fprintf(debug_file, "\n*** Failed target: %s\n*** Failed command: ", - gn->name); - for (cp = cmd; *cp; ) { - if (isspace((unsigned char)*cp)) { - fprintf(debug_file, " "); - while (isspace((unsigned char)*cp)) - cp++; - } else { - fprintf(debug_file, "%c", *cp); - cp++; - } - } - fprintf(debug_file, "\n"); - } - printf("*** Error code %d", status); - } - } else { - status = WTERMSIG(reason); /* signaled */ - printf("*** Signal %d", status); - } - - - if (!WIFEXITED(reason) || (status != 0)) { - if (errCheck) { -#ifdef USE_META - if (useMeta) { - meta_job_error(NULL, gn, 0, status); - } -#endif - gn->made = ERROR; - if (keepgoing) { - /* - * Abort the current target, but let others - * continue. - */ - printf(" (continuing)\n"); - } - } else { - /* - * Continue executing commands for this target. - * If we return 0, this will happen... - */ - printf(" (ignored)\n"); - status = 0; - } - } - break; - } else { - Fatal("error in wait: %d: %s", retstat, strerror(errno)); - /*NOTREACHED*/ - } - } - free(cmdStart); - - return (status); -} - -/*- - *----------------------------------------------------------------------- - * Compat_Make -- - * Make a target. - * - * Input: - * gnp The node to make - * pgnp Parent to abort if necessary - * - * Results: - * 0 - * - * Side Effects: - * If an error is detected and not being ignored, the process exits. - * - *----------------------------------------------------------------------- - */ -int -Compat_Make(void *gnp, void *pgnp) -{ - GNode *gn = (GNode *)gnp; - GNode *pgn = (GNode *)pgnp; - - if (!meta[0]) /* we came here from jobs */ - Compat_Init(); - if (gn->made == UNMADE && (gn == pgn || (pgn->type & OP_MADE) == 0)) { - /* - * First mark ourselves to be made, then apply whatever transformations - * the suffix module thinks are necessary. Once that's done, we can - * descend and make all our children. If any of them has an error - * but the -k flag was given, our 'make' field will be set FALSE again. - * This is our signal to not attempt to do anything but abort our - * parent as well. - */ - gn->flags |= REMAKE; - gn->made = BEINGMADE; - if ((gn->type & OP_MADE) == 0) - Suff_FindDeps(gn); - Lst_ForEach(gn->children, Compat_Make, gn); - if ((gn->flags & REMAKE) == 0) { - gn->made = ABORTED; - pgn->flags &= ~REMAKE; - goto cohorts; - } - - if (Lst_Member(gn->iParents, pgn) != NULL) { - char *p1; - Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0); - if (p1) - free(p1); - } - - /* - * All the children were made ok. Now cmgn->mtime contains the - * modification time of the newest child, we need to find out if we - * exist and when we were modified last. The criteria for datedness - * are defined by the Make_OODate function. - */ - if (DEBUG(MAKE)) { - fprintf(debug_file, "Examining %s...", gn->name); - } - if (! Make_OODate(gn)) { - gn->made = UPTODATE; - if (DEBUG(MAKE)) { - fprintf(debug_file, "up-to-date.\n"); - } - goto cohorts; - } else if (DEBUG(MAKE)) { - fprintf(debug_file, "out-of-date.\n"); - } - - /* - * If the user is just seeing if something is out-of-date, exit now - * to tell him/her "yes". - */ - if (queryFlag) { - exit(1); - } - - /* - * We need to be re-made. We also have to make sure we've got a $? - * variable. To be nice, we also define the $> variable using - * Make_DoAllVar(). - */ - Make_DoAllVar(gn); - - /* - * Alter our type to tell if errors should be ignored or things - * should not be printed so CompatRunCommand knows what to do. - */ - if (Targ_Ignore(gn)) { - gn->type |= OP_IGNORE; - } - if (Targ_Silent(gn)) { - gn->type |= OP_SILENT; - } - - if (Job_CheckCommands(gn, Fatal)) { - /* - * Our commands are ok, but we still have to worry about the -t - * flag... - */ - if (!touchFlag || (gn->type & OP_MAKE)) { - curTarg = gn; -#ifdef USE_META - if (useMeta && !NoExecute(gn)) { - meta_job_start(NULL, gn); - } -#endif - Lst_ForEach(gn->commands, CompatRunCommand, gn); - curTarg = NULL; - } else { - Job_Touch(gn, gn->type & OP_SILENT); - } - } else { - gn->made = ERROR; - } -#ifdef USE_META - if (useMeta && !NoExecute(gn)) { - meta_job_finish(NULL); - } -#endif - - if (gn->made != ERROR) { - /* - * If the node was made successfully, mark it so, update - * its modification time and timestamp all its parents. Note - * that for .ZEROTIME targets, the timestamping isn't done. - * This is to keep its state from affecting that of its parent. - */ - gn->made = MADE; - pgn->flags |= Make_Recheck(gn) == 0 ? FORCE : 0; - if (!(gn->type & OP_EXEC)) { - pgn->flags |= CHILDMADE; - Make_TimeStamp(pgn, gn); - } - } else if (keepgoing) { - pgn->flags &= ~REMAKE; - } else { - PrintOnError(gn, "\n\nStop."); - exit(1); - } - } else if (gn->made == ERROR) { - /* - * Already had an error when making this beastie. Tell the parent - * to abort. - */ - pgn->flags &= ~REMAKE; - } else { - if (Lst_Member(gn->iParents, pgn) != NULL) { - char *p1; - Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0); - if (p1) - free(p1); - } - switch(gn->made) { - case BEINGMADE: - Error("Graph cycles through %s", gn->name); - gn->made = ERROR; - pgn->flags &= ~REMAKE; - break; - case MADE: - if ((gn->type & OP_EXEC) == 0) { - pgn->flags |= CHILDMADE; - Make_TimeStamp(pgn, gn); - } - break; - case UPTODATE: - if ((gn->type & OP_EXEC) == 0) { - Make_TimeStamp(pgn, gn); - } - break; - default: - break; - } - } - -cohorts: - Lst_ForEach(gn->cohorts, Compat_Make, pgnp); - return (0); -} - -/*- - *----------------------------------------------------------------------- - * Compat_Run -- - * Initialize this mode and start making. - * - * Input: - * targs List of target nodes to re-create - * - * Results: - * None. - * - * Side Effects: - * Guess what? - * - *----------------------------------------------------------------------- - */ -void -Compat_Run(Lst targs) -{ - GNode *gn = NULL;/* Current root target */ - int errors; /* Number of targets not remade due to errors */ - - Compat_Init(); - - if (bmake_signal(SIGINT, SIG_IGN) != SIG_IGN) { - bmake_signal(SIGINT, CompatInterrupt); - } - if (bmake_signal(SIGTERM, SIG_IGN) != SIG_IGN) { - bmake_signal(SIGTERM, CompatInterrupt); - } - if (bmake_signal(SIGHUP, SIG_IGN) != SIG_IGN) { - bmake_signal(SIGHUP, CompatInterrupt); - } - if (bmake_signal(SIGQUIT, SIG_IGN) != SIG_IGN) { - bmake_signal(SIGQUIT, CompatInterrupt); - } - - ENDNode = Targ_FindNode(".END", TARG_CREATE); - ENDNode->type = OP_SPECIAL; - /* - * If the user has defined a .BEGIN target, execute the commands attached - * to it. - */ - if (!queryFlag) { - gn = Targ_FindNode(".BEGIN", TARG_NOCREATE); - if (gn != NULL) { - Compat_Make(gn, gn); - if (gn->made == ERROR) { - PrintOnError(gn, "\n\nStop."); - exit(1); - } - } - } - - /* - * Expand .USE nodes right now, because they can modify the structure - * of the tree. - */ - Make_ExpandUse(targs); - - /* - * For each entry in the list of targets to create, call Compat_Make on - * it to create the thing. Compat_Make will leave the 'made' field of gn - * in one of several states: - * UPTODATE gn was already up-to-date - * MADE gn was recreated successfully - * ERROR An error occurred while gn was being created - * ABORTED gn was not remade because one of its inferiors - * could not be made due to errors. - */ - errors = 0; - while (!Lst_IsEmpty (targs)) { - gn = (GNode *)Lst_DeQueue(targs); - Compat_Make(gn, gn); - - if (gn->made == UPTODATE) { - printf("`%s' is up to date.\n", gn->name); - } else if (gn->made == ABORTED) { - printf("`%s' not remade because of errors.\n", gn->name); - errors += 1; - } - } - - /* - * If the user has defined a .END target, run its commands. - */ - if (errors == 0) { - Compat_Make(ENDNode, ENDNode); - if (gn->made == ERROR) { - PrintOnError(gn, "\n\nStop."); - exit(1); - } - } -} diff --git a/20120831/cond.c b/20120831/cond.c deleted file mode 100644 index 6d0b965..0000000 --- a/20120831/cond.c +++ /dev/null @@ -1,1410 +0,0 @@ -/* $NetBSD: cond.c,v 1.64 2012/06/12 19:21:50 joerg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: cond.c,v 1.64 2012/06/12 19:21:50 joerg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)cond.c 8.2 (Berkeley) 1/2/94"; -#else -__RCSID("$NetBSD: cond.c,v 1.64 2012/06/12 19:21:50 joerg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * cond.c -- - * Functions to handle conditionals in a makefile. - * - * Interface: - * Cond_Eval Evaluate the conditional in the passed line. - * - */ - -#include <ctype.h> -#include <errno.h> /* For strtoul() error checking */ - -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "buf.h" - -/* - * The parsing of conditional expressions is based on this grammar: - * E -> F || E - * E -> F - * F -> T && F - * F -> T - * T -> defined(variable) - * T -> make(target) - * T -> exists(file) - * T -> empty(varspec) - * T -> target(name) - * T -> commands(name) - * T -> symbol - * T -> $(varspec) op value - * T -> $(varspec) == "string" - * T -> $(varspec) != "string" - * T -> "string" - * T -> ( E ) - * T -> ! T - * op -> == | != | > | < | >= | <= - * - * 'symbol' is some other symbol to which the default function (condDefProc) - * is applied. - * - * Tokens are scanned from the 'condExpr' string. The scanner (CondToken) - * will return TOK_AND for '&' and '&&', TOK_OR for '|' and '||', - * TOK_NOT for '!', TOK_LPAREN for '(', TOK_RPAREN for ')' and will evaluate - * the other terminal symbols, using either the default function or the - * function given in the terminal, and return the result as either TOK_TRUE - * or TOK_FALSE. - * - * TOK_FALSE is 0 and TOK_TRUE 1 so we can directly assign C comparisons. - * - * All Non-Terminal functions (CondE, CondF and CondT) return TOK_ERROR on - * error. - */ -typedef enum { - TOK_FALSE = 0, TOK_TRUE = 1, TOK_AND, TOK_OR, TOK_NOT, - TOK_LPAREN, TOK_RPAREN, TOK_EOF, TOK_NONE, TOK_ERROR -} Token; - -/*- - * Structures to handle elegantly the different forms of #if's. The - * last two fields are stored in condInvert and condDefProc, respectively. - */ -static void CondPushBack(Token); -static int CondGetArg(char **, char **, const char *); -static Boolean CondDoDefined(int, const char *); -static int CondStrMatch(const void *, const void *); -static Boolean CondDoMake(int, const char *); -static Boolean CondDoExists(int, const char *); -static Boolean CondDoTarget(int, const char *); -static Boolean CondDoCommands(int, const char *); -static Boolean CondCvtArg(char *, double *); -static Token CondToken(Boolean); -static Token CondT(Boolean); -static Token CondF(Boolean); -static Token CondE(Boolean); -static int do_Cond_EvalExpression(Boolean *); - -static const struct If { - const char *form; /* Form of if */ - int formlen; /* Length of form */ - Boolean doNot; /* TRUE if default function should be negated */ - Boolean (*defProc)(int, const char *); /* Default function to apply */ -} ifs[] = { - { "def", 3, FALSE, CondDoDefined }, - { "ndef", 4, TRUE, CondDoDefined }, - { "make", 4, FALSE, CondDoMake }, - { "nmake", 5, TRUE, CondDoMake }, - { "", 0, FALSE, CondDoDefined }, - { NULL, 0, FALSE, NULL } -}; - -static const struct If *if_info; /* Info for current statement */ -static char *condExpr; /* The expression to parse */ -static Token condPushBack=TOK_NONE; /* Single push-back token used in - * parsing */ - -static unsigned int cond_depth = 0; /* current .if nesting level */ -static unsigned int cond_min_depth = 0; /* depth at makefile open */ - -static int -istoken(const char *str, const char *tok, size_t len) -{ - return strncmp(str, tok, len) == 0 && !isalpha((unsigned char)str[len]); -} - -/*- - *----------------------------------------------------------------------- - * CondPushBack -- - * Push back the most recent token read. We only need one level of - * this, so the thing is just stored in 'condPushback'. - * - * Input: - * t Token to push back into the "stream" - * - * Results: - * None. - * - * Side Effects: - * condPushback is overwritten. - * - *----------------------------------------------------------------------- - */ -static void -CondPushBack(Token t) -{ - condPushBack = t; -} - -/*- - *----------------------------------------------------------------------- - * CondGetArg -- - * Find the argument of a built-in function. - * - * Input: - * parens TRUE if arg should be bounded by parens - * - * Results: - * The length of the argument and the address of the argument. - * - * Side Effects: - * The pointer is set to point to the closing parenthesis of the - * function call. - * - *----------------------------------------------------------------------- - */ -static int -CondGetArg(char **linePtr, char **argPtr, const char *func) -{ - char *cp; - int argLen; - Buffer buf; - int paren_depth; - char ch; - - cp = *linePtr; - if (func != NULL) - /* Skip opening '(' - verfied by caller */ - cp++; - - if (*cp == '\0') { - /* - * No arguments whatsoever. Because 'make' and 'defined' aren't really - * "reserved words", we don't print a message. I think this is better - * than hitting the user with a warning message every time s/he uses - * the word 'make' or 'defined' at the beginning of a symbol... - */ - *argPtr = NULL; - return (0); - } - - while (*cp == ' ' || *cp == '\t') { - cp++; - } - - /* - * Create a buffer for the argument and start it out at 16 characters - * long. Why 16? Why not? - */ - Buf_Init(&buf, 16); - - paren_depth = 0; - for (;;) { - ch = *cp; - if (ch == 0 || ch == ' ' || ch == '\t') - break; - if ((ch == '&' || ch == '|') && paren_depth == 0) - break; - if (*cp == '$') { - /* - * Parse the variable spec and install it as part of the argument - * if it's valid. We tell Var_Parse to complain on an undefined - * variable, so we don't do it too. Nor do we return an error, - * though perhaps we should... - */ - char *cp2; - int len; - void *freeIt; - - cp2 = Var_Parse(cp, VAR_CMD, TRUE, &len, &freeIt); - Buf_AddBytes(&buf, strlen(cp2), cp2); - if (freeIt) - free(freeIt); - cp += len; - continue; - } - if (ch == '(') - paren_depth++; - else - if (ch == ')' && --paren_depth < 0) - break; - Buf_AddByte(&buf, *cp); - cp++; - } - - *argPtr = Buf_GetAll(&buf, &argLen); - Buf_Destroy(&buf, FALSE); - - while (*cp == ' ' || *cp == '\t') { - cp++; - } - - if (func != NULL && *cp++ != ')') { - Parse_Error(PARSE_WARNING, "Missing closing parenthesis for %s()", - func); - return (0); - } - - *linePtr = cp; - return (argLen); -} - -/*- - *----------------------------------------------------------------------- - * CondDoDefined -- - * Handle the 'defined' function for conditionals. - * - * Results: - * TRUE if the given variable is defined. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -CondDoDefined(int argLen MAKE_ATTR_UNUSED, const char *arg) -{ - char *p1; - Boolean result; - - if (Var_Value(arg, VAR_CMD, &p1) != NULL) { - result = TRUE; - } else { - result = FALSE; - } - if (p1) - free(p1); - return (result); -} - -/*- - *----------------------------------------------------------------------- - * CondStrMatch -- - * Front-end for Str_Match so it returns 0 on match and non-zero - * on mismatch. Callback function for CondDoMake via Lst_Find - * - * Results: - * 0 if string matches pattern - * - * Side Effects: - * None - * - *----------------------------------------------------------------------- - */ -static int -CondStrMatch(const void *string, const void *pattern) -{ - return(!Str_Match(string, pattern)); -} - -/*- - *----------------------------------------------------------------------- - * CondDoMake -- - * Handle the 'make' function for conditionals. - * - * Results: - * TRUE if the given target is being made. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -CondDoMake(int argLen MAKE_ATTR_UNUSED, const char *arg) -{ - return Lst_Find(create, arg, CondStrMatch) != NULL; -} - -/*- - *----------------------------------------------------------------------- - * CondDoExists -- - * See if the given file exists. - * - * Results: - * TRUE if the file exists and FALSE if it does not. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -CondDoExists(int argLen MAKE_ATTR_UNUSED, const char *arg) -{ - Boolean result; - char *path; - - path = Dir_FindFile(arg, dirSearchPath); - if (DEBUG(COND)) { - fprintf(debug_file, "exists(%s) result is \"%s\"\n", - arg, path ? path : ""); - } - if (path != NULL) { - result = TRUE; - free(path); - } else { - result = FALSE; - } - return (result); -} - -/*- - *----------------------------------------------------------------------- - * CondDoTarget -- - * See if the given node exists and is an actual target. - * - * Results: - * TRUE if the node exists as a target and FALSE if it does not. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -CondDoTarget(int argLen MAKE_ATTR_UNUSED, const char *arg) -{ - GNode *gn; - - gn = Targ_FindNode(arg, TARG_NOCREATE); - return (gn != NULL) && !OP_NOP(gn->type); -} - -/*- - *----------------------------------------------------------------------- - * CondDoCommands -- - * See if the given node exists and is an actual target with commands - * associated with it. - * - * Results: - * TRUE if the node exists as a target and has commands associated with - * it and FALSE if it does not. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -CondDoCommands(int argLen MAKE_ATTR_UNUSED, const char *arg) -{ - GNode *gn; - - gn = Targ_FindNode(arg, TARG_NOCREATE); - return (gn != NULL) && !OP_NOP(gn->type) && !Lst_IsEmpty(gn->commands); -} - -/*- - *----------------------------------------------------------------------- - * CondCvtArg -- - * Convert the given number into a double. - * We try a base 10 or 16 integer conversion first, if that fails - * then we try a floating point conversion instead. - * - * Results: - * Sets 'value' to double value of string. - * Returns 'true' if the convertion suceeded - * - *----------------------------------------------------------------------- - */ -static Boolean -CondCvtArg(char *str, double *value) -{ - char *eptr, ech; - unsigned long l_val; - double d_val; - - errno = 0; - l_val = strtoul(str, &eptr, str[1] == 'x' ? 16 : 10); - ech = *eptr; - if (ech == 0 && errno != ERANGE) { - d_val = str[0] == '-' ? -(double)-l_val : (double)l_val; - } else { - if (ech != 0 && ech != '.' && ech != 'e' && ech != 'E') - return FALSE; - d_val = strtod(str, &eptr); - if (*eptr) - return FALSE; - } - - *value = d_val; - return TRUE; -} - -/*- - *----------------------------------------------------------------------- - * CondGetString -- - * Get a string from a variable reference or an optionally quoted - * string. This is called for the lhs and rhs of string compares. - * - * Results: - * Sets freeIt if needed, - * Sets quoted if string was quoted, - * Returns NULL on error, - * else returns string - absent any quotes. - * - * Side Effects: - * Moves condExpr to end of this token. - * - * - *----------------------------------------------------------------------- - */ -/* coverity:[+alloc : arg-*2] */ -static char * -CondGetString(Boolean doEval, Boolean *quoted, void **freeIt) -{ - Buffer buf; - char *cp; - char *str; - int len; - int qt; - char *start; - - Buf_Init(&buf, 0); - str = NULL; - *freeIt = NULL; - *quoted = qt = *condExpr == '"' ? 1 : 0; - if (qt) - condExpr++; - for (start = condExpr; *condExpr && str == NULL; condExpr++) { - switch (*condExpr) { - case '\\': - if (condExpr[1] != '\0') { - condExpr++; - Buf_AddByte(&buf, *condExpr); - } - break; - case '"': - if (qt) { - condExpr++; /* we don't want the quotes */ - goto got_str; - } else - Buf_AddByte(&buf, *condExpr); /* likely? */ - break; - case ')': - case '!': - case '=': - case '>': - case '<': - case ' ': - case '\t': - if (!qt) - goto got_str; - else - Buf_AddByte(&buf, *condExpr); - break; - case '$': - /* if we are in quotes, then an undefined variable is ok */ - str = Var_Parse(condExpr, VAR_CMD, (qt ? 0 : doEval), - &len, freeIt); - if (str == var_Error) { - if (*freeIt) { - free(*freeIt); - *freeIt = NULL; - } - /* - * Even if !doEval, we still report syntax errors, which - * is what getting var_Error back with !doEval means. - */ - str = NULL; - goto cleanup; - } - condExpr += len; - /* - * If the '$' was first char (no quotes), and we are - * followed by space, the operator or end of expression, - * we are done. - */ - if ((condExpr == start + len) && - (*condExpr == '\0' || - isspace((unsigned char) *condExpr) || - strchr("!=><)", *condExpr))) { - goto cleanup; - } - /* - * Nope, we better copy str to buf - */ - for (cp = str; *cp; cp++) { - Buf_AddByte(&buf, *cp); - } - if (*freeIt) { - free(*freeIt); - *freeIt = NULL; - } - str = NULL; /* not finished yet */ - condExpr--; /* don't skip over next char */ - break; - default: - Buf_AddByte(&buf, *condExpr); - break; - } - } - got_str: - str = Buf_GetAll(&buf, NULL); - *freeIt = str; - cleanup: - Buf_Destroy(&buf, FALSE); - return str; -} - -/*- - *----------------------------------------------------------------------- - * CondToken -- - * Return the next token from the input. - * - * Results: - * A Token for the next lexical token in the stream. - * - * Side Effects: - * condPushback will be set back to TOK_NONE if it is used. - * - *----------------------------------------------------------------------- - */ -static Token -compare_expression(Boolean doEval) -{ - Token t; - char *lhs; - char *rhs; - char *op; - void *lhsFree; - void *rhsFree; - Boolean lhsQuoted; - Boolean rhsQuoted; - double left, right; - - t = TOK_ERROR; - rhs = NULL; - lhsFree = rhsFree = FALSE; - lhsQuoted = rhsQuoted = FALSE; - - /* - * Parse the variable spec and skip over it, saving its - * value in lhs. - */ - lhs = CondGetString(doEval, &lhsQuoted, &lhsFree); - if (!lhs) - goto done; - - /* - * Skip whitespace to get to the operator - */ - while (isspace((unsigned char) *condExpr)) - condExpr++; - - /* - * Make sure the operator is a valid one. If it isn't a - * known relational operator, pretend we got a - * != 0 comparison. - */ - op = condExpr; - switch (*condExpr) { - case '!': - case '=': - case '<': - case '>': - if (condExpr[1] == '=') { - condExpr += 2; - } else { - condExpr += 1; - } - break; - default: - if (!doEval) { - t = TOK_FALSE; - goto done; - } - /* For .ifxxx "..." check for non-empty string. */ - if (lhsQuoted) { - t = lhs[0] != 0; - goto done; - } - /* For .ifxxx <number> compare against zero */ - if (CondCvtArg(lhs, &left)) { - t = left != 0.0; - goto done; - } - /* For .if ${...} check for non-empty string (defProc is ifdef). */ - if (if_info->form[0] == 0) { - t = lhs[0] != 0; - goto done; - } - /* Otherwise action default test ... */ - t = if_info->defProc(strlen(lhs), lhs) != if_info->doNot; - goto done; - } - - while (isspace((unsigned char)*condExpr)) - condExpr++; - - if (*condExpr == '\0') { - Parse_Error(PARSE_WARNING, - "Missing right-hand-side of operator"); - goto done; - } - - rhs = CondGetString(doEval, &rhsQuoted, &rhsFree); - if (!rhs) - goto done; - - if (rhsQuoted || lhsQuoted) { -do_string_compare: - if (((*op != '!') && (*op != '=')) || (op[1] != '=')) { - Parse_Error(PARSE_WARNING, - "String comparison operator should be either == or !="); - goto done; - } - - if (DEBUG(COND)) { - fprintf(debug_file, "lhs = \"%s\", rhs = \"%s\", op = %.2s\n", - lhs, rhs, op); - } - /* - * Null-terminate rhs and perform the comparison. - * t is set to the result. - */ - if (*op == '=') { - t = strcmp(lhs, rhs) == 0; - } else { - t = strcmp(lhs, rhs) != 0; - } - } else { - /* - * rhs is either a float or an integer. Convert both the - * lhs and the rhs to a double and compare the two. - */ - - if (!CondCvtArg(lhs, &left) || !CondCvtArg(rhs, &right)) - goto do_string_compare; - - if (DEBUG(COND)) { - fprintf(debug_file, "left = %f, right = %f, op = %.2s\n", left, - right, op); - } - switch(op[0]) { - case '!': - if (op[1] != '=') { - Parse_Error(PARSE_WARNING, - "Unknown operator"); - goto done; - } - t = (left != right); - break; - case '=': - if (op[1] != '=') { - Parse_Error(PARSE_WARNING, - "Unknown operator"); - goto done; - } - t = (left == right); - break; - case '<': - if (op[1] == '=') { - t = (left <= right); - } else { - t = (left < right); - } - break; - case '>': - if (op[1] == '=') { - t = (left >= right); - } else { - t = (left > right); - } - break; - } - } - -done: - if (lhsFree) - free(lhsFree); - if (rhsFree) - free(rhsFree); - return t; -} - -static int -get_mpt_arg(char **linePtr, char **argPtr, const char *func MAKE_ATTR_UNUSED) -{ - /* - * Use Var_Parse to parse the spec in parens and return - * TOK_TRUE if the resulting string is empty. - */ - int length; - void *freeIt; - char *val; - char *cp = *linePtr; - - /* We do all the work here and return the result as the length */ - *argPtr = NULL; - - val = Var_Parse(cp - 1, VAR_CMD, FALSE, &length, &freeIt); - /* - * Advance *linePtr to beyond the closing ). Note that - * we subtract one because 'length' is calculated from 'cp - 1'. - */ - *linePtr = cp - 1 + length; - - if (val == var_Error) { - free(freeIt); - return -1; - } - - /* A variable is empty when it just contains spaces... 4/15/92, christos */ - while (isspace(*(unsigned char *)val)) - val++; - - /* - * For consistency with the other functions we can't generate the - * true/false here. - */ - length = *val ? 2 : 1; - if (freeIt) - free(freeIt); - return length; -} - -static Boolean -CondDoEmpty(int arglen, const char *arg MAKE_ATTR_UNUSED) -{ - return arglen == 1; -} - -static Token -compare_function(Boolean doEval) -{ - static const struct fn_def { - const char *fn_name; - int fn_name_len; - int (*fn_getarg)(char **, char **, const char *); - Boolean (*fn_proc)(int, const char *); - } fn_defs[] = { - { "defined", 7, CondGetArg, CondDoDefined }, - { "make", 4, CondGetArg, CondDoMake }, - { "exists", 6, CondGetArg, CondDoExists }, - { "empty", 5, get_mpt_arg, CondDoEmpty }, - { "target", 6, CondGetArg, CondDoTarget }, - { "commands", 8, CondGetArg, CondDoCommands }, - { NULL, 0, NULL, NULL }, - }; - const struct fn_def *fn_def; - Token t; - char *arg = NULL; - int arglen; - char *cp = condExpr; - char *cp1; - - for (fn_def = fn_defs; fn_def->fn_name != NULL; fn_def++) { - if (!istoken(cp, fn_def->fn_name, fn_def->fn_name_len)) - continue; - cp += fn_def->fn_name_len; - /* There can only be whitespace before the '(' */ - while (isspace(*(unsigned char *)cp)) - cp++; - if (*cp != '(') - break; - - arglen = fn_def->fn_getarg(&cp, &arg, fn_def->fn_name); - if (arglen <= 0) { - condExpr = cp; - return arglen < 0 ? TOK_ERROR : TOK_FALSE; - } - /* Evaluate the argument using the required function. */ - t = !doEval || fn_def->fn_proc(arglen, arg); - if (arg) - free(arg); - condExpr = cp; - return t; - } - - /* Push anything numeric through the compare expression */ - cp = condExpr; - if (isdigit((unsigned char)cp[0]) || strchr("+-", cp[0])) - return compare_expression(doEval); - - /* - * Most likely we have a naked token to apply the default function to. - * However ".if a == b" gets here when the "a" is unquoted and doesn't - * start with a '$'. This surprises people. - * If what follows the function argument is a '=' or '!' then the syntax - * would be invalid if we did "defined(a)" - so instead treat as an - * expression. - */ - arglen = CondGetArg(&cp, &arg, NULL); - for (cp1 = cp; isspace(*(unsigned char *)cp1); cp1++) - continue; - if (*cp1 == '=' || *cp1 == '!') - return compare_expression(doEval); - condExpr = cp; - - /* - * Evaluate the argument using the default function. - * This path always treats .if as .ifdef. To get here the character - * after .if must have been taken literally, so the argument cannot - * be empty - even if it contained a variable expansion. - */ - t = !doEval || if_info->defProc(arglen, arg) != if_info->doNot; - if (arg) - free(arg); - return t; -} - -static Token -CondToken(Boolean doEval) -{ - Token t; - - t = condPushBack; - if (t != TOK_NONE) { - condPushBack = TOK_NONE; - return t; - } - - while (*condExpr == ' ' || *condExpr == '\t') { - condExpr++; - } - - switch (*condExpr) { - - case '(': - condExpr++; - return TOK_LPAREN; - - case ')': - condExpr++; - return TOK_RPAREN; - - case '|': - if (condExpr[1] == '|') { - condExpr++; - } - condExpr++; - return TOK_OR; - - case '&': - if (condExpr[1] == '&') { - condExpr++; - } - condExpr++; - return TOK_AND; - - case '!': - condExpr++; - return TOK_NOT; - - case '#': - case '\n': - case '\0': - return TOK_EOF; - - case '"': - case '$': - return compare_expression(doEval); - - default: - return compare_function(doEval); - } -} - -/*- - *----------------------------------------------------------------------- - * CondT -- - * Parse a single term in the expression. This consists of a terminal - * symbol or TOK_NOT and a terminal symbol (not including the binary - * operators): - * T -> defined(variable) | make(target) | exists(file) | symbol - * T -> ! T | ( E ) - * - * Results: - * TOK_TRUE, TOK_FALSE or TOK_ERROR. - * - * Side Effects: - * Tokens are consumed. - * - *----------------------------------------------------------------------- - */ -static Token -CondT(Boolean doEval) -{ - Token t; - - t = CondToken(doEval); - - if (t == TOK_EOF) { - /* - * If we reached the end of the expression, the expression - * is malformed... - */ - t = TOK_ERROR; - } else if (t == TOK_LPAREN) { - /* - * T -> ( E ) - */ - t = CondE(doEval); - if (t != TOK_ERROR) { - if (CondToken(doEval) != TOK_RPAREN) { - t = TOK_ERROR; - } - } - } else if (t == TOK_NOT) { - t = CondT(doEval); - if (t == TOK_TRUE) { - t = TOK_FALSE; - } else if (t == TOK_FALSE) { - t = TOK_TRUE; - } - } - return (t); -} - -/*- - *----------------------------------------------------------------------- - * CondF -- - * Parse a conjunctive factor (nice name, wot?) - * F -> T && F | T - * - * Results: - * TOK_TRUE, TOK_FALSE or TOK_ERROR - * - * Side Effects: - * Tokens are consumed. - * - *----------------------------------------------------------------------- - */ -static Token -CondF(Boolean doEval) -{ - Token l, o; - - l = CondT(doEval); - if (l != TOK_ERROR) { - o = CondToken(doEval); - - if (o == TOK_AND) { - /* - * F -> T && F - * - * If T is TOK_FALSE, the whole thing will be TOK_FALSE, but we have to - * parse the r.h.s. anyway (to throw it away). - * If T is TOK_TRUE, the result is the r.h.s., be it an TOK_ERROR or no. - */ - if (l == TOK_TRUE) { - l = CondF(doEval); - } else { - (void)CondF(FALSE); - } - } else { - /* - * F -> T - */ - CondPushBack(o); - } - } - return (l); -} - -/*- - *----------------------------------------------------------------------- - * CondE -- - * Main expression production. - * E -> F || E | F - * - * Results: - * TOK_TRUE, TOK_FALSE or TOK_ERROR. - * - * Side Effects: - * Tokens are, of course, consumed. - * - *----------------------------------------------------------------------- - */ -static Token -CondE(Boolean doEval) -{ - Token l, o; - - l = CondF(doEval); - if (l != TOK_ERROR) { - o = CondToken(doEval); - - if (o == TOK_OR) { - /* - * E -> F || E - * - * A similar thing occurs for ||, except that here we make sure - * the l.h.s. is TOK_FALSE before we bother to evaluate the r.h.s. - * Once again, if l is TOK_FALSE, the result is the r.h.s. and once - * again if l is TOK_TRUE, we parse the r.h.s. to throw it away. - */ - if (l == TOK_FALSE) { - l = CondE(doEval); - } else { - (void)CondE(FALSE); - } - } else { - /* - * E -> F - */ - CondPushBack(o); - } - } - return (l); -} - -/*- - *----------------------------------------------------------------------- - * Cond_EvalExpression -- - * Evaluate an expression in the passed line. The expression - * consists of &&, ||, !, make(target), defined(variable) - * and parenthetical groupings thereof. - * - * Results: - * COND_PARSE if the condition was valid grammatically - * COND_INVALID if not a valid conditional. - * - * (*value) is set to the boolean value of the condition - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -int -Cond_EvalExpression(const struct If *info, char *line, Boolean *value, int eprint) -{ - static const struct If *dflt_info; - const struct If *sv_if_info = if_info; - char *sv_condExpr = condExpr; - Token sv_condPushBack = condPushBack; - int rval; - - while (*line == ' ' || *line == '\t') - line++; - - if (info == NULL && (info = dflt_info) == NULL) { - /* Scan for the entry for .if - it can't be first */ - for (info = ifs; ; info++) - if (info->form[0] == 0) - break; - dflt_info = info; - } - - if_info = info != NULL ? info : ifs + 4; - condExpr = line; - condPushBack = TOK_NONE; - - rval = do_Cond_EvalExpression(value); - - if (rval == COND_INVALID && eprint) - Parse_Error(PARSE_FATAL, "Malformed conditional (%s)", line); - - if_info = sv_if_info; - condExpr = sv_condExpr; - condPushBack = sv_condPushBack; - - return rval; -} - -static int -do_Cond_EvalExpression(Boolean *value) -{ - - switch (CondE(TRUE)) { - case TOK_TRUE: - if (CondToken(TRUE) == TOK_EOF) { - *value = TRUE; - return COND_PARSE; - } - break; - case TOK_FALSE: - if (CondToken(TRUE) == TOK_EOF) { - *value = FALSE; - return COND_PARSE; - } - break; - default: - case TOK_ERROR: - break; - } - - return COND_INVALID; -} - - -/*- - *----------------------------------------------------------------------- - * Cond_Eval -- - * Evaluate the conditional in the passed line. The line - * looks like this: - * .<cond-type> <expr> - * where <cond-type> is any of if, ifmake, ifnmake, ifdef, - * ifndef, elif, elifmake, elifnmake, elifdef, elifndef - * and <expr> consists of &&, ||, !, make(target), defined(variable) - * and parenthetical groupings thereof. - * - * Input: - * line Line to parse - * - * Results: - * COND_PARSE if should parse lines after the conditional - * COND_SKIP if should skip lines after the conditional - * COND_INVALID if not a valid conditional. - * - * Side Effects: - * None. - * - * Note that the states IF_ACTIVE and ELSE_ACTIVE are only different in order - * to detect splurious .else lines (as are SKIP_TO_ELSE and SKIP_TO_ENDIF) - * otherwise .else could be treated as '.elif 1'. - * - *----------------------------------------------------------------------- - */ -int -Cond_Eval(char *line) -{ - #define MAXIF 128 /* maximum depth of .if'ing */ - enum if_states { - IF_ACTIVE, /* .if or .elif part active */ - ELSE_ACTIVE, /* .else part active */ - SEARCH_FOR_ELIF, /* searching for .elif/else to execute */ - SKIP_TO_ELSE, /* has been true, but not seen '.else' */ - SKIP_TO_ENDIF /* nothing else to execute */ - }; - static enum if_states cond_state[MAXIF + 1] = { IF_ACTIVE }; - - const struct If *ifp; - Boolean isElif; - Boolean value; - int level; /* Level at which to report errors. */ - enum if_states state; - - level = PARSE_FATAL; - - /* skip leading character (the '.') and any whitespace */ - for (line++; *line == ' ' || *line == '\t'; line++) - continue; - - /* Find what type of if we're dealing with. */ - if (line[0] == 'e') { - if (line[1] != 'l') { - if (!istoken(line + 1, "ndif", 4)) - return COND_INVALID; - /* End of conditional section */ - if (cond_depth == cond_min_depth) { - Parse_Error(level, "if-less endif"); - return COND_PARSE; - } - /* Return state for previous conditional */ - cond_depth--; - if (cond_depth > MAXIF) - return COND_SKIP; - return cond_state[cond_depth] <= ELSE_ACTIVE ? COND_PARSE : COND_SKIP; - } - - /* Quite likely this is 'else' or 'elif' */ - line += 2; - if (istoken(line, "se", 2)) { - /* It is else... */ - if (cond_depth == cond_min_depth) { - Parse_Error(level, "if-less else"); - return COND_PARSE; - } - - if (cond_depth > MAXIF) - return COND_SKIP; - state = cond_state[cond_depth]; - switch (state) { - case SEARCH_FOR_ELIF: - state = ELSE_ACTIVE; - break; - case ELSE_ACTIVE: - case SKIP_TO_ENDIF: - Parse_Error(PARSE_WARNING, "extra else"); - /* FALLTHROUGH */ - default: - case IF_ACTIVE: - case SKIP_TO_ELSE: - state = SKIP_TO_ENDIF; - break; - } - cond_state[cond_depth] = state; - return state <= ELSE_ACTIVE ? COND_PARSE : COND_SKIP; - } - /* Assume for now it is an elif */ - isElif = TRUE; - } else - isElif = FALSE; - - if (line[0] != 'i' || line[1] != 'f') - /* Not an ifxxx or elifxxx line */ - return COND_INVALID; - - /* - * Figure out what sort of conditional it is -- what its default - * function is, etc. -- by looking in the table of valid "ifs" - */ - line += 2; - for (ifp = ifs; ; ifp++) { - if (ifp->form == NULL) - return COND_INVALID; - if (istoken(ifp->form, line, ifp->formlen)) { - line += ifp->formlen; - break; - } - } - - /* Now we know what sort of 'if' it is... */ - - if (isElif) { - if (cond_depth == cond_min_depth) { - Parse_Error(level, "if-less elif"); - return COND_PARSE; - } - if (cond_depth > MAXIF) - /* Error reported when we saw the .if ... */ - return COND_SKIP; - state = cond_state[cond_depth]; - if (state == SKIP_TO_ENDIF || state == ELSE_ACTIVE) { - Parse_Error(PARSE_WARNING, "extra elif"); - cond_state[cond_depth] = SKIP_TO_ENDIF; - return COND_SKIP; - } - if (state != SEARCH_FOR_ELIF) { - /* Either just finished the 'true' block, or already SKIP_TO_ELSE */ - cond_state[cond_depth] = SKIP_TO_ELSE; - return COND_SKIP; - } - } else { - /* Normal .if */ - if (cond_depth >= MAXIF) { - cond_depth++; - Parse_Error(PARSE_FATAL, "Too many nested if's. %d max.", MAXIF); - return COND_SKIP; - } - state = cond_state[cond_depth]; - cond_depth++; - if (state > ELSE_ACTIVE) { - /* If we aren't parsing the data, treat as always false */ - cond_state[cond_depth] = SKIP_TO_ELSE; - return COND_SKIP; - } - } - - /* And evaluate the conditional expresssion */ - if (Cond_EvalExpression(ifp, line, &value, 1) == COND_INVALID) { - /* Syntax error in conditional, error message already output. */ - /* Skip everything to matching .endif */ - cond_state[cond_depth] = SKIP_TO_ELSE; - return COND_SKIP; - } - - if (!value) { - cond_state[cond_depth] = SEARCH_FOR_ELIF; - return COND_SKIP; - } - cond_state[cond_depth] = IF_ACTIVE; - return COND_PARSE; -} - - - -/*- - *----------------------------------------------------------------------- - * Cond_End -- - * Make sure everything's clean at the end of a makefile. - * - * Results: - * None. - * - * Side Effects: - * Parse_Error will be called if open conditionals are around. - * - *----------------------------------------------------------------------- - */ -void -Cond_restore_depth(unsigned int saved_depth) -{ - int open_conds = cond_depth - cond_min_depth; - - if (open_conds != 0 || saved_depth > cond_depth) { - Parse_Error(PARSE_FATAL, "%d open conditional%s", open_conds, - open_conds == 1 ? "" : "s"); - cond_depth = cond_min_depth; - } - - cond_min_depth = saved_depth; -} - -unsigned int -Cond_save_depth(void) -{ - int depth = cond_min_depth; - - cond_min_depth = cond_depth; - return depth; -} diff --git a/20120831/config.h.in b/20120831/config.h.in deleted file mode 100644 index 7108dcf..0000000 --- a/20120831/config.h.in +++ /dev/null @@ -1,314 +0,0 @@ -/* config.h.in. Generated from configure.in by autoheader. */ - -/* Define if building universal (internal helper macro) */ -#undef AC_APPLE_UNIVERSAL_BUILD - -/* Path of default shell */ -#undef DEFSHELL_CUSTOM - -/* Shell spec to use by default */ -#undef DEFSHELL_INDEX - -/* Define to 1 if you have the <ar.h> header file. */ -#undef HAVE_AR_H - -/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you - don't. */ -#undef HAVE_DECL_SYS_SIGLIST - -/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'. - */ -#undef HAVE_DIRENT_H - -/* Define to 1 if you have the `dirname' function. */ -#undef HAVE_DIRNAME - -/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ -#undef HAVE_DOPRNT - -/* Define to 1 if you have the `err' function. */ -#undef HAVE_ERR - -/* Define to 1 if you have the `errx' function. */ -#undef HAVE_ERRX - -/* Define to 1 if you have the <err.h> header file. */ -#undef HAVE_ERR_H - -/* Define to 1 if you have the <fcntl.h> header file. */ -#undef HAVE_FCNTL_H - -/* Define to 1 if you have the `fork' function. */ -#undef HAVE_FORK - -/* Define to 1 if you have the `getcwd' function. */ -#undef HAVE_GETCWD - -/* Define to 1 if you have the `getenv' function. */ -#undef HAVE_GETENV - -/* Define to 1 if you have the `getopt' function. */ -#undef HAVE_GETOPT - -/* Define to 1 if you have the `getwd' function. */ -#undef HAVE_GETWD - -/* Define to 1 if you have the <inttypes.h> header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the `killpg' function. */ -#undef HAVE_KILLPG - -/* Define to 1 if you have the <memory.h> header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the `mmap' function. */ -#undef HAVE_MMAP - -/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */ -#undef HAVE_NDIR_H - -/* Define to 1 if you have the <paths.h> header file. */ -#undef HAVE_PATHS_H - -/* Define to 1 if you have the <poll.h> header file. */ -#undef HAVE_POLL_H - -/* Define to 1 if you have the `putenv' function. */ -#undef HAVE_PUTENV - -/* Define to 1 if you have the <ranlib.h> header file. */ -#undef HAVE_RANLIB_H - -/* Define to 1 if you have the `realpath' function. */ -#undef HAVE_REALPATH - -/* Define to 1 if you have the `select' function. */ -#undef HAVE_SELECT - -/* Define to 1 if you have the `setenv' function. */ -#undef HAVE_SETENV - -/* Define to 1 if you have the `setpgid' function. */ -#undef HAVE_SETPGID - -/* Define to 1 if you have the `setsid' function. */ -#undef HAVE_SETSID - -/* Define to 1 if you have the `sigaction' function. */ -#undef HAVE_SIGACTION - -/* Define to 1 if you have the `sigvec' function. */ -#undef HAVE_SIGVEC - -/* Define to 1 if you have the `snprintf' function. */ -#undef HAVE_SNPRINTF - -/* Define to 1 if you have the <stdint.h> header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the <stdlib.h> header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the `strerror' function. */ -#undef HAVE_STRERROR - -/* Define to 1 if you have the `stresep' function. */ -#undef HAVE_STRESEP - -/* Define to 1 if you have the `strftime' function. */ -#undef HAVE_STRFTIME - -/* Define to 1 if you have the <strings.h> header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the <string.h> header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the `strlcpy' function. */ -#undef HAVE_STRLCPY - -/* Define to 1 if you have the `strsep' function. */ -#undef HAVE_STRSEP - -/* Define to 1 if you have the `strtod' function. */ -#undef HAVE_STRTOD - -/* Define to 1 if you have the `strtol' function. */ -#undef HAVE_STRTOL - -/* Define to 1 if `struct stat' is a member of `st_rdev'. */ -#undef HAVE_STRUCT_STAT_ST_RDEV - -/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use - `HAVE_STRUCT_STAT_ST_RDEV' instead. */ -#undef HAVE_ST_RDEV - -/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'. - */ -#undef HAVE_SYS_DIR_H - -/* Define to 1 if you have the <sys/mman.h> header file. */ -#undef HAVE_SYS_MMAN_H - -/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'. - */ -#undef HAVE_SYS_NDIR_H - -/* Define to 1 if you have the <sys/select.h> header file. */ -#undef HAVE_SYS_SELECT_H - -/* Define to 1 if you have the <sys/socket.h> header file. */ -#undef HAVE_SYS_SOCKET_H - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the <sys/time.h> header file. */ -#undef HAVE_SYS_TIME_H - -/* Define to 1 if you have the <sys/types.h> header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the <sys/uio.h> header file. */ -#undef HAVE_SYS_UIO_H - -/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */ -#undef HAVE_SYS_WAIT_H - -/* Define to 1 if you have the <unistd.h> header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have the `unsetenv' function. */ -#undef HAVE_UNSETENV - -/* Define to 1 if you have the <utime.h> header file. */ -#undef HAVE_UTIME_H - -/* Define to 1 if you have the `vfork' function. */ -#undef HAVE_VFORK - -/* Define to 1 if you have the <vfork.h> header file. */ -#undef HAVE_VFORK_H - -/* Define to 1 if you have the `vprintf' function. */ -#undef HAVE_VPRINTF - -/* Define to 1 if you have the `vsnprintf' function. */ -#undef HAVE_VSNPRINTF - -/* Define to 1 if you have the `wait3' function. */ -#undef HAVE_WAIT3 - -/* Define to 1 if you have the `wait4' function. */ -#undef HAVE_WAIT4 - -/* Define to 1 if you have the `waitpid' function. */ -#undef HAVE_WAITPID - -/* Define to 1 if you have the `warn' function. */ -#undef HAVE_WARN - -/* Define to 1 if you have the `warnx' function. */ -#undef HAVE_WARNX - -/* Define to 1 if `fork' works. */ -#undef HAVE_WORKING_FORK - -/* Define to 1 if `vfork' works. */ -#undef HAVE_WORKING_VFORK - -/* define if your compiler has __attribute__ */ -#undef HAVE___ATTRIBUTE__ - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define as the return type of signal handlers (`int' or `void'). */ -#undef RETSIGTYPE - -/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */ -#undef STAT_MACROS_BROKEN - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ -#undef TIME_WITH_SYS_TIME - -/* Define to 1 if your <sys/time.h> declares `struct tm'. */ -#undef TM_IN_SYS_TIME - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# undef _GNU_SOURCE -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# undef _POSIX_PTHREAD_SEMANTICS -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# undef _TANDEM_SOURCE -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# undef __EXTENSIONS__ -#endif - - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -# undef WORDS_BIGENDIAN -# endif -#endif - -/* Define to 1 if on MINIX. */ -#undef _MINIX - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -#undef _POSIX_1_SOURCE - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -#undef _POSIX_SOURCE - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to `long int' if <sys/types.h> does not define. */ -#undef off_t - -/* Define to `int' if <sys/types.h> does not define. */ -#undef pid_t - -/* Define to `unsigned int' if <sys/types.h> does not define. */ -#undef size_t - -/* Define as `fork' if `vfork' does not work. */ -#undef vfork diff --git a/20120831/configure b/20120831/configure deleted file mode 100755 index ee479f1..0000000 --- a/20120831/configure +++ /dev/null @@ -1,7134 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.64 for bmake 20120620. -# -# Report bugs to <sjg@NetBSD.org>. -# -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software -# Foundation, Inc. -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - # We cannot yet assume a decent shell, so we have to provide a - # neutralization value for shells without unset; and this also - # works around shells that cannot unset nonexistent variables. - BASH_ENV=/dev/null - ENV=/dev/null - (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org and sjg@NetBSD.org -$0: about your system, including any error possibly output -$0: before this message. Then install a modern shell, or -$0: manually run the script under such a shell if you do -$0: have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error ERROR [LINENO LOG_FD] -# --------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with status $?, using 1 if that was 0. -as_fn_error () -{ - as_status=$?; test $as_status -eq 0 && as_status=1 - if test "$3"; then - as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 - fi - $as_echo "$as_me: error: $1" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -p' - fi -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 7<&0 </dev/null 6>&1 - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='bmake' -PACKAGE_TARNAME='bmake' -PACKAGE_VERSION='20120620' -PACKAGE_STRING='bmake 20120620' -PACKAGE_BUGREPORT='sjg@NetBSD.org' -PACKAGE_URL='' - -# Factoring default headers for most tests. -ac_includes_default="\ -#include <stdio.h> -#ifdef HAVE_SYS_TYPES_H -# include <sys/types.h> -#endif -#ifdef HAVE_SYS_STAT_H -# include <sys/stat.h> -#endif -#ifdef STDC_HEADERS -# include <stdlib.h> -# include <stddef.h> -#else -# ifdef HAVE_STDLIB_H -# include <stdlib.h> -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include <memory.h> -# endif -# include <string.h> -#endif -#ifdef HAVE_STRINGS_H -# include <strings.h> -#endif -#ifdef HAVE_INTTYPES_H -# include <inttypes.h> -#endif -#ifdef HAVE_STDINT_H -# include <stdint.h> -#endif -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif" - -ac_subst_vars='LTLIBOBJS -filemon_h -use_meta -diff_u -GCC -INSTALL -default_sys_path -mksrc -machine_arch -force_machine -machine -LIBOBJS -ac_exe_suffix -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -EGREP -GREP -CPP -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -with_defshell -with_meta -with_filemon -with_machine -with_force_machine -with_force_machine_arch -with_machine_arch -with_default_sys_path -with_path_objdirprefix -enable_pwd_override -enable_check_make_chdir -with_mksrc -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information." - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures bmake 20120620 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/bmake] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of bmake 20120620:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-pwd-override disable \$PWD overriding getcwd() - --disable-check-make-chdir disable make trying to guess - when it should automatically cd \${.CURDIR} - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-defshell=SHELL use SHELL by default - must be sh compatible, use sh or ksh to pick the internal definitions - --without-meta dissable use of meta-mode - --with-filemon=path/filemon.h indicate path to filemon.h for meta-mode - --with-machine=MACHINE explicitly set MACHINE - --with-force-machine=MACHINE set FORCE_MACHINE - --with-force-machine-arch=MACHINE set FORCE_MACHINE_ARCH - --with-machine_arch=MACHINE_ARCH explicitly set MACHINE_ARCH - --with-default-sys-path=PATH:DIR:LIST use an explicit _PATH_DEFSYSPATH - MAKESYSPATH is a ':' separated list of directories - that bmake will search for system .mk files. - _PATH_DEFSYSPATH is its default value. - --with-path-objdirprefix=PATH override _PATH_OBJDIRPREFIX - --with-mksrc=PATH tell makefile.boot where to find mk src - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a - nonstandard directory <lib dir> - LIBS libraries to pass to the linker, e.g. -l<library> - CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if - you have headers in a nonstandard directory <include dir> - CPP C preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to <sjg@NetBSD.org>. -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -bmake configure 20120620 -generated by GNU Autoconf 2.64 - -Copyright (C) 2009 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( cat <<\_ASBOX -## ----------------------------- ## -## Report this to sjg@NetBSD.org ## -## ----------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - -} # ac_fn_c_check_header_mongrel - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - -} # ac_fn_c_check_header_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - return $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - -} # ac_fn_c_check_type - -# ac_fn_c_check_decl LINENO SYMBOL VAR -# ------------------------------------ -# Tests whether SYMBOL is declared, setting cache variable VAR accordingly. -ac_fn_c_check_decl () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5 -$as_echo_n "checking whether $2 is declared... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -#ifndef $2 - (void) $2; -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - -} # ac_fn_c_check_decl - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case <limits.h> declares $2. - For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - <limits.h> exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - -} # ac_fn_c_check_func - -# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES -# ---------------------------------------------------- -# Tries to find if the field MEMBER exists in type AGGR, after including -# INCLUDES, setting cache variable VAR accordingly. -ac_fn_c_check_member () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 -$as_echo_n "checking for $2.$3... " >&6; } -if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$5 -int -main () -{ -static $2 ac_aggr; -if (ac_aggr.$3) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$4=yes" -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$5 -int -main () -{ -static $2 ac_aggr; -if (sizeof ac_aggr.$3) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$4=yes" -else - eval "$4=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$4 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} - -} # ac_fn_c_check_member -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by bmake $as_me 20120620, which was -generated by GNU Autoconf 2.64. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - cat <<\_ASBOX -## ----------------- ## -## Output variables. ## -## ----------------- ## -_ASBOX - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------------- ## -## File substitutions. ## -## ------------------- ## -_ASBOX - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - ac_site_file1=$CONFIG_SITE -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -ac_config_headers="$ac_config_headers config.h" - - - -# Check whether --with-defshell was given. -if test "${with_defshell+set}" = set; then : - withval=$with_defshell; case "${withval}" in -yes) as_fn_error "bad value ${withval} given for bmake DEFSHELL" "$LINENO" 5 ;; -no) ;; -*) case "$with_defshell" in - sh) DEFSHELL_INDEX=DEFSHELL_INDEX_SH;; # it's the default anyway - ksh) DEFSHELL_INDEX=DEFSHELL_INDEX_KSH;; - csh) DEFSHELL_INDEX=DEFSHELL_INDEX_CSH;; # kidding right? - *) defshell_path=$with_defshell;; # better be sh compatible! - esac - ;; - esac -fi - -use_meta=yes - -# Check whether --with-meta was given. -if test "${with_meta+set}" = set; then : - withval=$with_meta; case "${withval}" in -yes|no) use_meta=${withval};; -*) as_fn_error "bad value ${withval} given for meta" "$LINENO" 5 ;; -esac -fi - - -# Check whether --with-filemon was given. -if test "${with_filemon+set}" = set; then : - withval=$with_filemon; case "/${withval}" in -/no|*/filemon.h) filemon_h="${withval}";; -*/filemon*) filemon_h="${withval}/filemon.h";; -*) as_fn_error "bad value ${withval} given for filemon" "$LINENO" 5 ;; -esac -else - -OS=`uname -s` -for d in "/usr/include/dev/filemon" "$prefix/include/dev/filemon" "$srcdir/filemon" "$srcdir/../filemon" "$srcdir/../../sys/dev/filemon" -do - for x in "/$OS" "" - do - filemon_h="$d$x/filemon.h" - test -s "$filemon_h" && break - done - test -s "$filemon_h" && break -done -test -s "${filemon_h:-/dev/null}" || filemon_h=no - -fi - -case "$use_meta" in -yes) - case "$filemon_h" in - *.h) echo "Using: filemon=$filemon_h" >&6;; - esac - ;; -esac -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "no acceptable C compiler found in \$PATH -See \`config.log' for more details." "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - rm -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdio.h> -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -if test -z "$ac_file"; then : - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "C compiler cannot create executables -See \`config.log' for more details." "$LINENO" 5; }; } -fi -ac_exeext=$ac_cv_exeext - -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out -ac_clean_files=$ac_clean_files_save -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." "$LINENO" 5; } -fi -rm -f conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if test "${ac_cv_objext+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot compute suffix of object files: cannot compile -See \`config.log' for more details." "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdarg.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if test "${ac_cv_path_GREP+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <float.h> - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <string.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ctype.h> -#include <stdlib.h> -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -eval as_val=\$$as_ac_Header - if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - - ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" -if test "x$ac_cv_header_minix_config_h" = x""yes; then : - MINIX=yes -else - MINIX= -fi - - - if test "$MINIX" = yes; then - -$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h - - -$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h - - -$as_echo "#define _MINIX 1" >>confdefs.h - - fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 -$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } -if test "${ac_cv_safe_to_define___extensions__+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -# define __EXTENSIONS__ 1 - $ac_includes_default -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_safe_to_define___extensions__=yes -else - ac_cv_safe_to_define___extensions__=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 -$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } - test $ac_cv_safe_to_define___extensions__ = yes && - $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h - - $as_echo "#define _ALL_SOURCE 1" >>confdefs.h - - $as_echo "#define _GNU_SOURCE 1" >>confdefs.h - - $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h - - $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "no acceptable C compiler found in \$PATH -See \`config.log' for more details." "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - rm -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdarg.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -if test $ac_cv_c_compiler_gnu = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 -$as_echo_n "checking whether $CC needs -traditional... " >&6; } -if test "${ac_cv_prog_gcc_traditional+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_pattern="Autoconf.*'x'" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sgtty.h> -Autoconf TIOCGETP -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "$ac_pattern" >/dev/null 2>&1; then : - ac_cv_prog_gcc_traditional=yes -else - ac_cv_prog_gcc_traditional=no -fi -rm -f conftest* - - - if test $ac_cv_prog_gcc_traditional = no; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <termio.h> -Autoconf TCGETA -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "$ac_pattern" >/dev/null 2>&1; then : - ac_cv_prog_gcc_traditional=yes -fi -rm -f conftest* - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 -$as_echo "$ac_cv_prog_gcc_traditional" >&6; } - if test $ac_cv_prog_gcc_traditional = yes; then - CC="$CC -traditional" - fi -fi - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - for ac_t in install-sh install.sh shtool; do - if test -f "$ac_dir/$ac_t"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/$ac_t -c" - break 2 - fi - done -done -if test -z "$ac_aux_dir"; then - as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - - -echo $ECHO_N "checking if sh will pass .MAKE. variables... $ECHO_C" >&6 -ok=`env .MAKE.LEVEL=1 /bin/sh -c env | grep LEVEL=` -case "$ok" in -"") echo no >&6; CPPFLAGS="${CPPFLAGS} -DNEED_MAKE_LEVEL_SAFE";; -*) echo yes >&6;; -esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <float.h> - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <string.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ctype.h> -#include <stdlib.h> -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 -$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } -if test "${ac_cv_header_sys_wait_h+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> -#include <sys/wait.h> -#ifndef WEXITSTATUS -# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) -#endif -#ifndef WIFEXITED -# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -#endif - -int -main () -{ - int s; - wait (&s); - s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_sys_wait_h=yes -else - ac_cv_header_sys_wait_h=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 -$as_echo "$ac_cv_header_sys_wait_h" >&6; } -if test $ac_cv_header_sys_wait_h = yes; then - -$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h - -fi - -ac_header_dirent=no -for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do - as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 -$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> -#include <$ac_hdr> - -int -main () -{ -if ((DIR *) 0) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$as_ac_Header=yes" -else - eval "$as_ac_Header=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$as_ac_Header - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -eval as_val=\$$as_ac_Header - if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 -_ACEOF - -ac_header_dirent=$ac_hdr; break -fi - -done -# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. -if test $ac_header_dirent = dirent.h; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 -$as_echo_n "checking for library containing opendir... " >&6; } -if test "${ac_cv_search_opendir+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char opendir (); -int -main () -{ -return opendir (); - ; - return 0; -} -_ACEOF -for ac_lib in '' dir; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_opendir=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if test "${ac_cv_search_opendir+set}" = set; then : - break -fi -done -if test "${ac_cv_search_opendir+set}" = set; then : - -else - ac_cv_search_opendir=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 -$as_echo "$ac_cv_search_opendir" >&6; } -ac_res=$ac_cv_search_opendir -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 -$as_echo_n "checking for library containing opendir... " >&6; } -if test "${ac_cv_search_opendir+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char opendir (); -int -main () -{ -return opendir (); - ; - return 0; -} -_ACEOF -for ac_lib in '' x; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_opendir=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if test "${ac_cv_search_opendir+set}" = set; then : - break -fi -done -if test "${ac_cv_search_opendir+set}" = set; then : - -else - ac_cv_search_opendir=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 -$as_echo "$ac_cv_search_opendir" >&6; } -ac_res=$ac_cv_search_opendir -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -fi - -for ac_header in \ - ar.h \ - err.h \ - fcntl.h \ - paths.h \ - poll.h \ - ranlib.h \ - string.h \ - sys/mman.h \ - sys/select.h \ - sys/socket.h \ - sys/time.h \ - sys/uio.h \ - unistd.h \ - utime.h \ - -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -eval as_val=\$$as_ac_Header - if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -ac_fn_c_check_header_mongrel "$LINENO" "sys/cdefs.h" "ac_cv_header_sys_cdefs_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_cdefs_h" = x""yes; then : - echo $ECHO_N "checking whether sys/cdefs.h is compatible... $ECHO_C" >&6 -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/cdefs.h> -#ifdef __RCSID -yes -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : - echo yes >&6 -else - echo no >&6; CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd` -DNEED_HOST_CDEFS_H" -fi -rm -f conftest* - -else - CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd`" -fi - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__" >&5 -$as_echo_n "checking for __attribute__... " >&6; } -if test "${ac_cv___attribute__+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include <stdlib.h> - -int -main () -{ - -static void foo(void) __attribute__ ((noreturn)); - -static void -foo(void) -{ - exit(1); -} - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv___attribute__=yes -else - ac_cv___attribute__=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -if test "$ac_cv___attribute__" = "yes"; then - -$as_echo "#define HAVE___ATTRIBUTE__ 1" >>confdefs.h - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___attribute__" >&5 -$as_echo "$ac_cv___attribute__" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 -$as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if test "${ac_cv_c_bigendian+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_c_bigendian=unknown - # See if we're dealing with a universal compiler. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifndef __APPLE_CC__ - not a universal capable compiler - #endif - typedef int dummy; - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - # Check for potential -arch flags. It is not universal unless - # there are at least two -arch flags with different values. - ac_arch= - ac_prev= - for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do - if test -n "$ac_prev"; then - case $ac_word in - i?86 | x86_64 | ppc | ppc64) - if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then - ac_arch=$ac_word - else - ac_cv_c_bigendian=universal - break - fi - ;; - esac - ac_prev= - elif test "x$ac_word" = "x-arch"; then - ac_prev=arch - fi - done -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if test $ac_cv_c_bigendian = unknown; then - # See if sys/param.h defines the BYTE_ORDER macro. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> - #include <sys/param.h> - -int -main () -{ -#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ - && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ - && LITTLE_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> - #include <sys/param.h> - -int -main () -{ -#if BYTE_ORDER != BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <limits.h> - -int -main () -{ -#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to _BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <limits.h> - -int -main () -{ -#ifndef _BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # Compile a test program. - if test "$cross_compiling" = yes; then : - # Try to guess by grepping values from an object file. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -short int ascii_mm[] = - { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; - short int ascii_ii[] = - { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; - int use_ascii (int i) { - return ascii_mm[i] + ascii_ii[i]; - } - short int ebcdic_ii[] = - { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; - short int ebcdic_mm[] = - { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; - int use_ebcdic (int i) { - return ebcdic_mm[i] + ebcdic_ii[i]; - } - extern int foo; - -int -main () -{ -return use_ascii (foo) == use_ebcdic (foo); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then - ac_cv_c_bigendian=yes - fi - if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then - if test "$ac_cv_c_bigendian" = unknown; then - ac_cv_c_bigendian=no - else - # finding both strings is unlikely to happen, but who knows? - ac_cv_c_bigendian=unknown - fi - fi -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long int l; - char c[sizeof (long int)]; - } u; - u.l = 1; - return u.c[sizeof (long int) - 1] == 1; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_c_bigendian=no -else - ac_cv_c_bigendian=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 -$as_echo "$ac_cv_c_bigendian" >&6; } - case $ac_cv_c_bigendian in #( - yes) - $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h -;; #( - no) - ;; #( - universal) - -$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h - - ;; #( - *) - as_fn_error "unknown endianness - presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; - esac - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 -$as_echo_n "checking for an ANSI C-conforming const... " >&6; } -if test "${ac_cv_c_const+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -/* FIXME: Include the comments suggested by Paul. */ -#ifndef __cplusplus - /* Ultrix mips cc rejects this. */ - typedef int charset[2]; - const charset cs; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *pcpcc; - char **ppc; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - pcpcc = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++pcpcc; - ppc = (char**) pcpcc; - pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this. */ - char *t; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !cs[0] && !zero.x; -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_const=yes -else - ac_cv_c_const=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 -$as_echo "$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -$as_echo "#define const /**/" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" -if test "x$ac_cv_type_off_t" = x""yes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define off_t long int -_ACEOF - -fi - -ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" -if test "x$ac_cv_type_pid_t" = x""yes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define pid_t int -_ACEOF - -fi - -ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = x""yes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF - -fi - -ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "#include <signal.h> -/* NetBSD declares sys_siglist in unistd.h. */ -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif - -" -if test "x$ac_cv_have_decl_sys_siglist" = x""yes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_SYS_SIGLIST $ac_have_decl -_ACEOF - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 -$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } -if test "${ac_cv_header_time+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> -#include <sys/time.h> -#include <time.h> - -int -main () -{ -if ((struct tm *) 0) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_time=yes -else - ac_cv_header_time=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 -$as_echo "$ac_cv_header_time" >&6; } -if test $ac_cv_header_time = yes; then - -$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 -$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } -if test "${ac_cv_struct_tm+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> -#include <time.h> - -int -main () -{ -struct tm tm; - int *p = &tm.tm_sec; - return !p; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_struct_tm=time.h -else - ac_cv_struct_tm=sys/time.h -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 -$as_echo "$ac_cv_struct_tm" >&6; } -if test $ac_cv_struct_tm = sys/time.h; then - -$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h - -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 -$as_echo_n "checking return type of signal handlers... " >&6; } -if test "${ac_cv_type_signal+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> -#include <signal.h> - -int -main () -{ -return *(signal (0, 0)) (0) == 1; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_type_signal=int -else - ac_cv_type_signal=void -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 -$as_echo "$ac_cv_type_signal" >&6; } - -cat >>confdefs.h <<_ACEOF -#define RETSIGTYPE $ac_cv_type_signal -_ACEOF - - -for ac_header in vfork.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" -if test "x$ac_cv_header_vfork_h" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_VFORK_H 1 -_ACEOF - -fi - -done - -for ac_func in fork vfork -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -eval as_val=\$$as_ac_var - if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_fork" = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5 -$as_echo_n "checking for working fork... " >&6; } -if test "${ac_cv_func_fork_works+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_func_fork_works=cross -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* By Ruediger Kuhlmann. */ - return fork () < 0; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_fork_works=yes -else - ac_cv_func_fork_works=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5 -$as_echo "$ac_cv_func_fork_works" >&6; } - -else - ac_cv_func_fork_works=$ac_cv_func_fork -fi -if test "x$ac_cv_func_fork_works" = xcross; then - case $host in - *-*-amigaos* | *-*-msdosdjgpp*) - # Override, as these systems have only a dummy fork() stub - ac_cv_func_fork_works=no - ;; - *) - ac_cv_func_fork_works=yes - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 -$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} -fi -ac_cv_func_vfork_works=$ac_cv_func_vfork -if test "x$ac_cv_func_vfork" = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5 -$as_echo_n "checking for working vfork... " >&6; } -if test "${ac_cv_func_vfork_works+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_func_vfork_works=cross -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Thanks to Paul Eggert for this test. */ -$ac_includes_default -#include <sys/wait.h> -#ifdef HAVE_VFORK_H -# include <vfork.h> -#endif -/* On some sparc systems, changes by the child to local and incoming - argument registers are propagated back to the parent. The compiler - is told about this with #include <vfork.h>, but some compilers - (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a - static variable whose address is put into a register that is - clobbered by the vfork. */ -static void -#ifdef __cplusplus -sparc_address_test (int arg) -# else -sparc_address_test (arg) int arg; -#endif -{ - static pid_t child; - if (!child) { - child = vfork (); - if (child < 0) { - perror ("vfork"); - _exit(2); - } - if (!child) { - arg = getpid(); - write(-1, "", 0); - _exit (arg); - } - } -} - -int -main () -{ - pid_t parent = getpid (); - pid_t child; - - sparc_address_test (0); - - child = vfork (); - - if (child == 0) { - /* Here is another test for sparc vfork register problems. This - test uses lots of local variables, at least as many local - variables as main has allocated so far including compiler - temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris - 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should - reuse the register of parent for one of the local variables, - since it will think that parent can't possibly be used any more - in this routine. Assigning to the local variable will thus - munge parent in the parent process. */ - pid_t - p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), - p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); - /* Convince the compiler that p..p7 are live; otherwise, it might - use the same hardware register for all 8 local variables. */ - if (p != p1 || p != p2 || p != p3 || p != p4 - || p != p5 || p != p6 || p != p7) - _exit(1); - - /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent - from child file descriptors. If the child closes a descriptor - before it execs or exits, this munges the parent's descriptor - as well. Test for this by closing stdout in the child. */ - _exit(close(fileno(stdout)) != 0); - } else { - int status; - struct stat st; - - while (wait(&status) != child) - ; - return ( - /* Was there some problem with vforking? */ - child < 0 - - /* Did the child fail? (This shouldn't happen.) */ - || status - - /* Did the vfork/compiler bug occur? */ - || parent != getpid() - - /* Did the file descriptor bug occur? */ - || fstat(fileno(stdout), &st) != 0 - ); - } -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_vfork_works=yes -else - ac_cv_func_vfork_works=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5 -$as_echo "$ac_cv_func_vfork_works" >&6; } - -fi; -if test "x$ac_cv_func_fork_works" = xcross; then - ac_cv_func_vfork_works=$ac_cv_func_vfork - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 -$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} -fi - -if test "x$ac_cv_func_vfork_works" = xyes; then - -$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h - -else - -$as_echo "#define vfork fork" >>confdefs.h - -fi -if test "x$ac_cv_func_fork_works" = xyes; then - -$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h - -fi - -for ac_func in vprintf -do : - ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" -if test "x$ac_cv_func_vprintf" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_VPRINTF 1 -_ACEOF - -ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" -if test "x$ac_cv_func__doprnt" = x""yes; then : - -$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h - -fi - -fi -done - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for wait3 that fills in rusage" >&5 -$as_echo_n "checking for wait3 that fills in rusage... " >&6; } -if test "${ac_cv_func_wait3_rusage+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_func_wait3_rusage=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/wait.h> -/* HP-UX has wait3 but does not fill in rusage at all. */ -int -main () -{ - struct rusage r; - int i; - /* Use a field that we can force nonzero -- - voluntary context switches. - For systems like NeXT and OSF/1 that don't set it, - also use the system CPU time. And page faults (I/O) for Linux. */ - r.ru_nvcsw = 0; - r.ru_stime.tv_sec = 0; - r.ru_stime.tv_usec = 0; - r.ru_majflt = r.ru_minflt = 0; - switch (fork ()) - { - case 0: /* Child. */ - sleep(1); /* Give up the CPU. */ - _exit(0); - break; - case -1: /* What can we do? */ - _exit(0); - break; - default: /* Parent. */ - wait3(&i, 0, &r); - /* Avoid "text file busy" from rm on fast HP-UX machines. */ - sleep(2); - return (r.ru_nvcsw == 0 && r.ru_majflt == 0 && r.ru_minflt == 0 - && r.ru_stime.tv_sec == 0 && r.ru_stime.tv_usec == 0); - } -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_wait3_rusage=yes -else - ac_cv_func_wait3_rusage=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_wait3_rusage" >&5 -$as_echo "$ac_cv_func_wait3_rusage" >&6; } -if test $ac_cv_func_wait3_rusage = yes; then - -$as_echo "#define HAVE_WAIT3 1" >>confdefs.h - -fi - -for ac_func in \ - err \ - errx \ - getcwd \ - getenv \ - getopt \ - getwd \ - killpg \ - mmap \ - putenv \ - select \ - setenv \ - setpgid \ - setsid \ - sigaction \ - sigvec \ - snprintf \ - strerror \ - strftime \ - strsep \ - strtod \ - strtol \ - unsetenv \ - vsnprintf \ - wait3 \ - wait4 \ - waitpid \ - warn \ - warnx \ - -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -eval as_val=\$$as_ac_var - if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -for ac_func in \ - realpath \ - dirname \ - stresep \ - strlcpy \ - -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -eval as_val=\$$as_ac_var - if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - case " $LIBOBJS " in - *" $ac_func.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" - ;; -esac - -fi -done - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for emalloc in -lutil" >&5 -$as_echo_n "checking for emalloc in -lutil... " >&6; } -if test "${ac_cv_lib_util_emalloc+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lutil $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char emalloc (); -int -main () -{ -return emalloc (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_util_emalloc=yes -else - ac_cv_lib_util_emalloc=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_emalloc" >&5 -$as_echo "$ac_cv_lib_util_emalloc" >&6; } -if test "x$ac_cv_lib_util_emalloc" = x""yes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erealloc in -lutil" >&5 -$as_echo_n "checking for erealloc in -lutil... " >&6; } -if test "${ac_cv_lib_util_erealloc+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lutil $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char erealloc (); -int -main () -{ -return erealloc (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_util_erealloc=yes -else - ac_cv_lib_util_erealloc=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_erealloc" >&5 -$as_echo "$ac_cv_lib_util_erealloc" >&6; } -if test "x$ac_cv_lib_util_erealloc" = x""yes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for estrdup in -lutil" >&5 -$as_echo_n "checking for estrdup in -lutil... " >&6; } -if test "${ac_cv_lib_util_estrdup+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lutil $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char estrdup (); -int -main () -{ -return estrdup (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_util_estrdup=yes -else - ac_cv_lib_util_estrdup=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_estrdup" >&5 -$as_echo "$ac_cv_lib_util_estrdup" >&6; } -if test "x$ac_cv_lib_util_estrdup" = x""yes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for estrndup in -lutil" >&5 -$as_echo_n "checking for estrndup in -lutil... " >&6; } -if test "${ac_cv_lib_util_estrndup+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lutil $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char estrndup (); -int -main () -{ -return estrndup (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_util_estrndup=yes -else - ac_cv_lib_util_estrndup=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_estrndup" >&5 -$as_echo "$ac_cv_lib_util_estrndup" >&6; } -if test "x$ac_cv_lib_util_estrndup" = x""yes; then : - LIBS="$LIBS -lutil" - CPPFLAGS="$CPPFLAGS -DUSE_EMALLOC" -fi - -fi - -fi - -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat file-mode macros are broken" >&5 -$as_echo_n "checking whether stat file-mode macros are broken... " >&6; } -if test "${ac_cv_header_stat_broken+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> -#include <sys/stat.h> - -#if defined S_ISBLK && defined S_IFDIR -extern char c1[S_ISBLK (S_IFDIR) ? -1 : 1]; -#endif - -#if defined S_ISBLK && defined S_IFCHR -extern char c2[S_ISBLK (S_IFCHR) ? -1 : 1]; -#endif - -#if defined S_ISLNK && defined S_IFREG -extern char c3[S_ISLNK (S_IFREG) ? -1 : 1]; -#endif - -#if defined S_ISSOCK && defined S_IFREG -extern char c4[S_ISSOCK (S_IFREG) ? -1 : 1]; -#endif - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stat_broken=no -else - ac_cv_header_stat_broken=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stat_broken" >&5 -$as_echo "$ac_cv_header_stat_broken" >&6; } -if test $ac_cv_header_stat_broken = yes; then - -$as_echo "#define STAT_MACROS_BROKEN 1" >>confdefs.h - -fi - -ac_fn_c_check_member "$LINENO" "struct stat" "st_rdev" "ac_cv_member_struct_stat_st_rdev" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_rdev" = x""yes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_RDEV 1 -_ACEOF - - -$as_echo "#define HAVE_ST_RDEV 1" >>confdefs.h - -fi - - -echo $ECHO_N "checking if diff -u works... $ECHO_C" >&6 -if diff -u /dev/null /dev/null > /dev/null 2>&1; then - diff_u=-u - echo yes >&6 -else - diff_u= - echo no >&6 -fi -echo "checking for MACHINE & MACHINE_ARCH..." >&6 -cat > conftest.$ac_ext <<EOF -#include "confdefs.h" -#include <sys/param.h> -#ifdef MACHINE -machine=MACHINE -#endif -#ifdef MACHINE_ARCH -machine_arch=MACHINE_ARCH -#endif -EOF - -default_machine=`(eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep machine= | tr -d ' "'` -rm -rf conftest* -if test "$default_machine"; then - eval "$default_machine" -fi -machine=${machine:-`$srcdir/machine.sh`} -machine_arch=${machine_arch:-`$srcdir/machine.sh arch`} -echo "defaults: MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6 - -# Check whether --with-machine was given. -if test "${with_machine+set}" = set; then : - withval=$with_machine; case "${withval}" in -yes) as_fn_error "bad value ${withval} given for bmake MACHINE" "$LINENO" 5 ;; -no) ;; -generic) machine=`$srcdir/machine.sh`;; -*) machine=$with_machine;; -esac -fi - -force_machine= - -# Check whether --with-force_machine was given. -if test "${with_force_machine+set}" = set; then : - withval=$with_force_machine; case "${withval}" in -yes) force_machine=FORCE_;; -no) ;; -*) force_machine=FORCE_; machine=$with_force_machine;; -esac -fi - -force_machine_arch= - -# Check whether --with-force_machine_arch was given. -if test "${with_force_machine_arch+set}" = set; then : - withval=$with_force_machine_arch; case "${withval}" in -yes) force_machine_arch=FORCE_;; -no) ;; -*) force_machine_arch=FORCE_; machine_arch=$with_force_machine;; -esac -fi - - -# Check whether --with-machine_arch was given. -if test "${with_machine_arch+set}" = set; then : - withval=$with_machine_arch; case "${withval}" in -yes) as_fn_error "bad value ${withval} given for bmake MACHINE_ARCH" "$LINENO" 5 ;; -no) ;; -*) machine_arch=$with_machine_arch;; -esac -fi - -echo "Using: ${force_machine}MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6 -default_sys_path=\${prefix}/share/mk - -# Check whether --with-default-sys-path was given. -if test "${with_default_sys_path+set}" = set; then : - withval=$with_default_sys_path; case "${withval}" in -yes) as_fn_error "bad value ${withval} given for bmake _PATH_DEFSYSPATH" "$LINENO" 5 ;; -no) ;; -*) default_sys_path="$with_default_sys_path" - ;; -esac -fi - - -# Check whether --with-path-objdirprefix was given. -if test "${with_path_objdirprefix+set}" = set; then : - withval=$with_path_objdirprefix; case "${withval}" in -yes) as_fn_error "bad value ${withval} given for bmake _PATH_OBJDIRPREFIX" "$LINENO" 5 ;; -no) CPPFLAGS="$CPPFLAGS -DNO_PATH_OBJDIRPREFIX" ;; -*) CPPFLAGS="$CPPFLAGS \"-D_PATH_OBJDIRPREFIX=\\\"$with_path-objdir\\\"\"" ;; -esac -fi - -# Check whether --enable-pwd-override was given. -if test "${enable_pwd_override+set}" = set; then : - enableval=$enable_pwd_override; case "${enableval}" in -yes) ;; -no) CPPFLAGS="$CPPFLAGS -DNO_PWD_OVERRIDE" ;; -*) as_fn_error "bad value ${enableval} given for pwd-override option" "$LINENO" 5 ;; -esac -fi - -# Check whether --enable-check-make-chdir was given. -if test "${enable_check_make_chdir+set}" = set; then : - enableval=$enable_check_make_chdir; case "${enableval}" in -yes) ;; -no) CPPFLAGS="$CPPFLAGS -DNO_CHECK_MAKE_CHDIR" ;; -*) as_fn_error "bad value ${enableval} given for check-make-chdir option" "$LINENO" 5 ;; -esac -fi - - -# Check whether --with-mksrc was given. -if test "${with_mksrc+set}" = set; then : - withval=$with_mksrc; case "${withval}" in -""|yes|no) ;; -*) test -s $withval/install-mk && mksrc=$withval || -as_fn_error "bad value ${withval} given for mksrc cannot find install-mk" "$LINENO" 5 -;; -esac - -fi - -srcdir=`cd $srcdir && pwd` -for mksrc in $mksrc $srcdir/mk $srcdir/../mk mk -do - test -s $mksrc/install-mk || continue - mksrc=`cd $mksrc && pwd` - break -done -mksrc=`echo $mksrc | sed "s,$srcdir,\\\${srcdir},"` -echo "Using: MKSRC=$mksrc" 1>&6 -if test -x /usr/xpg4/bin/sh; then - defshell_path=${defshell_path:-/usr/xpg4/bin/sh} -fi -if test -n "$defshell_path"; then - echo "Using: SHELL=$defshell_path" >&6 - -cat >>confdefs.h <<_ACEOF -#define DEFSHELL_CUSTOM "$defshell_path" -_ACEOF - -fi -if test -n "$DEFSHELL_INDEX"; then - -cat >>confdefs.h <<_ACEOF -#define DEFSHELL_INDEX $DEFSHELL_INDEX -_ACEOF - -fi - - - - - - - - - - -ac_config_files="$ac_config_files Makefile make-bootstrap.sh unit-tests/Makefile" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - - - -: ${CONFIG_STATUS=./config.status} -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error ERROR [LINENO LOG_FD] -# --------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with status $?, using 1 if that was 0. -as_fn_error () -{ - as_status=$?; test $as_status -eq 0 && as_status=1 - if test "$3"; then - as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 - fi - $as_echo "$as_me: error: $1" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -p' - fi -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by bmake $as_me 20120620, which was -generated by GNU Autoconf 2.64. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Report bugs to <sjg@NetBSD.org>." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_version="\\ -bmake config.status 20120620 -configured by $0, generated by GNU Autoconf 2.64, - with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" - -Copyright (C) 2009 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "make-bootstrap.sh") CONFIG_FILES="$CONFIG_FILES make-bootstrap.sh" ;; - "unit-tests/Makefile") CONFIG_FILES="$CONFIG_FILES unit-tests/Makefile" ;; - - *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= - trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\).*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\).*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' <conf$$subs.awk | sed ' -/^[^""]/{ - N - s/\n// -} -' >>$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ - || as_fn_error "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/ -s/:*\${srcdir}:*/:/ -s/:*@srcdir@:*/:/ -s/^\([^=]*=[ ]*\):*/\1/ -s/:*$// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_t=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_t"; then - break - elif $ac_last_try; then - as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' <confdefs.h | sed ' -s/'"$ac_delim"'/"\\\ -"/g' >>$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&2;} - - rm -f "$tmp/stdin" - case $ac_file in - -) cat "$tmp/out" && rm -f "$tmp/out";; - *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; - esac \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" - } >"$tmp/config.h" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$tmp/config.h" "$ac_file" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error "could not create -" "$LINENO" 5 - fi - ;; - - - esac - -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit $? -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - - -cat <<EOF - -You can now run - - sh ./make-bootstrap.sh - -to produce a fully functional bmake. - -EOF diff --git a/20120831/configure.in b/20120831/configure.in deleted file mode 100644 index 156034b9..0000000 --- a/20120831/configure.in +++ /dev/null @@ -1,370 +0,0 @@ -dnl -dnl RCSid: -dnl $Id: configure.in,v 1.45 2012/06/20 22:43:41 sjg Exp $ -dnl -dnl Process this file with autoconf to produce a configure script -dnl -AC_INIT([bmake], [20120620], [sjg@NetBSD.org]) -AC_CONFIG_HEADER(config.h) - -dnl -AC_ARG_WITH(defshell, -[ --with-defshell=SHELL use SHELL by default - must be sh compatible, use sh or ksh to pick the internal definitions], -[case "${withval}" in -yes) AC_MSG_ERROR(bad value ${withval} given for bmake DEFSHELL) ;; -no) ;; -*) case "$with_defshell" in - sh) DEFSHELL_INDEX=DEFSHELL_INDEX_SH;; # it's the default anyway - ksh) DEFSHELL_INDEX=DEFSHELL_INDEX_KSH;; - csh) DEFSHELL_INDEX=DEFSHELL_INDEX_CSH;; # kidding right? - *) defshell_path=$with_defshell;; # better be sh compatible! - esac - ;; - esac]) -dnl -use_meta=yes -AC_ARG_WITH(meta, -[ --without-meta dissable use of meta-mode], -[case "${withval}" in -yes|no) use_meta=${withval};; -*) AC_MSG_ERROR(bad value ${withval} given for meta) ;; -esac]) -dnl -AC_ARG_WITH(filemon, -[ --with-filemon=path/filemon.h indicate path to filemon.h for meta-mode], -[ case "/${withval}" in -/no|*/filemon.h) filemon_h="${withval}";; -*/filemon*) filemon_h="${withval}/filemon.h";; -*) AC_MSG_ERROR(bad value ${withval} given for filemon) ;; -esac], -[ -OS=`uname -s` -for d in "/usr/include/dev/filemon" "$prefix/include/dev/filemon" "$srcdir/filemon" "$srcdir/../filemon" "$srcdir/../../sys/dev/filemon" -do - for x in "/$OS" "" - do - filemon_h="$d$x/filemon.h" - test -s "$filemon_h" && break - done - test -s "$filemon_h" && break -done -test -s "${filemon_h:-/dev/null}" || filemon_h=no -]) -dnl echo "Note: use_meta=$use_meta filemon_h=$filemon_h" >&6 -case "$use_meta" in -yes) - case "$filemon_h" in - *.h) echo "Using: filemon=$filemon_h" >&6;; - esac - ;; -esac -dnl -dnl Check for OS problems -dnl Solaris's signal.h only privides sigset_t etc if one of -dnl _EXTENSIONS_ _POSIX_C_SOURCE or _XOPEN_SOURCE are defined. -dnl The later two seem to cause more problems than they solve so if we -dnl see _EXTENSIONS_ we use it. -AC_USE_SYSTEM_EXTENSIONS -dnl Checks for programs. -AC_PROG_CC -AC_PROG_GCC_TRADITIONAL -AC_PROG_INSTALL -dnl Executable suffix - normally empty; .exe on os2. -AC_SUBST(ac_exe_suffix)dnl - -dnl -dnl Check if /bin/sh will pass .MAKE.LEVEL -echo $ECHO_N "checking if sh will pass .MAKE. variables... $ECHO_C" >&6 -ok=`env .MAKE.LEVEL=1 /bin/sh -c env | grep LEVEL=` -case "$ok" in -"") echo no >&6; CPPFLAGS="${CPPFLAGS} -DNEED_MAKE_LEVEL_SAFE";; -*) echo yes >&6;; -esac - -dnl -dnl AC_C_CROSS -dnl - -dnl Checks for header files. -AC_HEADER_STDC -AC_HEADER_SYS_WAIT -AC_HEADER_DIRENT -dnl Keep this list sorted -AC_CHECK_HEADERS( \ - ar.h \ - err.h \ - fcntl.h \ - paths.h \ - poll.h \ - ranlib.h \ - string.h \ - sys/mman.h \ - sys/select.h \ - sys/socket.h \ - sys/time.h \ - sys/uio.h \ - unistd.h \ - utime.h \ - ) - -dnl Both *BSD and Linux have sys/cdefs.h, most do not. -dnl If it is missing, we add -I${srcdir}/missing to CFLAGS -dnl also if sys/cdefs.h does not have __RCSID we need to use ours -dnl but we need to include the host's one too *sigh* -AC_CHECK_HEADER(sys/cdefs.h, -echo $ECHO_N "checking whether sys/cdefs.h is compatible... $ECHO_C" >&6 -AC_EGREP_CPP(yes, -[#include <sys/cdefs.h> -#ifdef __RCSID -yes -#endif -], -echo yes >&6, -echo no >&6; CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd` -DNEED_HOST_CDEFS_H"), -CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd`") - -dnl Checks for typedefs, structures, and compiler characteristics. -AC_C___ATTRIBUTE__ -AC_C_BIGENDIAN -AC_C_CONST -AC_TYPE_OFF_T -AC_TYPE_PID_T -AC_TYPE_SIZE_T -AC_DECL_SYS_SIGLIST -AC_HEADER_TIME -AC_STRUCT_TM - -dnl Checks for library functions. -AC_TYPE_SIGNAL -AC_FUNC_VFORK -AC_FUNC_VPRINTF -AC_FUNC_WAIT3 -dnl Keep this list sorted -AC_CHECK_FUNCS( \ - err \ - errx \ - getcwd \ - getenv \ - getopt \ - getwd \ - killpg \ - mmap \ - putenv \ - select \ - setenv \ - setpgid \ - setsid \ - sigaction \ - sigvec \ - snprintf \ - strerror \ - strftime \ - strsep \ - strtod \ - strtol \ - unsetenv \ - vsnprintf \ - wait3 \ - wait4 \ - waitpid \ - warn \ - warnx \ - ) - -dnl functions which we may need to provide -AC_REPLACE_FUNCS( \ - realpath \ - dirname \ - stresep \ - strlcpy \ - ) - -AC_CHECK_LIB([util], [emalloc], - [ AC_CHECK_LIB([util], [erealloc], - [ AC_CHECK_LIB([util], [estrdup], - [ AC_CHECK_LIB([util], [estrndup], - [ LIBS="$LIBS -lutil" - CPPFLAGS="$CPPFLAGS -DUSE_EMALLOC" ])])])]) - -dnl -dnl Structures -dnl -AC_HEADER_STAT -AC_STRUCT_ST_RDEV -dnl -dnl we want this for unit-tests/Makefile -echo $ECHO_N "checking if diff -u works... $ECHO_C" >&6 -if diff -u /dev/null /dev/null > /dev/null 2>&1; then - diff_u=-u - echo yes >&6 -else - diff_u= - echo no >&6 -fi -dnl -dnl AC_* don't quite cut it. -dnl -echo "checking for MACHINE & MACHINE_ARCH..." >&6 -cat > conftest.$ac_ext <<EOF -#include "confdefs.h" -#include <sys/param.h> -#ifdef MACHINE -machine=MACHINE -#endif -#ifdef MACHINE_ARCH -machine_arch=MACHINE_ARCH -#endif -EOF - -default_machine=`(eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep machine= | tr -d ' "'` -rm -rf conftest* -if test "$default_machine"; then - eval "$default_machine" -fi -machine=${machine:-`$srcdir/machine.sh`} -machine_arch=${machine_arch:-`$srcdir/machine.sh arch`} -echo "defaults: MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6 -dnl -dnl now allow overrides -dnl -AC_ARG_WITH(machine, -[ --with-machine=MACHINE explicitly set MACHINE], -[case "${withval}" in -yes) AC_MSG_ERROR(bad value ${withval} given for bmake MACHINE) ;; -no) ;; -generic) machine=`$srcdir/machine.sh`;; -*) machine=$with_machine;; -esac]) -force_machine= -AC_ARG_WITH(force_machine, -[ --with-force-machine=MACHINE set FORCE_MACHINE], -[case "${withval}" in -yes) force_machine=FORCE_;; -no) ;; -*) force_machine=FORCE_; machine=$with_force_machine;; -esac]) -dnl -force_machine_arch= -AC_ARG_WITH(force_machine_arch, -[ --with-force-machine-arch=MACHINE set FORCE_MACHINE_ARCH], -[case "${withval}" in -yes) force_machine_arch=FORCE_;; -no) ;; -*) force_machine_arch=FORCE_; machine_arch=$with_force_machine;; -esac]) -dnl -AC_ARG_WITH(machine_arch, -[ --with-machine_arch=MACHINE_ARCH explicitly set MACHINE_ARCH], -[case "${withval}" in -yes) AC_MSG_ERROR(bad value ${withval} given for bmake MACHINE_ARCH) ;; -no) ;; -*) machine_arch=$with_machine_arch;; -esac]) -dnl -dnl Tell them what we ended up with -dnl -echo "Using: ${force_machine}MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6 -dnl -dnl Allow folk to control _PATH_DEFSYSPATH -dnl -default_sys_path=\${prefix}/share/mk -AC_ARG_WITH(default-sys-path, -[ --with-default-sys-path=PATH:DIR:LIST use an explicit _PATH_DEFSYSPATH - MAKESYSPATH is a ':' separated list of directories - that bmake will search for system .mk files. - _PATH_DEFSYSPATH is its default value.], -[case "${withval}" in -yes) AC_MSG_ERROR(bad value ${withval} given for bmake _PATH_DEFSYSPATH) ;; -no) ;; -*) default_sys_path="$with_default_sys_path" - ;; -esac]) -dnl -dnl Some folk don't like this one -dnl -AC_ARG_WITH(path-objdirprefix, -[ --with-path-objdirprefix=PATH override _PATH_OBJDIRPREFIX], -[case "${withval}" in -yes) AC_MSG_ERROR(bad value ${withval} given for bmake _PATH_OBJDIRPREFIX) ;; -no) CPPFLAGS="$CPPFLAGS -DNO_PATH_OBJDIRPREFIX" ;; -*) CPPFLAGS="$CPPFLAGS \"-D_PATH_OBJDIRPREFIX=\\\"$with_path-objdir\\\"\"" ;; -esac]) -dnl -dnl And this can be handy to do with out. -dnl -AC_ARG_ENABLE(pwd-override, -[ --disable-pwd-override disable \$PWD overriding getcwd()], -[case "${enableval}" in -yes) ;; -no) CPPFLAGS="$CPPFLAGS -DNO_PWD_OVERRIDE" ;; -*) AC_MSG_ERROR(bad value ${enableval} given for pwd-override option) ;; -esac]) -dnl -dnl Just for grins -dnl -AC_ARG_ENABLE(check-make-chdir, -[ --disable-check-make-chdir disable make trying to guess - when it should automatically cd \${.CURDIR}], -[case "${enableval}" in -yes) ;; -no) CPPFLAGS="$CPPFLAGS -DNO_CHECK_MAKE_CHDIR" ;; -*) AC_MSG_ERROR(bad value ${enableval} given for check-make-chdir option) ;; -esac]) -dnl -dnl On non-BSD systems, bootstrap won't work without mk -dnl -AC_ARG_WITH(mksrc, -[ --with-mksrc=PATH tell makefile.boot where to find mk src], -[case "${withval}" in -""|yes|no) ;; -*) test -s $withval/install-mk && mksrc=$withval || -AC_MSG_ERROR(bad value ${withval} given for mksrc cannot find install-mk) -;; -esac -]) -dnl -dnl Now make sure we have a value -dnl -srcdir=`cd $srcdir && pwd` -for mksrc in $mksrc $srcdir/mk $srcdir/../mk mk -do - test -s $mksrc/install-mk || continue - mksrc=`cd $mksrc && pwd` - break -done -mksrc=`echo $mksrc | sed "s,$srcdir,\\\${srcdir},"` -echo "Using: MKSRC=$mksrc" 1>&6 -dnl On some systems we want a different default shell by default -if test -x /usr/xpg4/bin/sh; then - defshell_path=${defshell_path:-/usr/xpg4/bin/sh} -fi -if test -n "$defshell_path"; then - echo "Using: SHELL=$defshell_path" >&6 - AC_DEFINE_UNQUOTED(DEFSHELL_CUSTOM, "$defshell_path", Path of default shell) -fi -if test -n "$DEFSHELL_INDEX"; then - AC_DEFINE_UNQUOTED(DEFSHELL_INDEX, $DEFSHELL_INDEX, Shell spec to use by default) -fi -dnl -AC_SUBST(machine) -AC_SUBST(force_machine) -AC_SUBST(machine_arch) -AC_SUBST(mksrc) -AC_SUBST(default_sys_path) -AC_SUBST(INSTALL) -AC_SUBST(GCC) -AC_SUBST(diff_u) -AC_SUBST(use_meta) -AC_SUBST(filemon_h) -AC_OUTPUT(Makefile make-bootstrap.sh unit-tests/Makefile) - -cat <<EOF - -You can now run - - sh ./make-bootstrap.sh - -to produce a fully functional bmake. - -EOF diff --git a/20120831/dir.c b/20120831/dir.c deleted file mode 100644 index 1c56ea3..0000000 --- a/20120831/dir.c +++ /dev/null @@ -1,1802 +0,0 @@ -/* $NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94"; -#else -__RCSID("$NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * dir.c -- - * Directory searching using wildcards and/or normal names... - * Used both for source wildcarding in the Makefile and for finding - * implicit sources. - * - * The interface for this module is: - * Dir_Init Initialize the module. - * - * Dir_InitCur Set the cur Path. - * - * Dir_InitDot Set the dot Path. - * - * Dir_End Cleanup the module. - * - * Dir_SetPATH Set ${.PATH} to reflect state of dirSearchPath. - * - * Dir_HasWildcards Returns TRUE if the name given it needs to - * be wildcard-expanded. - * - * Dir_Expand Given a pattern and a path, return a Lst of names - * which match the pattern on the search path. - * - * Dir_FindFile Searches for a file on a given search path. - * If it exists, the entire path is returned. - * Otherwise NULL is returned. - * - * Dir_FindHereOrAbove Search for a path in the current directory and - * then all the directories above it in turn until - * the path is found or we reach the root ("/"). - * - * Dir_MTime Return the modification time of a node. The file - * is searched for along the default search path. - * The path and mtime fields of the node are filled - * in. - * - * Dir_AddDir Add a directory to a search path. - * - * Dir_MakeFlags Given a search path and a command flag, create - * a string with each of the directories in the path - * preceded by the command flag and all of them - * separated by a space. - * - * Dir_Destroy Destroy an element of a search path. Frees up all - * things that can be freed for the element as long - * as the element is no longer referenced by any other - * search path. - * Dir_ClearPath Resets a search path to the empty list. - * - * For debugging: - * Dir_PrintDirectories Print stats about the directory cache. - */ - -#include <sys/types.h> -#include <sys/stat.h> - -#include <dirent.h> -#include <errno.h> -#include <stdio.h> - -#include "make.h" -#include "hash.h" -#include "dir.h" - -/* - * A search path consists of a Lst of Path structures. A Path structure - * has in it the name of the directory and a hash table of all the files - * in the directory. This is used to cut down on the number of system - * calls necessary to find implicit dependents and their like. Since - * these searches are made before any actions are taken, we need not - * worry about the directory changing due to creation commands. If this - * hampers the style of some makefiles, they must be changed. - * - * A list of all previously-read directories is kept in the - * openDirectories Lst. This list is checked first before a directory - * is opened. - * - * The need for the caching of whole directories is brought about by - * the multi-level transformation code in suff.c, which tends to search - * for far more files than regular make does. In the initial - * implementation, the amount of time spent performing "stat" calls was - * truly astronomical. The problem with hashing at the start is, - * of course, that pmake doesn't then detect changes to these directories - * during the course of the make. Three possibilities suggest themselves: - * - * 1) just use stat to test for a file's existence. As mentioned - * above, this is very inefficient due to the number of checks - * engendered by the multi-level transformation code. - * 2) use readdir() and company to search the directories, keeping - * them open between checks. I have tried this and while it - * didn't slow down the process too much, it could severely - * affect the amount of parallelism available as each directory - * open would take another file descriptor out of play for - * handling I/O for another job. Given that it is only recently - * that UNIX OS's have taken to allowing more than 20 or 32 - * file descriptors for a process, this doesn't seem acceptable - * to me. - * 3) record the mtime of the directory in the Path structure and - * verify the directory hasn't changed since the contents were - * hashed. This will catch the creation or deletion of files, - * but not the updating of files. However, since it is the - * creation and deletion that is the problem, this could be - * a good thing to do. Unfortunately, if the directory (say ".") - * were fairly large and changed fairly frequently, the constant - * rehashing could seriously degrade performance. It might be - * good in such cases to keep track of the number of rehashes - * and if the number goes over a (small) limit, resort to using - * stat in its place. - * - * An additional thing to consider is that pmake is used primarily - * to create C programs and until recently pcc-based compilers refused - * to allow you to specify where the resulting object file should be - * placed. This forced all objects to be created in the current - * directory. This isn't meant as a full excuse, just an explanation of - * some of the reasons for the caching used here. - * - * One more note: the location of a target's file is only performed - * on the downward traversal of the graph and then only for terminal - * nodes in the graph. This could be construed as wrong in some cases, - * but prevents inadvertent modification of files when the "installed" - * directory for a file is provided in the search path. - * - * Another data structure maintained by this module is an mtime - * cache used when the searching of cached directories fails to find - * a file. In the past, Dir_FindFile would simply perform an access() - * call in such a case to determine if the file could be found using - * just the name given. When this hit, however, all that was gained - * was the knowledge that the file existed. Given that an access() is - * essentially a stat() without the copyout() call, and that the same - * filesystem overhead would have to be incurred in Dir_MTime, it made - * sense to replace the access() with a stat() and record the mtime - * in a cache for when Dir_MTime was actually called. - */ - -Lst dirSearchPath; /* main search path */ - -static Lst openDirectories; /* the list of all open directories */ - -/* - * Variables for gathering statistics on the efficiency of the hashing - * mechanism. - */ -static int hits, /* Found in directory cache */ - misses, /* Sad, but not evil misses */ - nearmisses, /* Found under search path */ - bigmisses; /* Sought by itself */ - -static Path *dot; /* contents of current directory */ -static Path *cur; /* contents of current directory, if not dot */ -static Path *dotLast; /* a fake path entry indicating we need to - * look for . last */ -static Hash_Table mtimes; /* Results of doing a last-resort stat in - * Dir_FindFile -- if we have to go to the - * system to find the file, we might as well - * have its mtime on record. XXX: If this is done - * way early, there's a chance other rules will - * have already updated the file, in which case - * we'll update it again. Generally, there won't - * be two rules to update a single file, so this - * should be ok, but... */ - - -static int DirFindName(const void *, const void *); -static int DirMatchFiles(const char *, Path *, Lst); -static void DirExpandCurly(const char *, const char *, Lst, Lst); -static void DirExpandInt(const char *, Lst, Lst); -static int DirPrintWord(void *, void *); -static int DirPrintDir(void *, void *); -static char *DirLookup(Path *, const char *, const char *, Boolean); -static char *DirLookupSubdir(Path *, const char *); -static char *DirFindDot(Boolean, const char *, const char *); -static char *DirLookupAbs(Path *, const char *, const char *); - -/*- - *----------------------------------------------------------------------- - * Dir_Init -- - * initialize things for this module - * - * Results: - * none - * - * Side Effects: - * some directories may be opened. - *----------------------------------------------------------------------- - */ -void -Dir_Init(const char *cdname) -{ - dirSearchPath = Lst_Init(FALSE); - openDirectories = Lst_Init(FALSE); - Hash_InitTable(&mtimes, 0); - - Dir_InitCur(cdname); - - dotLast = bmake_malloc(sizeof(Path)); - dotLast->refCount = 1; - dotLast->hits = 0; - dotLast->name = bmake_strdup(".DOTLAST"); - Hash_InitTable(&dotLast->files, -1); -} - -/* - * Called by Dir_Init() and whenever .CURDIR is assigned to. - */ -void -Dir_InitCur(const char *cdname) -{ - Path *p; - - if (cdname != NULL) { - /* - * Our build directory is not the same as our source directory. - * Keep this one around too. - */ - if ((p = Dir_AddDir(NULL, cdname))) { - p->refCount += 1; - if (cur && cur != p) { - /* - * We've been here before, cleanup. - */ - cur->refCount -= 1; - Dir_Destroy(cur); - } - cur = p; - } - } -} - -/*- - *----------------------------------------------------------------------- - * Dir_InitDot -- - * (re)initialize "dot" (current/object directory) path hash - * - * Results: - * none - * - * Side Effects: - * some directories may be opened. - *----------------------------------------------------------------------- - */ -void -Dir_InitDot(void) -{ - if (dot != NULL) { - LstNode ln; - - /* Remove old entry from openDirectories, but do not destroy. */ - ln = Lst_Member(openDirectories, dot); - (void)Lst_Remove(openDirectories, ln); - } - - dot = Dir_AddDir(NULL, "."); - - if (dot == NULL) { - Error("Cannot open `.' (%s)", strerror(errno)); - exit(1); - } - - /* - * We always need to have dot around, so we increment its reference count - * to make sure it's not destroyed. - */ - dot->refCount += 1; - Dir_SetPATH(); /* initialize */ -} - -/*- - *----------------------------------------------------------------------- - * Dir_End -- - * cleanup things for this module - * - * Results: - * none - * - * Side Effects: - * none - *----------------------------------------------------------------------- - */ -void -Dir_End(void) -{ -#ifdef CLEANUP - if (cur) { - cur->refCount -= 1; - Dir_Destroy(cur); - } - dot->refCount -= 1; - dotLast->refCount -= 1; - Dir_Destroy(dotLast); - Dir_Destroy(dot); - Dir_ClearPath(dirSearchPath); - Lst_Destroy(dirSearchPath, NULL); - Dir_ClearPath(openDirectories); - Lst_Destroy(openDirectories, NULL); - Hash_DeleteTable(&mtimes); -#endif -} - -/* - * We want ${.PATH} to indicate the order in which we will actually - * search, so we rebuild it after any .PATH: target. - * This is the simplest way to deal with the effect of .DOTLAST. - */ -void -Dir_SetPATH(void) -{ - LstNode ln; /* a list element */ - Path *p; - Boolean hasLastDot = FALSE; /* true we should search dot last */ - - Var_Delete(".PATH", VAR_GLOBAL); - - if (Lst_Open(dirSearchPath) == SUCCESS) { - if ((ln = Lst_First(dirSearchPath)) != NULL) { - p = (Path *)Lst_Datum(ln); - if (p == dotLast) { - hasLastDot = TRUE; - Var_Append(".PATH", dotLast->name, VAR_GLOBAL); - } - } - - if (!hasLastDot) { - if (dot) - Var_Append(".PATH", dot->name, VAR_GLOBAL); - if (cur) - Var_Append(".PATH", cur->name, VAR_GLOBAL); - } - - while ((ln = Lst_Next(dirSearchPath)) != NULL) { - p = (Path *)Lst_Datum(ln); - if (p == dotLast) - continue; - if (p == dot && hasLastDot) - continue; - Var_Append(".PATH", p->name, VAR_GLOBAL); - } - - if (hasLastDot) { - if (dot) - Var_Append(".PATH", dot->name, VAR_GLOBAL); - if (cur) - Var_Append(".PATH", cur->name, VAR_GLOBAL); - } - Lst_Close(dirSearchPath); - } -} - -/*- - *----------------------------------------------------------------------- - * DirFindName -- - * See if the Path structure describes the same directory as the - * given one by comparing their names. Called from Dir_AddDir via - * Lst_Find when searching the list of open directories. - * - * Input: - * p Current name - * dname Desired name - * - * Results: - * 0 if it is the same. Non-zero otherwise - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static int -DirFindName(const void *p, const void *dname) -{ - return (strcmp(((const Path *)p)->name, dname)); -} - -/*- - *----------------------------------------------------------------------- - * Dir_HasWildcards -- - * see if the given name has any wildcard characters in it - * be careful not to expand unmatching brackets or braces. - * XXX: This code is not 100% correct. ([^]] fails etc.) - * I really don't think that make(1) should be expanding - * patterns, because then you have to set a mechanism for - * escaping the expansion! - * - * Input: - * name name to check - * - * Results: - * returns TRUE if the word should be expanded, FALSE otherwise - * - * Side Effects: - * none - *----------------------------------------------------------------------- - */ -Boolean -Dir_HasWildcards(char *name) -{ - char *cp; - int wild = 0, brace = 0, bracket = 0; - - for (cp = name; *cp; cp++) { - switch(*cp) { - case '{': - brace++; - wild = 1; - break; - case '}': - brace--; - break; - case '[': - bracket++; - wild = 1; - break; - case ']': - bracket--; - break; - case '?': - case '*': - wild = 1; - break; - default: - break; - } - } - return wild && bracket == 0 && brace == 0; -} - -/*- - *----------------------------------------------------------------------- - * DirMatchFiles -- - * Given a pattern and a Path structure, see if any files - * match the pattern and add their names to the 'expansions' list if - * any do. This is incomplete -- it doesn't take care of patterns like - * src / *src / *.c properly (just *.c on any of the directories), but it - * will do for now. - * - * Input: - * pattern Pattern to look for - * p Directory to search - * expansion Place to store the results - * - * Results: - * Always returns 0 - * - * Side Effects: - * File names are added to the expansions lst. The directory will be - * fully hashed when this is done. - *----------------------------------------------------------------------- - */ -static int -DirMatchFiles(const char *pattern, Path *p, Lst expansions) -{ - Hash_Search search; /* Index into the directory's table */ - Hash_Entry *entry; /* Current entry in the table */ - Boolean isDot; /* TRUE if the directory being searched is . */ - - isDot = (*p->name == '.' && p->name[1] == '\0'); - - for (entry = Hash_EnumFirst(&p->files, &search); - entry != NULL; - entry = Hash_EnumNext(&search)) - { - /* - * See if the file matches the given pattern. Note we follow the UNIX - * convention that dot files will only be found if the pattern - * begins with a dot (note also that as a side effect of the hashing - * scheme, .* won't match . or .. since they aren't hashed). - */ - if (Str_Match(entry->name, pattern) && - ((entry->name[0] != '.') || - (pattern[0] == '.'))) - { - (void)Lst_AtEnd(expansions, - (isDot ? bmake_strdup(entry->name) : - str_concat(p->name, entry->name, - STR_ADDSLASH))); - } - } - return (0); -} - -/*- - *----------------------------------------------------------------------- - * DirExpandCurly -- - * Expand curly braces like the C shell. Does this recursively. - * Note the special case: if after the piece of the curly brace is - * done there are no wildcard characters in the result, the result is - * placed on the list WITHOUT CHECKING FOR ITS EXISTENCE. - * - * Input: - * word Entire word to expand - * brace First curly brace in it - * path Search path to use - * expansions Place to store the expansions - * - * Results: - * None. - * - * Side Effects: - * The given list is filled with the expansions... - * - *----------------------------------------------------------------------- - */ -static void -DirExpandCurly(const char *word, const char *brace, Lst path, Lst expansions) -{ - const char *end; /* Character after the closing brace */ - const char *cp; /* Current position in brace clause */ - const char *start; /* Start of current piece of brace clause */ - int bracelevel; /* Number of braces we've seen. If we see a - * right brace when this is 0, we've hit the - * end of the clause. */ - char *file; /* Current expansion */ - int otherLen; /* The length of the other pieces of the - * expansion (chars before and after the - * clause in 'word') */ - char *cp2; /* Pointer for checking for wildcards in - * expansion before calling Dir_Expand */ - - start = brace+1; - - /* - * Find the end of the brace clause first, being wary of nested brace - * clauses. - */ - for (end = start, bracelevel = 0; *end != '\0'; end++) { - if (*end == '{') { - bracelevel++; - } else if ((*end == '}') && (bracelevel-- == 0)) { - break; - } - } - if (*end == '\0') { - Error("Unterminated {} clause \"%s\"", start); - return; - } else { - end++; - } - otherLen = brace - word + strlen(end); - - for (cp = start; cp < end; cp++) { - /* - * Find the end of this piece of the clause. - */ - bracelevel = 0; - while (*cp != ',') { - if (*cp == '{') { - bracelevel++; - } else if ((*cp == '}') && (bracelevel-- <= 0)) { - break; - } - cp++; - } - /* - * Allocate room for the combination and install the three pieces. - */ - file = bmake_malloc(otherLen + cp - start + 1); - if (brace != word) { - strncpy(file, word, brace-word); - } - if (cp != start) { - strncpy(&file[brace-word], start, cp-start); - } - strcpy(&file[(brace-word)+(cp-start)], end); - - /* - * See if the result has any wildcards in it. If we find one, call - * Dir_Expand right away, telling it to place the result on our list - * of expansions. - */ - for (cp2 = file; *cp2 != '\0'; cp2++) { - switch(*cp2) { - case '*': - case '?': - case '{': - case '[': - Dir_Expand(file, path, expansions); - goto next; - } - } - if (*cp2 == '\0') { - /* - * Hit the end w/o finding any wildcards, so stick the expansion - * on the end of the list. - */ - (void)Lst_AtEnd(expansions, file); - } else { - next: - free(file); - } - start = cp+1; - } -} - - -/*- - *----------------------------------------------------------------------- - * DirExpandInt -- - * Internal expand routine. Passes through the directories in the - * path one by one, calling DirMatchFiles for each. NOTE: This still - * doesn't handle patterns in directories... - * - * Input: - * word Word to expand - * path Path on which to look - * expansions Place to store the result - * - * Results: - * None. - * - * Side Effects: - * Things are added to the expansions list. - * - *----------------------------------------------------------------------- - */ -static void -DirExpandInt(const char *word, Lst path, Lst expansions) -{ - LstNode ln; /* Current node */ - Path *p; /* Directory in the node */ - - if (Lst_Open(path) == SUCCESS) { - while ((ln = Lst_Next(path)) != NULL) { - p = (Path *)Lst_Datum(ln); - DirMatchFiles(word, p, expansions); - } - Lst_Close(path); - } -} - -/*- - *----------------------------------------------------------------------- - * DirPrintWord -- - * Print a word in the list of expansions. Callback for Dir_Expand - * when DEBUG(DIR), via Lst_ForEach. - * - * Results: - * === 0 - * - * Side Effects: - * The passed word is printed, followed by a space. - * - *----------------------------------------------------------------------- - */ -static int -DirPrintWord(void *word, void *dummy) -{ - fprintf(debug_file, "%s ", (char *)word); - - return(dummy ? 0 : 0); -} - -/*- - *----------------------------------------------------------------------- - * Dir_Expand -- - * Expand the given word into a list of words by globbing it looking - * in the directories on the given search path. - * - * Input: - * word the word to expand - * path the list of directories in which to find the - * resulting files - * expansions the list on which to place the results - * - * Results: - * A list of words consisting of the files which exist along the search - * path matching the given pattern. - * - * Side Effects: - * Directories may be opened. Who knows? - *----------------------------------------------------------------------- - */ -void -Dir_Expand(const char *word, Lst path, Lst expansions) -{ - const char *cp; - - if (DEBUG(DIR)) { - fprintf(debug_file, "Expanding \"%s\"... ", word); - } - - cp = strchr(word, '{'); - if (cp) { - DirExpandCurly(word, cp, path, expansions); - } else { - cp = strchr(word, '/'); - if (cp) { - /* - * The thing has a directory component -- find the first wildcard - * in the string. - */ - for (cp = word; *cp; cp++) { - if (*cp == '?' || *cp == '[' || *cp == '*' || *cp == '{') { - break; - } - } - if (*cp == '{') { - /* - * This one will be fun. - */ - DirExpandCurly(word, cp, path, expansions); - return; - } else if (*cp != '\0') { - /* - * Back up to the start of the component - */ - char *dirpath; - - while (cp > word && *cp != '/') { - cp--; - } - if (cp != word) { - char sc; - /* - * If the glob isn't in the first component, try and find - * all the components up to the one with a wildcard. - */ - sc = cp[1]; - ((char *)UNCONST(cp))[1] = '\0'; - dirpath = Dir_FindFile(word, path); - ((char *)UNCONST(cp))[1] = sc; - /* - * dirpath is null if can't find the leading component - * XXX: Dir_FindFile won't find internal components. - * i.e. if the path contains ../Etc/Object and we're - * looking for Etc, it won't be found. Ah well. - * Probably not important. - */ - if (dirpath != NULL) { - char *dp = &dirpath[strlen(dirpath) - 1]; - if (*dp == '/') - *dp = '\0'; - path = Lst_Init(FALSE); - (void)Dir_AddDir(path, dirpath); - DirExpandInt(cp+1, path, expansions); - Lst_Destroy(path, NULL); - } - } else { - /* - * Start the search from the local directory - */ - DirExpandInt(word, path, expansions); - } - } else { - /* - * Return the file -- this should never happen. - */ - DirExpandInt(word, path, expansions); - } - } else { - /* - * First the files in dot - */ - DirMatchFiles(word, dot, expansions); - - /* - * Then the files in every other directory on the path. - */ - DirExpandInt(word, path, expansions); - } - } - if (DEBUG(DIR)) { - Lst_ForEach(expansions, DirPrintWord, NULL); - fprintf(debug_file, "\n"); - } -} - -/*- - *----------------------------------------------------------------------- - * DirLookup -- - * Find if the file with the given name exists in the given path. - * - * Results: - * The path to the file or NULL. This path is guaranteed to be in a - * different part of memory than name and so may be safely free'd. - * - * Side Effects: - * None. - *----------------------------------------------------------------------- - */ -static char * -DirLookup(Path *p, const char *name MAKE_ATTR_UNUSED, const char *cp, - Boolean hasSlash MAKE_ATTR_UNUSED) -{ - char *file; /* the current filename to check */ - - if (DEBUG(DIR)) { - fprintf(debug_file, " %s ...\n", p->name); - } - - if (Hash_FindEntry(&p->files, cp) == NULL) - return NULL; - - file = str_concat(p->name, cp, STR_ADDSLASH); - if (DEBUG(DIR)) { - fprintf(debug_file, " returning %s\n", file); - } - p->hits += 1; - hits += 1; - return file; -} - - -/*- - *----------------------------------------------------------------------- - * DirLookupSubdir -- - * Find if the file with the given name exists in the given path. - * - * Results: - * The path to the file or NULL. This path is guaranteed to be in a - * different part of memory than name and so may be safely free'd. - * - * Side Effects: - * If the file is found, it is added in the modification times hash - * table. - *----------------------------------------------------------------------- - */ -static char * -DirLookupSubdir(Path *p, const char *name) -{ - struct stat stb; /* Buffer for stat, if necessary */ - Hash_Entry *entry; /* Entry for mtimes table */ - char *file; /* the current filename to check */ - - if (p != dot) { - file = str_concat(p->name, name, STR_ADDSLASH); - } else { - /* - * Checking in dot -- DON'T put a leading ./ on the thing. - */ - file = bmake_strdup(name); - } - - if (DEBUG(DIR)) { - fprintf(debug_file, "checking %s ...\n", file); - } - - if (stat(file, &stb) == 0) { - if (stb.st_mtime == 0) - stb.st_mtime = 1; - /* - * Save the modification time so if it's needed, we don't have - * to fetch it again. - */ - if (DEBUG(DIR)) { - fprintf(debug_file, " Caching %s for %s\n", Targ_FmtTime(stb.st_mtime), - file); - } - entry = Hash_CreateEntry(&mtimes, file, NULL); - Hash_SetTimeValue(entry, stb.st_mtime); - nearmisses += 1; - return (file); - } - free(file); - return NULL; -} - -/*- - *----------------------------------------------------------------------- - * DirLookupAbs -- - * Find if the file with the given name exists in the given path. - * - * Results: - * The path to the file, the empty string or NULL. If the file is - * the empty string, the search should be terminated. - * This path is guaranteed to be in a different part of memory - * than name and so may be safely free'd. - * - * Side Effects: - * None. - *----------------------------------------------------------------------- - */ -static char * -DirLookupAbs(Path *p, const char *name, const char *cp) -{ - char *p1; /* pointer into p->name */ - const char *p2; /* pointer into name */ - - if (DEBUG(DIR)) { - fprintf(debug_file, " %s ...\n", p->name); - } - - /* - * If the file has a leading path component and that component - * exactly matches the entire name of the current search - * directory, we can attempt another cache lookup. And if we don't - * have a hit, we can safely assume the file does not exist at all. - */ - for (p1 = p->name, p2 = name; *p1 && *p1 == *p2; p1++, p2++) { - continue; - } - if (*p1 != '\0' || p2 != cp - 1) { - return NULL; - } - - if (Hash_FindEntry(&p->files, cp) == NULL) { - if (DEBUG(DIR)) { - fprintf(debug_file, " must be here but isn't -- returning\n"); - } - /* Return empty string: terminates search */ - return bmake_strdup(""); - } - - p->hits += 1; - hits += 1; - if (DEBUG(DIR)) { - fprintf(debug_file, " returning %s\n", name); - } - return (bmake_strdup(name)); -} - -/*- - *----------------------------------------------------------------------- - * DirFindDot -- - * Find the file given on "." or curdir - * - * Results: - * The path to the file or NULL. This path is guaranteed to be in a - * different part of memory than name and so may be safely free'd. - * - * Side Effects: - * Hit counts change - *----------------------------------------------------------------------- - */ -static char * -DirFindDot(Boolean hasSlash MAKE_ATTR_UNUSED, const char *name, const char *cp) -{ - - if (Hash_FindEntry(&dot->files, cp) != NULL) { - if (DEBUG(DIR)) { - fprintf(debug_file, " in '.'\n"); - } - hits += 1; - dot->hits += 1; - return (bmake_strdup(name)); - } - if (cur && - Hash_FindEntry(&cur->files, cp) != NULL) { - if (DEBUG(DIR)) { - fprintf(debug_file, " in ${.CURDIR} = %s\n", cur->name); - } - hits += 1; - cur->hits += 1; - return str_concat(cur->name, cp, STR_ADDSLASH); - } - - return NULL; -} - -/*- - *----------------------------------------------------------------------- - * Dir_FindFile -- - * Find the file with the given name along the given search path. - * - * Input: - * name the file to find - * path the Lst of directories to search - * - * Results: - * The path to the file or NULL. This path is guaranteed to be in a - * different part of memory than name and so may be safely free'd. - * - * Side Effects: - * If the file is found in a directory which is not on the path - * already (either 'name' is absolute or it is a relative path - * [ dir1/.../dirn/file ] which exists below one of the directories - * already on the search path), its directory is added to the end - * of the path on the assumption that there will be more files in - * that directory later on. Sometimes this is true. Sometimes not. - *----------------------------------------------------------------------- - */ -char * -Dir_FindFile(const char *name, Lst path) -{ - LstNode ln; /* a list element */ - char *file; /* the current filename to check */ - Path *p; /* current path member */ - const char *cp; /* Terminal name of file */ - Boolean hasLastDot = FALSE; /* true we should search dot last */ - Boolean hasSlash; /* true if 'name' contains a / */ - struct stat stb; /* Buffer for stat, if necessary */ - Hash_Entry *entry; /* Entry for mtimes table */ - const char *trailing_dot = "."; - - /* - * Find the final component of the name and note whether it has a - * slash in it (the name, I mean) - */ - cp = strrchr(name, '/'); - if (cp) { - hasSlash = TRUE; - cp += 1; - } else { - hasSlash = FALSE; - cp = name; - } - - if (DEBUG(DIR)) { - fprintf(debug_file, "Searching for %s ...", name); - } - - if (Lst_Open(path) == FAILURE) { - if (DEBUG(DIR)) { - fprintf(debug_file, "couldn't open path, file not found\n"); - } - misses += 1; - return NULL; - } - - if ((ln = Lst_First(path)) != NULL) { - p = (Path *)Lst_Datum(ln); - if (p == dotLast) { - hasLastDot = TRUE; - if (DEBUG(DIR)) - fprintf(debug_file, "[dot last]..."); - } - } - if (DEBUG(DIR)) { - fprintf(debug_file, "\n"); - } - - /* - * If there's no leading directory components or if the leading - * directory component is exactly `./', consult the cached contents - * of each of the directories on the search path. - */ - if (!hasSlash || (cp - name == 2 && *name == '.')) { - /* - * We look through all the directories on the path seeking one which - * contains the final component of the given name. If such a beast - * is found, we concatenate the directory name and the final - * component and return the resulting string. If we don't find any - * such thing, we go on to phase two... - * - * No matter what, we always look for the file in the current - * directory before anywhere else (unless we found the magic - * DOTLAST path, in which case we search it last) and we *do not* - * add the ./ to it if it exists. - * This is so there are no conflicts between what the user - * specifies (fish.c) and what pmake finds (./fish.c). - */ - if (!hasLastDot && - (file = DirFindDot(hasSlash, name, cp)) != NULL) { - Lst_Close(path); - return file; - } - - while ((ln = Lst_Next(path)) != NULL) { - p = (Path *)Lst_Datum(ln); - if (p == dotLast) - continue; - if ((file = DirLookup(p, name, cp, hasSlash)) != NULL) { - Lst_Close(path); - return file; - } - } - - if (hasLastDot && - (file = DirFindDot(hasSlash, name, cp)) != NULL) { - Lst_Close(path); - return file; - } - } - Lst_Close(path); - - /* - * We didn't find the file on any directory in the search path. - * If the name doesn't contain a slash, that means it doesn't exist. - * If it *does* contain a slash, however, there is still hope: it - * could be in a subdirectory of one of the members of the search - * path. (eg. /usr/include and sys/types.h. The above search would - * fail to turn up types.h in /usr/include, but it *is* in - * /usr/include/sys/types.h). - * [ This no longer applies: If we find such a beast, we assume there - * will be more (what else can we assume?) and add all but the last - * component of the resulting name onto the search path (at the - * end).] - * This phase is only performed if the file is *not* absolute. - */ - if (!hasSlash) { - if (DEBUG(DIR)) { - fprintf(debug_file, " failed.\n"); - } - misses += 1; - return NULL; - } - - if (*cp == '\0') { - /* we were given a trailing "/" */ - cp = trailing_dot; - } - - if (name[0] != '/') { - Boolean checkedDot = FALSE; - - if (DEBUG(DIR)) { - fprintf(debug_file, " Trying subdirectories...\n"); - } - - if (!hasLastDot) { - if (dot) { - checkedDot = TRUE; - if ((file = DirLookupSubdir(dot, name)) != NULL) - return file; - } - if (cur && (file = DirLookupSubdir(cur, name)) != NULL) - return file; - } - - (void)Lst_Open(path); - while ((ln = Lst_Next(path)) != NULL) { - p = (Path *)Lst_Datum(ln); - if (p == dotLast) - continue; - if (p == dot) { - if (checkedDot) - continue; - checkedDot = TRUE; - } - if ((file = DirLookupSubdir(p, name)) != NULL) { - Lst_Close(path); - return file; - } - } - Lst_Close(path); - - if (hasLastDot) { - if (dot && !checkedDot) { - checkedDot = TRUE; - if ((file = DirLookupSubdir(dot, name)) != NULL) - return file; - } - if (cur && (file = DirLookupSubdir(cur, name)) != NULL) - return file; - } - - if (checkedDot) { - /* - * Already checked by the given name, since . was in the path, - * so no point in proceeding... - */ - if (DEBUG(DIR)) { - fprintf(debug_file, " Checked . already, returning NULL\n"); - } - return NULL; - } - - } else { /* name[0] == '/' */ - - /* - * For absolute names, compare directory path prefix against the - * the directory path of each member on the search path for an exact - * match. If we have an exact match on any member of the search path, - * use the cached contents of that member to lookup the final file - * component. If that lookup fails we can safely assume that the - * file does not exist at all. This is signified by DirLookupAbs() - * returning an empty string. - */ - if (DEBUG(DIR)) { - fprintf(debug_file, " Trying exact path matches...\n"); - } - - if (!hasLastDot && cur && (file = DirLookupAbs(cur, name, cp)) != NULL) - return *file?file:NULL; - - (void)Lst_Open(path); - while ((ln = Lst_Next(path)) != NULL) { - p = (Path *)Lst_Datum(ln); - if (p == dotLast) - continue; - if ((file = DirLookupAbs(p, name, cp)) != NULL) { - Lst_Close(path); - return *file?file:NULL; - } - } - Lst_Close(path); - - if (hasLastDot && cur && (file = DirLookupAbs(cur, name, cp)) != NULL) - return *file?file:NULL; - } - - /* - * Didn't find it that way, either. Sigh. Phase 3. Add its directory - * onto the search path in any case, just in case, then look for the - * thing in the hash table. If we find it, grand. We return a new - * copy of the name. Otherwise we sadly return a NULL pointer. Sigh. - * Note that if the directory holding the file doesn't exist, this will - * do an extra search of the final directory on the path. Unless something - * weird happens, this search won't succeed and life will be groovy. - * - * Sigh. We cannot add the directory onto the search path because - * of this amusing case: - * $(INSTALLDIR)/$(FILE): $(FILE) - * - * $(FILE) exists in $(INSTALLDIR) but not in the current one. - * When searching for $(FILE), we will find it in $(INSTALLDIR) - * b/c we added it here. This is not good... - */ -#ifdef notdef - if (cp == traling_dot) { - cp = strrchr(name, '/'); - cp += 1; - } - cp[-1] = '\0'; - (void)Dir_AddDir(path, name); - cp[-1] = '/'; - - bigmisses += 1; - ln = Lst_Last(path); - if (ln == NULL) { - return NULL; - } else { - p = (Path *)Lst_Datum(ln); - } - - if (Hash_FindEntry(&p->files, cp) != NULL) { - return (bmake_strdup(name)); - } else { - return NULL; - } -#else /* !notdef */ - if (DEBUG(DIR)) { - fprintf(debug_file, " Looking for \"%s\" ...\n", name); - } - - bigmisses += 1; - entry = Hash_FindEntry(&mtimes, name); - if (entry != NULL) { - if (DEBUG(DIR)) { - fprintf(debug_file, " got it (in mtime cache)\n"); - } - return(bmake_strdup(name)); - } else if (stat(name, &stb) == 0) { - if (stb.st_mtime == 0) - stb.st_mtime = 1; - entry = Hash_CreateEntry(&mtimes, name, NULL); - if (DEBUG(DIR)) { - fprintf(debug_file, " Caching %s for %s\n", Targ_FmtTime(stb.st_mtime), - name); - } - Hash_SetTimeValue(entry, stb.st_mtime); - return (bmake_strdup(name)); - } else { - if (DEBUG(DIR)) { - fprintf(debug_file, " failed. Returning NULL\n"); - } - return NULL; - } -#endif /* notdef */ -} - - -/*- - *----------------------------------------------------------------------- - * Dir_FindHereOrAbove -- - * search for a path starting at a given directory and then working - * our way up towards the root. - * - * Input: - * here starting directory - * search_path the path we are looking for - * result the result of a successful search is placed here - * rlen the length of the result buffer - * (typically MAXPATHLEN + 1) - * - * Results: - * 0 on failure, 1 on success [in which case the found path is put - * in the result buffer]. - * - * Side Effects: - *----------------------------------------------------------------------- - */ -int -Dir_FindHereOrAbove(char *here, char *search_path, char *result, int rlen) { - - struct stat st; - char dirbase[MAXPATHLEN + 1], *db_end; - char try[MAXPATHLEN + 1], *try_end; - - /* copy out our starting point */ - snprintf(dirbase, sizeof(dirbase), "%s", here); - db_end = dirbase + strlen(dirbase); - - /* loop until we determine a result */ - while (1) { - - /* try and stat(2) it ... */ - snprintf(try, sizeof(try), "%s/%s", dirbase, search_path); - if (stat(try, &st) != -1) { - /* - * success! if we found a file, chop off - * the filename so we return a directory. - */ - if ((st.st_mode & S_IFMT) != S_IFDIR) { - try_end = try + strlen(try); - while (try_end > try && *try_end != '/') - try_end--; - if (try_end > try) - *try_end = 0; /* chop! */ - } - - /* - * done! - */ - snprintf(result, rlen, "%s", try); - return(1); - } - - /* - * nope, we didn't find it. if we used up dirbase we've - * reached the root and failed. - */ - if (db_end == dirbase) - break; /* failed! */ - - /* - * truncate dirbase from the end to move up a dir - */ - while (db_end > dirbase && *db_end != '/') - db_end--; - *db_end = 0; /* chop! */ - - } /* while (1) */ - - /* - * we failed... - */ - return(0); -} - -/*- - *----------------------------------------------------------------------- - * Dir_MTime -- - * Find the modification time of the file described by gn along the - * search path dirSearchPath. - * - * Input: - * gn the file whose modification time is desired - * - * Results: - * The modification time or 0 if it doesn't exist - * - * Side Effects: - * The modification time is placed in the node's mtime slot. - * If the node didn't have a path entry before, and Dir_FindFile - * found one for it, the full name is placed in the path slot. - *----------------------------------------------------------------------- - */ -int -Dir_MTime(GNode *gn, Boolean recheck) -{ - char *fullName; /* the full pathname of name */ - struct stat stb; /* buffer for finding the mod time */ - Hash_Entry *entry; - - if (gn->type & OP_ARCHV) { - return Arch_MTime(gn); - } else if (gn->type & OP_PHONY) { - gn->mtime = 0; - return 0; - } else if (gn->path == NULL) { - if (gn->type & OP_NOPATH) - fullName = NULL; - else { - fullName = Dir_FindFile(gn->name, Suff_FindPath(gn)); - if (fullName == NULL && gn->flags & FROM_DEPEND && - !Lst_IsEmpty(gn->iParents)) { - char *cp; - - cp = strrchr(gn->name, '/'); - if (cp) { - /* - * This is an implied source, and it may have moved, - * see if we can find it via the current .PATH - */ - cp++; - - fullName = Dir_FindFile(cp, Suff_FindPath(gn)); - if (fullName) { - /* - * Put the found file in gn->path - * so that we give that to the compiler. - */ - gn->path = bmake_strdup(fullName); - fprintf(stdout, - "%s: ignoring stale %s for %s, found %s\n", - progname, makeDependfile, gn->name, fullName); - } - } - } - if (DEBUG(DIR)) - fprintf(debug_file, "Found '%s' as '%s'\n", - gn->name, fullName ? fullName : "(not found)" ); - } - } else { - fullName = gn->path; - } - - if (fullName == NULL) { - fullName = bmake_strdup(gn->name); - } - - if (!recheck) - entry = Hash_FindEntry(&mtimes, fullName); - else - entry = NULL; - if (entry != NULL) { - if (DEBUG(DIR)) { - fprintf(debug_file, "Using cached time %s for %s\n", - Targ_FmtTime(Hash_GetTimeValue(entry)), fullName); - } - stb.st_mtime = Hash_GetTimeValue(entry); - } else if (stat(fullName, &stb) < 0) { - if (gn->type & OP_MEMBER) { - if (fullName != gn->path) - free(fullName); - return Arch_MemMTime(gn); - } else { - stb.st_mtime = 0; - } - } else { - if (stb.st_mtime == 0) { - /* - * 0 handled specially by the code, if the time is really 0, - * return something else instead - */ - stb.st_mtime = 1; - } - entry = Hash_CreateEntry(&mtimes, fullName, NULL); - Hash_SetTimeValue(entry, stb.st_mtime); - } - - if (fullName && gn->path == NULL) { - gn->path = fullName; - } - - gn->mtime = stb.st_mtime; - return (gn->mtime); -} - -/*- - *----------------------------------------------------------------------- - * Dir_AddDir -- - * Add the given name to the end of the given path. The order of - * the arguments is backwards so ParseDoDependency can do a - * Lst_ForEach of its list of paths... - * - * Input: - * path the path to which the directory should be - * added - * name the name of the directory to add - * - * Results: - * none - * - * Side Effects: - * A structure is added to the list and the directory is - * read and hashed. - *----------------------------------------------------------------------- - */ -Path * -Dir_AddDir(Lst path, const char *name) -{ - LstNode ln = NULL; /* node in case Path structure is found */ - Path *p = NULL; /* pointer to new Path structure */ - DIR *d; /* for reading directory */ - struct dirent *dp; /* entry in directory */ - - if (strcmp(name, ".DOTLAST") == 0) { - ln = Lst_Find(path, name, DirFindName); - if (ln != NULL) - return (Path *)Lst_Datum(ln); - else { - dotLast->refCount += 1; - (void)Lst_AtFront(path, dotLast); - } - } - - if (path) - ln = Lst_Find(openDirectories, name, DirFindName); - if (ln != NULL) { - p = (Path *)Lst_Datum(ln); - if (path && Lst_Member(path, p) == NULL) { - p->refCount += 1; - (void)Lst_AtEnd(path, p); - } - } else { - if (DEBUG(DIR)) { - fprintf(debug_file, "Caching %s ...", name); - } - - if ((d = opendir(name)) != NULL) { - p = bmake_malloc(sizeof(Path)); - p->name = bmake_strdup(name); - p->hits = 0; - p->refCount = 1; - Hash_InitTable(&p->files, -1); - - while ((dp = readdir(d)) != NULL) { -#if defined(sun) && defined(d_ino) /* d_ino is a sunos4 #define for d_fileno */ - /* - * The sun directory library doesn't check for a 0 inode - * (0-inode slots just take up space), so we have to do - * it ourselves. - */ - if (dp->d_fileno == 0) { - continue; - } -#endif /* sun && d_ino */ - (void)Hash_CreateEntry(&p->files, dp->d_name, NULL); - } - (void)closedir(d); - (void)Lst_AtEnd(openDirectories, p); - if (path != NULL) - (void)Lst_AtEnd(path, p); - } - if (DEBUG(DIR)) { - fprintf(debug_file, "done\n"); - } - } - return p; -} - -/*- - *----------------------------------------------------------------------- - * Dir_CopyDir -- - * Callback function for duplicating a search path via Lst_Duplicate. - * Ups the reference count for the directory. - * - * Results: - * Returns the Path it was given. - * - * Side Effects: - * The refCount of the path is incremented. - * - *----------------------------------------------------------------------- - */ -void * -Dir_CopyDir(void *p) -{ - ((Path *)p)->refCount += 1; - - return (p); -} - -/*- - *----------------------------------------------------------------------- - * Dir_MakeFlags -- - * Make a string by taking all the directories in the given search - * path and preceding them by the given flag. Used by the suffix - * module to create variables for compilers based on suffix search - * paths. - * - * Input: - * flag flag which should precede each directory - * path list of directories - * - * Results: - * The string mentioned above. Note that there is no space between - * the given flag and each directory. The empty string is returned if - * Things don't go well. - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -char * -Dir_MakeFlags(const char *flag, Lst path) -{ - char *str; /* the string which will be returned */ - char *s1, *s2;/* the current directory preceded by 'flag' */ - LstNode ln; /* the node of the current directory */ - Path *p; /* the structure describing the current directory */ - - str = bmake_strdup(""); - - if (Lst_Open(path) == SUCCESS) { - while ((ln = Lst_Next(path)) != NULL) { - p = (Path *)Lst_Datum(ln); - s2 = str_concat(flag, p->name, 0); - str = str_concat(s1 = str, s2, STR_ADDSPACE); - free(s1); - free(s2); - } - Lst_Close(path); - } - - return (str); -} - -/*- - *----------------------------------------------------------------------- - * Dir_Destroy -- - * Nuke a directory descriptor, if possible. Callback procedure - * for the suffixes module when destroying a search path. - * - * Input: - * pp The directory descriptor to nuke - * - * Results: - * None. - * - * Side Effects: - * If no other path references this directory (refCount == 0), - * the Path and all its data are freed. - * - *----------------------------------------------------------------------- - */ -void -Dir_Destroy(void *pp) -{ - Path *p = (Path *)pp; - p->refCount -= 1; - - if (p->refCount == 0) { - LstNode ln; - - ln = Lst_Member(openDirectories, p); - (void)Lst_Remove(openDirectories, ln); - - Hash_DeleteTable(&p->files); - free(p->name); - free(p); - } -} - -/*- - *----------------------------------------------------------------------- - * Dir_ClearPath -- - * Clear out all elements of the given search path. This is different - * from destroying the list, notice. - * - * Input: - * path Path to clear - * - * Results: - * None. - * - * Side Effects: - * The path is set to the empty list. - * - *----------------------------------------------------------------------- - */ -void -Dir_ClearPath(Lst path) -{ - Path *p; - while (!Lst_IsEmpty(path)) { - p = (Path *)Lst_DeQueue(path); - Dir_Destroy(p); - } -} - - -/*- - *----------------------------------------------------------------------- - * Dir_Concat -- - * Concatenate two paths, adding the second to the end of the first. - * Makes sure to avoid duplicates. - * - * Input: - * path1 Dest - * path2 Source - * - * Results: - * None - * - * Side Effects: - * Reference counts for added dirs are upped. - * - *----------------------------------------------------------------------- - */ -void -Dir_Concat(Lst path1, Lst path2) -{ - LstNode ln; - Path *p; - - for (ln = Lst_First(path2); ln != NULL; ln = Lst_Succ(ln)) { - p = (Path *)Lst_Datum(ln); - if (Lst_Member(path1, p) == NULL) { - p->refCount += 1; - (void)Lst_AtEnd(path1, p); - } - } -} - -/********** DEBUG INFO **********/ -void -Dir_PrintDirectories(void) -{ - LstNode ln; - Path *p; - - fprintf(debug_file, "#*** Directory Cache:\n"); - fprintf(debug_file, "# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n", - hits, misses, nearmisses, bigmisses, - (hits+bigmisses+nearmisses ? - hits * 100 / (hits + bigmisses + nearmisses) : 0)); - fprintf(debug_file, "# %-20s referenced\thits\n", "directory"); - if (Lst_Open(openDirectories) == SUCCESS) { - while ((ln = Lst_Next(openDirectories)) != NULL) { - p = (Path *)Lst_Datum(ln); - fprintf(debug_file, "# %-20s %10d\t%4d\n", p->name, p->refCount, p->hits); - } - Lst_Close(openDirectories); - } -} - -static int -DirPrintDir(void *p, void *dummy) -{ - fprintf(debug_file, "%s ", ((Path *)p)->name); - return (dummy ? 0 : 0); -} - -void -Dir_PrintPath(Lst path) -{ - Lst_ForEach(path, DirPrintDir, NULL); -} diff --git a/20120831/dir.h b/20120831/dir.h deleted file mode 100644 index aa00450..0000000 --- a/20120831/dir.h +++ /dev/null @@ -1,108 +0,0 @@ -/* $NetBSD: dir.h,v 1.15 2012/04/07 18:29:08 christos Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)dir.h 8.1 (Berkeley) 6/6/93 - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)dir.h 8.1 (Berkeley) 6/6/93 - */ - -/* dir.h -- - */ - -#ifndef _DIR -#define _DIR - -typedef struct Path { - char *name; /* Name of directory */ - int refCount; /* Number of paths with this directory */ - int hits; /* the number of times a file in this - * directory has been found */ - Hash_Table files; /* Hash table of files in directory */ -} Path; - -void Dir_Init(const char *); -void Dir_InitCur(const char *); -void Dir_InitDot(void); -void Dir_End(void); -void Dir_SetPATH(void); -Boolean Dir_HasWildcards(char *); -void Dir_Expand(const char *, Lst, Lst); -char *Dir_FindFile(const char *, Lst); -int Dir_FindHereOrAbove(char *, char *, char *, int); -int Dir_MTime(GNode *, Boolean); -Path *Dir_AddDir(Lst, const char *); -char *Dir_MakeFlags(const char *, Lst); -void Dir_ClearPath(Lst); -void Dir_Concat(Lst, Lst); -void Dir_PrintDirectories(void); -void Dir_PrintPath(Lst); -void Dir_Destroy(void *); -void * Dir_CopyDir(void *); - -#endif /* _DIR */ diff --git a/20120831/dirname.c b/20120831/dirname.c deleted file mode 100644 index 8b6b6c3..0000000 --- a/20120831/dirname.c +++ /dev/null @@ -1,95 +0,0 @@ -/* $NetBSD: dirname.c,v 1.11 2009/11/24 13:34:20 tnozaki Exp $ */ - -/*- - * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Klaus Klein and Jason R. Thorpe. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#ifndef HAVE_DIRNAME - -#include <sys/cdefs.h> - -#ifdef HAVE_LIMITS_H -#include <limits.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifndef PATH_MAX -# define PATH_MAX 1024 -#endif - -char * -dirname(char *path) -{ - static char result[PATH_MAX]; - const char *lastp; - size_t len; - - /* - * If `path' is a null pointer or points to an empty string, - * return a pointer to the string ".". - */ - if ((path == NULL) || (*path == '\0')) - goto singledot; - - - /* Strip trailing slashes, if any. */ - lastp = path + strlen(path) - 1; - while (lastp != path && *lastp == '/') - lastp--; - - /* Terminate path at the last occurence of '/'. */ - do { - if (*lastp == '/') { - /* Strip trailing slashes, if any. */ - while (lastp != path && *lastp == '/') - lastp--; - - /* ...and copy the result into the result buffer. */ - len = (lastp - path) + 1 /* last char */; - if (len > (PATH_MAX - 1)) - len = PATH_MAX - 1; - - memcpy(result, path, len); - result[len] = '\0'; - - return (result); - } - } while (--lastp >= path); - - /* No /'s found, return a pointer to the string ".". */ -singledot: - result[0] = '.'; - result[1] = '\0'; - - return (result); -} -#endif diff --git a/20120831/find_lib.sh b/20120831/find_lib.sh deleted file mode 100755 index 3c2e4af..0000000 --- a/20120831/find_lib.sh +++ /dev/null @@ -1,13 +0,0 @@ -: -re=$1; shift - -for lib in $* -do - found=`nm $lib | egrep "$re"` - case "$found" in - "") ;; - *) echo "$lib: $found";; - esac -done - - diff --git a/20120831/for.c b/20120831/for.c deleted file mode 100644 index 33bcf13..0000000 --- a/20120831/for.c +++ /dev/null @@ -1,496 +0,0 @@ -/* $NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $ */ - -/* - * Copyright (c) 1992, The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * for.c -- - * Functions to handle loops in a makefile. - * - * Interface: - * For_Eval Evaluate the loop in the passed line. - * For_Run Run accumulated loop - * - */ - -#include <assert.h> -#include <ctype.h> - -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "buf.h" -#include "strlist.h" - -#define FOR_SUB_ESCAPE_CHAR 1 -#define FOR_SUB_ESCAPE_BRACE 2 -#define FOR_SUB_ESCAPE_PAREN 4 - -/* - * For statements are of the form: - * - * .for <variable> in <varlist> - * ... - * .endfor - * - * The trick is to look for the matching end inside for for loop - * To do that, we count the current nesting level of the for loops. - * and the .endfor statements, accumulating all the statements between - * the initial .for loop and the matching .endfor; - * then we evaluate the for loop for each variable in the varlist. - * - * Note that any nested fors are just passed through; they get handled - * recursively in For_Eval when we're expanding the enclosing for in - * For_Run. - */ - -static int forLevel = 0; /* Nesting level */ - -/* - * State of a for loop. - */ -typedef struct _For { - Buffer buf; /* Body of loop */ - strlist_t vars; /* Iteration variables */ - strlist_t items; /* Substitution items */ - char *parse_buf; - int short_var; - int sub_next; -} For; - -static For *accumFor; /* Loop being accumulated */ - - - -static char * -make_str(const char *ptr, int len) -{ - char *new_ptr; - - new_ptr = bmake_malloc(len + 1); - memcpy(new_ptr, ptr, len); - new_ptr[len] = 0; - return new_ptr; -} - -static void -For_Free(For *arg) -{ - Buf_Destroy(&arg->buf, TRUE); - strlist_clean(&arg->vars); - strlist_clean(&arg->items); - free(arg->parse_buf); - - free(arg); -} - -/*- - *----------------------------------------------------------------------- - * For_Eval -- - * Evaluate the for loop in the passed line. The line - * looks like this: - * .for <variable> in <varlist> - * - * Input: - * line Line to parse - * - * Results: - * 0: Not a .for statement, parse the line - * 1: We found a for loop - * -1: A .for statement with a bad syntax error, discard. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -int -For_Eval(char *line) -{ - For *new_for; - char *ptr = line, *sub; - int len; - int escapes; - unsigned char ch; - char **words, *word_buf; - int n, nwords; - - /* Skip the '.' and any following whitespace */ - for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++) - continue; - - /* - * If we are not in a for loop quickly determine if the statement is - * a for. - */ - if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' || - !isspace((unsigned char) ptr[3])) { - if (ptr[0] == 'e' && strncmp(ptr+1, "ndfor", 5) == 0) { - Parse_Error(PARSE_FATAL, "for-less endfor"); - return -1; - } - return 0; - } - ptr += 3; - - /* - * we found a for loop, and now we are going to parse it. - */ - - new_for = bmake_malloc(sizeof *new_for); - memset(new_for, 0, sizeof *new_for); - - /* Grab the variables. Terminate on "in". */ - for (;; ptr += len) { - while (*ptr && isspace((unsigned char) *ptr)) - ptr++; - if (*ptr == '\0') { - Parse_Error(PARSE_FATAL, "missing `in' in for"); - For_Free(new_for); - return -1; - } - for (len = 1; ptr[len] && !isspace((unsigned char)ptr[len]); len++) - continue; - if (len == 2 && ptr[0] == 'i' && ptr[1] == 'n') { - ptr += 2; - break; - } - if (len == 1) - new_for->short_var = 1; - strlist_add_str(&new_for->vars, make_str(ptr, len), len); - } - - if (strlist_num(&new_for->vars) == 0) { - Parse_Error(PARSE_FATAL, "no iteration variables in for"); - For_Free(new_for); - return -1; - } - - while (*ptr && isspace((unsigned char) *ptr)) - ptr++; - - /* - * Make a list with the remaining words - * The values are substituted as ${:U<value>...} so we must \ escape - * characters that break that syntax. - * Variables are fully expanded - so it is safe for escape $. - * We can't do the escapes here - because we don't know whether - * we are substuting into ${...} or $(...). - */ - sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE); - - /* - * Split into words allowing for quoted strings. - */ - words = brk_string(sub, &nwords, FALSE, &word_buf); - - free(sub); - - if (words != NULL) { - for (n = 0; n < nwords; n++) { - ptr = words[n]; - if (!*ptr) - continue; - escapes = 0; - while ((ch = *ptr++)) { - switch(ch) { - case ':': - case '$': - case '\\': - escapes |= FOR_SUB_ESCAPE_CHAR; - break; - case ')': - escapes |= FOR_SUB_ESCAPE_PAREN; - break; - case /*{*/ '}': - escapes |= FOR_SUB_ESCAPE_BRACE; - break; - } - } - /* - * We have to dup words[n] to maintain the semantics of - * strlist. - */ - strlist_add_str(&new_for->items, bmake_strdup(words[n]), escapes); - } - - free(words); - free(word_buf); - - if ((len = strlist_num(&new_for->items)) > 0 && - len % (n = strlist_num(&new_for->vars))) { - Parse_Error(PARSE_FATAL, - "Wrong number of words (%d) in .for substitution list" - " with %d vars", len, n); - /* - * Return 'success' so that the body of the .for loop is - * accumulated. - * Remove all items so that the loop doesn't iterate. - */ - strlist_clean(&new_for->items); - } - } - - Buf_Init(&new_for->buf, 0); - accumFor = new_for; - forLevel = 1; - return 1; -} - -/* - * Add another line to a .for loop. - * Returns 0 when the matching .endfor is reached. - */ - -int -For_Accum(char *line) -{ - char *ptr = line; - - if (*ptr == '.') { - - for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++) - continue; - - if (strncmp(ptr, "endfor", 6) == 0 && - (isspace((unsigned char) ptr[6]) || !ptr[6])) { - if (DEBUG(FOR)) - (void)fprintf(debug_file, "For: end for %d\n", forLevel); - if (--forLevel <= 0) - return 0; - } else if (strncmp(ptr, "for", 3) == 0 && - isspace((unsigned char) ptr[3])) { - forLevel++; - if (DEBUG(FOR)) - (void)fprintf(debug_file, "For: new loop %d\n", forLevel); - } - } - - Buf_AddBytes(&accumFor->buf, strlen(line), line); - Buf_AddByte(&accumFor->buf, '\n'); - return 1; -} - - -/*- - *----------------------------------------------------------------------- - * For_Run -- - * Run the for loop, imitating the actions of an include file - * - * Results: - * None. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ - -static int -for_var_len(const char *var) -{ - char ch, var_start, var_end; - int depth; - int len; - - var_start = *var; - if (var_start == 0) - /* just escape the $ */ - return 0; - - if (var_start == '(') - var_end = ')'; - else if (var_start == '{') - var_end = '}'; - else - /* Single char variable */ - return 1; - - depth = 1; - for (len = 1; (ch = var[len++]) != 0;) { - if (ch == var_start) - depth++; - else if (ch == var_end && --depth == 0) - return len; - } - - /* Variable end not found, escape the $ */ - return 0; -} - -static void -for_substitute(Buffer *cmds, strlist_t *items, unsigned int item_no, char ech) -{ - const char *item = strlist_str(items, item_no); - int len; - char ch; - - /* If there were no escapes, or the only escape is the other variable - * terminator, then just substitute the full string */ - if (!(strlist_info(items, item_no) & - (ech == ')' ? ~FOR_SUB_ESCAPE_BRACE : ~FOR_SUB_ESCAPE_PAREN))) { - Buf_AddBytes(cmds, strlen(item), item); - return; - } - - /* Escape ':', '$', '\\' and 'ech' - removed by :U processing */ - while ((ch = *item++) != 0) { - if (ch == '$') { - len = for_var_len(item); - if (len != 0) { - Buf_AddBytes(cmds, len + 1, item - 1); - item += len; - continue; - } - Buf_AddByte(cmds, '\\'); - } else if (ch == ':' || ch == '\\' || ch == ech) - Buf_AddByte(cmds, '\\'); - Buf_AddByte(cmds, ch); - } -} - -static char * -For_Iterate(void *v_arg, size_t *ret_len) -{ - For *arg = v_arg; - int i, len; - char *var; - char *cp; - char *cmd_cp; - char *body_end; - char ch; - Buffer cmds; - - if (arg->sub_next + strlist_num(&arg->vars) > strlist_num(&arg->items)) { - /* No more iterations */ - For_Free(arg); - return NULL; - } - - free(arg->parse_buf); - arg->parse_buf = NULL; - - /* - * Scan the for loop body and replace references to the loop variables - * with variable references that expand to the required text. - * Using variable expansions ensures that the .for loop can't generate - * syntax, and that the later parsing will still see a variable. - * We assume that the null variable will never be defined. - * - * The detection of substitions of the loop control variable is naive. - * Many of the modifiers use \ to escape $ (not $) so it is possible - * to contrive a makefile where an unwanted substitution happens. - */ - - cmd_cp = Buf_GetAll(&arg->buf, &len); - body_end = cmd_cp + len; - Buf_Init(&cmds, len + 256); - for (cp = cmd_cp; (cp = strchr(cp, '$')) != NULL;) { - char ech; - ch = *++cp; - if ((ch == '(' && (ech = ')')) || (ch == '{' && (ech = '}'))) { - cp++; - /* Check variable name against the .for loop variables */ - STRLIST_FOREACH(var, &arg->vars, i) { - len = strlist_info(&arg->vars, i); - if (memcmp(cp, var, len) != 0) - continue; - if (cp[len] != ':' && cp[len] != ech && cp[len] != '\\') - continue; - /* Found a variable match. Replace with :U<value> */ - Buf_AddBytes(&cmds, cp - cmd_cp, cmd_cp); - Buf_AddBytes(&cmds, 2, ":U"); - cp += len; - cmd_cp = cp; - for_substitute(&cmds, &arg->items, arg->sub_next + i, ech); - break; - } - continue; - } - if (ch == 0) - break; - /* Probably a single character name, ignore $$ and stupid ones. {*/ - if (!arg->short_var || strchr("}):$", ch) != NULL) { - cp++; - continue; - } - STRLIST_FOREACH(var, &arg->vars, i) { - if (var[0] != ch || var[1] != 0) - continue; - /* Found a variable match. Replace with ${:U<value>} */ - Buf_AddBytes(&cmds, cp - cmd_cp, cmd_cp); - Buf_AddBytes(&cmds, 3, "{:U"); - cmd_cp = ++cp; - for_substitute(&cmds, &arg->items, arg->sub_next + i, /*{*/ '}'); - Buf_AddBytes(&cmds, 1, "}"); - break; - } - } - Buf_AddBytes(&cmds, body_end - cmd_cp, cmd_cp); - - cp = Buf_Destroy(&cmds, FALSE); - if (DEBUG(FOR)) - (void)fprintf(debug_file, "For: loop body:\n%s", cp); - - arg->sub_next += strlist_num(&arg->vars); - - arg->parse_buf = cp; - *ret_len = strlen(cp); - return cp; -} - -void -For_Run(int lineno) -{ - For *arg; - - arg = accumFor; - accumFor = NULL; - - if (strlist_num(&arg->items) == 0) { - /* Nothing to expand - possibly due to an earlier syntax error. */ - For_Free(arg); - return; - } - - Parse_SetInput(NULL, lineno, -1, For_Iterate, arg); -} diff --git a/20120831/getopt.c b/20120831/getopt.c deleted file mode 100644 index c40bc13..0000000 --- a/20120831/getopt.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 1987, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#if !defined(HAVE_GETOPT) || defined(WANT_GETOPT_LONG) || defined(BROKEN_GETOPT) - -#if defined(LIBC_SCCS) && !defined(lint) -/* static char sccsid[] = "from: @(#)getopt.c 8.2 (Berkeley) 4/2/94"; */ -static char *rcsid = "$Id: getopt.c,v 1.3 1999/01/08 02:14:18 sjg Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - - -#define BADCH (int)'?' -#define BADARG (int)':' -#define EMSG "" - -int opterr = 1, /* if error message should be printed */ - optind = 1, /* index into parent argv vector */ - optopt = BADCH, /* character checked for validity */ - optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ - -/* - * getopt -- - * Parse argc/argv argument vector. - */ -int -getopt(nargc, nargv, ostr) - int nargc; - char * const *nargv; - const char *ostr; -{ - extern char *__progname; - static char *place = EMSG; /* option letter processing */ - char *oli; /* option letter list index */ - -#ifndef BSD4_4 - if (!__progname) { - if (__progname = strrchr(nargv[0], '/')) - ++__progname; - else - __progname = nargv[0]; - } -#endif - - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc || *(place = nargv[optind]) != '-') { - place = EMSG; - return (-1); - } - if (place[1] && *++place == '-' /* found "--" */ - && !place[1]) { /* and not "--foo" */ - ++optind; - place = EMSG; - return (-1); - } - } /* option letter okay? */ - if ((optopt = (int)*place++) == (int)':' || - !(oli = strchr(ostr, optopt))) { - /* - * if the user didn't specify '-' as an option, - * assume it means -1. - */ - if (optopt == (int)'-') - return (-1); - if (!*place) - ++optind; - if (opterr && *ostr != ':') - (void)fprintf(stderr, - "%s: illegal option -- %c\n", __progname, optopt); - return (BADCH); - } - if (*++oli != ':') { /* don't need argument */ - optarg = NULL; - if (!*place) - ++optind; - } - else { /* need an argument */ - if (*place) /* no white space */ - optarg = place; - else if (nargc <= ++optind) { /* no arg */ - place = EMSG; - if (*ostr == ':') - return (BADARG); - if (opterr) - (void)fprintf(stderr, - "%s: option requires an argument -- %c\n", - __progname, optopt); - return (BADCH); - } - else /* white space */ - optarg = nargv[optind]; - place = EMSG; - ++optind; - } - return (optopt); /* dump back option letter */ -} -#endif -#ifdef MAIN -#ifndef BSD4_4 -char *__progname; -#endif - -int -main(argc, argv) - int argc; - char *argv[]; -{ - int c; - char *opts = argv[1]; - - --argc; - ++argv; - - while ((c = getopt(argc, argv, opts)) != EOF) { - switch (c) { - case '-': - if (optarg) - printf("--%s ", optarg); - break; - case '?': - exit(1); - break; - default: - if (optarg) - printf("-%c %s ", c, optarg); - else - printf("-%c ", c); - break; - } - } - - if (optind < argc) { - printf("-- "); - for (; optind < argc; ++optind) { - printf("%s ", argv[optind]); - } - } - printf("\n"); - exit(0); -} -#endif diff --git a/20120831/hash.c b/20120831/hash.c deleted file mode 100644 index a22e2f2..0000000 --- a/20120831/hash.c +++ /dev/null @@ -1,463 +0,0 @@ -/* $NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/* hash.c -- - * - * This module contains routines to manipulate a hash table. - * See hash.h for a definition of the structure of the hash - * table. Hash tables grow automatically as the amount of - * information increases. - */ -#include "sprite.h" -#include "make.h" -#include "hash.h" - -/* - * Forward references to local procedures that are used before they're - * defined: - */ - -static void RebuildTable(Hash_Table *); - -/* - * The following defines the ratio of # entries to # buckets - * at which we rebuild the table to make it larger. - */ - -#define rebuildLimit 3 - -/* - *--------------------------------------------------------- - * - * Hash_InitTable -- - * - * This routine just sets up the hash table. - * - * Input: - * t Structure to to hold table. - * numBuckets How many buckets to create for starters. This - * number is rounded up to a power of two. If - * <= 0, a reasonable default is chosen. The - * table will grow in size later as needed. - * - * Results: - * None. - * - * Side Effects: - * Memory is allocated for the initial bucket area. - * - *--------------------------------------------------------- - */ - -void -Hash_InitTable(Hash_Table *t, int numBuckets) -{ - int i; - struct Hash_Entry **hp; - - /* - * Round up the size to a power of two. - */ - if (numBuckets <= 0) - i = 16; - else { - for (i = 2; i < numBuckets; i <<= 1) - continue; - } - t->numEntries = 0; - t->size = i; - t->mask = i - 1; - t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i); - while (--i >= 0) - *hp++ = NULL; -} - -/* - *--------------------------------------------------------- - * - * Hash_DeleteTable -- - * - * This routine removes everything from a hash table - * and frees up the memory space it occupied (except for - * the space in the Hash_Table structure). - * - * Results: - * None. - * - * Side Effects: - * Lots of memory is freed up. - * - *--------------------------------------------------------- - */ - -void -Hash_DeleteTable(Hash_Table *t) -{ - struct Hash_Entry **hp, *h, *nexth = NULL; - int i; - - for (hp = t->bucketPtr, i = t->size; --i >= 0;) { - for (h = *hp++; h != NULL; h = nexth) { - nexth = h->next; - free(h); - } - } - free(t->bucketPtr); - - /* - * Set up the hash table to cause memory faults on any future access - * attempts until re-initialization. - */ - t->bucketPtr = NULL; -} - -/* - *--------------------------------------------------------- - * - * Hash_FindEntry -- - * - * Searches a hash table for an entry corresponding to key. - * - * Input: - * t Hash table to search. - * key A hash key. - * - * Results: - * The return value is a pointer to the entry for key, - * if key was present in the table. If key was not - * present, NULL is returned. - * - * Side Effects: - * None. - * - *--------------------------------------------------------- - */ - -Hash_Entry * -Hash_FindEntry(Hash_Table *t, const char *key) -{ - Hash_Entry *e; - unsigned h; - const char *p; - - for (h = 0, p = key; *p;) - h = (h << 5) - h + *p++; - p = key; - for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) - if (e->namehash == h && strcmp(e->name, p) == 0) - return (e); - return NULL; -} - -/* - *--------------------------------------------------------- - * - * Hash_CreateEntry -- - * - * Searches a hash table for an entry corresponding to - * key. If no entry is found, then one is created. - * - * Input: - * t Hash table to search. - * key A hash key. - * newPtr Filled in with TRUE if new entry created, - * FALSE otherwise. - * - * Results: - * The return value is a pointer to the entry. If *newPtr - * isn't NULL, then *newPtr is filled in with TRUE if a - * new entry was created, and FALSE if an entry already existed - * with the given key. - * - * Side Effects: - * Memory may be allocated, and the hash buckets may be modified. - *--------------------------------------------------------- - */ - -Hash_Entry * -Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr) -{ - Hash_Entry *e; - unsigned h; - const char *p; - int keylen; - struct Hash_Entry **hp; - - /* - * Hash the key. As a side effect, save the length (strlen) of the - * key in case we need to create the entry. - */ - for (h = 0, p = key; *p;) - h = (h << 5) - h + *p++; - keylen = p - key; - p = key; - for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) { - if (e->namehash == h && strcmp(e->name, p) == 0) { - if (newPtr != NULL) - *newPtr = FALSE; - return (e); - } - } - - /* - * The desired entry isn't there. Before allocating a new entry, - * expand the table if necessary (and this changes the resulting - * bucket chain). - */ - if (t->numEntries >= rebuildLimit * t->size) - RebuildTable(t); - e = bmake_malloc(sizeof(*e) + keylen); - hp = &t->bucketPtr[h & t->mask]; - e->next = *hp; - *hp = e; - Hash_SetValue(e, NULL); - e->namehash = h; - (void)strcpy(e->name, p); - t->numEntries++; - - if (newPtr != NULL) - *newPtr = TRUE; - return (e); -} - -/* - *--------------------------------------------------------- - * - * Hash_DeleteEntry -- - * - * Delete the given hash table entry and free memory associated with - * it. - * - * Results: - * None. - * - * Side Effects: - * Hash chain that entry lives in is modified and memory is freed. - * - *--------------------------------------------------------- - */ - -void -Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e) -{ - Hash_Entry **hp, *p; - - if (e == NULL) - return; - for (hp = &t->bucketPtr[e->namehash & t->mask]; - (p = *hp) != NULL; hp = &p->next) { - if (p == e) { - *hp = p->next; - free(p); - t->numEntries--; - return; - } - } - (void)write(2, "bad call to Hash_DeleteEntry\n", 29); - abort(); -} - -/* - *--------------------------------------------------------- - * - * Hash_EnumFirst -- - * This procedure sets things up for a complete search - * of all entries recorded in the hash table. - * - * Input: - * t Table to be searched. - * searchPtr Area in which to keep state about search. - * - * Results: - * The return value is the address of the first entry in - * the hash table, or NULL if the table is empty. - * - * Side Effects: - * The information in searchPtr is initialized so that successive - * calls to Hash_Next will return successive HashEntry's - * from the table. - * - *--------------------------------------------------------- - */ - -Hash_Entry * -Hash_EnumFirst(Hash_Table *t, Hash_Search *searchPtr) -{ - searchPtr->tablePtr = t; - searchPtr->nextIndex = 0; - searchPtr->hashEntryPtr = NULL; - return Hash_EnumNext(searchPtr); -} - -/* - *--------------------------------------------------------- - * - * Hash_EnumNext -- - * This procedure returns successive entries in the hash table. - * - * Input: - * searchPtr Area used to keep state about search. - * - * Results: - * The return value is a pointer to the next HashEntry - * in the table, or NULL when the end of the table is - * reached. - * - * Side Effects: - * The information in searchPtr is modified to advance to the - * next entry. - * - *--------------------------------------------------------- - */ - -Hash_Entry * -Hash_EnumNext(Hash_Search *searchPtr) -{ - Hash_Entry *e; - Hash_Table *t = searchPtr->tablePtr; - - /* - * The hashEntryPtr field points to the most recently returned - * entry, or is nil if we are starting up. If not nil, we have - * to start at the next one in the chain. - */ - e = searchPtr->hashEntryPtr; - if (e != NULL) - e = e->next; - /* - * If the chain ran out, or if we are starting up, we need to - * find the next nonempty chain. - */ - while (e == NULL) { - if (searchPtr->nextIndex >= t->size) - return NULL; - e = t->bucketPtr[searchPtr->nextIndex++]; - } - searchPtr->hashEntryPtr = e; - return (e); -} - -/* - *--------------------------------------------------------- - * - * RebuildTable -- - * This local routine makes a new hash table that - * is larger than the old one. - * - * Results: - * None. - * - * Side Effects: - * The entire hash table is moved, so any bucket numbers - * from the old table are invalid. - * - *--------------------------------------------------------- - */ - -static void -RebuildTable(Hash_Table *t) -{ - Hash_Entry *e, *next = NULL, **hp, **xp; - int i, mask; - Hash_Entry **oldhp; - int oldsize; - - oldhp = t->bucketPtr; - oldsize = i = t->size; - i <<= 1; - t->size = i; - t->mask = mask = i - 1; - t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i); - while (--i >= 0) - *hp++ = NULL; - for (hp = oldhp, i = oldsize; --i >= 0;) { - for (e = *hp++; e != NULL; e = next) { - next = e->next; - xp = &t->bucketPtr[e->namehash & mask]; - e->next = *xp; - *xp = e; - } - } - free(oldhp); -} diff --git a/20120831/hash.h b/20120831/hash.h deleted file mode 100644 index 31d2ff1..0000000 --- a/20120831/hash.h +++ /dev/null @@ -1,154 +0,0 @@ -/* $NetBSD: hash.h,v 1.10 2009/01/24 10:59:09 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)hash.h 8.1 (Berkeley) 6/6/93 - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)hash.h 8.1 (Berkeley) 6/6/93 - */ - -/* hash.h -- - * - * This file contains definitions used by the hash module, - * which maintains hash tables. - */ - -#ifndef _HASH -#define _HASH - -/* - * The following defines one entry in the hash table. - */ - -typedef struct Hash_Entry { - struct Hash_Entry *next; /* Used to link together all the - * entries associated with the same - * bucket. */ - union { - void *clientPtr; /* Arbitrary pointer */ - time_t clientTime; /* Arbitrary Time */ - } clientInfo; - unsigned namehash; /* hash value of key */ - char name[1]; /* key string */ -} Hash_Entry; - -typedef struct Hash_Table { - struct Hash_Entry **bucketPtr;/* Pointers to Hash_Entry, one - * for each bucket in the table. */ - int size; /* Actual size of array. */ - int numEntries; /* Number of entries in the table. */ - int mask; /* Used to select bits for hashing. */ -} Hash_Table; - -/* - * The following structure is used by the searching routines - * to record where we are in the search. - */ - -typedef struct Hash_Search { - Hash_Table *tablePtr; /* Table being searched. */ - int nextIndex; /* Next bucket to check (after current). */ - Hash_Entry *hashEntryPtr; /* Next entry to check in current bucket. */ -} Hash_Search; - -/* - * Macros. - */ - -/* - * void * Hash_GetValue(h) - * Hash_Entry *h; - */ - -#define Hash_GetValue(h) ((h)->clientInfo.clientPtr) -#define Hash_GetTimeValue(h) ((h)->clientInfo.clientTime) - -/* - * Hash_SetValue(h, val); - * Hash_Entry *h; - * char *val; - */ - -#define Hash_SetValue(h, val) ((h)->clientInfo.clientPtr = (val)) -#define Hash_SetTimeValue(h, val) ((h)->clientInfo.clientTime = (val)) - -/* - * Hash_Size(n) returns the number of words in an object of n bytes - */ - -#define Hash_Size(n) (((n) + sizeof (int) - 1) / sizeof (int)) - -void Hash_InitTable(Hash_Table *, int); -void Hash_DeleteTable(Hash_Table *); -Hash_Entry *Hash_FindEntry(Hash_Table *, const char *); -Hash_Entry *Hash_CreateEntry(Hash_Table *, const char *, Boolean *); -void Hash_DeleteEntry(Hash_Table *, Hash_Entry *); -Hash_Entry *Hash_EnumFirst(Hash_Table *, Hash_Search *); -Hash_Entry *Hash_EnumNext(Hash_Search *); - -#endif /* _HASH */ diff --git a/20120831/install-sh b/20120831/install-sh deleted file mode 100755 index a247329..0000000 --- a/20120831/install-sh +++ /dev/null @@ -1,201 +0,0 @@ -: -# NAME: -# install.sh - portable version of install(1) -# -# SYNOPSIS: -# install [-CNcs] [-f flags] [-i errs] [-o owner] [-g group] [-m mode] file1 file2 ... -# install -d [-i errs] [-o owner] [-g group] [-m mode] directory ... -# -# DESCRIPTION: -# Compatible with BSD install(1). Except that '-c' is always -# true and we always move an already installed target aside as -# this is important on many systems. Recent BSD install(1) -# versions have a '-b' option for this. -# -# -# OPTIONS: -# -b move previous target file aside (always true). -# -# -B "suffix" -# use "suffix" instead of .old for saving existing target. -# -# -c copy rather than move the file into place (always true). -# -# -C compare. Only install if target is missing or -# different. -# -# -N newer. Only install if target is missing or older. -# -# -s strip target -# -# -o "owner" -# make target owned by "owner" -# -# -g "group" -# make target group owned by "group" -# -# -m "mode" -# set permissions to "mode" -# -# -f "flags" -# Pass "flags" onto chflags(1) -# -# -i "errs" -# Ignore errors from steps indicated by "errs" (``s,o,g,m''). -# -# BUGS: -# The '-i' option is to save your sanity when 'bsd.prog.mk' -# insists on haveing a '-o' "owner" option which is doomed to -# fail on many systems. We ignore '-b', '-B' and '-c' options. -# -# AUTHOR: -# Simon J. Gerraty <sjg@quick.com.au> -# - -# RCSid: -# $Id: install-sh,v 1.18 2001/03/16 17:33:02 sjg Exp $ -# -# @(#) Copyright (c) 1993 Simon J. Gerraty -# -# This file is provided in the hope that it will -# be of use. There is absolutely NO WARRANTY. -# Permission to copy, redistribute or otherwise -# use this file is hereby granted provided that -# the above copyright notice and this notice are -# left intact. -# -# Please send copies of changes and bug-fixes to: -# sjg@quick.com.au -# - -set -- `getopt B:bpxCNcsdo:g:m:i:f: $*` - -Mydir=`dirname $0` -[ -s $Mydir/.installrc ] && . $Mydir/.installrc - -owner=: -group=: -mode=: -strip=: -mkdirs= -compare=: -newer=: -chflags=: -LS1= -CP_P= - -while [ $# -gt 1 ] -do - case $1 in - --) shift; break;; - -p) CP_P=-p;; - -x) set -x;; - -B) OLD_EXT=$2; shift;; - -C) compare=Different;; - -N) newer=Newer; - # check if /bin/ls supports -1 - /bin/ls -1 $0 >/dev/null 2>&1 && LS1=1 - ;; - -o) owner="${CHOWN:-chown} $2 "; shift;; - -g) group="${CHGRP:-chgrp} $2 "; shift;; - -m) mode="${CHMOD:-chmod} $2 "; shift;; - -s) strip=${STRIP:-strip};; - -d) mkdirs="mkdir -p";; - -i) ignore_err="$ignore_err$2"; shift;; - -f) chflags="${CHFLAGS:-chflags} $2 "; shift;; - esac - shift -done - -Newer() { - n=`/bin/ls -t$LS1 $* 2>/dev/null | head -1` - [ $1 = $n ] -} - -Different() { - cmp -s $* - [ $? != 0 ] -} - -Err() { - case "$ignore_err" in - *$1*) ;; - *) exit 1;; - esac -} - -Setem() { - # the order is important - if [ ! -d $1 ]; then - $strip $1 || Err s - fi - $group $1 || Err g - $owner $1 || Err o - $mode $1 || Err m - $chflags $1 || Err f - return 0 -} - -# a bug in HP-UX's /bin/sh, means we need to re-set $* -# after any calls to add_path() -args="$*" - -# all this just for chown! -add_path () { [ -d $1 ] && eval ${2:-PATH}="\$${2:-PATH}:$1"; } -add_path /etc -add_path /usr/etc -add_path /sbin -add_path /usr/sbin - -# restore saved $* -set -- $args - -# make directories if needed -# and ensure mode etc are as desired -if [ "$mkdirs" ]; then - for d in $* - do - [ ! -d $d ] && $mkdirs $d - Setem $d - done - exit 0 # that's all we do -fi - -# install files -if [ $# -gt 2 ]; then - dest_dir=yes -elif [ $# -eq 1 ]; then - echo "what should I do with $*?" >&2 - exit 1 -fi - -# get list of files -while [ $# -gt 1 ] -do - files="$files $1" - shift -done -# last one is dest -dest=$1 -shift - - -if [ "$dest_dir" = yes -a ! -d $dest ]; then - echo "no directory $dest" >&2 - exit 1 -fi - -for f in $files -do - b=`basename $f` - if [ -d $dest ]; then - t=$dest/$b - else - t=$dest - fi - $newer $f $t || continue - $compare $f $t || continue - [ -f $t ] && { mv -f $t $t.old || exit 1; } - { cp $CP_P $f $t && Setem $t; } || exit 1 -done -exit 0 diff --git a/20120831/job.c b/20120831/job.c deleted file mode 100644 index 99e05d5..0000000 --- a/20120831/job.c +++ /dev/null @@ -1,2994 +0,0 @@ -/* $NetBSD: job.c,v 1.163 2012/07/03 21:03:40 sjg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: job.c,v 1.163 2012/07/03 21:03:40 sjg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94"; -#else -__RCSID("$NetBSD: job.c,v 1.163 2012/07/03 21:03:40 sjg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * job.c -- - * handle the creation etc. of our child processes. - * - * Interface: - * Job_Make Start the creation of the given target. - * - * Job_CatchChildren Check for and handle the termination of any - * children. This must be called reasonably - * frequently to keep the whole make going at - * a decent clip, since job table entries aren't - * removed until their process is caught this way. - * - * Job_CatchOutput Print any output our children have produced. - * Should also be called fairly frequently to - * keep the user informed of what's going on. - * If no output is waiting, it will block for - * a time given by the SEL_* constants, below, - * or until output is ready. - * - * Job_Init Called to intialize this module. in addition, - * any commands attached to the .BEGIN target - * are executed before this function returns. - * Hence, the makefile must have been parsed - * before this function is called. - * - * Job_End Cleanup any memory used. - * - * Job_ParseShell Given the line following a .SHELL target, parse - * the line as a shell specification. Returns - * FAILURE if the spec was incorrect. - * - * Job_Finish Perform any final processing which needs doing. - * This includes the execution of any commands - * which have been/were attached to the .END - * target. It should only be called when the - * job table is empty. - * - * Job_AbortAll Abort all currently running jobs. It doesn't - * handle output or do anything for the jobs, - * just kills them. It should only be called in - * an emergency, as it were. - * - * Job_CheckCommands Verify that the commands for a target are - * ok. Provide them if necessary and possible. - * - * Job_Touch Update a target without really updating it. - * - * Job_Wait Wait for all currently-running jobs to finish. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/file.h> -#include <sys/time.h> -#include "wait.h" - -#include <errno.h> -#include <fcntl.h> -#if !defined(USE_SELECT) && defined(HAVE_POLL_H) -#include <poll.h> -#else -#ifndef USE_SELECT /* no poll.h */ -# define USE_SELECT -#endif -#if defined(HAVE_SYS_SELECT_H) -# include <sys/select.h> -#endif -#endif -#include <signal.h> -#include <stdio.h> -#include <string.h> -#include <utime.h> -#if defined(HAVE_SYS_SOCKET_H) -# include <sys/socket.h> -#endif - -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "job.h" -#include "pathnames.h" -#include "trace.h" -# define STATIC static - -/* - * error handling variables - */ -static int errors = 0; /* number of errors reported */ -static int aborting = 0; /* why is the make aborting? */ -#define ABORT_ERROR 1 /* Because of an error */ -#define ABORT_INTERRUPT 2 /* Because it was interrupted */ -#define ABORT_WAIT 3 /* Waiting for jobs to finish */ -#define JOB_TOKENS "+EI+" /* Token to requeue for each abort state */ - -/* - * this tracks the number of tokens currently "out" to build jobs. - */ -int jobTokensRunning = 0; -int not_parallel = 0; /* set if .NOT_PARALLEL */ - -/* - * XXX: Avoid SunOS bug... FILENO() is fp->_file, and file - * is a char! So when we go above 127 we turn negative! - */ -#define FILENO(a) ((unsigned) fileno(a)) - -/* - * post-make command processing. The node postCommands is really just the - * .END target but we keep it around to avoid having to search for it - * all the time. - */ -static GNode *postCommands = NULL; - /* node containing commands to execute when - * everything else is done */ -static int numCommands; /* The number of commands actually printed - * for a target. Should this number be - * 0, no shell will be executed. */ - -/* - * Return values from JobStart. - */ -#define JOB_RUNNING 0 /* Job is running */ -#define JOB_ERROR 1 /* Error in starting the job */ -#define JOB_FINISHED 2 /* The job is already finished */ - -/* - * Descriptions for various shells. - * - * The build environment may set DEFSHELL_INDEX to one of - * DEFSHELL_INDEX_SH, DEFSHELL_INDEX_KSH, or DEFSHELL_INDEX_CSH, to - * select one of the prefedined shells as the default shell. - * - * Alternatively, the build environment may set DEFSHELL_CUSTOM to the - * name or the full path of a sh-compatible shell, which will be used as - * the default shell. - * - * ".SHELL" lines in Makefiles can choose the default shell from the - # set defined here, or add additional shells. - */ - -#ifdef DEFSHELL_CUSTOM -#define DEFSHELL_INDEX_CUSTOM 0 -#define DEFSHELL_INDEX_SH 1 -#define DEFSHELL_INDEX_KSH 2 -#define DEFSHELL_INDEX_CSH 3 -#else /* !DEFSHELL_CUSTOM */ -#define DEFSHELL_INDEX_SH 0 -#define DEFSHELL_INDEX_KSH 1 -#define DEFSHELL_INDEX_CSH 2 -#endif /* !DEFSHELL_CUSTOM */ - -#ifndef DEFSHELL_INDEX -#define DEFSHELL_INDEX 0 /* DEFSHELL_INDEX_CUSTOM or DEFSHELL_INDEX_SH */ -#endif /* !DEFSHELL_INDEX */ - -static Shell shells[] = { -#ifdef DEFSHELL_CUSTOM - /* - * An sh-compatible shell with a non-standard name. - * - * Keep this in sync with the "sh" description below, but avoid - * non-portable features that might not be supplied by all - * sh-compatible shells. - */ -{ - DEFSHELL_CUSTOM, - FALSE, "", "", "", 0, - FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", "'\n'", '#', - "", - "", -}, -#endif /* DEFSHELL_CUSTOM */ - /* - * SH description. Echo control is also possible and, under - * sun UNIX anyway, one can even control error checking. - */ -{ - "sh", - FALSE, "", "", "", 0, - FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", "'\n'", '#', -#if defined(MAKE_NATIVE) && defined(__NetBSD__) - "q", -#else - "", -#endif - "", -}, - /* - * KSH description. - */ -{ - "ksh", - TRUE, "set +v", "set -v", "set +v", 6, - FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", "'\n'", '#', - "v", - "", -}, - /* - * CSH description. The csh can do echo control by playing - * with the setting of the 'echo' shell variable. Sadly, - * however, it is unable to do error control nicely. - */ -{ - "csh", - TRUE, "unset verbose", "set verbose", "unset verbose", 10, - FALSE, "echo \"%s\"\n", "csh -c \"%s || exit 0\"\n", "", "'\\\n'", '#', - "v", "e", -}, - /* - * UNKNOWN. - */ -{ - NULL, - FALSE, NULL, NULL, NULL, 0, - FALSE, NULL, NULL, NULL, NULL, 0, - NULL, NULL, -} -}; -static Shell *commandShell = &shells[DEFSHELL_INDEX]; /* this is the shell to - * which we pass all - * commands in the Makefile. - * It is set by the - * Job_ParseShell function */ -const char *shellPath = NULL, /* full pathname of - * executable image */ - *shellName = NULL; /* last component of shell */ -static const char *shellArgv = NULL; /* Custom shell args */ - - -STATIC Job *job_table; /* The structures that describe them */ -STATIC Job *job_table_end; /* job_table + maxJobs */ -static int wantToken; /* we want a token */ -static int lurking_children = 0; -static int make_suspended = 0; /* non-zero if we've seen a SIGTSTP (etc) */ - -/* - * Set of descriptors of pipes connected to - * the output channels of children - */ -static struct pollfd *fds = NULL; -static Job **jobfds = NULL; -static int nfds = 0; -static void watchfd(Job *); -static void clearfd(Job *); -static int readyfd(Job *); - -STATIC GNode *lastNode; /* The node for which output was most recently - * produced. */ -static char *targPrefix = NULL; /* What we print at the start of TARG_FMT */ -static Job tokenWaitJob; /* token wait pseudo-job */ - -static Job childExitJob; /* child exit pseudo-job */ -#define CHILD_EXIT "." -#define DO_JOB_RESUME "R" - -#define TARG_FMT "%s %s ---\n" /* Default format */ -#define MESSAGE(fp, gn) \ - if (maxJobs != 1) \ - (void)fprintf(fp, TARG_FMT, targPrefix, gn->name) - -static sigset_t caught_signals; /* Set of signals we handle */ -#if defined(SYSV) -#define KILLPG(pid, sig) kill(-(pid), (sig)) -#else -#define KILLPG(pid, sig) killpg((pid), (sig)) -#endif - -static void JobChildSig(int); -static void JobContinueSig(int); -static Job *JobFindPid(int, int, Boolean); -static int JobPrintCommand(void *, void *); -static int JobSaveCommand(void *, void *); -static void JobClose(Job *); -static void JobExec(Job *, char **); -static void JobMakeArgv(Job *, char **); -static int JobStart(GNode *, int); -static char *JobOutput(Job *, char *, char *, int); -static void JobDoOutput(Job *, Boolean); -static Shell *JobMatchShell(const char *); -static void JobInterrupt(int, int) MAKE_ATTR_DEAD; -static void JobRestartJobs(void); -static void JobTokenAdd(void); -static void JobSigLock(sigset_t *); -static void JobSigUnlock(sigset_t *); -static void JobSigReset(void); - -const char *malloc_options="A"; - -static void -job_table_dump(const char *where) -{ - Job *job; - - fprintf(debug_file, "job table @ %s\n", where); - for (job = job_table; job < job_table_end; job++) { - fprintf(debug_file, "job %d, status %d, flags %d, pid %d\n", - (int)(job - job_table), job->job_state, job->flags, job->pid); - } -} - -/* - * JobSigLock/JobSigUnlock - * - * Signal lock routines to get exclusive access. Currently used to - * protect `jobs' and `stoppedJobs' list manipulations. - */ -static void JobSigLock(sigset_t *omaskp) -{ - if (sigprocmask(SIG_BLOCK, &caught_signals, omaskp) != 0) { - Punt("JobSigLock: sigprocmask: %s", strerror(errno)); - sigemptyset(omaskp); - } -} - -static void JobSigUnlock(sigset_t *omaskp) -{ - (void)sigprocmask(SIG_SETMASK, omaskp, NULL); -} - -static void -JobCreatePipe(Job *job, int minfd) -{ - int i, fd; - - if (pipe(job->jobPipe) == -1) - Punt("Cannot create pipe: %s", strerror(errno)); - - /* Set close-on-exec flag for both */ - (void)fcntl(job->jobPipe[0], F_SETFD, 1); - (void)fcntl(job->jobPipe[1], F_SETFD, 1); - - /* - * We mark the input side of the pipe non-blocking; we poll(2) the - * pipe when we're waiting for a job token, but we might lose the - * race for the token when a new one becomes available, so the read - * from the pipe should not block. - */ - fcntl(job->jobPipe[0], F_SETFL, - fcntl(job->jobPipe[0], F_GETFL, 0) | O_NONBLOCK); - - for (i = 0; i < 2; i++) { - /* Avoid using low numbered fds */ - fd = fcntl(job->jobPipe[i], F_DUPFD, minfd); - if (fd != -1) { - close(job->jobPipe[i]); - job->jobPipe[i] = fd; - } - } -} - -/*- - *----------------------------------------------------------------------- - * JobCondPassSig -- - * Pass a signal to a job - * - * Input: - * signop Signal to send it - * - * Side Effects: - * None, except the job may bite it. - * - *----------------------------------------------------------------------- - */ -static void -JobCondPassSig(int signo) -{ - Job *job; - - if (DEBUG(JOB)) { - (void)fprintf(debug_file, "JobCondPassSig(%d) called.\n", signo); - } - - for (job = job_table; job < job_table_end; job++) { - if (job->job_state != JOB_ST_RUNNING) - continue; - if (DEBUG(JOB)) { - (void)fprintf(debug_file, - "JobCondPassSig passing signal %d to child %d.\n", - signo, job->pid); - } - KILLPG(job->pid, signo); - } -} - -/*- - *----------------------------------------------------------------------- - * JobChldSig -- - * SIGCHLD handler. - * - * Input: - * signo The signal number we've received - * - * Results: - * None. - * - * Side Effects: - * Sends a token on the child exit pipe to wake us up from - * select()/poll(). - * - *----------------------------------------------------------------------- - */ -static void -JobChildSig(int signo MAKE_ATTR_UNUSED) -{ - write(childExitJob.outPipe, CHILD_EXIT, 1); -} - - -/*- - *----------------------------------------------------------------------- - * JobContinueSig -- - * Resume all stopped jobs. - * - * Input: - * signo The signal number we've received - * - * Results: - * None. - * - * Side Effects: - * Jobs start running again. - * - *----------------------------------------------------------------------- - */ -static void -JobContinueSig(int signo MAKE_ATTR_UNUSED) -{ - /* - * Defer sending to SIGCONT to our stopped children until we return - * from the signal handler. - */ - write(childExitJob.outPipe, DO_JOB_RESUME, 1); -} - -/*- - *----------------------------------------------------------------------- - * JobPassSig -- - * Pass a signal on to all jobs, then resend to ourselves. - * - * Input: - * signo The signal number we've received - * - * Results: - * None. - * - * Side Effects: - * We die by the same signal. - * - *----------------------------------------------------------------------- - */ -MAKE_ATTR_DEAD static void -JobPassSig_int(int signo) -{ - /* Run .INTERRUPT target then exit */ - JobInterrupt(TRUE, signo); -} - -MAKE_ATTR_DEAD static void -JobPassSig_term(int signo) -{ - /* Dont run .INTERRUPT target then exit */ - JobInterrupt(FALSE, signo); -} - -static void -JobPassSig_suspend(int signo) -{ - sigset_t nmask, omask; - struct sigaction act; - - /* Suppress job started/continued messages */ - make_suspended = 1; - - /* Pass the signal onto every job */ - JobCondPassSig(signo); - - /* - * Send ourselves the signal now we've given the message to everyone else. - * Note we block everything else possible while we're getting the signal. - * This ensures that all our jobs get continued when we wake up before - * we take any other signal. - */ - sigfillset(&nmask); - sigdelset(&nmask, signo); - (void)sigprocmask(SIG_SETMASK, &nmask, &omask); - - act.sa_handler = SIG_DFL; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - (void)sigaction(signo, &act, NULL); - - if (DEBUG(JOB)) { - (void)fprintf(debug_file, - "JobPassSig passing signal %d to self.\n", signo); - } - - (void)kill(getpid(), signo); - - /* - * We've been continued. - * - * A whole host of signals continue to happen! - * SIGCHLD for any processes that actually suspended themselves. - * SIGCHLD for any processes that exited while we were alseep. - * The SIGCONT that actually caused us to wakeup. - * - * Since we defer passing the SIGCONT on to our children until - * the main processing loop, we can be sure that all the SIGCHLD - * events will have happened by then - and that the waitpid() will - * collect the child 'suspended' events. - * For correct sequencing we just need to ensure we process the - * waitpid() before passign on the SIGCONT. - * - * In any case nothing else is needed here. - */ - - /* Restore handler and signal mask */ - act.sa_handler = JobPassSig_suspend; - (void)sigaction(signo, &act, NULL); - (void)sigprocmask(SIG_SETMASK, &omask, NULL); -} - -/*- - *----------------------------------------------------------------------- - * JobFindPid -- - * Compare the pid of the job with the given pid and return 0 if they - * are equal. This function is called from Job_CatchChildren - * to find the job descriptor of the finished job. - * - * Input: - * job job to examine - * pid process id desired - * - * Results: - * Job with matching pid - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static Job * -JobFindPid(int pid, int status, Boolean isJobs) -{ - Job *job; - - for (job = job_table; job < job_table_end; job++) { - if ((job->job_state == status) && job->pid == pid) - return job; - } - if (DEBUG(JOB) && isJobs) - job_table_dump("no pid"); - return NULL; -} - -/*- - *----------------------------------------------------------------------- - * JobPrintCommand -- - * Put out another command for the given job. If the command starts - * with an @ or a - we process it specially. In the former case, - * so long as the -s and -n flags weren't given to make, we stick - * a shell-specific echoOff command in the script. In the latter, - * we ignore errors for the entire job, unless the shell has error - * control. - * If the command is just "..." we take all future commands for this - * job to be commands to be executed once the entire graph has been - * made and return non-zero to signal that the end of the commands - * was reached. These commands are later attached to the postCommands - * node and executed by Job_End when all things are done. - * This function is called from JobStart via Lst_ForEach. - * - * Input: - * cmdp command string to print - * jobp job for which to print it - * - * Results: - * Always 0, unless the command was "..." - * - * Side Effects: - * If the command begins with a '-' and the shell has no error control, - * the JOB_IGNERR flag is set in the job descriptor. - * If the command is "..." and we're not ignoring such things, - * tailCmds is set to the successor node of the cmd. - * numCommands is incremented if the command is actually printed. - *----------------------------------------------------------------------- - */ -static int -JobPrintCommand(void *cmdp, void *jobp) -{ - Boolean noSpecials; /* true if we shouldn't worry about - * inserting special commands into - * the input stream. */ - Boolean shutUp = FALSE; /* true if we put a no echo command - * into the command file */ - Boolean errOff = FALSE; /* true if we turned error checking - * off before printing the command - * and need to turn it back on */ - const char *cmdTemplate; /* Template to use when printing the - * command */ - char *cmdStart; /* Start of expanded command */ - char *escCmd = NULL; /* Command with quotes/backticks escaped */ - char *cmd = (char *)cmdp; - Job *job = (Job *)jobp; - char *cp, *tmp; - int i, j; - - noSpecials = NoExecute(job->node); - - if (strcmp(cmd, "...") == 0) { - job->node->type |= OP_SAVE_CMDS; - if ((job->flags & JOB_IGNDOTS) == 0) { - job->tailCmds = Lst_Succ(Lst_Member(job->node->commands, - cmd)); - return 1; - } - return 0; - } - -#define DBPRINTF(fmt, arg) if (DEBUG(JOB)) { \ - (void)fprintf(debug_file, fmt, arg); \ - } \ - (void)fprintf(job->cmdFILE, fmt, arg); \ - (void)fflush(job->cmdFILE); - - numCommands += 1; - - cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE); - - cmdTemplate = "%s\n"; - - /* - * Check for leading @' and -'s to control echoing and error checking. - */ - while (*cmd == '@' || *cmd == '-' || (*cmd == '+')) { - switch (*cmd) { - case '@': - shutUp = DEBUG(LOUD) ? FALSE : TRUE; - break; - case '-': - job->flags |= JOB_IGNERR; - errOff = TRUE; - break; - case '+': - if (noSpecials) { - /* - * We're not actually executing anything... - * but this one needs to be - use compat mode just for it. - */ - CompatRunCommand(cmdp, job->node); - return 0; - } - break; - } - cmd++; - } - - while (isspace((unsigned char) *cmd)) - cmd++; - - /* - * If the shell doesn't have error control the alternate echo'ing will - * be done (to avoid showing additional error checking code) - * and this will need the characters '$ ` \ "' escaped - */ - - if (!commandShell->hasErrCtl) { - /* Worst that could happen is every char needs escaping. */ - escCmd = bmake_malloc((strlen(cmd) * 2) + 1); - for (i = 0, j= 0; cmd[i] != '\0'; i++, j++) { - if (cmd[i] == '$' || cmd[i] == '`' || cmd[i] == '\\' || - cmd[i] == '"') - escCmd[j++] = '\\'; - escCmd[j] = cmd[i]; - } - escCmd[j] = 0; - } - - if (shutUp) { - if (!(job->flags & JOB_SILENT) && !noSpecials && - commandShell->hasEchoCtl) { - DBPRINTF("%s\n", commandShell->echoOff); - } else { - if (commandShell->hasErrCtl) - shutUp = FALSE; - } - } - - if (errOff) { - if (!noSpecials) { - if (commandShell->hasErrCtl) { - /* - * we don't want the error-control commands showing - * up either, so we turn off echoing while executing - * them. We could put another field in the shell - * structure to tell JobDoOutput to look for this - * string too, but why make it any more complex than - * it already is? - */ - if (!(job->flags & JOB_SILENT) && !shutUp && - commandShell->hasEchoCtl) { - DBPRINTF("%s\n", commandShell->echoOff); - DBPRINTF("%s\n", commandShell->ignErr); - DBPRINTF("%s\n", commandShell->echoOn); - } else { - DBPRINTF("%s\n", commandShell->ignErr); - } - } else if (commandShell->ignErr && - (*commandShell->ignErr != '\0')) - { - /* - * The shell has no error control, so we need to be - * weird to get it to ignore any errors from the command. - * If echoing is turned on, we turn it off and use the - * errCheck template to echo the command. Leave echoing - * off so the user doesn't see the weirdness we go through - * to ignore errors. Set cmdTemplate to use the weirdness - * instead of the simple "%s\n" template. - */ - if (!(job->flags & JOB_SILENT) && !shutUp) { - if (commandShell->hasEchoCtl) { - DBPRINTF("%s\n", commandShell->echoOff); - } - DBPRINTF(commandShell->errCheck, escCmd); - shutUp = TRUE; - } else { - if (!shutUp) { - DBPRINTF(commandShell->errCheck, escCmd); - } - } - cmdTemplate = commandShell->ignErr; - /* - * The error ignoration (hee hee) is already taken care - * of by the ignErr template, so pretend error checking - * is still on. - */ - errOff = FALSE; - } else { - errOff = FALSE; - } - } else { - errOff = FALSE; - } - } else { - - /* - * If errors are being checked and the shell doesn't have error control - * but does supply an errOut template, then setup commands to run - * through it. - */ - - if (!commandShell->hasErrCtl && commandShell->errOut && - (*commandShell->errOut != '\0')) { - if (!(job->flags & JOB_SILENT) && !shutUp) { - if (commandShell->hasEchoCtl) { - DBPRINTF("%s\n", commandShell->echoOff); - } - DBPRINTF(commandShell->errCheck, escCmd); - shutUp = TRUE; - } - /* If it's a comment line or blank, treat as an ignored error */ - if ((escCmd[0] == commandShell->commentChar) || - (escCmd[0] == 0)) - cmdTemplate = commandShell->ignErr; - else - cmdTemplate = commandShell->errOut; - errOff = FALSE; - } - } - - if (DEBUG(SHELL) && strcmp(shellName, "sh") == 0 && - (job->flags & JOB_TRACED) == 0) { - DBPRINTF("set -%s\n", "x"); - job->flags |= JOB_TRACED; - } - - if ((cp = Check_Cwd_Cmd(cmd)) != NULL) { - DBPRINTF("test -d %s && ", cp); - DBPRINTF("cd %s\n", cp); - } - - DBPRINTF(cmdTemplate, cmd); - free(cmdStart); - if (escCmd) - free(escCmd); - if (errOff) { - /* - * If echoing is already off, there's no point in issuing the - * echoOff command. Otherwise we issue it and pretend it was on - * for the whole command... - */ - if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl){ - DBPRINTF("%s\n", commandShell->echoOff); - shutUp = TRUE; - } - DBPRINTF("%s\n", commandShell->errCheck); - } - if (shutUp && commandShell->hasEchoCtl) { - DBPRINTF("%s\n", commandShell->echoOn); - } - if (cp != NULL) { - DBPRINTF("test -d %s && ", cp); - DBPRINTF("cd %s\n", Var_Value(".OBJDIR", VAR_GLOBAL, &tmp)); - } - return 0; -} - -/*- - *----------------------------------------------------------------------- - * JobSaveCommand -- - * Save a command to be executed when everything else is done. - * Callback function for JobFinish... - * - * Results: - * Always returns 0 - * - * Side Effects: - * The command is tacked onto the end of postCommands's commands list. - * - *----------------------------------------------------------------------- - */ -static int -JobSaveCommand(void *cmd, void *gn) -{ - cmd = Var_Subst(NULL, (char *)cmd, (GNode *)gn, FALSE); - (void)Lst_AtEnd(postCommands->commands, cmd); - return(0); -} - - -/*- - *----------------------------------------------------------------------- - * JobClose -- - * Called to close both input and output pipes when a job is finished. - * - * Results: - * Nada - * - * Side Effects: - * The file descriptors associated with the job are closed. - * - *----------------------------------------------------------------------- - */ -static void -JobClose(Job *job) -{ - clearfd(job); - (void)close(job->outPipe); - job->outPipe = -1; - - JobDoOutput(job, TRUE); - (void)close(job->inPipe); - job->inPipe = -1; -} - -/*- - *----------------------------------------------------------------------- - * JobFinish -- - * Do final processing for the given job including updating - * parents and starting new jobs as available/necessary. Note - * that we pay no attention to the JOB_IGNERR flag here. - * This is because when we're called because of a noexecute flag - * or something, jstat.w_status is 0 and when called from - * Job_CatchChildren, the status is zeroed if it s/b ignored. - * - * Input: - * job job to finish - * status sub-why job went away - * - * Results: - * None - * - * Side Effects: - * Final commands for the job are placed on postCommands. - * - * If we got an error and are aborting (aborting == ABORT_ERROR) and - * the job list is now empty, we are done for the day. - * If we recognized an error (errors !=0), we set the aborting flag - * to ABORT_ERROR so no more jobs will be started. - *----------------------------------------------------------------------- - */ -/*ARGSUSED*/ -static void -JobFinish (Job *job, WAIT_T status) -{ - Boolean done, return_job_token; - - if (DEBUG(JOB)) { - fprintf(debug_file, "Jobfinish: %d [%s], status %d\n", - job->pid, job->node->name, status); - } - - if ((WIFEXITED(status) && - (((WEXITSTATUS(status) != 0) && !(job->flags & JOB_IGNERR)))) || - WIFSIGNALED(status)) - { - /* - * If it exited non-zero and either we're doing things our - * way or we're not ignoring errors, the job is finished. - * Similarly, if the shell died because of a signal - * the job is also finished. In these - * cases, finish out the job's output before printing the exit - * status... - */ - JobClose(job); - if (job->cmdFILE != NULL && job->cmdFILE != stdout) { - (void)fclose(job->cmdFILE); - job->cmdFILE = NULL; - } - done = TRUE; - } else if (WIFEXITED(status)) { - /* - * Deal with ignored errors in -B mode. We need to print a message - * telling of the ignored error as well as setting status.w_status - * to 0 so the next command gets run. To do this, we set done to be - * TRUE if in -B mode and the job exited non-zero. - */ - done = WEXITSTATUS(status) != 0; - /* - * Old comment said: "Note we don't - * want to close down any of the streams until we know we're at the - * end." - * But we do. Otherwise when are we going to print the rest of the - * stuff? - */ - JobClose(job); - } else { - /* - * No need to close things down or anything. - */ - done = FALSE; - } - - if (done) { - if (WIFEXITED(status)) { - if (DEBUG(JOB)) { - (void)fprintf(debug_file, "Process %d [%s] exited.\n", - job->pid, job->node->name); - } - if (WEXITSTATUS(status) != 0) { - if (job->node != lastNode) { - MESSAGE(stdout, job->node); - lastNode = job->node; - } -#ifdef USE_META - if (useMeta) { - meta_job_error(job, job->node, job->flags, WEXITSTATUS(status)); - } -#endif - (void)printf("*** [%s] Error code %d%s\n", - job->node->name, - WEXITSTATUS(status), - (job->flags & JOB_IGNERR) ? " (ignored)" : ""); - if (job->flags & JOB_IGNERR) { - WAIT_STATUS(status) = 0; - } else { - PrintOnError(job->node, NULL); - } - } else if (DEBUG(JOB)) { - if (job->node != lastNode) { - MESSAGE(stdout, job->node); - lastNode = job->node; - } - (void)printf("*** [%s] Completed successfully\n", - job->node->name); - } - } else { - if (job->node != lastNode) { - MESSAGE(stdout, job->node); - lastNode = job->node; - } - (void)printf("*** [%s] Signal %d\n", - job->node->name, WTERMSIG(status)); - } - (void)fflush(stdout); - } - -#ifdef USE_META - if (useMeta) { - meta_job_finish(job); - } -#endif - - return_job_token = FALSE; - - Trace_Log(JOBEND, job); - if (!(job->flags & JOB_SPECIAL)) { - if ((WAIT_STATUS(status) != 0) || - (aborting == ABORT_ERROR) || - (aborting == ABORT_INTERRUPT)) - return_job_token = TRUE; - } - - if ((aborting != ABORT_ERROR) && (aborting != ABORT_INTERRUPT) && - (WAIT_STATUS(status) == 0)) { - /* - * As long as we aren't aborting and the job didn't return a non-zero - * status that we shouldn't ignore, we call Make_Update to update - * the parents. In addition, any saved commands for the node are placed - * on the .END target. - */ - if (job->tailCmds != NULL) { - Lst_ForEachFrom(job->node->commands, job->tailCmds, - JobSaveCommand, - job->node); - } - job->node->made = MADE; - if (!(job->flags & JOB_SPECIAL)) - return_job_token = TRUE; - Make_Update(job->node); - job->job_state = JOB_ST_FREE; - } else if (WAIT_STATUS(status)) { - errors += 1; - job->job_state = JOB_ST_FREE; - } - - /* - * Set aborting if any error. - */ - if (errors && !keepgoing && (aborting != ABORT_INTERRUPT)) { - /* - * If we found any errors in this batch of children and the -k flag - * wasn't given, we set the aborting flag so no more jobs get - * started. - */ - aborting = ABORT_ERROR; - } - - if (return_job_token) - Job_TokenReturn(); - - if (aborting == ABORT_ERROR && jobTokensRunning == 0) { - /* - * If we are aborting and the job table is now empty, we finish. - */ - Finish(errors); - } -} - -/*- - *----------------------------------------------------------------------- - * Job_Touch -- - * Touch the given target. Called by JobStart when the -t flag was - * given - * - * Input: - * gn the node of the file to touch - * silent TRUE if should not print message - * - * Results: - * None - * - * Side Effects: - * The data modification of the file is changed. In addition, if the - * file did not exist, it is created. - *----------------------------------------------------------------------- - */ -void -Job_Touch(GNode *gn, Boolean silent) -{ - int streamID; /* ID of stream opened to do the touch */ - struct utimbuf times; /* Times for utime() call */ - - if (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC|OP_OPTIONAL| - OP_SPECIAL|OP_PHONY)) { - /* - * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" targets - * and, as such, shouldn't really be created. - */ - return; - } - - if (!silent || NoExecute(gn)) { - (void)fprintf(stdout, "touch %s\n", gn->name); - (void)fflush(stdout); - } - - if (NoExecute(gn)) { - return; - } - - if (gn->type & OP_ARCHV) { - Arch_Touch(gn); - } else if (gn->type & OP_LIB) { - Arch_TouchLib(gn); - } else { - char *file = gn->path ? gn->path : gn->name; - - times.actime = times.modtime = now; - if (utime(file, ×) < 0){ - streamID = open(file, O_RDWR | O_CREAT, 0666); - - if (streamID >= 0) { - char c; - - /* - * Read and write a byte to the file to change the - * modification time, then close the file. - */ - if (read(streamID, &c, 1) == 1) { - (void)lseek(streamID, (off_t)0, SEEK_SET); - (void)write(streamID, &c, 1); - } - - (void)close(streamID); - } else { - (void)fprintf(stdout, "*** couldn't touch %s: %s", - file, strerror(errno)); - (void)fflush(stdout); - } - } - } -} - -/*- - *----------------------------------------------------------------------- - * Job_CheckCommands -- - * Make sure the given node has all the commands it needs. - * - * Input: - * gn The target whose commands need verifying - * abortProc Function to abort with message - * - * Results: - * TRUE if the commands list is/was ok. - * - * Side Effects: - * The node will have commands from the .DEFAULT rule added to it - * if it needs them. - *----------------------------------------------------------------------- - */ -Boolean -Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...)) -{ - if (OP_NOP(gn->type) && Lst_IsEmpty(gn->commands) && - ((gn->type & OP_LIB) == 0 || Lst_IsEmpty(gn->children))) { - /* - * No commands. Look for .DEFAULT rule from which we might infer - * commands - */ - if ((DEFAULT != NULL) && !Lst_IsEmpty(DEFAULT->commands) && - (gn->type & OP_SPECIAL) == 0) { - char *p1; - /* - * Make only looks for a .DEFAULT if the node was never the - * target of an operator, so that's what we do too. If - * a .DEFAULT was given, we substitute its commands for gn's - * commands and set the IMPSRC variable to be the target's name - * The DEFAULT node acts like a transformation rule, in that - * gn also inherits any attributes or sources attached to - * .DEFAULT itself. - */ - Make_HandleUse(DEFAULT, gn); - Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn, 0); - if (p1) - free(p1); - } else if (Dir_MTime(gn, 0) == 0 && (gn->type & OP_SPECIAL) == 0) { - /* - * The node wasn't the target of an operator we have no .DEFAULT - * rule to go on and the target doesn't already exist. There's - * nothing more we can do for this branch. If the -k flag wasn't - * given, we stop in our tracks, otherwise we just don't update - * this node's parents so they never get examined. - */ - static const char msg[] = ": don't know how to make"; - - if (gn->flags & FROM_DEPEND) { - fprintf(stdout, "%s: ignoring stale %s for %s\n", - progname, makeDependfile, gn->name); - return TRUE; - } - - if (gn->type & OP_OPTIONAL) { - (void)fprintf(stdout, "%s%s %s (ignored)\n", progname, - msg, gn->name); - (void)fflush(stdout); - } else if (keepgoing) { - (void)fprintf(stdout, "%s%s %s (continuing)\n", progname, - msg, gn->name); - (void)fflush(stdout); - return FALSE; - } else { - (*abortProc)("%s%s %s. Stop", progname, msg, gn->name); - return FALSE; - } - } - } - return TRUE; -} - -/*- - *----------------------------------------------------------------------- - * JobExec -- - * Execute the shell for the given job. Called from JobStart - * - * Input: - * job Job to execute - * - * Results: - * None. - * - * Side Effects: - * A shell is executed, outputs is altered and the Job structure added - * to the job table. - * - *----------------------------------------------------------------------- - */ -static void -JobExec(Job *job, char **argv) -{ - int cpid; /* ID of new child */ - sigset_t mask; - - job->flags &= ~JOB_TRACED; - - if (DEBUG(JOB)) { - int i; - - (void)fprintf(debug_file, "Running %s %sly\n", job->node->name, "local"); - (void)fprintf(debug_file, "\tCommand: "); - for (i = 0; argv[i] != NULL; i++) { - (void)fprintf(debug_file, "%s ", argv[i]); - } - (void)fprintf(debug_file, "\n"); - } - - /* - * Some jobs produce no output and it's disconcerting to have - * no feedback of their running (since they produce no output, the - * banner with their name in it never appears). This is an attempt to - * provide that feedback, even if nothing follows it. - */ - if ((lastNode != job->node) && !(job->flags & JOB_SILENT)) { - MESSAGE(stdout, job->node); - lastNode = job->node; - } - - /* No interruptions until this job is on the `jobs' list */ - JobSigLock(&mask); - - /* Pre-emptively mark job running, pid still zero though */ - job->job_state = JOB_ST_RUNNING; - - cpid = vFork(); - if (cpid == -1) - Punt("Cannot vfork: %s", strerror(errno)); - - if (cpid == 0) { - /* Child */ - sigset_t tmask; - -#ifdef USE_META - if (useMeta) { - meta_job_child(job); - } -#endif - /* - * Reset all signal handlers; this is necessary because we also - * need to unblock signals before we exec(2). - */ - JobSigReset(); - - /* Now unblock signals */ - sigemptyset(&tmask); - JobSigUnlock(&tmask); - - /* - * Must duplicate the input stream down to the child's input and - * reset it to the beginning (again). Since the stream was marked - * close-on-exec, we must clear that bit in the new input. - */ - if (dup2(FILENO(job->cmdFILE), 0) == -1) { - execError("dup2", "job->cmdFILE"); - _exit(1); - } - (void)fcntl(0, F_SETFD, 0); - (void)lseek(0, (off_t)0, SEEK_SET); - - if (job->node->type & OP_MAKE) { - /* - * Pass job token pipe to submakes. - */ - fcntl(tokenWaitJob.inPipe, F_SETFD, 0); - fcntl(tokenWaitJob.outPipe, F_SETFD, 0); - } - - /* - * Set up the child's output to be routed through the pipe - * we've created for it. - */ - if (dup2(job->outPipe, 1) == -1) { - execError("dup2", "job->outPipe"); - _exit(1); - } - /* - * The output channels are marked close on exec. This bit was - * duplicated by the dup2(on some systems), so we have to clear - * it before routing the shell's error output to the same place as - * its standard output. - */ - (void)fcntl(1, F_SETFD, 0); - if (dup2(1, 2) == -1) { - execError("dup2", "1, 2"); - _exit(1); - } - - /* - * We want to switch the child into a different process family so - * we can kill it and all its descendants in one fell swoop, - * by killing its process family, but not commit suicide. - */ -#if defined(HAVE_SETPGID) - (void)setpgid(0, getpid()); -#else -#if defined(HAVE_SETSID) - /* XXX: dsl - I'm sure this should be setpgrp()... */ - (void)setsid(); -#else - (void)setpgrp(0, getpid()); -#endif -#endif - - Var_ExportVars(); - - (void)execv(shellPath, argv); - execError("exec", shellPath); - _exit(1); - } - - /* Parent, continuing after the child exec */ - job->pid = cpid; - - Trace_Log(JOBSTART, job); - - /* - * Set the current position in the buffer to the beginning - * and mark another stream to watch in the outputs mask - */ - job->curPos = 0; - - watchfd(job); - - if (job->cmdFILE != NULL && job->cmdFILE != stdout) { - (void)fclose(job->cmdFILE); - job->cmdFILE = NULL; - } - - /* - * Now the job is actually running, add it to the table. - */ - if (DEBUG(JOB)) { - fprintf(debug_file, "JobExec(%s): pid %d added to jobs table\n", - job->node->name, job->pid); - job_table_dump("job started"); - } - JobSigUnlock(&mask); -} - -/*- - *----------------------------------------------------------------------- - * JobMakeArgv -- - * Create the argv needed to execute the shell for a given job. - * - * - * Results: - * - * Side Effects: - * - *----------------------------------------------------------------------- - */ -static void -JobMakeArgv(Job *job, char **argv) -{ - int argc; - static char args[10]; /* For merged arguments */ - - argv[0] = UNCONST(shellName); - argc = 1; - - if ((commandShell->exit && (*commandShell->exit != '-')) || - (commandShell->echo && (*commandShell->echo != '-'))) - { - /* - * At least one of the flags doesn't have a minus before it, so - * merge them together. Have to do this because the *(&(@*#*&#$# - * Bourne shell thinks its second argument is a file to source. - * Grrrr. Note the ten-character limitation on the combined arguments. - */ - (void)snprintf(args, sizeof(args), "-%s%s", - ((job->flags & JOB_IGNERR) ? "" : - (commandShell->exit ? commandShell->exit : "")), - ((job->flags & JOB_SILENT) ? "" : - (commandShell->echo ? commandShell->echo : ""))); - - if (args[1]) { - argv[argc] = args; - argc++; - } - } else { - if (!(job->flags & JOB_IGNERR) && commandShell->exit) { - argv[argc] = UNCONST(commandShell->exit); - argc++; - } - if (!(job->flags & JOB_SILENT) && commandShell->echo) { - argv[argc] = UNCONST(commandShell->echo); - argc++; - } - } - argv[argc] = NULL; -} - -/*- - *----------------------------------------------------------------------- - * JobStart -- - * Start a target-creation process going for the target described - * by the graph node gn. - * - * Input: - * gn target to create - * flags flags for the job to override normal ones. - * e.g. JOB_SPECIAL or JOB_IGNDOTS - * previous The previous Job structure for this node, if any. - * - * Results: - * JOB_ERROR if there was an error in the commands, JOB_FINISHED - * if there isn't actually anything left to do for the job and - * JOB_RUNNING if the job has been started. - * - * Side Effects: - * A new Job node is created and added to the list of running - * jobs. PMake is forked and a child shell created. - * - * NB: I'm fairly sure that this code is never called with JOB_SPECIAL set - * JOB_IGNDOTS is never set (dsl) - * Also the return value is ignored by everyone. - *----------------------------------------------------------------------- - */ -static int -JobStart(GNode *gn, int flags) -{ - Job *job; /* new job descriptor */ - char *argv[10]; /* Argument vector to shell */ - Boolean cmdsOK; /* true if the nodes commands were all right */ - Boolean noExec; /* Set true if we decide not to run the job */ - int tfd; /* File descriptor to the temp file */ - - for (job = job_table; job < job_table_end; job++) { - if (job->job_state == JOB_ST_FREE) - break; - } - if (job >= job_table_end) - Punt("JobStart no job slots vacant"); - - memset(job, 0, sizeof *job); - job->job_state = JOB_ST_SETUP; - if (gn->type & OP_SPECIAL) - flags |= JOB_SPECIAL; - - job->node = gn; - job->tailCmds = NULL; - - /* - * Set the initial value of the flags for this job based on the global - * ones and the node's attributes... Any flags supplied by the caller - * are also added to the field. - */ - job->flags = 0; - if (Targ_Ignore(gn)) { - job->flags |= JOB_IGNERR; - } - if (Targ_Silent(gn)) { - job->flags |= JOB_SILENT; - } - job->flags |= flags; - - /* - * Check the commands now so any attributes from .DEFAULT have a chance - * to migrate to the node - */ - cmdsOK = Job_CheckCommands(gn, Error); - - job->inPollfd = NULL; - /* - * If the -n flag wasn't given, we open up OUR (not the child's) - * temporary file to stuff commands in it. The thing is rd/wr so we don't - * need to reopen it to feed it to the shell. If the -n flag *was* given, - * we just set the file to be stdout. Cute, huh? - */ - if (((gn->type & OP_MAKE) && !(noRecursiveExecute)) || - (!noExecute && !touchFlag)) { - /* - * tfile is the name of a file into which all shell commands are - * put. It is removed before the child shell is executed, unless - * DEBUG(SCRIPT) is set. - */ - char *tfile; - sigset_t mask; - /* - * We're serious here, but if the commands were bogus, we're - * also dead... - */ - if (!cmdsOK) { - PrintOnError(gn, NULL); /* provide some clue */ - DieHorribly(); - } - - JobSigLock(&mask); - tfd = mkTempFile(TMPPAT, &tfile); - if (!DEBUG(SCRIPT)) - (void)eunlink(tfile); - JobSigUnlock(&mask); - - job->cmdFILE = fdopen(tfd, "w+"); - if (job->cmdFILE == NULL) { - Punt("Could not fdopen %s", tfile); - } - (void)fcntl(FILENO(job->cmdFILE), F_SETFD, 1); - /* - * Send the commands to the command file, flush all its buffers then - * rewind and remove the thing. - */ - noExec = FALSE; - -#ifdef USE_META - if (useMeta) { - meta_job_start(job, gn); - if (Targ_Silent(gn)) { /* might have changed */ - job->flags |= JOB_SILENT; - } - } -#endif - /* - * We can do all the commands at once. hooray for sanity - */ - numCommands = 0; - Lst_ForEach(gn->commands, JobPrintCommand, job); - - /* - * If we didn't print out any commands to the shell script, - * there's not much point in executing the shell, is there? - */ - if (numCommands == 0) { - noExec = TRUE; - } - - free(tfile); - } else if (NoExecute(gn)) { - /* - * Not executing anything -- just print all the commands to stdout - * in one fell swoop. This will still set up job->tailCmds correctly. - */ - if (lastNode != gn) { - MESSAGE(stdout, gn); - lastNode = gn; - } - job->cmdFILE = stdout; - /* - * Only print the commands if they're ok, but don't die if they're - * not -- just let the user know they're bad and keep going. It - * doesn't do any harm in this case and may do some good. - */ - if (cmdsOK) { - Lst_ForEach(gn->commands, JobPrintCommand, job); - } - /* - * Don't execute the shell, thank you. - */ - noExec = TRUE; - } else { - /* - * Just touch the target and note that no shell should be executed. - * Set cmdFILE to stdout to make life easier. Check the commands, too, - * but don't die if they're no good -- it does no harm to keep working - * up the graph. - */ - job->cmdFILE = stdout; - Job_Touch(gn, job->flags&JOB_SILENT); - noExec = TRUE; - } - /* Just in case it isn't already... */ - (void)fflush(job->cmdFILE); - - /* - * If we're not supposed to execute a shell, don't. - */ - if (noExec) { - if (!(job->flags & JOB_SPECIAL)) - Job_TokenReturn(); - /* - * Unlink and close the command file if we opened one - */ - if (job->cmdFILE != stdout) { - if (job->cmdFILE != NULL) { - (void)fclose(job->cmdFILE); - job->cmdFILE = NULL; - } - } - - /* - * We only want to work our way up the graph if we aren't here because - * the commands for the job were no good. - */ - if (cmdsOK && aborting == 0) { - if (job->tailCmds != NULL) { - Lst_ForEachFrom(job->node->commands, job->tailCmds, - JobSaveCommand, - job->node); - } - job->node->made = MADE; - Make_Update(job->node); - } - job->job_state = JOB_ST_FREE; - return cmdsOK ? JOB_FINISHED : JOB_ERROR; - } - - /* - * Set up the control arguments to the shell. This is based on the flags - * set earlier for this job. - */ - JobMakeArgv(job, argv); - - /* Create the pipe by which we'll get the shell's output. */ - JobCreatePipe(job, 3); - - JobExec(job, argv); - return(JOB_RUNNING); -} - -static char * -JobOutput(Job *job, char *cp, char *endp, int msg) -{ - char *ecp; - - if (commandShell->noPrint) { - ecp = Str_FindSubstring(cp, commandShell->noPrint); - while (ecp != NULL) { - if (cp != ecp) { - *ecp = '\0'; - if (!beSilent && msg && job->node != lastNode) { - MESSAGE(stdout, job->node); - lastNode = job->node; - } - /* - * The only way there wouldn't be a newline after - * this line is if it were the last in the buffer. - * however, since the non-printable comes after it, - * there must be a newline, so we don't print one. - */ - (void)fprintf(stdout, "%s", cp); - (void)fflush(stdout); - } - cp = ecp + commandShell->noPLen; - if (cp != endp) { - /* - * Still more to print, look again after skipping - * the whitespace following the non-printable - * command.... - */ - cp++; - while (*cp == ' ' || *cp == '\t' || *cp == '\n') { - cp++; - } - ecp = Str_FindSubstring(cp, commandShell->noPrint); - } else { - return cp; - } - } - } - return cp; -} - -/*- - *----------------------------------------------------------------------- - * JobDoOutput -- - * This function is called at different times depending on - * whether the user has specified that output is to be collected - * via pipes or temporary files. In the former case, we are called - * whenever there is something to read on the pipe. We collect more - * output from the given job and store it in the job's outBuf. If - * this makes up a line, we print it tagged by the job's identifier, - * as necessary. - * If output has been collected in a temporary file, we open the - * file and read it line by line, transfering it to our own - * output channel until the file is empty. At which point we - * remove the temporary file. - * In both cases, however, we keep our figurative eye out for the - * 'noPrint' line for the shell from which the output came. If - * we recognize a line, we don't print it. If the command is not - * alone on the line (the character after it is not \0 or \n), we - * do print whatever follows it. - * - * Input: - * job the job whose output needs printing - * finish TRUE if this is the last time we'll be called - * for this job - * - * Results: - * None - * - * Side Effects: - * curPos may be shifted as may the contents of outBuf. - *----------------------------------------------------------------------- - */ -STATIC void -JobDoOutput(Job *job, Boolean finish) -{ - Boolean gotNL = FALSE; /* true if got a newline */ - Boolean fbuf; /* true if our buffer filled up */ - int nr; /* number of bytes read */ - int i; /* auxiliary index into outBuf */ - int max; /* limit for i (end of current data) */ - int nRead; /* (Temporary) number of bytes read */ - - /* - * Read as many bytes as will fit in the buffer. - */ -end_loop: - gotNL = FALSE; - fbuf = FALSE; - - nRead = read(job->inPipe, &job->outBuf[job->curPos], - JOB_BUFSIZE - job->curPos); - if (nRead < 0) { - if (errno == EAGAIN) - return; - if (DEBUG(JOB)) { - perror("JobDoOutput(piperead)"); - } - nr = 0; - } else { - nr = nRead; - } - - /* - * If we hit the end-of-file (the job is dead), we must flush its - * remaining output, so pretend we read a newline if there's any - * output remaining in the buffer. - * Also clear the 'finish' flag so we stop looping. - */ - if ((nr == 0) && (job->curPos != 0)) { - job->outBuf[job->curPos] = '\n'; - nr = 1; - finish = FALSE; - } else if (nr == 0) { - finish = FALSE; - } - - /* - * Look for the last newline in the bytes we just got. If there is - * one, break out of the loop with 'i' as its index and gotNL set - * TRUE. - */ - max = job->curPos + nr; - for (i = job->curPos + nr - 1; i >= job->curPos; i--) { - if (job->outBuf[i] == '\n') { - gotNL = TRUE; - break; - } else if (job->outBuf[i] == '\0') { - /* - * Why? - */ - job->outBuf[i] = ' '; - } - } - - if (!gotNL) { - job->curPos += nr; - if (job->curPos == JOB_BUFSIZE) { - /* - * If we've run out of buffer space, we have no choice - * but to print the stuff. sigh. - */ - fbuf = TRUE; - i = job->curPos; - } - } - if (gotNL || fbuf) { - /* - * Need to send the output to the screen. Null terminate it - * first, overwriting the newline character if there was one. - * So long as the line isn't one we should filter (according - * to the shell description), we print the line, preceded - * by a target banner if this target isn't the same as the - * one for which we last printed something. - * The rest of the data in the buffer are then shifted down - * to the start of the buffer and curPos is set accordingly. - */ - job->outBuf[i] = '\0'; - if (i >= job->curPos) { - char *cp; - - cp = JobOutput(job, job->outBuf, &job->outBuf[i], FALSE); - - /* - * There's still more in that thar buffer. This time, though, - * we know there's no newline at the end, so we add one of - * our own free will. - */ - if (*cp != '\0') { - if (!beSilent && job->node != lastNode) { - MESSAGE(stdout, job->node); - lastNode = job->node; - } -#ifdef USE_META - if (useMeta) { - meta_job_output(job, cp, gotNL ? "\n" : ""); - } -#endif - (void)fprintf(stdout, "%s%s", cp, gotNL ? "\n" : ""); - (void)fflush(stdout); - } - } - if (i < max - 1) { - /* shift the remaining characters down */ - (void)memcpy(job->outBuf, &job->outBuf[i + 1], max - (i + 1)); - job->curPos = max - (i + 1); - - } else { - /* - * We have written everything out, so we just start over - * from the start of the buffer. No copying. No nothing. - */ - job->curPos = 0; - } - } - if (finish) { - /* - * If the finish flag is true, we must loop until we hit - * end-of-file on the pipe. This is guaranteed to happen - * eventually since the other end of the pipe is now closed - * (we closed it explicitly and the child has exited). When - * we do get an EOF, finish will be set FALSE and we'll fall - * through and out. - */ - goto end_loop; - } -} - -static void -JobRun(GNode *targ) -{ -#ifdef notyet - /* - * Unfortunately it is too complicated to run .BEGIN, .END, - * and .INTERRUPT job in the parallel job module. This has - * the nice side effect that it avoids a lot of other problems. - */ - Lst lst = Lst_Init(FALSE); - Lst_AtEnd(lst, targ); - (void)Make_Run(lst); - Lst_Destroy(lst, NULL); - JobStart(targ, JOB_SPECIAL); - while (jobTokensRunning) { - Job_CatchOutput(); - } -#else - Compat_Make(targ, targ); - if (targ->made == ERROR) { - PrintOnError(targ, "\n\nStop."); - exit(1); - } -#endif -} - -/*- - *----------------------------------------------------------------------- - * Job_CatchChildren -- - * Handle the exit of a child. Called from Make_Make. - * - * Input: - * block TRUE if should block on the wait - * - * Results: - * none. - * - * Side Effects: - * The job descriptor is removed from the list of children. - * - * Notes: - * We do waits, blocking or not, according to the wisdom of our - * caller, until there are no more children to report. For each - * job, call JobFinish to finish things off. - * - *----------------------------------------------------------------------- - */ - -void -Job_CatchChildren(void) -{ - int pid; /* pid of dead child */ - WAIT_T status; /* Exit/termination status */ - - /* - * Don't even bother if we know there's no one around. - */ - if (jobTokensRunning == 0) - return; - - while ((pid = waitpid((pid_t) -1, &status, WNOHANG | WUNTRACED)) > 0) { - if (DEBUG(JOB)) { - (void)fprintf(debug_file, "Process %d exited/stopped status %x.\n", pid, - WAIT_STATUS(status)); - } - JobReapChild(pid, status, TRUE); - } -} - -/* - * It is possible that wait[pid]() was called from elsewhere, - * this lets us reap jobs regardless. - */ -void -JobReapChild(pid_t pid, WAIT_T status, Boolean isJobs) -{ - Job *job; /* job descriptor for dead child */ - - /* - * Don't even bother if we know there's no one around. - */ - if (jobTokensRunning == 0) - return; - - job = JobFindPid(pid, JOB_ST_RUNNING, isJobs); - if (job == NULL) { - if (isJobs) { - if (!lurking_children) - Error("Child (%d) status %x not in table?", pid, status); - } - return; /* not ours */ - } - if (WIFSTOPPED(status)) { - if (DEBUG(JOB)) { - (void)fprintf(debug_file, "Process %d (%s) stopped.\n", - job->pid, job->node->name); - } - if (!make_suspended) { - switch (WSTOPSIG(status)) { - case SIGTSTP: - (void)printf("*** [%s] Suspended\n", job->node->name); - break; - case SIGSTOP: - (void)printf("*** [%s] Stopped\n", job->node->name); - break; - default: - (void)printf("*** [%s] Stopped -- signal %d\n", - job->node->name, WSTOPSIG(status)); - } - job->job_suspended = 1; - } - (void)fflush(stdout); - return; - } - - job->job_state = JOB_ST_FINISHED; - job->exit_status = WAIT_STATUS(status); - - JobFinish(job, status); -} - -/*- - *----------------------------------------------------------------------- - * Job_CatchOutput -- - * Catch the output from our children, if we're using - * pipes do so. Otherwise just block time until we get a - * signal(most likely a SIGCHLD) since there's no point in - * just spinning when there's nothing to do and the reaping - * of a child can wait for a while. - * - * Results: - * None - * - * Side Effects: - * Output is read from pipes if we're piping. - * ----------------------------------------------------------------------- - */ -void -Job_CatchOutput(void) -{ - int nready; - Job *job; - int i; - - (void)fflush(stdout); - - /* The first fd in the list is the job token pipe */ - nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC); - - if (nready < 0 || readyfd(&childExitJob)) { - char token = 0; - nready -= 1; - (void)read(childExitJob.inPipe, &token, 1); - if (token == DO_JOB_RESUME[0]) - /* Complete relay requested from our SIGCONT handler */ - JobRestartJobs(); - Job_CatchChildren(); - } - - if (nready <= 0) - return; - - if (wantToken && readyfd(&tokenWaitJob)) - nready--; - - for (i = 2; i < nfds; i++) { - if (!fds[i].revents) - continue; - job = jobfds[i]; - if (job->job_state != JOB_ST_RUNNING) - continue; - JobDoOutput(job, FALSE); - } -} - -/*- - *----------------------------------------------------------------------- - * Job_Make -- - * Start the creation of a target. Basically a front-end for - * JobStart used by the Make module. - * - * Results: - * None. - * - * Side Effects: - * Another job is started. - * - *----------------------------------------------------------------------- - */ -void -Job_Make(GNode *gn) -{ - (void)JobStart(gn, 0); -} - -void -Shell_Init(void) -{ - if (shellPath == NULL) { - /* - * We are using the default shell, which may be an absolute - * path if DEFSHELL_CUSTOM is defined. - */ - shellName = commandShell->name; -#ifdef DEFSHELL_CUSTOM - if (*shellName == '/') { - shellPath = shellName; - shellName = strrchr(shellPath, '/'); - shellName++; - } else -#endif - shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH); - } - if (commandShell->exit == NULL) { - commandShell->exit = ""; - } - if (commandShell->echo == NULL) { - commandShell->echo = ""; - } -} - -/*- - * Returns the string literal that is used in the current command shell - * to produce a newline character. - */ -const char * -Shell_GetNewline(void) -{ - - return commandShell->newline; -} - -void -Job_SetPrefix(void) -{ - - if (targPrefix) { - free(targPrefix); - } else if (!Var_Exists(MAKE_JOB_PREFIX, VAR_GLOBAL)) { - Var_Set(MAKE_JOB_PREFIX, "---", VAR_GLOBAL, 0); - } - - targPrefix = Var_Subst(NULL, "${" MAKE_JOB_PREFIX "}", VAR_GLOBAL, 0); -} - -/*- - *----------------------------------------------------------------------- - * Job_Init -- - * Initialize the process module - * - * Input: - * - * Results: - * none - * - * Side Effects: - * lists and counters are initialized - *----------------------------------------------------------------------- - */ -void -Job_Init(void) -{ - GNode *begin; /* node for commands to do at the very start */ - - /* Allocate space for all the job info */ - job_table = bmake_malloc(maxJobs * sizeof *job_table); - memset(job_table, 0, maxJobs * sizeof *job_table); - job_table_end = job_table + maxJobs; - wantToken = 0; - - aborting = 0; - errors = 0; - - lastNode = NULL; - - /* - * There is a non-zero chance that we already have children. - * eg after 'make -f- <<EOF' - * Since their termination causes a 'Child (pid) not in table' message, - * Collect the status of any that are already dead, and suppress the - * error message if there are any undead ones. - */ - for (;;) { - int rval, status; - rval = waitpid((pid_t) -1, &status, WNOHANG); - if (rval > 0) - continue; - if (rval == 0) - lurking_children = 1; - break; - } - - Shell_Init(); - - JobCreatePipe(&childExitJob, 3); - - /* We can only need to wait for tokens, children and output from each job */ - fds = bmake_malloc(sizeof (*fds) * (2 + maxJobs)); - jobfds = bmake_malloc(sizeof (*jobfds) * (2 + maxJobs)); - - /* These are permanent entries and take slots 0 and 1 */ - watchfd(&tokenWaitJob); - watchfd(&childExitJob); - - sigemptyset(&caught_signals); - /* - * Install a SIGCHLD handler. - */ - (void)bmake_signal(SIGCHLD, JobChildSig); - sigaddset(&caught_signals, SIGCHLD); - -#define ADDSIG(s,h) \ - if (bmake_signal(s, SIG_IGN) != SIG_IGN) { \ - sigaddset(&caught_signals, s); \ - (void)bmake_signal(s, h); \ - } - - /* - * Catch the four signals that POSIX specifies if they aren't ignored. - * JobPassSig will take care of calling JobInterrupt if appropriate. - */ - ADDSIG(SIGINT, JobPassSig_int) - ADDSIG(SIGHUP, JobPassSig_term) - ADDSIG(SIGTERM, JobPassSig_term) - ADDSIG(SIGQUIT, JobPassSig_term) - - /* - * There are additional signals that need to be caught and passed if - * either the export system wants to be told directly of signals or if - * we're giving each job its own process group (since then it won't get - * signals from the terminal driver as we own the terminal) - */ - ADDSIG(SIGTSTP, JobPassSig_suspend) - ADDSIG(SIGTTOU, JobPassSig_suspend) - ADDSIG(SIGTTIN, JobPassSig_suspend) - ADDSIG(SIGWINCH, JobCondPassSig) - ADDSIG(SIGCONT, JobContinueSig) -#undef ADDSIG - - begin = Targ_FindNode(".BEGIN", TARG_NOCREATE); - - if (begin != NULL) { - JobRun(begin); - if (begin->made == ERROR) { - PrintOnError(begin, "\n\nStop."); - exit(1); - } - } - postCommands = Targ_FindNode(".END", TARG_CREATE); -} - -static void JobSigReset(void) -{ -#define DELSIG(s) \ - if (sigismember(&caught_signals, s)) { \ - (void)bmake_signal(s, SIG_DFL); \ - } - - DELSIG(SIGINT) - DELSIG(SIGHUP) - DELSIG(SIGQUIT) - DELSIG(SIGTERM) - DELSIG(SIGTSTP) - DELSIG(SIGTTOU) - DELSIG(SIGTTIN) - DELSIG(SIGWINCH) - DELSIG(SIGCONT) -#undef DELSIG - (void)bmake_signal(SIGCHLD, SIG_DFL); -} - -/*- - *----------------------------------------------------------------------- - * JobMatchShell -- - * Find a shell in 'shells' given its name. - * - * Results: - * A pointer to the Shell structure. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Shell * -JobMatchShell(const char *name) -{ - Shell *sh; - - for (sh = shells; sh->name != NULL; sh++) { - if (strcmp(name, sh->name) == 0) - return (sh); - } - return NULL; -} - -/*- - *----------------------------------------------------------------------- - * Job_ParseShell -- - * Parse a shell specification and set up commandShell, shellPath - * and shellName appropriately. - * - * Input: - * line The shell spec - * - * Results: - * FAILURE if the specification was incorrect. - * - * Side Effects: - * commandShell points to a Shell structure (either predefined or - * created from the shell spec), shellPath is the full path of the - * shell described by commandShell, while shellName is just the - * final component of shellPath. - * - * Notes: - * A shell specification consists of a .SHELL target, with dependency - * operator, followed by a series of blank-separated words. Double - * quotes can be used to use blanks in words. A backslash escapes - * anything (most notably a double-quote and a space) and - * provides the functionality it does in C. Each word consists of - * keyword and value separated by an equal sign. There should be no - * unnecessary spaces in the word. The keywords are as follows: - * name Name of shell. - * path Location of shell. - * quiet Command to turn off echoing. - * echo Command to turn echoing on - * filter Result of turning off echoing that shouldn't be - * printed. - * echoFlag Flag to turn echoing on at the start - * errFlag Flag to turn error checking on at the start - * hasErrCtl True if shell has error checking control - * newline String literal to represent a newline char - * check Command to turn on error checking if hasErrCtl - * is TRUE or template of command to echo a command - * for which error checking is off if hasErrCtl is - * FALSE. - * ignore Command to turn off error checking if hasErrCtl - * is TRUE or template of command to execute a - * command so as to ignore any errors it returns if - * hasErrCtl is FALSE. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Job_ParseShell(char *line) -{ - char **words; - char **argv; - int argc; - char *path; - Shell newShell; - Boolean fullSpec = FALSE; - Shell *sh; - - while (isspace((unsigned char)*line)) { - line++; - } - - if (shellArgv) - free(UNCONST(shellArgv)); - - memset(&newShell, 0, sizeof(newShell)); - - /* - * Parse the specification by keyword - */ - words = brk_string(line, &argc, TRUE, &path); - if (words == NULL) { - Error("Unterminated quoted string [%s]", line); - return FAILURE; - } - shellArgv = path; - - for (path = NULL, argv = words; argc != 0; argc--, argv++) { - if (strncmp(*argv, "path=", 5) == 0) { - path = &argv[0][5]; - } else if (strncmp(*argv, "name=", 5) == 0) { - newShell.name = &argv[0][5]; - } else { - if (strncmp(*argv, "quiet=", 6) == 0) { - newShell.echoOff = &argv[0][6]; - } else if (strncmp(*argv, "echo=", 5) == 0) { - newShell.echoOn = &argv[0][5]; - } else if (strncmp(*argv, "filter=", 7) == 0) { - newShell.noPrint = &argv[0][7]; - newShell.noPLen = strlen(newShell.noPrint); - } else if (strncmp(*argv, "echoFlag=", 9) == 0) { - newShell.echo = &argv[0][9]; - } else if (strncmp(*argv, "errFlag=", 8) == 0) { - newShell.exit = &argv[0][8]; - } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) { - char c = argv[0][10]; - newShell.hasErrCtl = !((c != 'Y') && (c != 'y') && - (c != 'T') && (c != 't')); - } else if (strncmp(*argv, "newline=", 8) == 0) { - newShell.newline = &argv[0][8]; - } else if (strncmp(*argv, "check=", 6) == 0) { - newShell.errCheck = &argv[0][6]; - } else if (strncmp(*argv, "ignore=", 7) == 0) { - newShell.ignErr = &argv[0][7]; - } else if (strncmp(*argv, "errout=", 7) == 0) { - newShell.errOut = &argv[0][7]; - } else if (strncmp(*argv, "comment=", 8) == 0) { - newShell.commentChar = argv[0][8]; - } else { - Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"", - *argv); - free(words); - return(FAILURE); - } - fullSpec = TRUE; - } - } - - if (path == NULL) { - /* - * If no path was given, the user wants one of the pre-defined shells, - * yes? So we find the one s/he wants with the help of JobMatchShell - * and set things up the right way. shellPath will be set up by - * Shell_Init. - */ - if (newShell.name == NULL) { - Parse_Error(PARSE_FATAL, "Neither path nor name specified"); - free(words); - return(FAILURE); - } else { - if ((sh = JobMatchShell(newShell.name)) == NULL) { - Parse_Error(PARSE_WARNING, "%s: No matching shell", - newShell.name); - free(words); - return(FAILURE); - } - commandShell = sh; - shellName = newShell.name; - if (shellPath) { - /* Shell_Init has already been called! Do it again. */ - free(UNCONST(shellPath)); - shellPath = NULL; - Shell_Init(); - } - } - } else { - /* - * The user provided a path. If s/he gave nothing else (fullSpec is - * FALSE), try and find a matching shell in the ones we know of. - * Else we just take the specification at its word and copy it - * to a new location. In either case, we need to record the - * path the user gave for the shell. - */ - shellPath = path; - path = strrchr(path, '/'); - if (path == NULL) { - path = UNCONST(shellPath); - } else { - path += 1; - } - if (newShell.name != NULL) { - shellName = newShell.name; - } else { - shellName = path; - } - if (!fullSpec) { - if ((sh = JobMatchShell(shellName)) == NULL) { - Parse_Error(PARSE_WARNING, "%s: No matching shell", - shellName); - free(words); - return(FAILURE); - } - commandShell = sh; - } else { - commandShell = bmake_malloc(sizeof(Shell)); - *commandShell = newShell; - } - } - - if (commandShell->echoOn && commandShell->echoOff) { - commandShell->hasEchoCtl = TRUE; - } - - if (!commandShell->hasErrCtl) { - if (commandShell->errCheck == NULL) { - commandShell->errCheck = ""; - } - if (commandShell->ignErr == NULL) { - commandShell->ignErr = "%s\n"; - } - } - - /* - * Do not free up the words themselves, since they might be in use by the - * shell specification. - */ - free(words); - return SUCCESS; -} - -/*- - *----------------------------------------------------------------------- - * JobInterrupt -- - * Handle the receipt of an interrupt. - * - * Input: - * runINTERRUPT Non-zero if commands for the .INTERRUPT target - * should be executed - * signo signal received - * - * Results: - * None - * - * Side Effects: - * All children are killed. Another job will be started if the - * .INTERRUPT target was given. - *----------------------------------------------------------------------- - */ -static void -JobInterrupt(int runINTERRUPT, int signo) -{ - Job *job; /* job descriptor in that element */ - GNode *interrupt; /* the node describing the .INTERRUPT target */ - sigset_t mask; - GNode *gn; - - aborting = ABORT_INTERRUPT; - - JobSigLock(&mask); - - for (job = job_table; job < job_table_end; job++) { - if (job->job_state != JOB_ST_RUNNING) - continue; - - gn = job->node; - - if ((gn->type & (OP_JOIN|OP_PHONY)) == 0 && !Targ_Precious(gn)) { - char *file = (gn->path == NULL ? gn->name : gn->path); - if (!noExecute && eunlink(file) != -1) { - Error("*** %s removed", file); - } - } - if (job->pid) { - if (DEBUG(JOB)) { - (void)fprintf(debug_file, - "JobInterrupt passing signal %d to child %d.\n", - signo, job->pid); - } - KILLPG(job->pid, signo); - } - } - - JobSigUnlock(&mask); - - if (runINTERRUPT && !touchFlag) { - interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); - if (interrupt != NULL) { - ignoreErrors = FALSE; - JobRun(interrupt); - } - } - Trace_Log(MAKEINTR, 0); - exit(signo); -} - -/* - *----------------------------------------------------------------------- - * Job_Finish -- - * Do final processing such as the running of the commands - * attached to the .END target. - * - * Results: - * Number of errors reported. - * - * Side Effects: - * None. - *----------------------------------------------------------------------- - */ -int -Job_Finish(void) -{ - if (postCommands != NULL && - (!Lst_IsEmpty(postCommands->commands) || - !Lst_IsEmpty(postCommands->children))) { - if (errors) { - Error("Errors reported so .END ignored"); - } else { - JobRun(postCommands); - } - } - return(errors); -} - -/*- - *----------------------------------------------------------------------- - * Job_End -- - * Cleanup any memory used by the jobs module - * - * Results: - * None. - * - * Side Effects: - * Memory is freed - *----------------------------------------------------------------------- - */ -void -Job_End(void) -{ -#ifdef CLEANUP - if (shellArgv) - free(shellArgv); -#endif -} - -/*- - *----------------------------------------------------------------------- - * Job_Wait -- - * Waits for all running jobs to finish and returns. Sets 'aborting' - * to ABORT_WAIT to prevent other jobs from starting. - * - * Results: - * None. - * - * Side Effects: - * Currently running jobs finish. - * - *----------------------------------------------------------------------- - */ -void -Job_Wait(void) -{ - aborting = ABORT_WAIT; - while (jobTokensRunning != 0) { - Job_CatchOutput(); - } - aborting = 0; -} - -/*- - *----------------------------------------------------------------------- - * Job_AbortAll -- - * Abort all currently running jobs without handling output or anything. - * This function is to be called only in the event of a major - * error. Most definitely NOT to be called from JobInterrupt. - * - * Results: - * None - * - * Side Effects: - * All children are killed, not just the firstborn - *----------------------------------------------------------------------- - */ -void -Job_AbortAll(void) -{ - Job *job; /* the job descriptor in that element */ - WAIT_T foo; - - aborting = ABORT_ERROR; - - if (jobTokensRunning) { - for (job = job_table; job < job_table_end; job++) { - if (job->job_state != JOB_ST_RUNNING) - continue; - /* - * kill the child process with increasingly drastic signals to make - * darn sure it's dead. - */ - KILLPG(job->pid, SIGINT); - KILLPG(job->pid, SIGKILL); - } - } - - /* - * Catch as many children as want to report in at first, then give up - */ - while (waitpid((pid_t) -1, &foo, WNOHANG) > 0) - continue; -} - - -/*- - *----------------------------------------------------------------------- - * JobRestartJobs -- - * Tries to restart stopped jobs if there are slots available. - * Called in process context in response to a SIGCONT. - * - * Results: - * None. - * - * Side Effects: - * Resumes jobs. - * - *----------------------------------------------------------------------- - */ -static void -JobRestartJobs(void) -{ - Job *job; - - for (job = job_table; job < job_table_end; job++) { - if (job->job_state == JOB_ST_RUNNING && - (make_suspended || job->job_suspended)) { - if (DEBUG(JOB)) { - (void)fprintf(debug_file, "Restarting stopped job pid %d.\n", - job->pid); - } - if (job->job_suspended) { - (void)printf("*** [%s] Continued\n", job->node->name); - (void)fflush(stdout); - } - job->job_suspended = 0; - if (KILLPG(job->pid, SIGCONT) != 0 && DEBUG(JOB)) { - fprintf(debug_file, "Failed to send SIGCONT to %d\n", job->pid); - } - } - if (job->job_state == JOB_ST_FINISHED) - /* Job exit deferred after calling waitpid() in a signal handler */ - JobFinish(job, job->exit_status); - } - make_suspended = 0; -} - -static void -watchfd(Job *job) -{ - if (job->inPollfd != NULL) - Punt("Watching watched job"); - - fds[nfds].fd = job->inPipe; - fds[nfds].events = POLLIN; - jobfds[nfds] = job; - job->inPollfd = &fds[nfds]; - nfds++; -} - -static void -clearfd(Job *job) -{ - int i; - if (job->inPollfd == NULL) - Punt("Unwatching unwatched job"); - i = job->inPollfd - fds; - nfds--; - /* - * Move last job in table into hole made by dead job. - */ - if (nfds != i) { - fds[i] = fds[nfds]; - jobfds[i] = jobfds[nfds]; - jobfds[i]->inPollfd = &fds[i]; - } - job->inPollfd = NULL; -} - -static int -readyfd(Job *job) -{ - if (job->inPollfd == NULL) - Punt("Polling unwatched job"); - return (job->inPollfd->revents & POLLIN) != 0; -} - -/*- - *----------------------------------------------------------------------- - * JobTokenAdd -- - * Put a token into the job pipe so that some make process can start - * another job. - * - * Side Effects: - * Allows more build jobs to be spawned somewhere. - * - *----------------------------------------------------------------------- - */ - -static void -JobTokenAdd(void) -{ - char tok = JOB_TOKENS[aborting], tok1; - - /* If we are depositing an error token flush everything else */ - while (tok != '+' && read(tokenWaitJob.inPipe, &tok1, 1) == 1) - continue; - - if (DEBUG(JOB)) - fprintf(debug_file, "(%d) aborting %d, deposit token %c\n", - getpid(), aborting, JOB_TOKENS[aborting]); - write(tokenWaitJob.outPipe, &tok, 1); -} - -/*- - *----------------------------------------------------------------------- - * Job_ServerStartTokenAdd -- - * Prep the job token pipe in the root make process. - * - *----------------------------------------------------------------------- - */ - -void -Job_ServerStart(int max_tokens, int jp_0, int jp_1) -{ - int i; - char jobarg[64]; - - if (jp_0 >= 0 && jp_1 >= 0) { - /* Pipe passed in from parent */ - tokenWaitJob.inPipe = jp_0; - tokenWaitJob.outPipe = jp_1; - return; - } - - JobCreatePipe(&tokenWaitJob, 15); - - snprintf(jobarg, sizeof(jobarg), "%d,%d", - tokenWaitJob.inPipe, tokenWaitJob.outPipe); - - Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL); - Var_Append(MAKEFLAGS, jobarg, VAR_GLOBAL); - - /* - * Preload the job pipe with one token per job, save the one - * "extra" token for the primary job. - * - * XXX should clip maxJobs against PIPE_BUF -- if max_tokens is - * larger than the write buffer size of the pipe, we will - * deadlock here. - */ - for (i = 1; i < max_tokens; i++) - JobTokenAdd(); -} - -/*- - *----------------------------------------------------------------------- - * Job_TokenReturn -- - * Return a withdrawn token to the pool. - * - *----------------------------------------------------------------------- - */ - -void -Job_TokenReturn(void) -{ - jobTokensRunning--; - if (jobTokensRunning < 0) - Punt("token botch"); - if (jobTokensRunning || JOB_TOKENS[aborting] != '+') - JobTokenAdd(); -} - -/*- - *----------------------------------------------------------------------- - * Job_TokenWithdraw -- - * Attempt to withdraw a token from the pool. - * - * Results: - * Returns TRUE if a token was withdrawn, and FALSE if the pool - * is currently empty. - * - * Side Effects: - * If pool is empty, set wantToken so that we wake up - * when a token is released. - * - *----------------------------------------------------------------------- - */ - - -Boolean -Job_TokenWithdraw(void) -{ - char tok, tok1; - int count; - - wantToken = 0; - if (DEBUG(JOB)) - fprintf(debug_file, "Job_TokenWithdraw(%d): aborting %d, running %d\n", - getpid(), aborting, jobTokensRunning); - - if (aborting || (jobTokensRunning >= maxJobs)) - return FALSE; - - count = read(tokenWaitJob.inPipe, &tok, 1); - if (count == 0) - Fatal("eof on job pipe!"); - if (count < 0 && jobTokensRunning != 0) { - if (errno != EAGAIN) { - Fatal("job pipe read: %s", strerror(errno)); - } - if (DEBUG(JOB)) - fprintf(debug_file, "(%d) blocked for token\n", getpid()); - wantToken = 1; - return FALSE; - } - - if (count == 1 && tok != '+') { - /* make being abvorted - remove any other job tokens */ - if (DEBUG(JOB)) - fprintf(debug_file, "(%d) aborted by token %c\n", getpid(), tok); - while (read(tokenWaitJob.inPipe, &tok1, 1) == 1) - continue; - /* And put the stopper back */ - write(tokenWaitJob.outPipe, &tok, 1); - Fatal("A failure has been detected in another branch of the parallel make"); - } - - if (count == 1 && jobTokensRunning == 0) - /* We didn't want the token really */ - write(tokenWaitJob.outPipe, &tok, 1); - - jobTokensRunning++; - if (DEBUG(JOB)) - fprintf(debug_file, "(%d) withdrew token\n", getpid()); - return TRUE; -} - -#ifdef USE_SELECT -int -emul_poll(struct pollfd *fd, int nfd, int timeout) -{ - fd_set rfds, wfds; - int i, maxfd, nselect, npoll; - struct timeval tv, *tvp; - long usecs; - - FD_ZERO(&rfds); - FD_ZERO(&wfds); - - maxfd = -1; - for (i = 0; i < nfd; i++) { - fd[i].revents = 0; - - if (fd[i].events & POLLIN) - FD_SET(fd[i].fd, &rfds); - - if (fd[i].events & POLLOUT) - FD_SET(fd[i].fd, &wfds); - - if (fd[i].fd > maxfd) - maxfd = fd[i].fd; - } - - if (maxfd >= FD_SETSIZE) { - Punt("Ran out of fd_set slots; " - "recompile with a larger FD_SETSIZE."); - } - - if (timeout < 0) { - tvp = NULL; - } else { - usecs = timeout * 1000; - tv.tv_sec = usecs / 1000000; - tv.tv_usec = usecs % 1000000; - tvp = &tv; - } - - nselect = select(maxfd + 1, &rfds, &wfds, 0, tvp); - - if (nselect <= 0) - return nselect; - - npoll = 0; - for (i = 0; i < nfd; i++) { - if (FD_ISSET(fd[i].fd, &rfds)) - fd[i].revents |= POLLIN; - - if (FD_ISSET(fd[i].fd, &wfds)) - fd[i].revents |= POLLOUT; - - if (fd[i].revents) - npoll++; - } - - return npoll; -} -#endif /* USE_SELECT */ diff --git a/20120831/job.h b/20120831/job.h deleted file mode 100644 index 560b70b..0000000 --- a/20120831/job.h +++ /dev/null @@ -1,272 +0,0 @@ -/* $NetBSD: job.h,v 1.40 2010/09/13 15:36:57 sjg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)job.h 8.1 (Berkeley) 6/6/93 - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)job.h 8.1 (Berkeley) 6/6/93 - */ - -/*- - * job.h -- - * Definitions pertaining to the running of jobs in parallel mode. - */ -#ifndef _JOB_H_ -#define _JOB_H_ - -#define TMPPAT "makeXXXXXX" /* relative to tmpdir */ - -#ifdef USE_SELECT -/* - * Emulate poll() in terms of select(). This is not a complete - * emulation but it is sufficient for make's purposes. - */ - -#define poll emul_poll -#define pollfd emul_pollfd - -struct emul_pollfd { - int fd; - short events; - short revents; -}; - -#define POLLIN 0x0001 -#define POLLOUT 0x0004 - -int -emul_poll(struct pollfd *fd, int nfd, int timeout); -#endif - -/* - * The POLL_MSEC constant determines the maximum number of milliseconds spent - * in poll before coming out to see if a child has finished. - */ -#define POLL_MSEC 5000 - - -/*- - * Job Table definitions. - * - * Each job has several things associated with it: - * 1) The process id of the child shell - * 2) The graph node describing the target being made by this job - * 3) A LstNode for the first command to be saved after the job - * completes. This is NULL if there was no "..." in the job's - * commands. - * 4) An FILE* for writing out the commands. This is only - * used before the job is actually started. - * 5) The output is being caught via a pipe and - * the descriptors of our pipe, an array in which output is line - * buffered and the current position in that buffer are all - * maintained for each job. - * 6) A word of flags which determine how the module handles errors, - * echoing, etc. for the job - * - * When a job is finished, the Make_Update function is called on each of the - * parents of the node which was just remade. This takes care of the upward - * traversal of the dependency graph. - */ -struct pollfd; - - -#ifdef USE_META -# include "meta.h" -#endif - -#define JOB_BUFSIZE 1024 -typedef struct Job { - int pid; /* The child's process ID */ - GNode *node; /* The target the child is making */ - LstNode tailCmds; /* The node of the first command to be - * saved when the job has been run */ - FILE *cmdFILE; /* When creating the shell script, this is - * where the commands go */ - int exit_status; /* from wait4() in signal handler */ - char job_state; /* status of the job entry */ -#define JOB_ST_FREE 0 /* Job is available */ -#define JOB_ST_SETUP 1 /* Job is allocated but otherwise invalid */ -#define JOB_ST_RUNNING 3 /* Job is running, pid valid */ -#define JOB_ST_FINISHED 4 /* Job is done (ie after SIGCHILD) */ - char job_suspended; - short flags; /* Flags to control treatment of job */ -#define JOB_IGNERR 0x001 /* Ignore non-zero exits */ -#define JOB_SILENT 0x002 /* no output */ -#define JOB_SPECIAL 0x004 /* Target is a special one. i.e. run it locally - * if we can't export it and maxLocal is 0 */ -#define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing - * commands */ -#define JOB_TRACED 0x400 /* we've sent 'set -x' */ - - int jobPipe[2]; /* Pipe for readind output from job */ - struct pollfd *inPollfd; /* pollfd associated with inPipe */ - char outBuf[JOB_BUFSIZE + 1]; - /* Buffer for storing the output of the - * job, line by line */ - int curPos; /* Current position in op_outBuf */ - -#ifdef USE_META - struct BuildMon bm; -#endif -} Job; - -#define inPipe jobPipe[0] -#define outPipe jobPipe[1] - - -/*- - * Shell Specifications: - * Each shell type has associated with it the following information: - * 1) The string which must match the last character of the shell name - * for the shell to be considered of this type. The longest match - * wins. - * 2) A command to issue to turn off echoing of command lines - * 3) A command to issue to turn echoing back on again - * 4) What the shell prints, and its length, when given the echo-off - * command. This line will not be printed when received from the shell - * 5) A boolean to tell if the shell has the ability to control - * error checking for individual commands. - * 6) The string to turn this checking on. - * 7) The string to turn it off. - * 8) The command-flag to give to cause the shell to start echoing - * commands right away. - * 9) The command-flag to cause the shell to Lib_Exit when an error is - * detected in one of the commands. - * - * Some special stuff goes on if a shell doesn't have error control. In such - * a case, errCheck becomes a printf template for echoing the command, - * should echoing be on and ignErr becomes another printf template for - * executing the command while ignoring the return status. Finally errOut - * is a printf template for running the command and causing the shell to - * exit on error. If any of these strings are empty when hasErrCtl is FALSE, - * the command will be executed anyway as is and if it causes an error, so be - * it. Any templates setup to echo the command will escape any '$ ` \ "'i - * characters in the command string to avoid common problems with - * echo "%s\n" as a template. - */ -typedef struct Shell { - const char *name; /* the name of the shell. For Bourne and C - * shells, this is used only to find the - * shell description when used as the single - * source of a .SHELL target. For user-defined - * shells, this is the full path of the shell. - */ - Boolean hasEchoCtl; /* True if both echoOff and echoOn defined */ - const char *echoOff; /* command to turn off echo */ - const char *echoOn; /* command to turn it back on again */ - const char *noPrint; /* command to skip when printing output from - * shell. This is usually the command which - * was executed to turn off echoing */ - int noPLen; /* length of noPrint command */ - Boolean hasErrCtl; /* set if can control error checking for - * individual commands */ - const char *errCheck; /* string to turn error checking on */ - const char *ignErr; /* string to turn off error checking */ - const char *errOut; /* string to use for testing exit code */ - const char *newline; /* string literal that results in a newline - * character when it appears outside of any - * 'quote' or "quote" characters */ - char commentChar; /* character used by shell for comment lines */ - - /* - * command-line flags - */ - const char *echo; /* echo commands */ - const char *exit; /* exit on error */ -} Shell; - -extern const char *shellPath; -extern const char *shellName; - -extern int jobTokensRunning; /* tokens currently "out" */ -extern int maxJobs; /* Max jobs we can run */ - -void Shell_Init(void); -const char *Shell_GetNewline(void); -void Job_Touch(GNode *, Boolean); -Boolean Job_CheckCommands(GNode *, void (*abortProc )(const char *, ...)); -#define CATCH_BLOCK 1 -void Job_CatchChildren(void); -void Job_CatchOutput(void); -void Job_Make(GNode *); -void Job_Init(void); -Boolean Job_Full(void); -Boolean Job_Empty(void); -ReturnStatus Job_ParseShell(char *); -int Job_Finish(void); -void Job_End(void); -void Job_Wait(void); -void Job_AbortAll(void); -void JobFlagForMigration(int); -void Job_TokenReturn(void); -Boolean Job_TokenWithdraw(void); -void Job_ServerStart(int, int, int); -void Job_SetPrefix(void); - -#endif /* _JOB_H_ */ diff --git a/20120831/lst.h b/20120831/lst.h deleted file mode 100644 index e067407..0000000 --- a/20120831/lst.h +++ /dev/null @@ -1,189 +0,0 @@ -/* $NetBSD: lst.h,v 1.18 2009/01/23 21:58:27 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)lst.h 8.1 (Berkeley) 6/6/93 - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)lst.h 8.1 (Berkeley) 6/6/93 - */ - -/*- - * lst.h -- - * Header for using the list library - */ -#ifndef _LST_H_ -#define _LST_H_ - -#include <sys/param.h> -#include <stdlib.h> - -#include "sprite.h" - -/* - * basic typedef. This is what the Lst_ functions handle - */ - -typedef struct List *Lst; -typedef struct ListNode *LstNode; - -typedef void *DuplicateProc(void *); -typedef void FreeProc(void *); - -#define LST_CONCNEW 0 /* create new LstNode's when using Lst_Concat */ -#define LST_CONCLINK 1 /* relink LstNode's when using Lst_Concat */ - -/* - * Creation/destruction functions - */ -/* Create a new list */ -Lst Lst_Init(Boolean); -/* Duplicate an existing list */ -Lst Lst_Duplicate(Lst, DuplicateProc *); -/* Destroy an old one */ -void Lst_Destroy(Lst, FreeProc *); -/* True if list is empty */ -Boolean Lst_IsEmpty(Lst); - -/* - * Functions to modify a list - */ -/* Insert an element before another */ -ReturnStatus Lst_InsertBefore(Lst, LstNode, void *); -/* Insert an element after another */ -ReturnStatus Lst_InsertAfter(Lst, LstNode, void *); -/* Place an element at the front of a lst. */ -ReturnStatus Lst_AtFront(Lst, void *); -/* Place an element at the end of a lst. */ -ReturnStatus Lst_AtEnd(Lst, void *); -/* Remove an element */ -ReturnStatus Lst_Remove(Lst, LstNode); -/* Replace a node with a new value */ -ReturnStatus Lst_Replace(LstNode, void *); -/* Concatenate two lists */ -ReturnStatus Lst_Concat(Lst, Lst, int); - -/* - * Node-specific functions - */ -/* Return first element in list */ -LstNode Lst_First(Lst); -/* Return last element in list */ -LstNode Lst_Last(Lst); -/* Return successor to given element */ -LstNode Lst_Succ(LstNode); -/* Return predecessor to given element */ -LstNode Lst_Prev(LstNode); -/* Get datum from LstNode */ -void *Lst_Datum(LstNode); - -/* - * Functions for entire lists - */ -/* Find an element in a list */ -LstNode Lst_Find(Lst, const void *, int (*)(const void *, const void *)); -/* Find an element starting from somewhere */ -LstNode Lst_FindFrom(Lst, LstNode, const void *, - int (*cProc)(const void *, const void *)); -/* - * See if the given datum is on the list. Returns the LstNode containing - * the datum - */ -LstNode Lst_Member(Lst, void *); -/* Apply a function to all elements of a lst */ -int Lst_ForEach(Lst, int (*)(void *, void *), void *); -/* - * Apply a function to all elements of a lst starting from a certain point. - * If the list is circular, the application will wrap around to the - * beginning of the list again. - */ -int Lst_ForEachFrom(Lst, LstNode, int (*)(void *, void *), - void *); -/* - * these functions are for dealing with a list as a table, of sorts. - * An idea of the "current element" is kept and used by all the functions - * between Lst_Open() and Lst_Close(). - */ -/* Open the list */ -ReturnStatus Lst_Open(Lst); -/* Next element please */ -LstNode Lst_Next(Lst); -/* Done yet? */ -Boolean Lst_IsAtEnd(Lst); -/* Finish table access */ -void Lst_Close(Lst); - -/* - * for using the list as a queue - */ -/* Place an element at tail of queue */ -ReturnStatus Lst_EnQueue(Lst, void *); -/* Remove an element from head of queue */ -void *Lst_DeQueue(Lst); - -#endif /* _LST_H_ */ diff --git a/20120831/lst.lib/Makefile b/20120831/lst.lib/Makefile deleted file mode 100644 index e69de29..0000000 --- a/20120831/lst.lib/Makefile +++ /dev/null diff --git a/20120831/lst.lib/lstAppend.c b/20120831/lst.lib/lstAppend.c deleted file mode 100644 index 4dafe83..0000000 --- a/20120831/lst.lib/lstAppend.c +++ /dev/null @@ -1,122 +0,0 @@ -/* $NetBSD: lstAppend.c,v 1.14 2009/01/23 21:26:30 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstAppend.c,v 1.14 2009/01/23 21:26:30 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstAppend.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstAppend.c,v 1.14 2009/01/23 21:26:30 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstAppend.c -- - * Add a new node with a new datum after an existing node - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_InsertAfter -- - * Create a new node and add it to the given list after the given node. - * - * Input: - * l affected list - * ln node after which to append the datum - * d said datum - * - * Results: - * SUCCESS if all went well. - * - * Side Effects: - * A new ListNode is created and linked in to the List. The lastPtr - * field of the List will be altered if ln is the last node in the - * list. lastPtr and firstPtr will alter if the list was empty and - * ln was NULL. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_InsertAfter(Lst l, LstNode ln, void *d) -{ - List list; - ListNode lNode; - ListNode nLNode; - - if (LstValid (l) && (ln == NULL && LstIsEmpty (l))) { - goto ok; - } - - if (!LstValid (l) || LstIsEmpty (l) || ! LstNodeValid (ln, l)) { - return (FAILURE); - } - ok: - - list = l; - lNode = ln; - - PAlloc (nLNode, ListNode); - nLNode->datum = d; - nLNode->useCount = nLNode->flags = 0; - - if (lNode == NULL) { - if (list->isCirc) { - nLNode->nextPtr = nLNode->prevPtr = nLNode; - } else { - nLNode->nextPtr = nLNode->prevPtr = NULL; - } - list->firstPtr = list->lastPtr = nLNode; - } else { - nLNode->prevPtr = lNode; - nLNode->nextPtr = lNode->nextPtr; - - lNode->nextPtr = nLNode; - if (nLNode->nextPtr != NULL) { - nLNode->nextPtr->prevPtr = nLNode; - } - - if (lNode == list->lastPtr) { - list->lastPtr = nLNode; - } - } - - return (SUCCESS); -} - diff --git a/20120831/lst.lib/lstAtEnd.c b/20120831/lst.lib/lstAtEnd.c deleted file mode 100644 index 10f191a..0000000 --- a/20120831/lst.lib/lstAtEnd.c +++ /dev/null @@ -1,79 +0,0 @@ -/* $NetBSD: lstAtEnd.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstAtEnd.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstAtEnd.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstAtEnd.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstAtEnd.c -- - * Add a node at the end of the list - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_AtEnd -- - * Add a node to the end of the given list - * - * Input: - * l List to which to add the datum - * d Datum to add - * - * Results: - * SUCCESS if life is good. - * - * Side Effects: - * A new ListNode is created and added to the list. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_AtEnd(Lst l, void *d) -{ - LstNode end; - - end = Lst_Last(l); - return (Lst_InsertAfter(l, end, d)); -} diff --git a/20120831/lst.lib/lstAtFront.c b/20120831/lst.lib/lstAtFront.c deleted file mode 100644 index d8be166..0000000 --- a/20120831/lst.lib/lstAtFront.c +++ /dev/null @@ -1,76 +0,0 @@ -/* $NetBSD: lstAtFront.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstAtFront.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstAtFront.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstAtFront.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstAtFront.c -- - * Add a node at the front of the list - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_AtFront -- - * Place a piece of data at the front of a list - * - * Results: - * SUCCESS or FAILURE - * - * Side Effects: - * A new ListNode is created and stuck at the front of the list. - * hence, firstPtr (and possible lastPtr) in the list are altered. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_AtFront(Lst l, void *d) -{ - LstNode front; - - front = Lst_First(l); - return (Lst_InsertBefore(l, front, d)); -} diff --git a/20120831/lst.lib/lstClose.c b/20120831/lst.lib/lstClose.c deleted file mode 100644 index 06b68c5..0000000 --- a/20120831/lst.lib/lstClose.c +++ /dev/null @@ -1,86 +0,0 @@ -/* $NetBSD: lstClose.c,v 1.11 2006/10/27 21:37:25 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstClose.c,v 1.11 2006/10/27 21:37:25 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstClose.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstClose.c,v 1.11 2006/10/27 21:37:25 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstClose.c -- - * Close a list for sequential access. - * The sequential functions access the list in a slightly different way. - * CurPtr points to their idea of the current node in the list and they - * access the list based on it. Because the list is circular, Lst_Next - * and Lst_Prev will go around the list forever. Lst_IsAtEnd must be - * used to determine when to stop. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Close -- - * Close a list which was opened for sequential access. - * - * Input: - * l The list to close - * - * Results: - * None. - * - * Side Effects: - * The list is closed. - * - *----------------------------------------------------------------------- - */ -void -Lst_Close(Lst l) -{ - List list = l; - - if (LstValid(l) == TRUE) { - list->isOpen = FALSE; - list->atEnd = Unknown; - } -} - diff --git a/20120831/lst.lib/lstConcat.c b/20120831/lst.lib/lstConcat.c deleted file mode 100644 index 534d34e..0000000 --- a/20120831/lst.lib/lstConcat.c +++ /dev/null @@ -1,185 +0,0 @@ -/* $NetBSD: lstConcat.c,v 1.16 2008/12/13 15:19:29 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstConcat.c,v 1.16 2008/12/13 15:19:29 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstConcat.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstConcat.c,v 1.16 2008/12/13 15:19:29 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * listConcat.c -- - * Function to concatentate two lists. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Concat -- - * Concatenate two lists. New elements are created to hold the data - * elements, if specified, but the elements themselves are not copied. - * If the elements should be duplicated to avoid confusion with another - * list, the Lst_Duplicate function should be called first. - * If LST_CONCLINK is specified, the second list is destroyed since - * its pointers have been corrupted and the list is no longer useable. - * - * Input: - * l1 The list to which l2 is to be appended - * l2 The list to append to l1 - * flags LST_CONCNEW if LstNode's should be duplicated - * LST_CONCLINK if should just be relinked - * - * Results: - * SUCCESS if all went well. FAILURE otherwise. - * - * Side Effects: - * New elements are created and appended the first list. - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_Concat(Lst l1, Lst l2, int flags) -{ - ListNode ln; /* original LstNode */ - ListNode nln; /* new LstNode */ - ListNode last; /* the last element in the list. Keeps - * bookkeeping until the end */ - List list1 = l1; - List list2 = l2; - - if (!LstValid (l1) || !LstValid (l2)) { - return (FAILURE); - } - - if (flags == LST_CONCLINK) { - if (list2->firstPtr != NULL) { - /* - * We set the nextPtr of the - * last element of list two to be NIL to make the loop easier and - * so we don't need an extra case should the first list turn - * out to be non-circular -- the final element will already point - * to NIL space and the first element will be untouched if it - * existed before and will also point to NIL space if it didn't. - */ - list2->lastPtr->nextPtr = NULL; - /* - * So long as the second list isn't empty, we just link the - * first element of the second list to the last element of the - * first list. If the first list isn't empty, we then link the - * last element of the list to the first element of the second list - * The last element of the second list, if it exists, then becomes - * the last element of the first list. - */ - list2->firstPtr->prevPtr = list1->lastPtr; - if (list1->lastPtr != NULL) { - list1->lastPtr->nextPtr = list2->firstPtr; - } else { - list1->firstPtr = list2->firstPtr; - } - list1->lastPtr = list2->lastPtr; - } - if (list1->isCirc && list1->firstPtr != NULL) { - /* - * If the first list is supposed to be circular and it is (now) - * non-empty, we must make sure it's circular by linking the - * first element to the last and vice versa - */ - list1->firstPtr->prevPtr = list1->lastPtr; - list1->lastPtr->nextPtr = list1->firstPtr; - } - free(l2); - } else if (list2->firstPtr != NULL) { - /* - * We set the nextPtr of the last element of list 2 to be nil to make - * the loop less difficult. The loop simply goes through the entire - * second list creating new LstNodes and filling in the nextPtr, and - * prevPtr to fit into l1 and its datum field from the - * datum field of the corresponding element in l2. The 'last' node - * follows the last of the new nodes along until the entire l2 has - * been appended. Only then does the bookkeeping catch up with the - * changes. During the first iteration of the loop, if 'last' is nil, - * the first list must have been empty so the newly-created node is - * made the first node of the list. - */ - list2->lastPtr->nextPtr = NULL; - for (last = list1->lastPtr, ln = list2->firstPtr; - ln != NULL; - ln = ln->nextPtr) - { - PAlloc (nln, ListNode); - nln->datum = ln->datum; - if (last != NULL) { - last->nextPtr = nln; - } else { - list1->firstPtr = nln; - } - nln->prevPtr = last; - nln->flags = nln->useCount = 0; - last = nln; - } - - /* - * Finish bookkeeping. The last new element becomes the last element - * of list one. - */ - list1->lastPtr = last; - - /* - * The circularity of both list one and list two must be corrected - * for -- list one because of the new nodes added to it; list two - * because of the alteration of list2->lastPtr's nextPtr to ease the - * above for loop. - */ - if (list1->isCirc) { - list1->lastPtr->nextPtr = list1->firstPtr; - list1->firstPtr->prevPtr = list1->lastPtr; - } else { - last->nextPtr = NULL; - } - - if (list2->isCirc) { - list2->lastPtr->nextPtr = list2->firstPtr; - } - } - - return (SUCCESS); -} - diff --git a/20120831/lst.lib/lstDatum.c b/20120831/lst.lib/lstDatum.c deleted file mode 100644 index 6e2d9ad..0000000 --- a/20120831/lst.lib/lstDatum.c +++ /dev/null @@ -1,77 +0,0 @@ -/* $NetBSD: lstDatum.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstDatum.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstDatum.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstDatum.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstDatum.c -- - * Return the datum associated with a list node. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Datum -- - * Return the datum stored in the given node. - * - * Results: - * The datum or NULL if the node is invalid. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -void * -Lst_Datum(LstNode ln) -{ - if (ln != NULL) { - return ((ln)->datum); - } else { - return NULL; - } -} - diff --git a/20120831/lst.lib/lstDeQueue.c b/20120831/lst.lib/lstDeQueue.c deleted file mode 100644 index bdb05cc..0000000 --- a/20120831/lst.lib/lstDeQueue.c +++ /dev/null @@ -1,87 +0,0 @@ -/* $NetBSD: lstDeQueue.c,v 1.14 2009/01/23 21:26:30 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstDeQueue.c,v 1.14 2009/01/23 21:26:30 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstDeQueue.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstDeQueue.c,v 1.14 2009/01/23 21:26:30 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstDeQueue.c -- - * Remove the node and return its datum from the head of the list - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_DeQueue -- - * Remove and return the datum at the head of the given list. - * - * Results: - * The datum in the node at the head or NULL if the list - * is empty. - * - * Side Effects: - * The head node is removed from the list. - * - *----------------------------------------------------------------------- - */ -void * -Lst_DeQueue(Lst l) -{ - void *rd; - ListNode tln; - - tln = Lst_First(l); - if (tln == NULL) { - return NULL; - } - - rd = tln->datum; - if (Lst_Remove(l, tln) == FAILURE) { - return NULL; - } else { - return (rd); - } -} - diff --git a/20120831/lst.lib/lstDestroy.c b/20120831/lst.lib/lstDestroy.c deleted file mode 100644 index 92c5b2b..0000000 --- a/20120831/lst.lib/lstDestroy.c +++ /dev/null @@ -1,101 +0,0 @@ -/* $NetBSD: lstDestroy.c,v 1.16 2008/12/13 15:19:29 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstDestroy.c,v 1.16 2008/12/13 15:19:29 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstDestroy.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstDestroy.c,v 1.16 2008/12/13 15:19:29 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstDestroy.c -- - * Nuke a list and all its resources - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Destroy -- - * Destroy a list and free all its resources. If the freeProc is - * given, it is called with the datum from each node in turn before - * the node is freed. - * - * Results: - * None. - * - * Side Effects: - * The given list is freed in its entirety. - * - *----------------------------------------------------------------------- - */ -void -Lst_Destroy(Lst list, FreeProc *freeProc) -{ - ListNode ln; - ListNode tln = NULL; - - if (list == NULL) - return; - - /* To ease scanning */ - if (list->lastPtr != NULL) - list->lastPtr->nextPtr = NULL; - else { - free(list); - return; - } - - if (freeProc) { - for (ln = list->firstPtr; ln != NULL; ln = tln) { - tln = ln->nextPtr; - freeProc(ln->datum); - free(ln); - } - } else { - for (ln = list->firstPtr; ln != NULL; ln = tln) { - tln = ln->nextPtr; - free(ln); - } - } - - free(list); -} diff --git a/20120831/lst.lib/lstDupl.c b/20120831/lst.lib/lstDupl.c deleted file mode 100644 index 2174ff7..0000000 --- a/20120831/lst.lib/lstDupl.c +++ /dev/null @@ -1,107 +0,0 @@ -/* $NetBSD: lstDupl.c,v 1.16 2009/01/23 21:26:30 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstDupl.c,v 1.16 2009/01/23 21:26:30 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstDupl.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstDupl.c,v 1.16 2009/01/23 21:26:30 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * listDupl.c -- - * Duplicate a list. This includes duplicating the individual - * elements. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Duplicate -- - * Duplicate an entire list. If a function to copy a void *is - * given, the individual client elements will be duplicated as well. - * - * Input: - * l the list to duplicate - * copyProc A function to duplicate each void * - * - * Results: - * The new Lst structure or NULL if failure. - * - * Side Effects: - * A new list is created. - *----------------------------------------------------------------------- - */ -Lst -Lst_Duplicate(Lst l, DuplicateProc *copyProc) -{ - Lst nl; - ListNode ln; - List list = l; - - if (!LstValid (l)) { - return NULL; - } - - nl = Lst_Init(list->isCirc); - if (nl == NULL) { - return NULL; - } - - ln = list->firstPtr; - while (ln != NULL) { - if (copyProc != NULL) { - if (Lst_AtEnd(nl, copyProc(ln->datum)) == FAILURE) { - return NULL; - } - } else if (Lst_AtEnd(nl, ln->datum) == FAILURE) { - return NULL; - } - - if (list->isCirc && ln == list->lastPtr) { - ln = NULL; - } else { - ln = ln->nextPtr; - } - } - - return (nl); -} diff --git a/20120831/lst.lib/lstEnQueue.c b/20120831/lst.lib/lstEnQueue.c deleted file mode 100644 index be386c9..0000000 --- a/20120831/lst.lib/lstEnQueue.c +++ /dev/null @@ -1,78 +0,0 @@ -/* $NetBSD: lstEnQueue.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstEnQueue.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstEnQueue.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstEnQueue.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstEnQueue.c-- - * Treat the list as a queue and place a datum at its end - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_EnQueue -- - * Add the datum to the tail of the given list. - * - * Results: - * SUCCESS or FAILURE as returned by Lst_InsertAfter. - * - * Side Effects: - * the lastPtr field is altered all the time and the firstPtr field - * will be altered if the list used to be empty. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_EnQueue(Lst l, void *d) -{ - if (LstValid (l) == FALSE) { - return (FAILURE); - } - - return (Lst_InsertAfter(l, Lst_Last(l), d)); -} - diff --git a/20120831/lst.lib/lstFind.c b/20120831/lst.lib/lstFind.c deleted file mode 100644 index d07dbe7..0000000 --- a/20120831/lst.lib/lstFind.c +++ /dev/null @@ -1,74 +0,0 @@ -/* $NetBSD: lstFind.c,v 1.15 2009/01/23 21:58:28 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstFind.c,v 1.15 2009/01/23 21:58:28 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstFind.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstFind.c,v 1.15 2009/01/23 21:58:28 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstFind.c -- - * Find a node on a list. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Find -- - * Find a node on the given list using the given comparison function - * and the given datum. - * - * Results: - * The found node or NULL if none matches. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -LstNode -Lst_Find(Lst l, const void *d, int (*cProc)(const void *, const void *)) -{ - return (Lst_FindFrom(l, Lst_First(l), d, cProc)); -} - diff --git a/20120831/lst.lib/lstFindFrom.c b/20120831/lst.lib/lstFindFrom.c deleted file mode 100644 index e2beab6..0000000 --- a/20120831/lst.lib/lstFindFrom.c +++ /dev/null @@ -1,90 +0,0 @@ -/* $NetBSD: lstFindFrom.c,v 1.15 2009/01/23 21:58:28 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstFindFrom.c,v 1.15 2009/01/23 21:58:28 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstFindFrom.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstFindFrom.c,v 1.15 2009/01/23 21:58:28 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstFindFrom.c -- - * Find a node on a list from a given starting point. Used by Lst_Find. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_FindFrom -- - * Search for a node starting and ending with the given one on the - * given list using the passed datum and comparison function to - * determine when it has been found. - * - * Results: - * The found node or NULL - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -LstNode -Lst_FindFrom(Lst l, LstNode ln, const void *d, - int (*cProc)(const void *, const void *)) -{ - ListNode tln; - - if (!LstValid (l) || LstIsEmpty (l) || !LstNodeValid (ln, l)) { - return NULL; - } - - tln = ln; - - do { - if ((*cProc)(tln->datum, d) == 0) - return (tln); - tln = tln->nextPtr; - } while (tln != ln && tln != NULL); - - return NULL; -} - diff --git a/20120831/lst.lib/lstFirst.c b/20120831/lst.lib/lstFirst.c deleted file mode 100644 index 4e8334f..0000000 --- a/20120831/lst.lib/lstFirst.c +++ /dev/null @@ -1,77 +0,0 @@ -/* $NetBSD: lstFirst.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstFirst.c,v 1.12 2008/12/13 15:19:29 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstFirst.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstFirst.c,v 1.12 2008/12/13 15:19:29 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstFirst.c -- - * Return the first node of a list - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_First -- - * Return the first node on the given list. - * - * Results: - * The first node or NULL if the list is empty. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -LstNode -Lst_First(Lst l) -{ - if (!LstValid (l) || LstIsEmpty (l)) { - return NULL; - } else { - return (l->firstPtr); - } -} - diff --git a/20120831/lst.lib/lstForEach.c b/20120831/lst.lib/lstForEach.c deleted file mode 100644 index 917e4ea..0000000 --- a/20120831/lst.lib/lstForEach.c +++ /dev/null @@ -1,76 +0,0 @@ -/* $NetBSD: lstForEach.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstForEach.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstForEach.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstForEach.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstForeach.c -- - * Perform a given function on all elements of a list. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_ForEach -- - * Apply the given function to each element of the given list. The - * function should return 0 if Lst_ForEach should continue and non- - * zero if it should abort. - * - * Results: - * None. - * - * Side Effects: - * Only those created by the passed-in function. - * - *----------------------------------------------------------------------- - */ -/*VARARGS2*/ -int -Lst_ForEach(Lst l, int (*proc)(void *, void *), void *d) -{ - return Lst_ForEachFrom(l, Lst_First(l), proc, d); -} - diff --git a/20120831/lst.lib/lstForEachFrom.c b/20120831/lst.lib/lstForEachFrom.c deleted file mode 100644 index c7f44ad..0000000 --- a/20120831/lst.lib/lstForEachFrom.c +++ /dev/null @@ -1,125 +0,0 @@ -/* $NetBSD: lstForEachFrom.c,v 1.17 2009/01/23 21:26:30 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstForEachFrom.c,v 1.17 2009/01/23 21:26:30 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstForEachFrom.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstForEachFrom.c,v 1.17 2009/01/23 21:26:30 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * lstForEachFrom.c -- - * Perform a given function on all elements of a list starting from - * a given point. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_ForEachFrom -- - * Apply the given function to each element of the given list. The - * function should return 0 if traversal should continue and non- - * zero if it should abort. - * - * Results: - * None. - * - * Side Effects: - * Only those created by the passed-in function. - * - *----------------------------------------------------------------------- - */ -/*VARARGS2*/ -int -Lst_ForEachFrom(Lst l, LstNode ln, int (*proc)(void *, void *), - void *d) -{ - ListNode tln = ln; - List list = l; - ListNode next; - Boolean done; - int result; - - if (!LstValid (list) || LstIsEmpty (list)) { - return 0; - } - - do { - /* - * Take care of having the current element deleted out from under - * us. - */ - - next = tln->nextPtr; - - /* - * We're done with the traversal if - * - the next node to examine is the first in the queue or - * doesn't exist and - * - nothing's been added after the current node (check this - * after proc() has been called). - */ - done = (next == NULL || next == list->firstPtr); - - (void) tln->useCount++; - result = (*proc) (tln->datum, d); - (void) tln->useCount--; - - /* - * Now check whether a node has been added. - * Note: this doesn't work if this node was deleted before - * the new node was added. - */ - if (next != tln->nextPtr) { - next = tln->nextPtr; - done = 0; - } - - if (tln->flags & LN_DELETED) { - free((char *)tln); - } - tln = next; - } while (!result && !LstIsEmpty(list) && !done); - - return result; -} - diff --git a/20120831/lst.lib/lstInit.c b/20120831/lst.lib/lstInit.c deleted file mode 100644 index f98ac42..0000000 --- a/20120831/lst.lib/lstInit.c +++ /dev/null @@ -1,85 +0,0 @@ -/* $NetBSD: lstInit.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstInit.c,v 1.12 2008/12/13 15:19:29 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstInit.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstInit.c,v 1.12 2008/12/13 15:19:29 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * init.c -- - * Initialize a new linked list. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Init -- - * Create and initialize a new list. - * - * Input: - * circ TRUE if the list should be made circular - * - * Results: - * The created list. - * - * Side Effects: - * A list is created, what else? - * - *----------------------------------------------------------------------- - */ -Lst -Lst_Init(Boolean circ) -{ - List nList; - - PAlloc (nList, List); - - nList->firstPtr = NULL; - nList->lastPtr = NULL; - nList->isOpen = FALSE; - nList->isCirc = circ; - nList->atEnd = Unknown; - - return (nList); -} diff --git a/20120831/lst.lib/lstInsert.c b/20120831/lst.lib/lstInsert.c deleted file mode 100644 index 77187bb..0000000 --- a/20120831/lst.lib/lstInsert.c +++ /dev/null @@ -1,122 +0,0 @@ -/* $NetBSD: lstInsert.c,v 1.14 2009/01/23 21:26:30 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstInsert.c,v 1.14 2009/01/23 21:26:30 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstInsert.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstInsert.c,v 1.14 2009/01/23 21:26:30 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstInsert.c -- - * Insert a new datum before an old one - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_InsertBefore -- - * Insert a new node with the given piece of data before the given - * node in the given list. - * - * Input: - * l list to manipulate - * ln node before which to insert d - * d datum to be inserted - * - * Results: - * SUCCESS or FAILURE. - * - * Side Effects: - * the firstPtr field will be changed if ln is the first node in the - * list. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_InsertBefore(Lst l, LstNode ln, void *d) -{ - ListNode nLNode; /* new lnode for d */ - ListNode lNode = ln; - List list = l; - - - /* - * check validity of arguments - */ - if (LstValid (l) && (LstIsEmpty (l) && ln == NULL)) - goto ok; - - if (!LstValid (l) || LstIsEmpty (l) || !LstNodeValid (ln, l)) { - return (FAILURE); - } - - ok: - PAlloc (nLNode, ListNode); - - nLNode->datum = d; - nLNode->useCount = nLNode->flags = 0; - - if (ln == NULL) { - if (list->isCirc) { - nLNode->prevPtr = nLNode->nextPtr = nLNode; - } else { - nLNode->prevPtr = nLNode->nextPtr = NULL; - } - list->firstPtr = list->lastPtr = nLNode; - } else { - nLNode->prevPtr = lNode->prevPtr; - nLNode->nextPtr = lNode; - - if (nLNode->prevPtr != NULL) { - nLNode->prevPtr->nextPtr = nLNode; - } - lNode->prevPtr = nLNode; - - if (lNode == list->firstPtr) { - list->firstPtr = nLNode; - } - } - - return (SUCCESS); -} - diff --git a/20120831/lst.lib/lstInt.h b/20120831/lst.lib/lstInt.h deleted file mode 100644 index 34a2fbd..0000000 --- a/20120831/lst.lib/lstInt.h +++ /dev/null @@ -1,105 +0,0 @@ -/* $NetBSD: lstInt.h,v 1.20 2009/01/24 14:43:29 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)lstInt.h 8.1 (Berkeley) 6/6/93 - */ - -/*- - * lstInt.h -- - * Internals for the list library - */ -#ifndef _LSTINT_H_ -#define _LSTINT_H_ - -#include "../lst.h" -#include "../make_malloc.h" - -typedef struct ListNode { - struct ListNode *prevPtr; /* previous element in list */ - struct ListNode *nextPtr; /* next in list */ - unsigned int useCount:8, /* Count of functions using the node. - * node may not be deleted until count - * goes to 0 */ - flags:8; /* Node status flags */ - void *datum; /* datum associated with this element */ -} *ListNode; -/* - * Flags required for synchronization - */ -#define LN_DELETED 0x0001 /* List node should be removed when done */ - -typedef enum { - Head, Middle, Tail, Unknown -} Where; - -typedef struct List { - ListNode firstPtr; /* first node in list */ - ListNode lastPtr; /* last node in list */ - Boolean isCirc; /* true if the list should be considered - * circular */ -/* - * fields for sequential access - */ - Where atEnd; /* Where in the list the last access was */ - Boolean isOpen; /* true if list has been Lst_Open'ed */ - ListNode curPtr; /* current node, if open. NULL if - * *just* opened */ - ListNode prevPtr; /* Previous node, if open. Used by - * Lst_Remove */ -} *List; - -/* - * PAlloc (var, ptype) -- - * Allocate a pointer-typedef structure 'ptype' into the variable 'var' - */ -#define PAlloc(var,ptype) var = (ptype) bmake_malloc(sizeof *(var)) - -/* - * LstValid (l) -- - * Return TRUE if the list l is valid - */ -#define LstValid(l) ((Lst)(l) != NULL) - -/* - * LstNodeValid (ln, l) -- - * Return TRUE if the LstNode ln is valid with respect to l - */ -#define LstNodeValid(ln, l) ((ln) != NULL) - -/* - * LstIsEmpty (l) -- - * TRUE if the list l is empty. - */ -#define LstIsEmpty(l) (((List)(l))->firstPtr == NULL) - -#endif /* _LSTINT_H_ */ diff --git a/20120831/lst.lib/lstIsAtEnd.c b/20120831/lst.lib/lstIsAtEnd.c deleted file mode 100644 index 70270d2..0000000 --- a/20120831/lst.lib/lstIsAtEnd.c +++ /dev/null @@ -1,87 +0,0 @@ -/* $NetBSD: lstIsAtEnd.c,v 1.13 2008/02/15 21:29:50 christos Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstIsAtEnd.c,v 1.13 2008/02/15 21:29:50 christos Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstIsAtEnd.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstIsAtEnd.c,v 1.13 2008/02/15 21:29:50 christos Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstIsAtEnd.c -- - * Tell if the current node is at the end of the list. - * The sequential functions access the list in a slightly different way. - * CurPtr points to their idea of the current node in the list and they - * access the list based on it. Because the list is circular, Lst_Next - * and Lst_Prev will go around the list forever. Lst_IsAtEnd must be - * used to determine when to stop. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_IsAtEnd -- - * Return true if have reached the end of the given list. - * - * Results: - * TRUE if at the end of the list (this includes the list not being - * open or being invalid) or FALSE if not. We return TRUE if the list - * is invalid or unopend so as to cause the caller to exit its loop - * asap, the assumption being that the loop is of the form - * while (!Lst_IsAtEnd (l)) { - * ... - * } - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -Boolean -Lst_IsAtEnd(Lst l) -{ - List list = l; - - return (!LstValid (l) || !list->isOpen || - (list->atEnd == Head) || (list->atEnd == Tail)); -} - diff --git a/20120831/lst.lib/lstIsEmpty.c b/20120831/lst.lib/lstIsEmpty.c deleted file mode 100644 index 8b1d6ed..0000000 --- a/20120831/lst.lib/lstIsEmpty.c +++ /dev/null @@ -1,75 +0,0 @@ -/* $NetBSD: lstIsEmpty.c,v 1.11 2008/12/13 15:19:29 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstIsEmpty.c,v 1.11 2008/12/13 15:19:29 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstIsEmpty.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstIsEmpty.c,v 1.11 2008/12/13 15:19:29 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstIsEmpty.c -- - * A single function to decide if a list is empty - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_IsEmpty -- - * Return TRUE if the given list is empty. - * - * Results: - * TRUE if the list is empty, FALSE otherwise. - * - * Side Effects: - * None. - * - * A list is considered empty if its firstPtr == NULL (or if - * the list itself is NULL). - *----------------------------------------------------------------------- - */ -Boolean -Lst_IsEmpty(Lst l) -{ - return ( ! LstValid (l) || LstIsEmpty(l)); -} - diff --git a/20120831/lst.lib/lstLast.c b/20120831/lst.lib/lstLast.c deleted file mode 100644 index 096ca24..0000000 --- a/20120831/lst.lib/lstLast.c +++ /dev/null @@ -1,77 +0,0 @@ -/* $NetBSD: lstLast.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstLast.c,v 1.12 2008/12/13 15:19:29 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstLast.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstLast.c,v 1.12 2008/12/13 15:19:29 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstLast.c -- - * Return the last element of a list - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Last -- - * Return the last node on the list l. - * - * Results: - * The requested node or NULL if the list is empty. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -LstNode -Lst_Last(Lst l) -{ - if (!LstValid(l) || LstIsEmpty (l)) { - return NULL; - } else { - return (l->lastPtr); - } -} - diff --git a/20120831/lst.lib/lstMember.c b/20120831/lst.lib/lstMember.c deleted file mode 100644 index 0ff2ed1..0000000 --- a/20120831/lst.lib/lstMember.c +++ /dev/null @@ -1,74 +0,0 @@ -/* $NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstMember.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * lstMember.c -- - * See if a given datum is on a given list. - */ - -#include "lstInt.h" - -LstNode -Lst_Member(Lst l, void *d) -{ - List list = l; - ListNode lNode; - - lNode = list->firstPtr; - if (lNode == NULL) { - return NULL; - } - - do { - if (lNode->datum == d) { - return lNode; - } - lNode = lNode->nextPtr; - } while (lNode != NULL && lNode != list->firstPtr); - - return NULL; -} diff --git a/20120831/lst.lib/lstNext.c b/20120831/lst.lib/lstNext.c deleted file mode 100644 index 5c2e0ee..0000000 --- a/20120831/lst.lib/lstNext.c +++ /dev/null @@ -1,120 +0,0 @@ -/* $NetBSD: lstNext.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstNext.c,v 1.12 2008/12/13 15:19:29 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstNext.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstNext.c,v 1.12 2008/12/13 15:19:29 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstNext.c -- - * Return the next node for a list. - * The sequential functions access the list in a slightly different way. - * CurPtr points to their idea of the current node in the list and they - * access the list based on it. Because the list is circular, Lst_Next - * and Lst_Prev will go around the list forever. Lst_IsAtEnd must be - * used to determine when to stop. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Next -- - * Return the next node for the given list. - * - * Results: - * The next node or NULL if the list has yet to be opened. Also - * if the list is non-circular and the end has been reached, NULL - * is returned. - * - * Side Effects: - * the curPtr field is updated. - * - *----------------------------------------------------------------------- - */ -LstNode -Lst_Next(Lst l) -{ - ListNode tln; - List list = l; - - if ((LstValid (l) == FALSE) || - (list->isOpen == FALSE)) { - return NULL; - } - - list->prevPtr = list->curPtr; - - if (list->curPtr == NULL) { - if (list->atEnd == Unknown) { - /* - * If we're just starting out, atEnd will be Unknown. - * Then we want to start this thing off in the right - * direction -- at the start with atEnd being Middle. - */ - list->curPtr = tln = list->firstPtr; - list->atEnd = Middle; - } else { - tln = NULL; - list->atEnd = Tail; - } - } else { - tln = list->curPtr->nextPtr; - list->curPtr = tln; - - if (tln == list->firstPtr || tln == NULL) { - /* - * If back at the front, then we've hit the end... - */ - list->atEnd = Tail; - } else { - /* - * Reset to Middle if gone past first. - */ - list->atEnd = Middle; - } - } - - return (tln); -} - diff --git a/20120831/lst.lib/lstOpen.c b/20120831/lst.lib/lstOpen.c deleted file mode 100644 index 941293e..0000000 --- a/20120831/lst.lib/lstOpen.c +++ /dev/null @@ -1,87 +0,0 @@ -/* $NetBSD: lstOpen.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstOpen.c,v 1.12 2008/12/13 15:19:29 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstOpen.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstOpen.c,v 1.12 2008/12/13 15:19:29 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstOpen.c -- - * Open a list for sequential access. The sequential functions access the - * list in a slightly different way. CurPtr points to their idea of the - * current node in the list and they access the list based on it. - * If the list is circular, Lst_Next and Lst_Prev will go around - * the list forever. Lst_IsAtEnd must be used to determine when to stop. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Open -- - * Open a list for sequential access. A list can still be searched, - * etc., without confusing these functions. - * - * Results: - * SUCCESS or FAILURE. - * - * Side Effects: - * isOpen is set TRUE and curPtr is set to NULL so the - * other sequential functions no it was just opened and can choose - * the first element accessed based on this. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_Open(Lst l) -{ - if (LstValid (l) == FALSE) { - return (FAILURE); - } - (l)->isOpen = TRUE; - (l)->atEnd = LstIsEmpty (l) ? Head : Unknown; - (l)->curPtr = NULL; - - return (SUCCESS); -} - diff --git a/20120831/lst.lib/lstPrev.c b/20120831/lst.lib/lstPrev.c deleted file mode 100644 index 0ec865d..0000000 --- a/20120831/lst.lib/lstPrev.c +++ /dev/null @@ -1,79 +0,0 @@ -/* $NetBSD: lstPrev.c,v 1.3 2008/12/13 15:19:29 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstPrev.c,v 1.3 2008/12/13 15:19:29 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstPrev.c,v 1.3 2008/12/13 15:19:29 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstPrev.c -- - * return the predecessor to a given node - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Prev -- - * Return the predecessor to the given node on its list. - * - * Results: - * The predecessor of the node, if it exists (note that on a circular - * list, if the node is the only one in the list, it is its own - * predecessor). - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -LstNode -Lst_Prev(LstNode ln) -{ - if (ln == NULL) { - return NULL; - } else { - return (ln->prevPtr); - } -} - diff --git a/20120831/lst.lib/lstRemove.c b/20120831/lst.lib/lstRemove.c deleted file mode 100644 index 54d7b33..0000000 --- a/20120831/lst.lib/lstRemove.c +++ /dev/null @@ -1,136 +0,0 @@ -/* $NetBSD: lstRemove.c,v 1.14 2008/12/13 15:19:29 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstRemove.c,v 1.14 2008/12/13 15:19:29 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstRemove.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstRemove.c,v 1.14 2008/12/13 15:19:29 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstRemove.c -- - * Remove an element from a list - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Remove -- - * Remove the given node from the given list. - * - * Results: - * SUCCESS or FAILURE. - * - * Side Effects: - * The list's firstPtr will be set to NULL if ln is the last - * node on the list. firsPtr and lastPtr will be altered if ln is - * either the first or last node, respectively, on the list. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_Remove(Lst l, LstNode ln) -{ - List list = l; - ListNode lNode = ln; - - if (!LstValid (l) || - !LstNodeValid (ln, l)) { - return (FAILURE); - } - - /* - * unlink it from the list - */ - if (lNode->nextPtr != NULL) { - lNode->nextPtr->prevPtr = lNode->prevPtr; - } - if (lNode->prevPtr != NULL) { - lNode->prevPtr->nextPtr = lNode->nextPtr; - } - - /* - * if either the firstPtr or lastPtr of the list point to this node, - * adjust them accordingly - */ - if (list->firstPtr == lNode) { - list->firstPtr = lNode->nextPtr; - } - if (list->lastPtr == lNode) { - list->lastPtr = lNode->prevPtr; - } - - /* - * Sequential access stuff. If the node we're removing is the current - * node in the list, reset the current node to the previous one. If the - * previous one was non-existent (prevPtr == NULL), we set the - * end to be Unknown, since it is. - */ - if (list->isOpen && (list->curPtr == lNode)) { - list->curPtr = list->prevPtr; - if (list->curPtr == NULL) { - list->atEnd = Unknown; - } - } - - /* - * the only way firstPtr can still point to ln is if ln is the last - * node on the list (the list is circular, so lNode->nextptr == lNode in - * this case). The list is, therefore, empty and is marked as such - */ - if (list->firstPtr == lNode) { - list->firstPtr = NULL; - } - - /* - * note that the datum is unmolested. The caller must free it as - * necessary and as expected. - */ - if (lNode->useCount == 0) { - free(ln); - } else { - lNode->flags |= LN_DELETED; - } - - return (SUCCESS); -} - diff --git a/20120831/lst.lib/lstReplace.c b/20120831/lst.lib/lstReplace.c deleted file mode 100644 index 090e91a..0000000 --- a/20120831/lst.lib/lstReplace.c +++ /dev/null @@ -1,78 +0,0 @@ -/* $NetBSD: lstReplace.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstReplace.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstReplace.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstReplace.c,v 1.13 2009/01/23 21:26:30 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstReplace.c -- - * Replace the datum in a node with a new datum - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Replace -- - * Replace the datum in the given node with the new datum - * - * Results: - * SUCCESS or FAILURE. - * - * Side Effects: - * The datum field fo the node is altered. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_Replace(LstNode ln, void *d) -{ - if (ln == NULL) { - return (FAILURE); - } else { - (ln)->datum = d; - return (SUCCESS); - } -} - diff --git a/20120831/lst.lib/lstSucc.c b/20120831/lst.lib/lstSucc.c deleted file mode 100644 index 3f13aa5..0000000 --- a/20120831/lst.lib/lstSucc.c +++ /dev/null @@ -1,79 +0,0 @@ -/* $NetBSD: lstSucc.c,v 1.13 2008/12/13 15:19:29 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstSucc.c,v 1.13 2008/12/13 15:19:29 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstSucc.c,v 1.13 2008/12/13 15:19:29 dsl Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstSucc.c -- - * return the successor to a given node - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Succ -- - * Return the successor to the given node on its list. - * - * Results: - * The successor of the node, if it exists (note that on a circular - * list, if the node is the only one in the list, it is its own - * successor). - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -LstNode -Lst_Succ(LstNode ln) -{ - if (ln == NULL) { - return NULL; - } else { - return (ln->nextPtr); - } -} - diff --git a/20120831/machine.sh b/20120831/machine.sh deleted file mode 100755 index 32a0f7a..0000000 --- a/20120831/machine.sh +++ /dev/null @@ -1,96 +0,0 @@ -: -# derrived from /etc/rc_d/os.sh - -# RCSid: -# $Id: machine.sh,v 1.16 2010/10/17 00:05:51 sjg Exp $ -# -# @(#) Copyright (c) 1994-2002 Simon J. Gerraty -# -# This file is provided in the hope that it will -# be of use. There is absolutely NO WARRANTY. -# Permission to copy, redistribute or otherwise -# use this file is hereby granted provided that -# the above copyright notice and this notice are -# left intact. -# -# Please send copies of changes and bug-fixes to: -# sjg@crufty.net -# - -OS=`uname` -OSREL=`uname -r` -OSMAJOR=`IFS=.; set $OSREL; echo $1` -machine=`uname -p 2>/dev/null || uname -m` -MACHINE= - -# there is at least one case of `uname -p` outputting -# a bunch of usless drivel -case "$machine" in -unknown|*[!A-Za-z0-9_-]*) - machine=`uname -m` - ;; -esac - -# Great! Solaris keeps moving arch(1) -# we need this here, and it is not always available... -Which() { - # some shells cannot correctly handle `IFS` - # in conjunction with the for loop. - _dirs=`IFS=:; echo ${2:-$PATH}` - for d in $_dirs - do - test -x $d/$1 && { echo $d/$1; break; } - done -} - -case $OS in -OpenBSD) - MACHINE=$OS$OSMAJOR.$machine - arch=`Which arch /usr/bin:/usr/ucb:$PATH` - MACHINE_ARCH=`$arch -s`; - ;; -*BSD) - MACHINE=$OS$OSMAJOR.$machine - ;; -SunOS) - arch=`Which arch /usr/bin:/usr/ucb:$PATH` - test "$arch" && machine_arch=`$arch` - - case "$OSREL" in - 4.0*) MACHINE_ARCH=$machine_arch MACHINE=$machine_arch;; - 4*) MACHINE_ARCH=$machine_arch;; - esac - ;; -HP-UX) - MACHINE_ARCH=`IFS="/-."; set $machine; echo $1` - ;; -Interix) - MACHINE=i386 - MACHINE_ARCH=i386 - ;; -UnixWare) - OSREL=`uname -v` - OSMAJOR=`IFS=.; set $OSREL; echo $1` - MACHINE_ARCH=`uname -m` - ;; -Linux) - case "$machine" in - i?86) MACHINE_ARCH=i386;;# does anyone really care about 686 vs 586? - esac - ;; -esac - -MACHINE=${MACHINE:-$OS$OSMAJOR} -MACHINE_ARCH=${MACHINE_ARCH:-$machine} - -( -case "$0" in -arch*) echo $MACHINE_ARCH;; -*) - case "$1" in - "") echo $MACHINE;; - *) echo $MACHINE_ARCH;; - esac - ;; -esac -) | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz diff --git a/20120831/main.c b/20120831/main.c deleted file mode 100644 index 085c534..0000000 --- a/20120831/main.c +++ /dev/null @@ -1,2078 +0,0 @@ -/* $NetBSD: main.c,v 1.200 2012/06/12 19:21:51 joerg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: main.c,v 1.200 2012/06/12 19:21:51 joerg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\ - The Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94"; -#else -__RCSID("$NetBSD: main.c,v 1.200 2012/06/12 19:21:51 joerg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * main.c -- - * The main file for this entire program. Exit routines etc - * reside here. - * - * Utility functions defined in this file: - * Main_ParseArgLine Takes a line of arguments, breaks them and - * treats them as if they were given when first - * invoked. Used by the parse module to implement - * the .MFLAGS target. - * - * Error Print a tagged error message. The global - * MAKE variable must have been defined. This - * takes a format string and two optional - * arguments for it. - * - * Fatal Print an error message and exit. Also takes - * a format string and two arguments. - * - * Punt Aborts all jobs and exits with a message. Also - * takes a format string and two arguments. - * - * Finish Finish things up by printing the number of - * errors which occurred, as passed to it, and - * exiting. - */ - -#include <sys/types.h> -#include <sys/time.h> -#include <sys/param.h> -#include <sys/resource.h> -#include <signal.h> -#include <sys/stat.h> -#ifdef MAKE_NATIVE -#include <sys/utsname.h> -#endif -#include "wait.h" - -#include <errno.h> -#include <fcntl.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <time.h> - -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "job.h" -#include "pathnames.h" -#include "trace.h" - -#ifdef USE_IOVEC -#include <sys/uio.h> -#endif - -#ifndef DEFMAXLOCAL -#define DEFMAXLOCAL DEFMAXJOBS -#endif /* DEFMAXLOCAL */ - -Lst create; /* Targets to be made */ -time_t now; /* Time at start of make */ -GNode *DEFAULT; /* .DEFAULT node */ -Boolean allPrecious; /* .PRECIOUS given on line by itself */ - -static Boolean noBuiltins; /* -r flag */ -static Lst makefiles; /* ordered list of makefiles to read */ -static Boolean printVars; /* print value of one or more vars */ -static Lst variables; /* list of variables to print */ -int maxJobs; /* -j argument */ -static int maxJobTokens; /* -j argument */ -Boolean compatMake; /* -B argument */ -int debug; /* -d argument */ -Boolean noExecute; /* -n flag */ -Boolean noRecursiveExecute; /* -N flag */ -Boolean keepgoing; /* -k flag */ -Boolean queryFlag; /* -q flag */ -Boolean touchFlag; /* -t flag */ -Boolean ignoreErrors; /* -i flag */ -Boolean beSilent; /* -s flag */ -Boolean oldVars; /* variable substitution style */ -Boolean checkEnvFirst; /* -e flag */ -Boolean parseWarnFatal; /* -W flag */ -Boolean jobServer; /* -J flag */ -static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */ -Boolean varNoExportEnv; /* -X flag */ -Boolean doing_depend; /* Set while reading .depend */ -static Boolean jobsRunning; /* TRUE if the jobs might be running */ -static const char * tracefile; -#ifndef NO_CHECK_MAKE_CHDIR -static char * Check_Cwd_av(int, char **, int); -#endif -static void MainParseArgs(int, char **); -static int ReadMakefile(const void *, const void *); -static void usage(void) MAKE_ATTR_DEAD; - -static Boolean ignorePWD; /* if we use -C, PWD is meaningless */ -static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */ -char curdir[MAXPATHLEN + 1]; /* Startup directory */ -char *progname; /* the program name */ -char *makeDependfile; -pid_t myPid; - -Boolean forceJobs = FALSE; - -/* - * On some systems MACHINE is defined as something other than - * what we want. - */ -#ifdef FORCE_MACHINE -# undef MACHINE -# define MACHINE FORCE_MACHINE -#endif - -extern Lst parseIncPath; - -static void -parse_debug_options(const char *argvalue) -{ - const char *modules; - const char *mode; - char *fname; - int len; - - for (modules = argvalue; *modules; ++modules) { - switch (*modules) { - case 'A': - debug = ~0; - break; - case 'a': - debug |= DEBUG_ARCH; - break; - case 'C': - debug |= DEBUG_CWD; - break; - case 'c': - debug |= DEBUG_COND; - break; - case 'd': - debug |= DEBUG_DIR; - break; - case 'e': - debug |= DEBUG_ERROR; - break; - case 'f': - debug |= DEBUG_FOR; - break; - case 'g': - if (modules[1] == '1') { - debug |= DEBUG_GRAPH1; - ++modules; - } - else if (modules[1] == '2') { - debug |= DEBUG_GRAPH2; - ++modules; - } - else if (modules[1] == '3') { - debug |= DEBUG_GRAPH3; - ++modules; - } - break; - case 'j': - debug |= DEBUG_JOB; - break; - case 'l': - debug |= DEBUG_LOUD; - break; - case 'M': - debug |= DEBUG_META; - break; - case 'm': - debug |= DEBUG_MAKE; - break; - case 'n': - debug |= DEBUG_SCRIPT; - break; - case 'p': - debug |= DEBUG_PARSE; - break; - case 's': - debug |= DEBUG_SUFF; - break; - case 't': - debug |= DEBUG_TARG; - break; - case 'v': - debug |= DEBUG_VAR; - break; - case 'x': - debug |= DEBUG_SHELL; - break; - case 'F': - if (debug_file != stdout && debug_file != stderr) - fclose(debug_file); - if (*++modules == '+') { - modules++; - mode = "a"; - } else - mode = "w"; - if (strcmp(modules, "stdout") == 0) { - debug_file = stdout; - goto debug_setbuf; - } - if (strcmp(modules, "stderr") == 0) { - debug_file = stderr; - goto debug_setbuf; - } - len = strlen(modules); - fname = malloc(len + 20); - memcpy(fname, modules, len + 1); - /* Let the filename be modified by the pid */ - if (strcmp(fname + len - 3, ".%d") == 0) - snprintf(fname + len - 2, 20, "%d", getpid()); - debug_file = fopen(fname, mode); - if (!debug_file) { - fprintf(stderr, "Cannot open debug file %s\n", - fname); - usage(); - } - free(fname); - goto debug_setbuf; - default: - (void)fprintf(stderr, - "%s: illegal argument to d option -- %c\n", - progname, *modules); - usage(); - } - } -debug_setbuf: - /* - * Make the debug_file unbuffered, and make - * stdout line buffered (unless debugfile == stdout). - */ - setvbuf(debug_file, NULL, _IONBF, 0); - if (debug_file != stdout) { - setvbuf(stdout, NULL, _IOLBF, 0); - } -} - -/*- - * MainParseArgs -- - * Parse a given argument vector. Called from main() and from - * Main_ParseArgLine() when the .MAKEFLAGS target is used. - * - * XXX: Deal with command line overriding .MAKEFLAGS in makefile - * - * Results: - * None - * - * Side Effects: - * Various global and local flags will be set depending on the flags - * given - */ -static void -MainParseArgs(int argc, char **argv) -{ - char *p; - int c = '?'; - int arginc; - char *argvalue; - const char *getopt_def; - char *optscan; - Boolean inOption, dashDash = FALSE; - char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */ - -#define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrst" -/* Can't actually use getopt(3) because rescanning is not portable */ - - getopt_def = OPTFLAGS; -rearg: - inOption = FALSE; - optscan = NULL; - while(argc > 1) { - char *getopt_spec; - if(!inOption) - optscan = argv[1]; - c = *optscan++; - arginc = 0; - if(inOption) { - if(c == '\0') { - ++argv; - --argc; - inOption = FALSE; - continue; - } - } else { - if (c != '-' || dashDash) - break; - inOption = TRUE; - c = *optscan++; - } - /* '-' found at some earlier point */ - getopt_spec = strchr(getopt_def, c); - if(c != '\0' && getopt_spec != NULL && getopt_spec[1] == ':') { - /* -<something> found, and <something> should have an arg */ - inOption = FALSE; - arginc = 1; - argvalue = optscan; - if(*argvalue == '\0') { - if (argc < 3) - goto noarg; - argvalue = argv[2]; - arginc = 2; - } - } else { - argvalue = NULL; - } - switch(c) { - case '\0': - arginc = 1; - inOption = FALSE; - break; - case 'B': - compatMake = TRUE; - Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL); - Var_Set(MAKE_MODE, "compat", VAR_GLOBAL, 0); - break; - case 'C': - if (chdir(argvalue) == -1) { - (void)fprintf(stderr, - "%s: chdir %s: %s\n", - progname, argvalue, - strerror(errno)); - exit(1); - } - if (getcwd(curdir, MAXPATHLEN) == NULL) { - (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno)); - exit(2); - } - ignorePWD = TRUE; - break; - case 'D': - if (argvalue == NULL || argvalue[0] == 0) goto noarg; - Var_Set(argvalue, "1", VAR_GLOBAL, 0); - Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - break; - case 'I': - if (argvalue == NULL) goto noarg; - Parse_AddIncludeDir(argvalue); - Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - break; - case 'J': - if (argvalue == NULL) goto noarg; - if (sscanf(argvalue, "%d,%d", &jp_0, &jp_1) != 2) { - (void)fprintf(stderr, - "%s: internal error -- J option malformed (%s)\n", - progname, argvalue); - usage(); - } - if ((fcntl(jp_0, F_GETFD, 0) < 0) || - (fcntl(jp_1, F_GETFD, 0) < 0)) { -#if 0 - (void)fprintf(stderr, - "%s: ###### warning -- J descriptors were closed!\n", - progname); - exit(2); -#endif - jp_0 = -1; - jp_1 = -1; - compatMake = TRUE; - } else { - Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - jobServer = TRUE; - } - break; - case 'N': - noExecute = TRUE; - noRecursiveExecute = TRUE; - Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL); - break; - case 'S': - keepgoing = FALSE; - Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL); - break; - case 'T': - if (argvalue == NULL) goto noarg; - tracefile = bmake_strdup(argvalue); - Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - break; - case 'V': - if (argvalue == NULL) goto noarg; - printVars = TRUE; - (void)Lst_AtEnd(variables, argvalue); - Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - break; - case 'W': - parseWarnFatal = TRUE; - break; - case 'X': - varNoExportEnv = TRUE; - Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL); - break; - case 'd': - if (argvalue == NULL) goto noarg; - /* If '-d-opts' don't pass to children */ - if (argvalue[0] == '-') - argvalue++; - else { - Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - } - parse_debug_options(argvalue); - break; - case 'e': - checkEnvFirst = TRUE; - Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL); - break; - case 'f': - if (argvalue == NULL) goto noarg; - (void)Lst_AtEnd(makefiles, argvalue); - break; - case 'i': - ignoreErrors = TRUE; - Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL); - break; - case 'j': - if (argvalue == NULL) goto noarg; - forceJobs = TRUE; - maxJobs = strtol(argvalue, &p, 0); - if (*p != '\0' || maxJobs < 1) { - (void)fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n", - progname); - exit(1); - } - Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL, 0); - maxJobTokens = maxJobs; - break; - case 'k': - keepgoing = TRUE; - Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL); - break; - case 'm': - if (argvalue == NULL) goto noarg; - /* look for magic parent directory search string */ - if (strncmp(".../", argvalue, 4) == 0) { - if (!Dir_FindHereOrAbove(curdir, argvalue+4, - found_path, sizeof(found_path))) - break; /* nothing doing */ - (void)Dir_AddDir(sysIncPath, found_path); - } else { - (void)Dir_AddDir(sysIncPath, argvalue); - } - Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - break; - case 'n': - noExecute = TRUE; - Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL); - break; - case 'q': - queryFlag = TRUE; - /* Kind of nonsensical, wot? */ - Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL); - break; - case 'r': - noBuiltins = TRUE; - Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL); - break; - case 's': - beSilent = TRUE; - Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL); - break; - case 't': - touchFlag = TRUE; - Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL); - break; - case '-': - dashDash = TRUE; - break; - default: - case '?': -#ifndef MAKE_NATIVE - fprintf(stderr, "getopt(%s) -> %d (%c)\n", - OPTFLAGS, c, c); -#endif - usage(); - } - argv += arginc; - argc -= arginc; - } - - oldVars = TRUE; - - /* - * See if the rest of the arguments are variable assignments and - * perform them if so. Else take them to be targets and stuff them - * on the end of the "create" list. - */ - for (; argc > 1; ++argv, --argc) - if (Parse_IsVar(argv[1])) { - Parse_DoVar(argv[1], VAR_CMD); - } else { - if (!*argv[1]) - Punt("illegal (null) argument."); - if (*argv[1] == '-' && !dashDash) - goto rearg; - (void)Lst_AtEnd(create, bmake_strdup(argv[1])); - } - - return; -noarg: - (void)fprintf(stderr, "%s: option requires an argument -- %c\n", - progname, c); - usage(); -} - -/*- - * Main_ParseArgLine -- - * Used by the parse module when a .MFLAGS or .MAKEFLAGS target - * is encountered and by main() when reading the .MAKEFLAGS envariable. - * Takes a line of arguments and breaks it into its - * component words and passes those words and the number of them to the - * MainParseArgs function. - * The line should have all its leading whitespace removed. - * - * Input: - * line Line to fracture - * - * Results: - * None - * - * Side Effects: - * Only those that come from the various arguments. - */ -void -Main_ParseArgLine(const char *line) -{ - char **argv; /* Manufactured argument vector */ - int argc; /* Number of arguments in argv */ - char *args; /* Space used by the args */ - char *buf, *p1; - char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1); - size_t len; - - if (line == NULL) - return; - for (; *line == ' '; ++line) - continue; - if (!*line) - return; - -#ifndef POSIX - { - /* - * $MAKE may simply be naming the make(1) binary - */ - char *cp; - - if (!(cp = strrchr(line, '/'))) - cp = line; - if ((cp = strstr(cp, "make")) && - strcmp(cp, "make") == 0) - return; - } -#endif - buf = bmake_malloc(len = strlen(line) + strlen(argv0) + 2); - (void)snprintf(buf, len, "%s %s", argv0, line); - if (p1) - free(p1); - - argv = brk_string(buf, &argc, TRUE, &args); - if (argv == NULL) { - Error("Unterminated quoted string [%s]", buf); - free(buf); - return; - } - free(buf); - MainParseArgs(argc, argv); - - free(args); - free(argv); -} - -Boolean -Main_SetObjdir(const char *path) -{ - struct stat sb; - char *p = NULL; - char buf[MAXPATHLEN + 1]; - Boolean rc = FALSE; - - /* expand variable substitutions */ - if (strchr(path, '$') != 0) { - snprintf(buf, MAXPATHLEN, "%s", path); - path = p = Var_Subst(NULL, buf, VAR_GLOBAL, 0); - } - - if (path[0] != '/') { - snprintf(buf, MAXPATHLEN, "%s/%s", curdir, path); - path = buf; - } - - /* look for the directory and try to chdir there */ - if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { - if (chdir(path)) { - (void)fprintf(stderr, "make warning: %s: %s.\n", - path, strerror(errno)); - } else { - strncpy(objdir, path, MAXPATHLEN); - Var_Set(".OBJDIR", objdir, VAR_GLOBAL, 0); - setenv("PWD", objdir, 1); - Dir_InitDot(); - rc = TRUE; - } - } - - if (p) - free(p); - return rc; -} - -/*- - * ReadAllMakefiles -- - * wrapper around ReadMakefile() to read all. - * - * Results: - * TRUE if ok, FALSE on error - */ -static int -ReadAllMakefiles(const void *p, const void *q) -{ - return (ReadMakefile(p, q) == 0); -} - -int -str2Lst_Append(Lst lp, char *str, const char *sep) -{ - char *cp; - int n; - - if (!sep) - sep = " \t"; - - for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) { - (void)Lst_AtEnd(lp, cp); - n++; - } - return (n); -} - -#ifdef SIGINFO -/*ARGSUSED*/ -static void -siginfo(int signo MAKE_ATTR_UNUSED) -{ - char dir[MAXPATHLEN]; - char str[2 * MAXPATHLEN]; - int len; - if (getcwd(dir, sizeof(dir)) == NULL) - return; - len = snprintf(str, sizeof(str), "%s: Working in: %s\n", progname, dir); - if (len > 0) - (void)write(STDERR_FILENO, str, (size_t)len); -} -#endif - -/* - * Allow makefiles some control over the mode we run in. - */ -void -MakeMode(const char *mode) -{ - char *mp = NULL; - - if (!mode) - mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}", VAR_GLOBAL, 0); - - if (mode && *mode) { - if (strstr(mode, "compat")) { - compatMake = TRUE; - forceJobs = FALSE; - } -#if USE_META - if (strstr(mode, "meta")) - meta_init(mode); -#endif - } - if (mp) - free(mp); -} - -/*- - * main -- - * The main function, for obvious reasons. Initializes variables - * and a few modules, then parses the arguments give it in the - * environment and on the command line. Reads the system makefile - * followed by either Makefile, makefile or the file given by the - * -f argument. Sets the .MAKEFLAGS PMake variable based on all the - * flags it has received by then uses either the Make or the Compat - * module to create the initial list of targets. - * - * Results: - * If -q was given, exits -1 if anything was out-of-date. Else it exits - * 0. - * - * Side Effects: - * The program exits when done. Targets are created. etc. etc. etc. - */ -int -main(int argc, char **argv) -{ - Lst targs; /* target nodes to create -- passed to Make_Init */ - Boolean outOfDate = FALSE; /* FALSE if all targets up to date */ - struct stat sb, sa; - char *p1, *path, *pwd; - char mdpath[MAXPATHLEN]; -#ifdef FORCE_MACHINE - const char *machine = FORCE_MACHINE; -#else - const char *machine = getenv("MACHINE"); -#endif - const char *machine_arch = getenv("MACHINE_ARCH"); - char *syspath = getenv("MAKESYSPATH"); - Lst sysMkPath; /* Path of sys.mk */ - char *cp = NULL, *start; - /* avoid faults on read-only strings */ - static char defsyspath[] = _PATH_DEFSYSPATH; - char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */ - struct timeval rightnow; /* to initialize random seed */ -#ifdef MAKE_NATIVE - struct utsname utsname; -#endif - - /* default to writing debug to stderr */ - debug_file = stderr; - -#ifdef SIGINFO - (void)bmake_signal(SIGINFO, siginfo); -#endif - /* - * Set the seed to produce a different random sequence - * on each program execution. - */ - gettimeofday(&rightnow, NULL); - srandom(rightnow.tv_sec + rightnow.tv_usec); - - if ((progname = strrchr(argv[0], '/')) != NULL) - progname++; - else - progname = argv[0]; -#ifdef RLIMIT_NOFILE - /* - * get rid of resource limit on file descriptors - */ - { - struct rlimit rl; - if (getrlimit(RLIMIT_NOFILE, &rl) != -1 && - rl.rlim_cur != rl.rlim_max) { - rl.rlim_cur = rl.rlim_max; - (void)setrlimit(RLIMIT_NOFILE, &rl); - } - } -#endif - - /* - * Get the name of this type of MACHINE from utsname - * so we can share an executable for similar machines. - * (i.e. m68k: amiga hp300, mac68k, sun3, ...) - * - * Note that both MACHINE and MACHINE_ARCH are decided at - * run-time. - */ - if (!machine) { -#ifdef MAKE_NATIVE - if (uname(&utsname) == -1) { - (void)fprintf(stderr, "%s: uname failed (%s).\n", progname, - strerror(errno)); - exit(2); - } - machine = utsname.machine; -#else -#ifdef MAKE_MACHINE - machine = MAKE_MACHINE; -#else - machine = "unknown"; -#endif -#endif - } - - if (!machine_arch) { -#ifndef MACHINE_ARCH -#ifdef MAKE_MACHINE_ARCH - machine_arch = MAKE_MACHINE_ARCH; -#else - machine_arch = "unknown"; -#endif -#else - machine_arch = MACHINE_ARCH; -#endif - } - - myPid = getpid(); /* remember this for vFork() */ - - /* - * Just in case MAKEOBJDIR wants us to do something tricky. - */ - Var_Init(); /* Initialize the lists of variables for - * parsing arguments */ - Var_Set("MACHINE", machine, VAR_GLOBAL, 0); - Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0); -#ifdef MAKE_VERSION - Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0); -#endif - Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */ - /* - * This is the traditional preference for makefiles. - */ -#ifndef MAKEFILE_PREFERENCE_LIST -# define MAKEFILE_PREFERENCE_LIST "makefile Makefile" -#endif - Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST, - VAR_GLOBAL, 0); - Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL, 0); - - create = Lst_Init(FALSE); - makefiles = Lst_Init(FALSE); - printVars = FALSE; - variables = Lst_Init(FALSE); - beSilent = FALSE; /* Print commands as executed */ - ignoreErrors = FALSE; /* Pay attention to non-zero returns */ - noExecute = FALSE; /* Execute all commands */ - noRecursiveExecute = FALSE; /* Execute all .MAKE targets */ - keepgoing = FALSE; /* Stop on error */ - allPrecious = FALSE; /* Remove targets when interrupted */ - queryFlag = FALSE; /* This is not just a check-run */ - noBuiltins = FALSE; /* Read the built-in rules */ - touchFlag = FALSE; /* Actually update targets */ - debug = 0; /* No debug verbosity, please. */ - jobsRunning = FALSE; - - maxJobs = DEFMAXLOCAL; /* Set default local max concurrency */ - maxJobTokens = maxJobs; - compatMake = FALSE; /* No compat mode */ - ignorePWD = FALSE; - - /* - * Initialize the parsing, directory and variable modules to prepare - * for the reading of inclusion paths and variable settings on the - * command line - */ - - /* - * Initialize various variables. - * MAKE also gets this name, for compatibility - * .MAKEFLAGS gets set to the empty string just in case. - * MFLAGS also gets initialized empty, for compatibility. - */ - Parse_Init(); - if (argv[0][0] == '/' || strchr(argv[0], '/') == NULL) { - /* - * Leave alone if it is an absolute path, or if it does - * not contain a '/' in which case we need to find it in - * the path, like execvp(3) and the shells do. - */ - p1 = argv[0]; - } else { - /* - * A relative path, canonicalize it. - */ - p1 = realpath(argv[0], mdpath); - if (!p1 || *p1 != '/' || stat(p1, &sb) < 0) { - p1 = argv[0]; /* realpath failed */ - } - } - Var_Set("MAKE", p1, VAR_GLOBAL, 0); - Var_Set(".MAKE", p1, VAR_GLOBAL, 0); - Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0); - Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0); - Var_Set("MFLAGS", "", VAR_GLOBAL, 0); - Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0); - - /* - * Set some other useful macros - */ - { - char tmp[64]; - const char *ep; - - if (!(ep = getenv(MAKE_LEVEL))) { -#ifdef MAKE_LEVEL_SAFE - if (!(ep = getenv(MAKE_LEVEL_SAFE))) -#endif - ep = "0"; - } - Var_Set(MAKE_LEVEL, ep, VAR_GLOBAL, 0); - snprintf(tmp, sizeof(tmp), "%u", myPid); - Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0); - snprintf(tmp, sizeof(tmp), "%u", getppid()); - Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0); - } - Job_SetPrefix(); - - /* - * First snag any flags out of the MAKE environment variable. - * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's - * in a different format). - */ -#ifdef POSIX - Main_ParseArgLine(getenv("MAKEFLAGS")); -#else - Main_ParseArgLine(getenv("MAKE")); -#endif - - /* - * Find where we are (now). - * We take care of PWD for the automounter below... - */ - if (getcwd(curdir, MAXPATHLEN) == NULL) { - (void)fprintf(stderr, "%s: getcwd: %s.\n", - progname, strerror(errno)); - exit(2); - } - - MainParseArgs(argc, argv); - - /* - * Verify that cwd is sane. - */ - if (stat(curdir, &sa) == -1) { - (void)fprintf(stderr, "%s: %s: %s.\n", - progname, curdir, strerror(errno)); - exit(2); - } - - /* - * All this code is so that we know where we are when we start up - * on a different machine with pmake. - * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX - * since the value of curdir can vary depending on how we got - * here. Ie sitting at a shell prompt (shell that provides $PWD) - * or via subdir.mk in which case its likely a shell which does - * not provide it. - * So, to stop it breaking this case only, we ignore PWD if - * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform. - */ -#ifndef NO_PWD_OVERRIDE - if (!ignorePWD && - (pwd = getenv("PWD")) != NULL && - getenv("MAKEOBJDIRPREFIX") == NULL) { - const char *makeobjdir = getenv("MAKEOBJDIR"); - - if (makeobjdir == NULL || !strchr(makeobjdir, '$')) { - if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino && - sa.st_dev == sb.st_dev) - (void)strncpy(curdir, pwd, MAXPATHLEN); - } - } -#endif - Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0); - - /* - * Find the .OBJDIR. If MAKEOBJDIRPREFIX, or failing that, - * MAKEOBJDIR is set in the environment, try only that value - * and fall back to .CURDIR if it does not exist. - * - * Otherwise, try _PATH_OBJDIR.MACHINE, _PATH_OBJDIR, and - * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none - * of these paths exist, just use .CURDIR. - */ - Dir_Init(curdir); - (void)Main_SetObjdir(curdir); - - if ((path = getenv("MAKEOBJDIRPREFIX")) != NULL) { - (void)snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir); - (void)Main_SetObjdir(mdpath); - } else if ((path = getenv("MAKEOBJDIR")) != NULL) { - (void)Main_SetObjdir(path); - } else { - (void)snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine); - if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) { - (void)snprintf(mdpath, MAXPATHLEN, "%s%s", - _PATH_OBJDIRPREFIX, curdir); - (void)Main_SetObjdir(mdpath); - } - } - - /* - * Be compatible if user did not specify -j and did not explicitly - * turned compatibility on - */ - if (!compatMake && !forceJobs) { - compatMake = TRUE; - } - - /* - * Initialize archive, target and suffix modules in preparation for - * parsing the makefile(s) - */ - Arch_Init(); - Targ_Init(); - Suff_Init(); - Trace_Init(tracefile); - - DEFAULT = NULL; - (void)time(&now); - - Trace_Log(MAKESTART, NULL); - - /* - * Set up the .TARGETS variable to contain the list of targets to be - * created. If none specified, make the variable empty -- the parser - * will fill the thing in with the default or .MAIN target. - */ - if (!Lst_IsEmpty(create)) { - LstNode ln; - - for (ln = Lst_First(create); ln != NULL; - ln = Lst_Succ(ln)) { - char *name = (char *)Lst_Datum(ln); - - Var_Append(".TARGETS", name, VAR_GLOBAL); - } - } else - Var_Set(".TARGETS", "", VAR_GLOBAL, 0); - - - /* - * If no user-supplied system path was given (through the -m option) - * add the directories from the DEFSYSPATH (more than one may be given - * as dir1:...:dirn) to the system include path. - */ - if (syspath == NULL || *syspath == '\0') - syspath = defsyspath; - else - syspath = bmake_strdup(syspath); - - for (start = syspath; *start != '\0'; start = cp) { - for (cp = start; *cp != '\0' && *cp != ':'; cp++) - continue; - if (*cp == ':') { - *cp++ = '\0'; - } - /* look for magic parent directory search string */ - if (strncmp(".../", start, 4) != 0) { - (void)Dir_AddDir(defIncPath, start); - } else { - if (Dir_FindHereOrAbove(curdir, start+4, - found_path, sizeof(found_path))) { - (void)Dir_AddDir(defIncPath, found_path); - } - } - } - if (syspath != defsyspath) - free(syspath); - - /* - * Read in the built-in rules first, followed by the specified - * makefile, if it was (makefile != NULL), or the default - * makefile and Makefile, in that order, if it wasn't. - */ - if (!noBuiltins) { - LstNode ln; - - sysMkPath = Lst_Init(FALSE); - Dir_Expand(_PATH_DEFSYSMK, - Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath, - sysMkPath); - if (Lst_IsEmpty(sysMkPath)) - Fatal("%s: no system rules (%s).", progname, - _PATH_DEFSYSMK); - ln = Lst_Find(sysMkPath, NULL, ReadMakefile); - if (ln == NULL) - Fatal("%s: cannot open %s.", progname, - (char *)Lst_Datum(ln)); - } - - if (!Lst_IsEmpty(makefiles)) { - LstNode ln; - - ln = Lst_Find(makefiles, NULL, ReadAllMakefiles); - if (ln != NULL) - Fatal("%s: cannot open %s.", progname, - (char *)Lst_Datum(ln)); - } else { - p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}", - VAR_CMD, 0); - if (p1) { - (void)str2Lst_Append(makefiles, p1, NULL); - (void)Lst_Find(makefiles, NULL, ReadMakefile); - free(p1); - } - } - - /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */ - if (!noBuiltins || !printVars) { - makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}", - VAR_CMD, 0); - doing_depend = TRUE; - (void)ReadMakefile(makeDependfile, NULL); - doing_depend = FALSE; - } - - MakeMode(NULL); - - Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL); - if (p1) - free(p1); - - if (!compatMake) - Job_ServerStart(maxJobTokens, jp_0, jp_1); - if (DEBUG(JOB)) - fprintf(debug_file, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n", - jp_0, jp_1, maxJobs, maxJobTokens, compatMake); - - Main_ExportMAKEFLAGS(TRUE); /* initial export */ - -#ifndef NO_CHECK_MAKE_CHDIR - Check_Cwd_av(0, NULL, 0); /* initialize it */ -#endif - - /* - * For compatibility, look at the directories in the VPATH variable - * and add them to the search path, if the variable is defined. The - * variable's value is in the same format as the PATH envariable, i.e. - * <directory>:<directory>:<directory>... - */ - if (Var_Exists("VPATH", VAR_CMD)) { - char *vpath, savec; - /* - * GCC stores string constants in read-only memory, but - * Var_Subst will want to write this thing, so store it - * in an array - */ - static char VPATH[] = "${VPATH}"; - - vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE); - path = vpath; - do { - /* skip to end of directory */ - for (cp = path; *cp != ':' && *cp != '\0'; cp++) - continue; - /* Save terminator character so know when to stop */ - savec = *cp; - *cp = '\0'; - /* Add directory to search path */ - (void)Dir_AddDir(dirSearchPath, path); - *cp = savec; - path = cp + 1; - } while (savec == ':'); - free(vpath); - } - - /* - * Now that all search paths have been read for suffixes et al, it's - * time to add the default search path to their lists... - */ - Suff_DoPaths(); - - /* - * Propagate attributes through :: dependency lists. - */ - Targ_Propagate(); - - /* print the initial graph, if the user requested it */ - if (DEBUG(GRAPH1)) - Targ_PrintGraph(1); - - /* print the values of any variables requested by the user */ - if (printVars) { - LstNode ln; - - for (ln = Lst_First(variables); ln != NULL; - ln = Lst_Succ(ln)) { - char *var = (char *)Lst_Datum(ln); - char *value; - - if (strchr(var, '$')) { - value = p1 = Var_Subst(NULL, var, VAR_GLOBAL, 0); - } else { - value = Var_Value(var, VAR_GLOBAL, &p1); - } - printf("%s\n", value ? value : ""); - if (p1) - free(p1); - } - } else { - /* - * Have now read the entire graph and need to make a list of - * targets to create. If none was given on the command line, - * we consult the parsing module to find the main target(s) - * to create. - */ - if (Lst_IsEmpty(create)) - targs = Parse_MainName(); - else - targs = Targ_FindList(create, TARG_CREATE); - - if (!compatMake) { - /* - * Initialize job module before traversing the graph - * now that any .BEGIN and .END targets have been read. - * This is done only if the -q flag wasn't given - * (to prevent the .BEGIN from being executed should - * it exist). - */ - if (!queryFlag) { - Job_Init(); - jobsRunning = TRUE; - } - - /* Traverse the graph, checking on all the targets */ - outOfDate = Make_Run(targs); - } else { - /* - * Compat_Init will take care of creating all the - * targets as well as initializing the module. - */ - Compat_Run(targs); - } - } - -#ifdef CLEANUP - Lst_Destroy(targs, NULL); - Lst_Destroy(variables, NULL); - Lst_Destroy(makefiles, NULL); - Lst_Destroy(create, (FreeProc *)free); -#endif - - /* print the graph now it's been processed if the user requested it */ - if (DEBUG(GRAPH2)) - Targ_PrintGraph(2); - - Trace_Log(MAKEEND, 0); - - Suff_End(); - Targ_End(); - Arch_End(); - Var_End(); - Parse_End(); - Dir_End(); - Job_End(); - Trace_End(); - - return outOfDate ? 1 : 0; -} - -/*- - * ReadMakefile -- - * Open and parse the given makefile. - * - * Results: - * 0 if ok. -1 if couldn't open file. - * - * Side Effects: - * lots - */ -static int -ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED) -{ - const char *fname = p; /* makefile to read */ - int fd; - size_t len = MAXPATHLEN; - char *name, *path = bmake_malloc(len); - - if (!strcmp(fname, "-")) { - Parse_File(NULL /*stdin*/, -1); - Var_Set("MAKEFILE", "", VAR_GLOBAL, 0); - } else { - /* if we've chdir'd, rebuild the path name */ - if (strcmp(curdir, objdir) && *fname != '/') { - size_t plen = strlen(curdir) + strlen(fname) + 2; - if (len < plen) - path = bmake_realloc(path, len = 2 * plen); - - (void)snprintf(path, len, "%s/%s", curdir, fname); - fd = open(path, O_RDONLY); - if (fd != -1) { - fname = path; - goto found; - } - - /* If curdir failed, try objdir (ala .depend) */ - plen = strlen(objdir) + strlen(fname) + 2; - if (len < plen) - path = bmake_realloc(path, len = 2 * plen); - (void)snprintf(path, len, "%s/%s", objdir, fname); - fd = open(path, O_RDONLY); - if (fd != -1) { - fname = path; - goto found; - } - } else { - fd = open(fname, O_RDONLY); - if (fd != -1) - goto found; - } - /* look in -I and system include directories. */ - name = Dir_FindFile(fname, parseIncPath); - if (!name) - name = Dir_FindFile(fname, - Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath); - if (!name || (fd = open(name, O_RDONLY)) == -1) { - if (name) - free(name); - free(path); - return(-1); - } - fname = name; - /* - * set the MAKEFILE variable desired by System V fans -- the - * placement of the setting here means it gets set to the last - * makefile specified, as it is set by SysV make. - */ -found: - if (!doing_depend) - Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0); - Parse_File(fname, fd); - } - free(path); - return(0); -} - - -/* - * If MAKEOBJDIRPREFIX is in use, make ends up not in .CURDIR - * in situations that would not arrise with ./obj (links or not). - * This tends to break things like: - * - * build: - * ${MAKE} includes - * - * This function spots when ${.MAKE:T} or ${.MAKE} is a command (as - * opposed to an argument) in a command line and if so returns - * ${.CURDIR} so caller can chdir() so that the assumptions made by - * the Makefile hold true. - * - * If ${.MAKE} does not contain any '/', then ${.MAKE:T} is skipped. - * - * The chdir() only happens in the child process, and does nothing if - * MAKEOBJDIRPREFIX and MAKEOBJDIR are not in the environment so it - * should not break anything. Also if NOCHECKMAKECHDIR is set we - * do nothing - to ensure historic semantics can be retained. - */ -#ifdef NO_CHECK_MAKE_CHDIR -char * -Check_Cwd_Cmd(cmd) - char *cmd; -{ - return 0; -} - -void -Check_Cwd(argv) - char **argv; -{ - return; -} - -#else - -static int Check_Cwd_Off = 0; - -static char * -Check_Cwd_av(int ac, char **av, int copy) -{ - static char *make[4]; - static char *cur_dir = NULL; - char **mp; - char *cp; - int is_cmd, next_cmd; - int i; - int n; - - if (Check_Cwd_Off) { - if (DEBUG(CWD)) - fprintf(debug_file, "check_cwd: check is off.\n"); - return NULL; - } - - if (make[0] == NULL) { - if (Var_Exists("NOCHECKMAKECHDIR", VAR_GLOBAL)) { - Check_Cwd_Off = 1; - if (DEBUG(CWD)) - fprintf(debug_file, "check_cwd: turning check off.\n"); - return NULL; - } - - make[1] = Var_Value(".MAKE", VAR_GLOBAL, &cp); - if ((make[0] = strrchr(make[1], '/')) == NULL) { - make[0] = make[1]; - make[1] = NULL; - } else - ++make[0]; - make[2] = NULL; - cur_dir = Var_Value(".CURDIR", VAR_GLOBAL, &cp); - } - if (ac == 0 || av == NULL) { - if (DEBUG(CWD)) - fprintf(debug_file, "check_cwd: empty command.\n"); - return NULL; /* initialization only */ - } - - if (getenv("MAKEOBJDIR") == NULL && - getenv("MAKEOBJDIRPREFIX") == NULL) { - if (DEBUG(CWD)) - fprintf(debug_file, "check_cwd: no obj dirs.\n"); - return NULL; - } - - - next_cmd = 1; - for (i = 0; i < ac; ++i) { - is_cmd = next_cmd; - - n = strlen(av[i]); - cp = &(av[i])[n - 1]; - if (strspn(av[i], "|&;") == (size_t)n) { - next_cmd = 1; - continue; - } else if (*cp == ';' || *cp == '&' || *cp == '|' || *cp == ')') { - next_cmd = 1; - if (copy) { - do { - *cp-- = '\0'; - } while (*cp == ';' || *cp == '&' || *cp == '|' || - *cp == ')' || *cp == '}') ; - } else { - /* - * XXX this should not happen. - */ - fprintf(stderr, "%s: WARNING: raw arg ends in shell meta '%s'\n", - progname, av[i]); - } - } else - next_cmd = 0; - - cp = av[i]; - if (*cp == ';' || *cp == '&' || *cp == '|') - is_cmd = 1; - - if (DEBUG(CWD)) - fprintf(debug_file, "av[%d] == %s '%s'", - i, (is_cmd) ? "cmd" : "arg", av[i]); - if (is_cmd != 0) { - if (*cp == '(' || *cp == '{' || - *cp == ';' || *cp == '&' || *cp == '|') { - do { - ++cp; - } while (*cp == '(' || *cp == '{' || - *cp == ';' || *cp == '&' || *cp == '|'); - if (*cp == '\0') { - next_cmd = 1; - continue; - } - } - if (strcmp(cp, "cd") == 0 || strcmp(cp, "chdir") == 0) { - if (DEBUG(CWD)) - fprintf(debug_file, " == cd, done.\n"); - return NULL; - } - for (mp = make; *mp != NULL; ++mp) { - n = strlen(*mp); - if (strcmp(cp, *mp) == 0) { - if (DEBUG(CWD)) - fprintf(debug_file, " %s == '%s', chdir(%s)\n", - cp, *mp, cur_dir); - return cur_dir; - } - } - } - if (DEBUG(CWD)) - fprintf(debug_file, "\n"); - } - return NULL; -} - -char * -Check_Cwd_Cmd(const char *cmd) -{ - char *cp, *bp; - char **av; - int ac; - - if (Check_Cwd_Off) - return NULL; - - if (cmd) { - av = brk_string(cmd, &ac, TRUE, &bp); - if (DEBUG(CWD)) - fprintf(debug_file, "splitting: '%s' -> %d words\n", - cmd, ac); - } else { - ac = 0; - av = NULL; - bp = NULL; - } - cp = Check_Cwd_av(ac, av, 1); - if (bp) - free(bp); - if (av) - free(av); - return cp; -} - -void -Check_Cwd(const char **argv) -{ - char *cp; - int ac; - - if (Check_Cwd_Off) - return; - - for (ac = 0; argv[ac] != NULL; ++ac) - /* NOTHING */; - if (ac == 3 && *argv[1] == '-') { - cp = Check_Cwd_Cmd(argv[2]); - } else { - cp = Check_Cwd_av(ac, UNCONST(argv), 0); - } - if (cp) { - chdir(cp); - } -} -#endif /* NO_CHECK_MAKE_CHDIR */ - -/*- - * Cmd_Exec -- - * Execute the command in cmd, and return the output of that command - * in a string. - * - * Results: - * A string containing the output of the command, or the empty string - * If errnum is not NULL, it contains the reason for the command failure - * - * Side Effects: - * The string must be freed by the caller. - */ -char * -Cmd_Exec(const char *cmd, const char **errnum) -{ - const char *args[4]; /* Args for invoking the shell */ - int fds[2]; /* Pipe streams */ - int cpid; /* Child PID */ - int pid; /* PID from wait() */ - char *res; /* result */ - WAIT_T status; /* command exit status */ - Buffer buf; /* buffer to store the result */ - char *cp; - int cc; - - - *errnum = NULL; - - if (!shellName) - Shell_Init(); - /* - * Set up arguments for shell - */ - args[0] = shellName; - args[1] = "-c"; - args[2] = cmd; - args[3] = NULL; - - /* - * Open a pipe for fetching its output - */ - if (pipe(fds) == -1) { - *errnum = "Couldn't create pipe for \"%s\""; - goto bad; - } - - /* - * Fork - */ - switch (cpid = vFork()) { - case 0: - /* - * Close input side of pipe - */ - (void)close(fds[0]); - - /* - * Duplicate the output stream to the shell's output, then - * shut the extra thing down. Note we don't fetch the error - * stream...why not? Why? - */ - (void)dup2(fds[1], 1); - (void)close(fds[1]); - - Var_ExportVars(); - - (void)execv(shellPath, UNCONST(args)); - _exit(1); - /*NOTREACHED*/ - - case -1: - *errnum = "Couldn't exec \"%s\""; - goto bad; - - default: - /* - * No need for the writing half - */ - (void)close(fds[1]); - - Buf_Init(&buf, 0); - - do { - char result[BUFSIZ]; - cc = read(fds[0], result, sizeof(result)); - if (cc > 0) - Buf_AddBytes(&buf, cc, result); - } - while (cc > 0 || (cc == -1 && errno == EINTR)); - - /* - * Close the input side of the pipe. - */ - (void)close(fds[0]); - - /* - * Wait for the process to exit. - */ - while(((pid = waitpid(cpid, &status, 0)) != cpid) && (pid >= 0)) { - JobReapChild(pid, status, FALSE); - continue; - } - cc = Buf_Size(&buf); - res = Buf_Destroy(&buf, FALSE); - - if (cc == 0) - *errnum = "Couldn't read shell's output for \"%s\""; - - if (WIFSIGNALED(status)) - *errnum = "\"%s\" exited on a signal"; - else if (WEXITSTATUS(status) != 0) - *errnum = "\"%s\" returned non-zero status"; - - /* - * Null-terminate the result, convert newlines to spaces and - * install it in the variable. - */ - res[cc] = '\0'; - cp = &res[cc]; - - if (cc > 0 && *--cp == '\n') { - /* - * A final newline is just stripped - */ - *cp-- = '\0'; - } - while (cp >= res) { - if (*cp == '\n') { - *cp = ' '; - } - cp--; - } - break; - } - return res; -bad: - res = bmake_malloc(1); - *res = '\0'; - return res; -} - -/*- - * Error -- - * Print an error message given its format. - * - * Results: - * None. - * - * Side Effects: - * The message is printed. - */ -/* VARARGS */ -void -Error(const char *fmt, ...) -{ - va_list ap; - FILE *err_file; - - err_file = debug_file; - if (err_file == stdout) - err_file = stderr; - (void)fflush(stdout); - for (;;) { - va_start(ap, fmt); - fprintf(err_file, "%s: ", progname); - (void)vfprintf(err_file, fmt, ap); - va_end(ap); - (void)fprintf(err_file, "\n"); - (void)fflush(err_file); - if (err_file == stderr) - break; - err_file = stderr; - } -} - -/*- - * Fatal -- - * Produce a Fatal error message. If jobs are running, waits for them - * to finish. - * - * Results: - * None - * - * Side Effects: - * The program exits - */ -/* VARARGS */ -void -Fatal(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - if (jobsRunning) - Job_Wait(); - - (void)fflush(stdout); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - (void)fprintf(stderr, "\n"); - (void)fflush(stderr); - - PrintOnError(NULL, NULL); - - if (DEBUG(GRAPH2) || DEBUG(GRAPH3)) - Targ_PrintGraph(2); - Trace_Log(MAKEERROR, 0); - exit(2); /* Not 1 so -q can distinguish error */ -} - -/* - * Punt -- - * Major exception once jobs are being created. Kills all jobs, prints - * a message and exits. - * - * Results: - * None - * - * Side Effects: - * All children are killed indiscriminately and the program Lib_Exits - */ -/* VARARGS */ -void -Punt(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - (void)fflush(stdout); - (void)fprintf(stderr, "%s: ", progname); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - (void)fprintf(stderr, "\n"); - (void)fflush(stderr); - - PrintOnError(NULL, NULL); - - DieHorribly(); -} - -/*- - * DieHorribly -- - * Exit without giving a message. - * - * Results: - * None - * - * Side Effects: - * A big one... - */ -void -DieHorribly(void) -{ - if (jobsRunning) - Job_AbortAll(); - if (DEBUG(GRAPH2)) - Targ_PrintGraph(2); - Trace_Log(MAKEERROR, 0); - exit(2); /* Not 1, so -q can distinguish error */ -} - -/* - * Finish -- - * Called when aborting due to errors in child shell to signal - * abnormal exit. - * - * Results: - * None - * - * Side Effects: - * The program exits - */ -void -Finish(int errors) - /* number of errors encountered in Make_Make */ -{ - Fatal("%d error%s", errors, errors == 1 ? "" : "s"); -} - -/* - * enunlink -- - * Remove a file carefully, avoiding directories. - */ -int -eunlink(const char *file) -{ - struct stat st; - - if (lstat(file, &st) == -1) - return -1; - - if (S_ISDIR(st.st_mode)) { - errno = EISDIR; - return -1; - } - return unlink(file); -} - -/* - * execError -- - * Print why exec failed, avoiding stdio. - */ -void -execError(const char *af, const char *av) -{ -#ifdef USE_IOVEC - int i = 0; - struct iovec iov[8]; -#define IOADD(s) \ - (void)(iov[i].iov_base = UNCONST(s), \ - iov[i].iov_len = strlen(iov[i].iov_base), \ - i++) -#else -#define IOADD(s) (void)write(2, s, strlen(s)) -#endif - - IOADD(progname); - IOADD(": "); - IOADD(af); - IOADD("("); - IOADD(av); - IOADD(") failed ("); - IOADD(strerror(errno)); - IOADD(")\n"); - -#ifdef USE_IOVEC - (void)writev(2, iov, 8); -#endif -} - -/* - * usage -- - * exit with usage message - */ -static void -usage(void) -{ - (void)fprintf(stderr, -"usage: %s [-BeikNnqrstWX] \n\ - [-C directory] [-D variable] [-d flags] [-f makefile]\n\ - [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\ - [-V variable] [variable=value] [target ...]\n", progname); - exit(2); -} - - -int -PrintAddr(void *a, void *b) -{ - printf("%lx ", (unsigned long) a); - return b ? 0 : 0; -} - - - -void -PrintOnError(GNode *gn, const char *s) -{ - static GNode *en = NULL; - char tmp[64]; - char *cp; - - if (s) - printf("%s", s); - - printf("\n%s: stopped in %s\n", progname, curdir); - - if (en) - return; /* we've been here! */ - if (gn) { - /* - * We can print this even if there is no .ERROR target. - */ - Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL, 0); - } - strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}", - sizeof(tmp) - 1); - cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); - if (cp) { - if (*cp) - printf("%s", cp); - free(cp); - } - /* - * Finally, see if there is a .ERROR target, and run it if so. - */ - en = Targ_FindNode(".ERROR", TARG_NOCREATE); - if (en) { - en->type |= OP_SPECIAL; - Compat_Make(en, en); - } -} - -void -Main_ExportMAKEFLAGS(Boolean first) -{ - static int once = 1; - char tmp[64]; - char *s; - - if (once != first) - return; - once = 0; - - strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}", - sizeof(tmp)); - s = Var_Subst(NULL, tmp, VAR_CMD, 0); - if (s && *s) { -#ifdef POSIX - setenv("MAKEFLAGS", s, 1); -#else - setenv("MAKE", s, 1); -#endif - } -} - -char * -getTmpdir(void) -{ - static char *tmpdir = NULL; - - if (!tmpdir) { - struct stat st; - - /* - * Honor $TMPDIR but only if it is valid. - * Ensure it ends with /. - */ - tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL, 0); - if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) { - free(tmpdir); - tmpdir = bmake_strdup(_PATH_TMP); - } - } - return tmpdir; -} - -/* - * Create and open a temp file using "pattern". - * If "fnamep" is provided set it to a copy of the filename created. - * Otherwise unlink the file once open. - */ -int -mkTempFile(const char *pattern, char **fnamep) -{ - static char *tmpdir = NULL; - char tfile[MAXPATHLEN]; - int fd; - - if (!pattern) - pattern = TMPPAT; - if (!tmpdir) - tmpdir = getTmpdir(); - if (pattern[0] == '/') { - snprintf(tfile, sizeof(tfile), "%s", pattern); - } else { - snprintf(tfile, sizeof(tfile), "%s%s", tmpdir, pattern); - } - if ((fd = mkstemp(tfile)) < 0) - Punt("Could not create temporary file %s: %s", tfile, strerror(errno)); - if (fnamep) { - *fnamep = bmake_strdup(tfile); - } else { - unlink(tfile); /* we just want the descriptor */ - } - return fd; -} diff --git a/20120831/make-bootstrap.sh.in b/20120831/make-bootstrap.sh.in deleted file mode 100755 index d9ff9ff..0000000 --- a/20120831/make-bootstrap.sh.in +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/sh - -set -e - -srcdir=@srcdir@ - -DEFAULT_SYS_PATH="@default_sys_path@" - -case "@use_meta@" in -yes) XDEFS="-DUSE_META ${XDEFS}";; -esac - -CC="@CC@" -CFLAGS="@CFLAGS@ -I. -I${srcdir} @DEFS@ @CPPFLAGS@ -DMAKE_NATIVE ${XDEFS}" - -MAKE_VERSION=`sed -n '/^MAKE_VERSION=/s,.*=[^0-9]*,,p' Makefile` - -MDEFS="-DMAKE_VERSION=\"$MAKE_VERSION\" \ --D@force_machine@MACHINE=\"@machine@\" -DMACHINE_ARCH=\"@machine_arch@\" \ --D_PATH_DEFSYSPATH=\"${DEFAULT_SYS_PATH}\"" - - -LDFLAGS="@LDFLAGS@" -LIBS="@LIBS@" - -do_compile2() { - obj="$1"; shift - src="$1"; shift - echo ${CC} -c ${CFLAGS} "$@" -o "$obj" "$src" - ${CC} -c ${CFLAGS} "$@" -o "$obj" "$src" -} - -do_compile() { - obj="$1"; shift - src=`basename "$obj" .o`.c - - for d in "$srcdir" "$srcdir/lst.lib" - do - test -s "$d/$src" || continue - - do_compile2 "$obj" "$d/$src" "$@" || exit 1 - return - done - echo "Unknown object file '$obj'" >&2 - exit 1 -} - -do_link() { - output="$1"; shift - echo ${CC} ${LDSTATIC} ${LDFLAGS} -o "$output" "$@" ${LIBS} - ${CC} ${LDSTATIC} ${LDFLAGS} -o "$output" "$@" ${LIBS} -} - -BASE_OBJECTS="arch.o buf.o compat.o cond.o dir.o for.o getopt hash.o \ -job.o make.o make_malloc.o parse.o sigcompat.o str.o strlist.o \ -suff.o targ.o trace.o var.o util.o" - -LST_OBJECTS="lstAppend.o lstDupl.o lstInit.o lstOpen.o \ -lstAtEnd.o lstEnQueue.o lstInsert.o lstAtFront.o lstIsAtEnd.o \ -lstClose.o lstFind.o lstIsEmpty.o lstRemove.o lstConcat.o \ -lstFindFrom.o lstLast.o lstReplace.o lstFirst.o lstDatum.o \ -lstForEach.o lstMember.o lstSucc.o lstDeQueue.o lstForEachFrom.o \ -lstDestroy.o lstNext.o lstPrev.o" - -LIB_OBJECTS="@LIBOBJS@" - -do_compile main.o ${MDEFS} - -for o in ${BASE_OBJECTS} ${LST_OBJECTS} ${LIB_OBJECTS} -do - do_compile "$o" -done - -case "@use_meta@" in -yes) - case "@filemon_h@" in - */filemon.h) FDEFS="-DHAVE_FILEMON_H -I`dirname @filemon_h@`";; - esac - do_compile meta.o ${FDEFS} - BASE_OBJECTS="meta.o ${BASE_OBJECTS}" - ;; -esac - -do_link bmake main.o ${BASE_OBJECTS} ${LST_OBJECTS} ${LIB_OBJECTS} diff --git a/20120831/make-conf.h b/20120831/make-conf.h deleted file mode 100644 index a85b86d..0000000 --- a/20120831/make-conf.h +++ /dev/null @@ -1,162 +0,0 @@ -/* $NetBSD: config.h,v 1.21 2012/03/31 00:12:24 christos Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)config.h 8.1 (Berkeley) 6/6/93 - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)config.h 8.1 (Berkeley) 6/6/93 - */ - -/* - * DEFMAXJOBS - * DEFMAXLOCAL - * These control the default concurrency. On no occasion will more - * than DEFMAXJOBS targets be created at once (locally or remotely) - * DEFMAXLOCAL is the highest number of targets which will be - * created on the local machine at once. Note that if you set this - * to 0, nothing will ever happen... - */ -#define DEFMAXJOBS 4 -#define DEFMAXLOCAL 1 - -/* - * INCLUDES - * LIBRARIES - * These control the handling of the .INCLUDES and .LIBS variables. - * If INCLUDES is defined, the .INCLUDES variable will be filled - * from the search paths of those suffixes which are marked by - * .INCLUDES dependency lines. Similarly for LIBRARIES and .LIBS - * See suff.c for more details. - */ -#define INCLUDES -#define LIBRARIES - -/* - * LIBSUFF - * Is the suffix used to denote libraries and is used by the Suff module - * to find the search path on which to seek any -l<xx> targets. - * - * RECHECK - * If defined, Make_Update will check a target for its current - * modification time after it has been re-made, setting it to the - * starting time of the make only if the target still doesn't exist. - * Unfortunately, under NFS the modification time often doesn't - * get updated in time, so a target will appear to not have been - * re-made, causing later targets to appear up-to-date. On systems - * that don't have this problem, you should defined this. Under - * NFS you probably should not, unless you aren't exporting jobs. - */ -#define LIBSUFF ".a" -#define RECHECK - -/* - * POSIX - * Adhere to the POSIX 1003.2 draft for the make(1) program. - * - Use MAKEFLAGS instead of MAKE to pick arguments from the - * environment. - * - Allow empty command lines if starting with tab. - */ -#define POSIX - -/* - * SYSVINCLUDE - * Recognize system V like include directives [include "filename"] - * SYSVVARSUB - * Recognize system V like ${VAR:x=y} variable substitutions - */ -#define SYSVINCLUDE -#define SYSVVARSUB - -/* - * GMAKEEXPORT - * Recognize gmake like variable export directives [export <VAR>=<VALUE>] - */ -#define GMAKEEXPORT - -/* - * SUNSHCMD - * Recognize SunOS and Solaris: - * VAR :sh= CMD # Assign VAR to the command substitution of CMD - * ${VAR:sh} # Return the command substitution of the value - * # of ${VAR} - */ -#define SUNSHCMD - -/* - * USE_IOVEC - * We have writev(2) - */ -#ifdef HAVE_SYS_UIO_H -# define USE_IOVEC -#endif - -#if defined(MAKE_NATIVE) && !defined(__ELF__) -# ifndef RANLIBMAG -# define RANLIBMAG "__.SYMDEF" -# endif -#endif diff --git a/20120831/make.1 b/20120831/make.1 deleted file mode 100644 index 86f747b..0000000 --- a/20120831/make.1 +++ /dev/null @@ -1,2061 +0,0 @@ -.\" $NetBSD: make.1,v 1.204 2012/04/24 20:12:16 sjg Exp $ -.\" -.\" Copyright (c) 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 -.\" -.Dd April 24, 2012 -.Dt MAKE 1 -.Os -.Sh NAME -.Nm make -.Nd maintain program dependencies -.Sh SYNOPSIS -.Nm -.Op Fl BeikNnqrstWX -.Op Fl C Ar directory -.Op Fl D Ar variable -.Op Fl d Ar flags -.Op Fl f Ar makefile -.Op Fl I Ar directory -.Op Fl J Ar private -.Op Fl j Ar max_jobs -.Op Fl m Ar directory -.Op Fl T Ar file -.Op Fl V Ar variable -.Op Ar variable=value -.Op Ar target ... -.Sh DESCRIPTION -.Nm -is a program designed to simplify the maintenance of other programs. -Its input is a list of specifications as to the files upon which programs -and other files depend. -If no -.Fl f Ar makefile -makefile option is given, -.Nm -will try to open -.Ql Pa makefile -then -.Ql Pa Makefile -in order to find the specifications. -If the file -.Ql Pa .depend -exists, it is read (see -.Xr mkdep 1 ) . -.Pp -This manual page is intended as a reference document only. -For a more thorough description of -.Nm -and makefiles, please refer to -.%T "PMake \- A Tutorial" . -.Pp -.Nm -will prepend the contents of the -.Va MAKEFLAGS -environment variable to the command line arguments before parsing them. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl B -Try to be backwards compatible by executing a single shell per command and -by executing the commands to make the sources of a dependency line in sequence. -.It Fl C Ar directory -Change to -.Ar directory -before reading the makefiles or doing anything else. -If multiple -.Fl C -options are specified, each is interpreted relative to the previous one: -.Fl C Pa / Fl C Pa etc -is equivalent to -.Fl C Pa /etc . -.It Fl D Ar variable -Define -.Ar variable -to be 1, in the global context. -.It Fl d Ar [-]flags -Turn on debugging, and specify which portions of -.Nm -are to print debugging information. -Unless the flags are preceded by -.Ql \- -they are added to the -.Va MAKEFLAGS -environment variable and will be processed by any child make processes. -By default, debugging information is printed to standard error, -but this can be changed using the -.Ar F -debugging flag. -The debugging output is always unbuffered; in addition, if debugging -is enabled but debugging output is not directed to standard output, -then the standard output is line buffered. -.Ar Flags -is one or more of the following: -.Bl -tag -width Ds -.It Ar A -Print all possible debugging information; -equivalent to specifying all of the debugging flags. -.It Ar a -Print debugging information about archive searching and caching. -.It Ar C -Print debugging information about current working directory. -.It Ar c -Print debugging information about conditional evaluation. -.It Ar d -Print debugging information about directory searching and caching. -.It Ar e -Print debugging information about failed commands and targets. -.It Ar F Ns Oo Sy \&+ Oc Ns Ar filename -Specify where debugging output is written. -This must be the last flag, because it consumes the remainder of -the argument. -If the character immediately after the -.Ql F -flag is -.Ql \&+ , -then the file will be opened in append mode; -otherwise the file will be overwritten. -If the file name is -.Ql stdout -or -.Ql stderr -then debugging output will be written to the -standard output or standard error output file descriptors respectively -(and the -.Ql \&+ -option has no effect). -Otherwise, the output will be written to the named file. -If the file name ends -.Ql .%d -then the -.Ql %d -is replaced by the pid. -.It Ar f -Print debugging information about loop evaluation. -.It Ar "g1" -Print the input graph before making anything. -.It Ar "g2" -Print the input graph after making everything, or before exiting -on error. -.It Ar "g3" -Print the input graph before exiting on error. -.It Ar j -Print debugging information about running multiple shells. -.It Ar l -Print commands in Makefiles regardless of whether or not they are prefixed by -.Ql @ -or other "quiet" flags. -Also known as "loud" behavior. -.It Ar M -Print debugging information about "meta" mode decisions about targets. -.It Ar m -Print debugging information about making targets, including modification -dates. -.It Ar n -Don't delete the temporary command scripts created when running commands. -These temporary scripts are created in the directory -referred to by the -.Ev TMPDIR -environment variable, or in -.Pa /tmp -if -.Ev TMPDIR -is unset or set to the empty string. -The temporary scripts are created by -.Xr mkstemp 3 , -and have names of the form -.Pa makeXXXXXX . -.Em NOTE : -This can create many files in -.Ev TMPDIR -or -.Pa /tmp , -so use with care. -.It Ar p -Print debugging information about makefile parsing. -.It Ar s -Print debugging information about suffix-transformation rules. -.It Ar t -Print debugging information about target list maintenance. -.It Ar v -Print debugging information about variable assignment. -.It Ar x -Run shell commands with -.Fl x -so the actual commands are printed as they are executed. -.El -.It Fl e -Specify that environment variables override macro assignments within -makefiles. -.It Fl f Ar makefile -Specify a makefile to read instead of the default -.Ql Pa makefile . -If -.Ar makefile -is -.Ql Fl , -standard input is read. -Multiple makefiles may be specified, and are read in the order specified. -.It Fl I Ar directory -Specify a directory in which to search for makefiles and included makefiles. -The system makefile directory (or directories, see the -.Fl m -option) is automatically included as part of this list. -.It Fl i -Ignore non-zero exit of shell commands in the makefile. -Equivalent to specifying -.Ql Fl -before each command line in the makefile. -.It Fl J Ar private -This option should -.Em not -be specified by the user. -.Pp -When the -.Ar j -option is in use in a recursive build, this option is passed by a make -to child makes to allow all the make processes in the build to -cooperate to avoid overloading the system. -.It Fl j Ar max_jobs -Specify the maximum number of jobs that -.Nm -may have running at any one time. -The value is saved in -.Va .MAKE.JOBS . -Turns compatibility mode off, unless the -.Ar B -flag is also specified. -When compatibility mode is off, all commands associated with a -target are executed in a single shell invocation as opposed to the -traditional one shell invocation per line. -This can break traditional scripts which change directories on each -command invocation and then expect to start with a fresh environment -on the next line. -It is more efficient to correct the scripts rather than turn backwards -compatibility on. -.It Fl k -Continue processing after errors are encountered, but only on those targets -that do not depend on the target whose creation caused the error. -.It Fl m Ar directory -Specify a directory in which to search for sys.mk and makefiles included -via the -.Ao Ar file Ac Ns -style -include statement. -The -.Fl m -option can be used multiple times to form a search path. -This path will override the default system include path: /usr/share/mk. -Furthermore the system include path will be appended to the search path used -for -.Qo Ar file Qc Ns -style -include statements (see the -.Fl I -option). -.Pp -If a file or directory name in the -.Fl m -argument (or the -.Ev MAKESYSPATH -environment variable) starts with the string -.Qq \&.../ -then -.Nm -will search for the specified file or directory named in the remaining part -of the argument string. -The search starts with the current directory of -the Makefile and then works upward towards the root of the filesystem. -If the search is successful, then the resulting directory replaces the -.Qq \&.../ -specification in the -.Fl m -argument. -If used, this feature allows -.Nm -to easily search in the current source tree for customized sys.mk files -(e.g., by using -.Qq \&.../mk/sys.mk -as an argument). -.It Fl n -Display the commands that would have been executed, but do not -actually execute them unless the target depends on the .MAKE special -source (see below). -.It Fl N -Display the commands which would have been executed, but do not -actually execute any of them; useful for debugging top-level makefiles -without descending into subdirectories. -.It Fl q -Do not execute any commands, but exit 0 if the specified targets are -up-to-date and 1, otherwise. -.It Fl r -Do not use the built-in rules specified in the system makefile. -.It Fl s -Do not echo any commands as they are executed. -Equivalent to specifying -.Ql Ic @ -before each command line in the makefile. -.It Fl T Ar tracefile -When used with the -.Fl j -flag, -append a trace record to -.Ar tracefile -for each job started and completed. -.It Fl t -Rather than re-building a target as specified in the makefile, create it -or update its modification time to make it appear up-to-date. -.It Fl V Ar variable -Print -.Nm Ns 's -idea of the value of -.Ar variable , -in the global context. -Do not build any targets. -Multiple instances of this option may be specified; -the variables will be printed one per line, -with a blank line for each null or undefined variable. -If -.Ar variable -contains a -.Ql \&$ -then the value will be expanded before printing. -.It Fl W -Treat any warnings during makefile parsing as errors. -.It Fl X -Don't export variables passed on the command line to the environment -individually. -Variables passed on the command line are still exported -via the -.Va MAKEFLAGS -environment variable. -This option may be useful on systems which have a small limit on the -size of command arguments. -.It Ar variable=value -Set the value of the variable -.Ar variable -to -.Ar value . -Normally, all values passed on the command line are also exported to -sub-makes in the environment. -The -.Fl X -flag disables this behavior. -Variable assignments should follow options for POSIX compatibility -but no ordering is enforced. -.El -.Pp -There are seven different types of lines in a makefile: file dependency -specifications, shell commands, variable assignments, include statements, -conditional directives, for loops, and comments. -.Pp -In general, lines may be continued from one line to the next by ending -them with a backslash -.Pq Ql \e . -The trailing newline character and initial whitespace on the following -line are compressed into a single space. -.Sh FILE DEPENDENCY SPECIFICATIONS -Dependency lines consist of one or more targets, an operator, and zero -or more sources. -This creates a relationship where the targets -.Dq depend -on the sources -and are usually created from them. -The exact relationship between the target and the source is determined -by the operator that separates them. -The three operators are as follows: -.Bl -tag -width flag -.It Ic \&: -A target is considered out-of-date if its modification time is less than -those of any of its sources. -Sources for a target accumulate over dependency lines when this operator -is used. -The target is removed if -.Nm -is interrupted. -.It Ic \&! -Targets are always re-created, but not until all sources have been -examined and re-created as necessary. -Sources for a target accumulate over dependency lines when this operator -is used. -The target is removed if -.Nm -is interrupted. -.It Ic \&:: -If no sources are specified, the target is always re-created. -Otherwise, a target is considered out-of-date if any of its sources has -been modified more recently than the target. -Sources for a target do not accumulate over dependency lines when this -operator is used. -The target will not be removed if -.Nm -is interrupted. -.El -.Pp -Targets and sources may contain the shell wildcard values -.Ql \&? , -.Ql * , -.Ql [] , -and -.Ql {} . -The values -.Ql \&? , -.Ql * , -and -.Ql [] -may only be used as part of the final -component of the target or source, and must be used to describe existing -files. -The value -.Ql {} -need not necessarily be used to describe existing files. -Expansion is in directory order, not alphabetically as done in the shell. -.Sh SHELL COMMANDS -Each target may have associated with it a series of shell commands, normally -used to create the target. -Each of the commands in this script -.Em must -be preceded by a tab. -While any target may appear on a dependency line, only one of these -dependencies may be followed by a creation script, unless the -.Ql Ic \&:: -operator is used. -.Pp -If the first characters of the command line are any combination of -.Ql Ic @ , -.Ql Ic + , -or -.Ql Ic \- , -the command is treated specially. -A -.Ql Ic @ -causes the command not to be echoed before it is executed. -A -.Ql Ic + -causes the command to be executed even when -.Fl n -is given. -This is similar to the effect of the .MAKE special source, -except that the effect can be limited to a single line of a script. -A -.Ql Ic \- -causes any non-zero exit status of the command line to be ignored. -.Sh VARIABLE ASSIGNMENTS -Variables in make are much like variables in the shell, and, by tradition, -consist of all upper-case letters. -.Ss Variable assignment modifiers -The five operators that can be used to assign values to variables are as -follows: -.Bl -tag -width Ds -.It Ic \&= -Assign the value to the variable. -Any previous value is overridden. -.It Ic \&+= -Append the value to the current value of the variable. -.It Ic \&?= -Assign the value to the variable if it is not already defined. -.It Ic \&:= -Assign with expansion, i.e. expand the value before assigning it -to the variable. -Normally, expansion is not done until the variable is referenced. -.Em NOTE : -References to undefined variables are -.Em not -expanded. -This can cause problems when variable modifiers are used. -.It Ic \&!= -Expand the value and pass it to the shell for execution and assign -the result to the variable. -Any newlines in the result are replaced with spaces. -.El -.Pp -Any white-space before the assigned -.Ar value -is removed; if the value is being appended, a single space is inserted -between the previous contents of the variable and the appended value. -.Pp -Variables are expanded by surrounding the variable name with either -curly braces -.Pq Ql {} -or parentheses -.Pq Ql () -and preceding it with -a dollar sign -.Pq Ql \&$ . -If the variable name contains only a single letter, the surrounding -braces or parentheses are not required. -This shorter form is not recommended. -.Pp -If the variable name contains a dollar, then the name itself is expanded first. -This allows almost arbitrary variable names, however names containing dollar, -braces, parenthesis, or whitespace are really best avoided! -.Pp -If the result of expanding a variable contains a dollar sign -.Pq Ql \&$ -the string is expanded again. -.Pp -Variable substitution occurs at three distinct times, depending on where -the variable is being used. -.Bl -enum -.It -Variables in dependency lines are expanded as the line is read. -.It -Variables in shell commands are expanded when the shell command is -executed. -.It -.Dq .for -loop index variables are expanded on each loop iteration. -Note that other variables are not expanded inside loops so -the following example code: -.Bd -literal -offset indent - -.Dv .for i in 1 2 3 -a+= ${i} -j= ${i} -b+= ${j} -.Dv .endfor - -all: - @echo ${a} - @echo ${b} - -.Ed -will print: -.Bd -literal -offset indent -1 2 3 -3 3 3 - -.Ed -Because while ${a} contains -.Dq 1 2 3 -after the loop is executed, ${b} -contains -.Dq ${j} ${j} ${j} -which expands to -.Dq 3 3 3 -since after the loop completes ${j} contains -.Dq 3 . -.El -.Ss Variable classes -The four different classes of variables (in order of increasing precedence) -are: -.Bl -tag -width Ds -.It Environment variables -Variables defined as part of -.Nm Ns 's -environment. -.It Global variables -Variables defined in the makefile or in included makefiles. -.It Command line variables -Variables defined as part of the command line. -.It Local variables -Variables that are defined specific to a certain target. -The seven local variables are as follows: -.Bl -tag -width ".ARCHIVE" -.It Va .ALLSRC -The list of all sources for this target; also known as -.Ql Va \&\*[Gt] . -.It Va .ARCHIVE -The name of the archive file. -.It Va .IMPSRC -In suffix-transformation rules, the name/path of the source from which the -target is to be transformed (the -.Dq implied -source); also known as -.Ql Va \&\*[Lt] . -It is not defined in explicit rules. -.It Va .MEMBER -The name of the archive member. -.It Va .OODATE -The list of sources for this target that were deemed out-of-date; also -known as -.Ql Va \&? . -.It Va .PREFIX -The file prefix of the target, containing only the file portion, no suffix -or preceding directory components; also known as -.Ql Va * . -.It Va .TARGET -The name of the target; also known as -.Ql Va @ . -.El -.Pp -The shorter forms -.Ql Va @ , -.Ql Va \&? , -.Ql Va \&\*[Lt] , -.Ql Va \&\*[Gt] , -and -.Ql Va * -are permitted for backward -compatibility with historical makefiles and are not recommended. -The six variables -.Ql Va "@F" , -.Ql Va "@D" , -.Ql Va "\*[Lt]F" , -.Ql Va "\*[Lt]D" , -.Ql Va "*F" , -and -.Ql Va "*D" -are permitted for compatibility with -.At V -makefiles and are not recommended. -.Pp -Four of the local variables may be used in sources on dependency lines -because they expand to the proper value for each target on the line. -These variables are -.Ql Va .TARGET , -.Ql Va .PREFIX , -.Ql Va .ARCHIVE , -and -.Ql Va .MEMBER . -.El -.Ss Additional built-in variables -In addition, -.Nm -sets or knows about the following variables: -.Bl -tag -width .MAKEOVERRIDES -.It Va \&$ -A single dollar sign -.Ql \&$ , -i.e. -.Ql \&$$ -expands to a single dollar -sign. -.It Va .ALLTARGETS -The list of all targets encountered in the Makefile. -If evaluated during -Makefile parsing, lists only those targets encountered thus far. -.It Va .CURDIR -A path to the directory where -.Nm -was executed. -Refer to the description of -.Ql Ev PWD -for more details. -.It Ev MAKE -The name that -.Nm -was executed with -.Pq Va argv[0] . -For compatibility -.Nm -also sets -.Va .MAKE -with the same value. -The preferred variable to use is the environment variable -.Ev MAKE -because it is more compatible with other versions of -.Nm -and cannot be confused with the special target with the same name. -.It Va .MAKE.DEPENDFILE -Names the makefile (default -.Ql Pa .depend ) -from which generated dependencies are read. -.It Va .MAKE.EXPORTED -The list of variables exported by -.Nm . -.It Va .MAKE.JOBS -The argument to the -.Fl j -option. -.It Va .MAKE.JOB.PREFIX -If -.Nm -is run with -.Ar j -then output for each target is prefixed with a token -.Ql --- target --- -the first part of which can be controlled via -.Va .MAKE.JOB.PREFIX . -.br -For example: -.Li .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}] -would produce tokens like -.Ql ---make[1234] target --- -making it easier to track the degree of parallelism being achieved. -.It Ev MAKEFLAGS -The environment variable -.Ql Ev MAKEFLAGS -may contain anything that -may be specified on -.Nm Ns 's -command line. -Anything specified on -.Nm Ns 's -command line is appended to the -.Ql Ev MAKEFLAGS -variable which is then -entered into the environment for all programs which -.Nm -executes. -.It Va .MAKE.LEVEL -The recursion depth of -.Nm . -The initial instance of -.Nm -will be 0, and an incremented value is put into the environment -to be seen by the next generation. -This allows tests like: -.Li .if ${.MAKE.LEVEL} == 0 -to protect things which should only be evaluated in the initial instance of -.Nm . -.It Va .MAKE.MAKEFILE_PREFERENCE -The ordered list of makefile names -(default -.Ql Pa makefile , -.Ql Pa Makefile ) -that -.Nm -will look for. -.It Va .MAKE.MAKEFILES -The list of makefiles read by -.Nm , -which is useful for tracking dependencies. -Each makefile is recorded only once, regardless of the number of times read. -.It Va .MAKE.MODE -Processed after reading all makefiles. -Can affect the mode that -.Nm -runs in. -It can contain a number of keywords: -.Bl -hang -width ignore-cmd -.It Pa compat -Like -.Fl B , -puts -.Nm -into "compat" mode. -.It Pa meta -Puts -.Nm -into "meta" mode, where meta files are created for each target -to capture the command run, the output generated and if -.Xr filemon 4 -is available, the system calls which are of interest to -.Nm . -The captured output can be very useful when diagnosing errors. -.It Pa curdirOk= Ar bf -Normally -.Nm -will not create .meta files in -.Ql Va .CURDIR . -This can be overridden by setting -.Va bf -to a value which represents True. -.It Pa env -For debugging, it can be useful to inlcude the environment -in the .meta file. -.It Pa verbose -If in "meta" mode, print a clue about the target being built. -This is useful if the build is otherwise running silently. -The message printed the value of: -.Va .MAKE.META.PREFIX . -.It Pa ignore-cmd -Some makefiles have commands which are simply not stable. -This keyword causes them to be ignored for -determining whether a target is out of date in "meta" mode. -See also -.Ic .NOMETA_CMP . -.It Pa silent= Ar bf -If -.Va bf -is True, when a .meta file is created, mark the target -.Ic .SILENT . -.El -.It Va .MAKE.META.BAILIWICK -In "meta" mode, provides a list of prefixes which -match the directories controlled by -.Nm . -If a file that was generated outside of -.Va .OBJDIR -but within said bailiwick is missing, -the current target is considered out-of-date. -.It Va .MAKE.META.CREATED -In "meta" mode, this variable contains a list of all the meta files -updated. -If not empty, it can be used to trigger processing of -.Va .MAKE.META.FILES . -.It Va .MAKE.META.FILES -In "meta" mode, this variable contains a list of all the meta files -used (updated or not). -This list can be used to process the meta files to extract dependency -information. -.It Va .MAKE.META.PREFIX -Defines the message printed for each meta file updated in "meta verbose" mode. -The default value is: -.Dl Building ${.TARGET:H:tA}/${.TARGET:T} -.It Va .MAKEOVERRIDES -This variable is used to record the names of variables assigned to -on the command line, so that they may be exported as part of -.Ql Ev MAKEFLAGS . -This behaviour can be disabled by assigning an empty value to -.Ql Va .MAKEOVERRIDES -within a makefile. -Extra variables can be exported from a makefile -by appending their names to -.Ql Va .MAKEOVERRIDES . -.Ql Ev MAKEFLAGS -is re-exported whenever -.Ql Va .MAKEOVERRIDES -is modified. -.It Va .MAKE.PID -The process-id of -.Nm . -.It Va .MAKE.PPID -The parent process-id of -.Nm . -.It Va MAKE_PRINT_VAR_ON_ERROR -When -.Nm -stops due to an error, it prints its name and the value of -.Ql Va .CURDIR -as well as the value of any variables named in -.Ql Va MAKE_PRINT_VAR_ON_ERROR . -.It Va .newline -This variable is simply assigned a newline character as its value. -This allows expansions using the -.Cm \&:@ -modifier to put a newline between -iterations of the loop rather than a space. -For example, the printing of -.Ql Va MAKE_PRINT_VAR_ON_ERROR -could be done as ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}. -.It Va .OBJDIR -A path to the directory where the targets are built. -Its value is determined by trying to -.Xr chdir 2 -to the following directories in order and using the first match: -.Bl -enum -.It -.Ev ${MAKEOBJDIRPREFIX}${.CURDIR} -.Pp -(Only if -.Ql Ev MAKEOBJDIRPREFIX -is set in the environment or on the command line.) -.It -.Ev ${MAKEOBJDIR} -.Pp -(Only if -.Ql Ev MAKEOBJDIR -is set in the environment or on the command line.) -.It -.Ev ${.CURDIR} Ns Pa /obj. Ns Ev ${MACHINE} -.It -.Ev ${.CURDIR} Ns Pa /obj -.It -.Pa /usr/obj/ Ns Ev ${.CURDIR} -.It -.Ev ${.CURDIR} -.El -.Pp -Variable expansion is performed on the value before it's used, -so expressions such as -.Dl ${.CURDIR:S,^/usr/src,/var/obj,} -may be used. -This is especially useful with -.Ql Ev MAKEOBJDIR . -.Pp -.Ql Va .OBJDIR -may be modified in the makefile as a global variable. -In all cases, -.Nm -will -.Xr chdir 2 -to -.Ql Va .OBJDIR -and set -.Ql Ev PWD -to that directory before executing any targets. -. -.It Va .PARSEDIR -A path to the directory of the current -.Ql Pa Makefile -being parsed. -.It Va .PARSEFILE -The basename of the current -.Ql Pa Makefile -being parsed. -This variable and -.Ql Va .PARSEDIR -are both set only while the -.Ql Pa Makefiles -are being parsed. -If you want to retain their current values, assign them to a variable -using assignment with expansion: -.Pq Ql Cm \&:= . -.It Va .PATH -A variable that represents the list of directories that -.Nm -will search for files. -The search list should be updated using the target -.Ql Va .PATH -rather than the variable. -.It Ev PWD -Alternate path to the current directory. -.Nm -normally sets -.Ql Va .CURDIR -to the canonical path given by -.Xr getcwd 3 . -However, if the environment variable -.Ql Ev PWD -is set and gives a path to the current directory, then -.Nm -sets -.Ql Va .CURDIR -to the value of -.Ql Ev PWD -instead. -This behaviour is disabled if -.Ql Ev MAKEOBJDIRPREFIX -is set or -.Ql Ev MAKEOBJDIR -contains a variable transform. -.Ql Ev PWD -is set to the value of -.Ql Va .OBJDIR -for all programs which -.Nm -executes. -.It Ev .TARGETS -The list of targets explicitly specified on the command line, if any. -.It Ev VPATH -Colon-separated -.Pq Dq \&: -lists of directories that -.Nm -will search for files. -The variable is supported for compatibility with old make programs only, -use -.Ql Va .PATH -instead. -.El -.Ss Variable modifiers -Variable expansion may be modified to select or modify each word of the -variable (where a -.Dq word -is white-space delimited sequence of characters). -The general format of a variable expansion is as follows: -.Pp -.Dl ${variable[:modifier[:...]]} -.Pp -Each modifier begins with a colon, -which may be escaped with a backslash -.Pq Ql \e . -.Pp -A set of modifiers can be specified via a variable, as follows: -.Pp -.Dl modifier_variable=modifier[:...] -.Dl ${variable:${modifier_variable}[:...]} -.Pp -In this case the first modifier in the modifier_variable does not -start with a colon, since that must appear in the referencing -variable. -If any of the modifiers in the modifier_variable contain a dollar sign -.Pq Ql $ , -these must be doubled to avoid early expansion. -.Pp -The supported modifiers are: -.Bl -tag -width EEE -.It Cm \&:E -Replaces each word in the variable with its suffix. -.It Cm \&:H -Replaces each word in the variable with everything but the last component. -.It Cm \&:M Ns Ar pattern -Select only those words that match -.Ar pattern . -The standard shell wildcard characters -.Pf ( Ql * , -.Ql \&? , -and -.Ql Oo Oc ) -may -be used. -The wildcard characters may be escaped with a backslash -.Pq Ql \e . -.It Cm \&:N Ns Ar pattern -This is identical to -.Ql Cm \&:M , -but selects all words which do not match -.Ar pattern . -.It Cm \&:O -Order every word in variable alphabetically. -To sort words in -reverse order use the -.Ql Cm \&:O:[-1..1] -combination of modifiers. -.It Cm \&:Ox -Randomize words in variable. -The results will be different each time you are referring to the -modified variable; use the assignment with expansion -.Pq Ql Cm \&:= -to prevent such behaviour. -For example, -.Bd -literal -offset indent -LIST= uno due tre quattro -RANDOM_LIST= ${LIST:Ox} -STATIC_RANDOM_LIST:= ${LIST:Ox} - -all: - @echo "${RANDOM_LIST}" - @echo "${RANDOM_LIST}" - @echo "${STATIC_RANDOM_LIST}" - @echo "${STATIC_RANDOM_LIST}" -.Ed -may produce output similar to: -.Bd -literal -offset indent -quattro due tre uno -tre due quattro uno -due uno quattro tre -due uno quattro tre -.Ed -.It Cm \&:Q -Quotes every shell meta-character in the variable, so that it can be passed -safely through recursive invocations of -.Nm . -.It Cm \&:R -Replaces each word in the variable with everything but its suffix. -.It Cm \&:gmtime -The value is a format string for -.Xr strftime 3 , -using the current -.Xr gmtime 3 . -.It Cm \&:hash -Compute a 32bit hash of the value and encode it as hex digits. -.It Cm \&:localtime -The value is a format string for -.Xr strftime 3 , -using the current -.Xr localtime 3 . -.It Cm \&:tA -Attempt to convert variable to an absolute path using -.Xr realpath 3 , -if that fails, the value is unchanged. -.It Cm \&:tl -Converts variable to lower-case letters. -.It Cm \&:ts Ns Ar c -Words in the variable are normally separated by a space on expansion. -This modifier sets the separator to the character -.Ar c . -If -.Ar c -is omitted, then no separator is used. -The common escapes (including octal numeric codes), work as expected. -.It Cm \&:tu -Converts variable to upper-case letters. -.It Cm \&:tW -Causes the value to be treated as a single word -(possibly containing embedded white space). -See also -.Ql Cm \&:[*] . -.It Cm \&:tw -Causes the value to be treated as a sequence of -words delimited by white space. -See also -.Ql Cm \&:[@] . -.Sm off -.It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW -.Sm on -Modify the first occurrence of -.Ar old_string -in the variable's value, replacing it with -.Ar new_string . -If a -.Ql g -is appended to the last slash of the pattern, all occurrences -in each word are replaced. -If a -.Ql 1 -is appended to the last slash of the pattern, only the first word -is affected. -If a -.Ql W -is appended to the last slash of the pattern, -then the value is treated as a single word -(possibly containing embedded white space). -If -.Ar old_string -begins with a caret -.Pq Ql ^ , -.Ar old_string -is anchored at the beginning of each word. -If -.Ar old_string -ends with a dollar sign -.Pq Ql \&$ , -it is anchored at the end of each word. -Inside -.Ar new_string , -an ampersand -.Pq Ql \*[Am] -is replaced by -.Ar old_string -(without any -.Ql ^ -or -.Ql \&$ ) . -Any character may be used as a delimiter for the parts of the modifier -string. -The anchoring, ampersand and delimiter characters may be escaped with a -backslash -.Pq Ql \e . -.Pp -Variable expansion occurs in the normal fashion inside both -.Ar old_string -and -.Ar new_string -with the single exception that a backslash is used to prevent the expansion -of a dollar sign -.Pq Ql \&$ , -not a preceding dollar sign as is usual. -.Sm off -.It Cm \&:C No \&/ Ar pattern No \&/ Ar replacement No \&/ Op Cm 1gW -.Sm on -The -.Cm \&:C -modifier is just like the -.Cm \&:S -modifier except that the old and new strings, instead of being -simple strings, are a regular expression (see -.Xr regex 3 ) -string -.Ar pattern -and an -.Xr ed 1 Ns \-style -string -.Ar replacement . -Normally, the first occurrence of the pattern -.Ar pattern -in each word of the value is substituted with -.Ar replacement . -The -.Ql 1 -modifier causes the substitution to apply to at most one word; the -.Ql g -modifier causes the substitution to apply to as many instances of the -search pattern -.Ar pattern -as occur in the word or words it is found in; the -.Ql W -modifier causes the value to be treated as a single word -(possibly containing embedded white space). -Note that -.Ql 1 -and -.Ql g -are orthogonal; the former specifies whether multiple words are -potentially affected, the latter whether multiple substitutions can -potentially occur within each affected word. -.It Cm \&:T -Replaces each word in the variable with its last component. -.It Cm \&:u -Remove adjacent duplicate words (like -.Xr uniq 1 ) . -.Sm off -.It Cm \&:\&? Ar true_string Cm \&: Ar false_string -.Sm on -If the variable name (not its value), when parsed as a .if conditional -expression, evaluates to true, return as its value the -.Ar true_string , -otherwise return the -.Ar false_string . -Since the variable name is used as the expression, \&:\&? must be the -first modifier after the variable name itself - which will, of course, -usually contain variable expansions. -A common error is trying to use expressions like -.Dl ${NUMBERS:M42:?match:no} -which actually tests defined(NUMBERS), -to determine is any words match "42" you need to use something like: -.Dl ${"${NUMBERS:M42}" != \&"\&":?match:no} . -.It Ar :old_string=new_string -This is the -.At V -style variable substitution. -It must be the last modifier specified. -If -.Ar old_string -or -.Ar new_string -do not contain the pattern matching character -.Ar % -then it is assumed that they are -anchored at the end of each word, so only suffixes or entire -words may be replaced. -Otherwise -.Ar % -is the substring of -.Ar old_string -to be replaced in -.Ar new_string . -.Pp -Variable expansion occurs in the normal fashion inside both -.Ar old_string -and -.Ar new_string -with the single exception that a backslash is used to prevent the -expansion of a dollar sign -.Pq Ql \&$ , -not a preceding dollar sign as is usual. -.Sm off -.It Cm \&:@ Ar temp Cm @ Ar string Cm @ -.Sm on -This is the loop expansion mechanism from the OSF Development -Environment (ODE) make. -Unlike -.Cm \&.for -loops expansion occurs at the time of -reference. -Assign -.Ar temp -to each word in the variable and evaluate -.Ar string . -The ODE convention is that -.Ar temp -should start and end with a period. -For example. -.Dl ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@} -.Pp -However a single character varaiable is often more readable: -.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@} -.It Cm \&:U Ns Ar newval -If the variable is undefined -.Ar newval -is the value. -If the variable is defined, the existing value is returned. -This is another ODE make feature. -It is handy for setting per-target CFLAGS for instance: -.Dl ${_${.TARGET:T}_CFLAGS:U${DEF_CFLAGS}} -If a value is only required if the variable is undefined, use: -.Dl ${VAR:D:Unewval} -.It Cm \&:D Ns Ar newval -If the variable is defined -.Ar newval -is the value. -.It Cm \&:L -The name of the variable is the value. -.It Cm \&:P -The path of the node which has the same name as the variable -is the value. -If no such node exists or its path is null, then the -name of the variable is used. -In order for this modifier to work, the name (node) must at least have -appeared on the rhs of a dependency. -.Sm off -.It Cm \&:\&! Ar cmd Cm \&! -.Sm on -The output of running -.Ar cmd -is the value. -.It Cm \&:sh -If the variable is non-empty it is run as a command and the output -becomes the new value. -.It Cm \&::= Ns Ar str -The variable is assigned the value -.Ar str -after substitution. -This modifier and its variations are useful in -obscure situations such as wanting to set a variable when shell commands -are being parsed. -These assignment modifiers always expand to -nothing, so if appearing in a rule line by themselves should be -preceded with something to keep -.Nm -happy. -.Pp -The -.Ql Cm \&:: -helps avoid false matches with the -.At V -style -.Cm \&:= -modifier and since substitution always occurs the -.Cm \&::= -form is vaguely appropriate. -.It Cm \&::?= Ns Ar str -As for -.Cm \&::= -but only if the variable does not already have a value. -.It Cm \&::+= Ns Ar str -Append -.Ar str -to the variable. -.It Cm \&::!= Ns Ar cmd -Assign the output of -.Ar cmd -to the variable. -.It Cm \&:\&[ Ns Ar range Ns Cm \&] -Selects one or more words from the value, -or performs other operations related to the way in which the -value is divided into words. -.Pp -Ordinarily, a value is treated as a sequence of words -delimited by white space. -Some modifiers suppress this behaviour, -causing a value to be treated as a single word -(possibly containing embedded white space). -An empty value, or a value that consists entirely of white-space, -is treated as a single word. -For the purposes of the -.Ql Cm \&:[] -modifier, the words are indexed both forwards using positive integers -(where index 1 represents the first word), -and backwards using negative integers -(where index \-1 represents the last word). -.Pp -The -.Ar range -is subjected to variable expansion, and the expanded result is -then interpreted as follows: -.Bl -tag -width index -.\" :[n] -.It Ar index -Selects a single word from the value. -.\" :[start..end] -.It Ar start Ns Cm \&.. Ns Ar end -Selects all words from -.Ar start -to -.Ar end , -inclusive. -For example, -.Ql Cm \&:[2..-1] -selects all words from the second word to the last word. -If -.Ar start -is greater than -.Ar end , -then the words are output in reverse order. -For example, -.Ql Cm \&:[-1..1] -selects all the words from last to first. -.\" :[*] -.It Cm \&* -Causes subsequent modifiers to treat the value as a single word -(possibly containing embedded white space). -Analogous to the effect of -\&"$*\&" -in Bourne shell. -.\" :[0] -.It 0 -Means the same as -.Ql Cm \&:[*] . -.\" :[*] -.It Cm \&@ -Causes subsequent modifiers to treat the value as a sequence of words -delimited by white space. -Analogous to the effect of -\&"$@\&" -in Bourne shell. -.\" :[#] -.It Cm \&# -Returns the number of words in the value. -.El \" :[range] -.El -.Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS -Makefile inclusion, conditional structures and for loops reminiscent -of the C programming language are provided in -.Nm . -All such structures are identified by a line beginning with a single -dot -.Pq Ql \&. -character. -Files are included with either -.Cm \&.include Aq Ar file -or -.Cm \&.include Pf \*q Ar file Ns \*q . -Variables between the angle brackets or double quotes are expanded -to form the file name. -If angle brackets are used, the included makefile is expected to be in -the system makefile directory. -If double quotes are used, the including makefile's directory and any -directories specified using the -.Fl I -option are searched before the system -makefile directory. -For compatibility with other versions of -.Nm -.Ql include file ... -is also accepted. -If the include statement is written as -.Cm .-include -or as -.Cm .sinclude -then errors locating and/or opening include files are ignored. -.Pp -Conditional expressions are also preceded by a single dot as the first -character of a line. -The possible conditionals are as follows: -.Bl -tag -width Ds -.It Ic .error Ar message -The message is printed along with the name of the makefile and line number, -then -.Nm -will exit. -.It Ic .export Ar variable ... -Export the specified global variable. -If no variable list is provided, all globals are exported -except for internal variables (those that start with -.Ql \&. ) . -This is not affected by the -.Fl X -flag, so should be used with caution. -For compatibility with other -.Nm -programs -.Ql export variable=value -is also accepted. -.Pp -Appending a variable name to -.Va .MAKE.EXPORTED -is equivalent to exporting a variable. -.It Ic .export-env Ar variable ... -The same as -.Ql .export , -except that the variable is not appended to -.Va .MAKE.EXPORTED . -This allows exporting a value to the environment which is different from that -used by -.Nm -internally. -.It Ic .info Ar message -The message is printed along with the name of the makefile and line number. -.It Ic .undef Ar variable -Un-define the specified global variable. -Only global variables may be un-defined. -.It Ic .unexport Ar variable ... -The opposite of -.Ql .export . -The specified global -.Va variable -will be removed from -.Va .MAKE.EXPORTED . -If no variable list is provided, all globals are unexported, -and -.Va .MAKE.EXPORTED -deleted. -.It Ic .unexport-env -Unexport all globals previously exported and -clear the environment inherited from the parent. -This operation will cause a memory leak of the original environment, -so should be used sparingly. -Testing for -.Va .MAKE.LEVEL -being 0, would make sense. -Also note that any variables which originated in the parent environment -should be explicitly preserved if desired. -For example: -.Bd -literal -offset indent -.Li .if ${.MAKE.LEVEL} == 0 -PATH := ${PATH} -.Li .unexport-env -.Li .export PATH -.Li .endif -.Pp -.Ed -Would result in an environment containing only -.Ql Ev PATH , -which is the minimal useful environment. -Actually -.Ql Ev .MAKE.LEVEL -will also be pushed into the new environment. -.It Ic .warning Ar message -The message prefixed by -.Ql Pa warning: -is printed along with the name of the makefile and line number. -.It Ic \&.if Oo \&! Oc Ns Ar expression Op Ar operator expression ... -Test the value of an expression. -.It Ic .ifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -Test the value of a variable. -.It Ic .ifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -Test the value of a variable. -.It Ic .ifmake Oo \&! Oc Ns Ar target Op Ar operator target ... -Test the target being built. -.It Ic .ifnmake Oo \&! Ns Oc Ar target Op Ar operator target ... -Test the target being built. -.It Ic .else -Reverse the sense of the last conditional. -.It Ic .elif Oo \&! Ns Oc Ar expression Op Ar operator expression ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .if . -.It Ic .elifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifdef . -.It Ic .elifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifndef . -.It Ic .elifmake Oo \&! Oc Ns Ar target Op Ar operator target ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifmake . -.It Ic .elifnmake Oo \&! Oc Ns Ar target Op Ar operator target ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifnmake . -.It Ic .endif -End the body of the conditional. -.El -.Pp -The -.Ar operator -may be any one of the following: -.Bl -tag -width "Cm XX" -.It Cm \&|\&| -Logical OR. -.It Cm \&\*[Am]\*[Am] -Logical -.Tn AND ; -of higher precedence than -.Dq \&|\&| . -.El -.Pp -As in C, -.Nm -will only evaluate a conditional as far as is necessary to determine -its value. -Parentheses may be used to change the order of evaluation. -The boolean operator -.Ql Ic \&! -may be used to logically negate an entire -conditional. -It is of higher precedence than -.Ql Ic \&\*[Am]\*[Am] . -.Pp -The value of -.Ar expression -may be any of the following: -.Bl -tag -width defined -.It Ic defined -Takes a variable name as an argument and evaluates to true if the variable -has been defined. -.It Ic make -Takes a target name as an argument and evaluates to true if the target -was specified as part of -.Nm Ns 's -command line or was declared the default target (either implicitly or -explicitly, see -.Va .MAIN ) -before the line containing the conditional. -.It Ic empty -Takes a variable, with possible modifiers, and evaluates to true if -the expansion of the variable would result in an empty string. -.It Ic exists -Takes a file name as an argument and evaluates to true if the file exists. -The file is searched for on the system search path (see -.Va .PATH ) . -.It Ic target -Takes a target name as an argument and evaluates to true if the target -has been defined. -.It Ic commands -Takes a target name as an argument and evaluates to true if the target -has been defined and has commands associated with it. -.El -.Pp -.Ar Expression -may also be an arithmetic or string comparison. -Variable expansion is -performed on both sides of the comparison, after which the integral -values are compared. -A value is interpreted as hexadecimal if it is -preceded by 0x, otherwise it is decimal; octal numbers are not supported. -The standard C relational operators are all supported. -If after -variable expansion, either the left or right hand side of a -.Ql Ic == -or -.Ql Ic "!=" -operator is not an integral value, then -string comparison is performed between the expanded -variables. -If no relational operator is given, it is assumed that the expanded -variable is being compared against 0 or an empty string in the case -of a string comparison. -.Pp -When -.Nm -is evaluating one of these conditional expressions, and it encounters -a (white-space separated) word it doesn't recognize, either the -.Dq make -or -.Dq defined -expression is applied to it, depending on the form of the conditional. -If the form is -.Ql Ic .ifdef , -.Ql Ic .ifndef , -or -.Ql Ic .if -the -.Dq defined -expression is applied. -Similarly, if the form is -.Ql Ic .ifmake -or -.Ql Ic .ifnmake , the -.Dq make -expression is applied. -.Pp -If the conditional evaluates to true the parsing of the makefile continues -as before. -If it evaluates to false, the following lines are skipped. -In both cases this continues until a -.Ql Ic .else -or -.Ql Ic .endif -is found. -.Pp -For loops are typically used to apply a set of rules to a list of files. -The syntax of a for loop is: -.Pp -.Bl -tag -compact -width Ds -.It Ic \&.for Ar variable Oo Ar variable ... Oc Ic in Ar expression -.It Aq make-rules -.It Ic \&.endfor -.El -.Pp -After the for -.Ic expression -is evaluated, it is split into words. -On each iteration of the loop, one word is taken and assigned to each -.Ic variable , -in order, and these -.Ic variables -are substituted into the -.Ic make-rules -inside the body of the for loop. -The number of words must come out even; that is, if there are three -iteration variables, the number of words provided must be a multiple -of three. -.Sh COMMENTS -Comments begin with a hash -.Pq Ql \&# -character, anywhere but in a shell -command line, and continue to the end of an unescaped new line. -.Sh SPECIAL SOURCES (ATTRIBUTES) -.Bl -tag -width .IGNOREx -.It Ic .EXEC -Target is never out of date, but always execute commands anyway. -.It Ic .IGNORE -Ignore any errors from the commands associated with this target, exactly -as if they all were preceded by a dash -.Pq Ql \- . -.\" .It Ic .INVISIBLE -.\" XXX -.\" .It Ic .JOIN -.\" XXX -.It Ic .MADE -Mark all sources of this target as being up-to-date. -.It Ic .MAKE -Execute the commands associated with this target even if the -.Fl n -or -.Fl t -options were specified. -Normally used to mark recursive -.Nm Ns 's . -.It Ic .META -Create a meta file for the target, even if it is flagged as -.Ic .PHONY , -.Ic .MAKE , -or -.Ic .SPECIAL . -Usage in conjunction with -.Ic .MAKE -is the most likely case. -In "meta" mode, the target is out-of-date if the meta file is missing. -.It Ic .NOMETA -Do not create a meta file for the target. -Meta files are also not created for -.Ic .PHONY , -.Ic .MAKE , -or -.Ic .SPECIAL -targets. -.It Ic .NOMETA_CMP -Ignore differences in commands when deciding if target is out of date. -This is useful if the command contains a value which always changes. -If the number of commands change, though, the target will still be out of date. -.It Ic .NOPATH -Do not search for the target in the directories specified by -.Ic .PATH . -.It Ic .NOTMAIN -Normally -.Nm -selects the first target it encounters as the default target to be built -if no target was specified. -This source prevents this target from being selected. -.It Ic .OPTIONAL -If a target is marked with this attribute and -.Nm -can't figure out how to create it, it will ignore this fact and assume -the file isn't needed or already exists. -.It Ic .PHONY -The target does not -correspond to an actual file; it is always considered to be out of date, -and will not be created with the -.Fl t -option. -Suffix-transformation rules are not applied to -.Ic .PHONY -targets. -.It Ic .PRECIOUS -When -.Nm -is interrupted, it normally removes any partially made targets. -This source prevents the target from being removed. -.It Ic .RECURSIVE -Synonym for -.Ic .MAKE . -.It Ic .SILENT -Do not echo any of the commands associated with this target, exactly -as if they all were preceded by an at sign -.Pq Ql @ . -.It Ic .USE -Turn the target into -.Nm Ns 's -version of a macro. -When the target is used as a source for another target, the other target -acquires the commands, sources, and attributes (except for -.Ic .USE ) -of the -source. -If the target already has commands, the -.Ic .USE -target's commands are appended -to them. -.It Ic .USEBEFORE -Exactly like -.Ic .USE , -but prepend the -.Ic .USEBEFORE -target commands to the target. -.It Ic .WAIT -If -.Ic .WAIT -appears in a dependency line, the sources that precede it are -made before the sources that succeed it in the line. -Since the dependents of files are not made until the file itself -could be made, this also stops the dependents being built unless they -are needed for another branch of the dependency tree. -So given: -.Bd -literal -x: a .WAIT b - echo x -a: - echo a -b: b1 - echo b -b1: - echo b1 - -.Ed -the output is always -.Ql a , -.Ql b1 , -.Ql b , -.Ql x . -.br -The ordering imposed by -.Ic .WAIT -is only relevant for parallel makes. -.El -.Sh SPECIAL TARGETS -Special targets may not be included with other targets, i.e. they must be -the only target specified. -.Bl -tag -width .BEGINx -.It Ic .BEGIN -Any command lines attached to this target are executed before anything -else is done. -.It Ic .DEFAULT -This is sort of a -.Ic .USE -rule for any target (that was used only as a -source) that -.Nm -can't figure out any other way to create. -Only the shell script is used. -The -.Ic .IMPSRC -variable of a target that inherits -.Ic .DEFAULT Ns 's -commands is set -to the target's own name. -.It Ic .END -Any command lines attached to this target are executed after everything -else is done. -.It Ic .ERROR -Any command lines attached to this target are executed when another target fails. -The -.Ic .ERROR_TARGET -variable is set to the target that failed. -See also -.Ic MAKE_PRINT_VAR_ON_ERROR . -.It Ic .IGNORE -Mark each of the sources with the -.Ic .IGNORE -attribute. -If no sources are specified, this is the equivalent of specifying the -.Fl i -option. -.It Ic .INTERRUPT -If -.Nm -is interrupted, the commands for this target will be executed. -.It Ic .MAIN -If no target is specified when -.Nm -is invoked, this target will be built. -.It Ic .MAKEFLAGS -This target provides a way to specify flags for -.Nm -when the makefile is used. -The flags are as if typed to the shell, though the -.Fl f -option will have -no effect. -.\" XXX: NOT YET!!!! -.\" .It Ic .NOTPARALLEL -.\" The named targets are executed in non parallel mode. -.\" If no targets are -.\" specified, then all targets are executed in non parallel mode. -.It Ic .NOPATH -Apply the -.Ic .NOPATH -attribute to any specified sources. -.It Ic .NOTPARALLEL -Disable parallel mode. -.It Ic .NO_PARALLEL -Synonym for -.Ic .NOTPARALLEL , -for compatibility with other pmake variants. -.It Ic .ORDER -The named targets are made in sequence. -This ordering does not add targets to the list of targets to be made. -Since the dependents of a target do not get built until the target itself -could be built, unless -.Ql a -is built by another part of the dependency graph, -the following is a dependency loop: -.Bd -literal -\&.ORDER: b a -b: a -.Ed -.Pp -The ordering imposed by -.Ic .ORDER -is only relevant for parallel makes. -.\" XXX: NOT YET!!!! -.\" .It Ic .PARALLEL -.\" The named targets are executed in parallel mode. -.\" If no targets are -.\" specified, then all targets are executed in parallel mode. -.It Ic .PATH -The sources are directories which are to be searched for files not -found in the current directory. -If no sources are specified, any previously specified directories are -deleted. -If the source is the special -.Ic .DOTLAST -target, then the current working -directory is searched last. -.It Ic .PHONY -Apply the -.Ic .PHONY -attribute to any specified sources. -.It Ic .PRECIOUS -Apply the -.Ic .PRECIOUS -attribute to any specified sources. -If no sources are specified, the -.Ic .PRECIOUS -attribute is applied to every -target in the file. -.It Ic .SHELL -Sets the shell that -.Nm -will use to execute commands. -The sources are a set of -.Ar field=value -pairs. -.Bl -tag -width hasErrCtls -.It Ar name -This is the minimal specification, used to select one of the builtin -shell specs; -.Ar sh , -.Ar ksh , -and -.Ar csh . -.It Ar path -Specifies the path to the shell. -.It Ar hasErrCtl -Indicates whether the shell supports exit on error. -.It Ar check -The command to turn on error checking. -.It Ar ignore -The command to disable error checking. -.It Ar echo -The command to turn on echoing of commands executed. -.It Ar quiet -The command to turn off echoing of commands executed. -.It Ar filter -The output to filter after issuing the -.Ar quiet -command. -It is typically identical to -.Ar quiet . -.It Ar errFlag -The flag to pass the shell to enable error checking. -.It Ar echoFlag -The flag to pass the shell to enable command echoing. -.It Ar newline -The string literal to pass the shell that results in a single newline -character when used outside of any quoting characters. -.El -Example: -.Bd -literal -\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \e - check="set \-e" ignore="set +e" \e - echo="set \-v" quiet="set +v" filter="set +v" \e - echoFlag=v errFlag=e newline="'\en'" -.Ed -.It Ic .SILENT -Apply the -.Ic .SILENT -attribute to any specified sources. -If no sources are specified, the -.Ic .SILENT -attribute is applied to every -command in the file. -.It Ic .SUFFIXES -Each source specifies a suffix to -.Nm . -If no sources are specified, any previously specified suffixes are deleted. -It allows the creation of suffix-transformation rules. -.Pp -Example: -.Bd -literal -\&.SUFFIXES: .o -\&.c.o: - cc \-o ${.TARGET} \-c ${.IMPSRC} -.Ed -.El -.Sh ENVIRONMENT -.Nm -uses the following environment variables, if they exist: -.Ev MACHINE , -.Ev MACHINE_ARCH , -.Ev MAKE , -.Ev MAKEFLAGS , -.Ev MAKEOBJDIR , -.Ev MAKEOBJDIRPREFIX , -.Ev MAKESYSPATH , -.Ev PWD , -and -.Ev TMPDIR . -.Pp -.Ev MAKEOBJDIRPREFIX -and -.Ev MAKEOBJDIR -may only be set in the environment or on the command line to -.Nm -and not as makefile variables; -see the description of -.Ql Va .OBJDIR -for more details. -.Sh FILES -.Bl -tag -width /usr/share/mk -compact -.It .depend -list of dependencies -.It Makefile -list of dependencies -.It makefile -list of dependencies -.It sys.mk -system makefile -.It /usr/share/mk -system makefile directory -.El -.Sh COMPATIBILITY -The basic make syntax is compatible between different versions of make, -however the special variables, variable modifiers and conditionals are not. -.Pp -The way that parallel makes are scheduled changed in -.Nx 4.0 -so that .ORDER and .WAIT apply recursively to the dependent nodes. -The algorithms used may change again in the future. -.Pp -The way that .for loop variables are substituted changed after -.Nx 5.0 -so that they still appear to be variable expansions. -In particular this stops them being treated as syntax, and removes some -obscure problems using them in .if statements. -.Pp -Unlike other -.Nm -programs, this implementation by default executes all commands for a given -target using a single shell invocation. -This is done for both efficiency and to simplify error handling in remote -command invocations. -Typically this is transparent to the user, unless the target commands change -the current working directory using -.Dq cd -or -.Dq chdir . -To be compatible with Makefiles that do this, one can use -.Fl B -to disable this behavior. -.Sh SEE ALSO -.Xr mkdep 1 -.Sh HISTORY -A -.Nm -command appeared in -.At v7 . -This -.Nm -implementation is based on Adam De Boor's pmake program which was written -for Sprint at Berkeley. -It was designed to be a parallel distributed make running jobs on different -machines using a daemon called -.Dq customs . -.Sh BUGS -The -.Nm -syntax is difficult to parse without actually acting of the data. -For instance finding the end of a variable use should involve scanning each -the modifiers using the correct terminator for each field. -In many places -.Nm -just counts {} and () in order to find the end of a variable expansion. -.Pp -There is no way of escaping a space character in a filename. diff --git a/20120831/make.c b/20120831/make.c deleted file mode 100644 index 4fa4ff9..0000000 --- a/20120831/make.c +++ /dev/null @@ -1,1561 +0,0 @@ -/* $NetBSD: make.c,v 1.87 2012/06/12 19:21:51 joerg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: make.c,v 1.87 2012/06/12 19:21:51 joerg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: make.c,v 1.87 2012/06/12 19:21:51 joerg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * make.c -- - * The functions which perform the examination of targets and - * their suitability for creation - * - * Interface: - * Make_Run Initialize things for the module and recreate - * whatever needs recreating. Returns TRUE if - * work was (or would have been) done and FALSE - * otherwise. - * - * Make_Update Update all parents of a given child. Performs - * various bookkeeping chores like the updating - * of the cmgn field of the parent, filling - * of the IMPSRC context variable, etc. It will - * place the parent on the toBeMade queue if it - * should be. - * - * Make_TimeStamp Function to set the parent's cmgn field - * based on a child's modification time. - * - * Make_DoAllVar Set up the various local variables for a - * target, including the .ALLSRC variable, making - * sure that any variable that needs to exist - * at the very least has the empty value. - * - * Make_OODate Determine if a target is out-of-date. - * - * Make_HandleUse See if a child is a .USE node for a parent - * and perform the .USE actions if so. - * - * Make_ExpandUse Expand .USE nodes - */ - -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "job.h" - -static unsigned int checked = 1;/* Sequence # to detect recursion */ -static Lst toBeMade; /* The current fringe of the graph. These - * are nodes which await examination by - * MakeOODate. It is added to by - * Make_Update and subtracted from by - * MakeStartJobs */ - -static int MakeAddChild(void *, void *); -static int MakeFindChild(void *, void *); -static int MakeUnmark(void *, void *); -static int MakeAddAllSrc(void *, void *); -static int MakeTimeStamp(void *, void *); -static int MakeHandleUse(void *, void *); -static Boolean MakeStartJobs(void); -static int MakePrintStatus(void *, void *); -static int MakeCheckOrder(void *, void *); -static int MakeBuildChild(void *, void *); -static int MakeBuildParent(void *, void *); - -MAKE_ATTR_DEAD static void -make_abort(GNode *gn, int line) -{ - static int two = 2; - - fprintf(debug_file, "make_abort from line %d\n", line); - Targ_PrintNode(gn, &two); - Lst_ForEach(toBeMade, Targ_PrintNode, &two); - Targ_PrintGraph(3); - abort(); -} - -/*- - *----------------------------------------------------------------------- - * Make_TimeStamp -- - * Set the cmgn field of a parent node based on the mtime stamp in its - * child. Called from MakeOODate via Lst_ForEach. - * - * Input: - * pgn the current parent - * cgn the child we've just examined - * - * Results: - * Always returns 0. - * - * Side Effects: - * The cmgn of the parent node will be changed if the mtime - * field of the child is greater than it. - *----------------------------------------------------------------------- - */ -int -Make_TimeStamp(GNode *pgn, GNode *cgn) -{ - if (pgn->cmgn == NULL || cgn->mtime > pgn->cmgn->mtime) { - pgn->cmgn = cgn; - } - return (0); -} - -/* - * Input: - * pgn the current parent - * cgn the child we've just examined - * - */ -static int -MakeTimeStamp(void *pgn, void *cgn) -{ - return Make_TimeStamp((GNode *)pgn, (GNode *)cgn); -} - -/*- - *----------------------------------------------------------------------- - * Make_OODate -- - * See if a given node is out of date with respect to its sources. - * Used by Make_Run when deciding which nodes to place on the - * toBeMade queue initially and by Make_Update to screen out USE and - * EXEC nodes. In the latter case, however, any other sort of node - * must be considered out-of-date since at least one of its children - * will have been recreated. - * - * Input: - * gn the node to check - * - * Results: - * TRUE if the node is out of date. FALSE otherwise. - * - * Side Effects: - * The mtime field of the node and the cmgn field of its parents - * will/may be changed. - *----------------------------------------------------------------------- - */ -Boolean -Make_OODate(GNode *gn) -{ - Boolean oodate; - - /* - * Certain types of targets needn't even be sought as their datedness - * doesn't depend on their modification time... - */ - if ((gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC)) == 0) { - (void)Dir_MTime(gn, 1); - if (DEBUG(MAKE)) { - if (gn->mtime != 0) { - fprintf(debug_file, "modified %s...", Targ_FmtTime(gn->mtime)); - } else { - fprintf(debug_file, "non-existent..."); - } - } - } - - /* - * A target is remade in one of the following circumstances: - * its modification time is smaller than that of its youngest child - * and it would actually be run (has commands or type OP_NOP) - * it's the object of a force operator - * 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. - * - * These weird rules are brought to you by Backward-Compatibility and - * the strange people who wrote 'Make'. - */ - if (gn->type & (OP_USE|OP_USEBEFORE)) { - /* - * If the node is a USE node it is *never* out of date - * no matter *what*. - */ - if (DEBUG(MAKE)) { - fprintf(debug_file, ".USE node..."); - } - oodate = FALSE; - } else if ((gn->type & OP_LIB) && - ((gn->mtime==0) || Arch_IsLib(gn))) { - if (DEBUG(MAKE)) { - fprintf(debug_file, "library..."); - } - - /* - * always out of date if no children and :: target - * or non-existent. - */ - oodate = (gn->mtime == 0 || Arch_LibOODate(gn) || - (gn->cmgn == NULL && (gn->type & OP_DOUBLEDEP))); - } else if (gn->type & OP_JOIN) { - /* - * A target with the .JOIN attribute is only considered - * out-of-date if any of its children was out-of-date. - */ - if (DEBUG(MAKE)) { - fprintf(debug_file, ".JOIN node..."); - } - if (DEBUG(MAKE)) { - fprintf(debug_file, "source %smade...", gn->flags & CHILDMADE ? "" : "not "); - } - oodate = (gn->flags & CHILDMADE) ? TRUE : FALSE; - } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) { - /* - * A node which is the object of the force (!) operator or which has - * the .EXEC attribute is always considered out-of-date. - */ - if (DEBUG(MAKE)) { - if (gn->type & OP_FORCE) { - fprintf(debug_file, "! operator..."); - } else if (gn->type & OP_PHONY) { - fprintf(debug_file, ".PHONY node..."); - } else { - fprintf(debug_file, ".EXEC node..."); - } - } - oodate = TRUE; - } else if ((gn->cmgn != NULL && gn->mtime < gn->cmgn->mtime) || - (gn->cmgn == NULL && - ((gn->mtime == 0 && !(gn->type & OP_OPTIONAL)) - || gn->type & OP_DOUBLEDEP))) - { - /* - * A node whose modification time is less than that of its - * youngest child or that has no children (cmgn == NULL) and - * either doesn't exist (mtime == 0) and it isn't optional - * or was the object of a * :: operator is out-of-date. - * Why? Because that's the way Make does it. - */ - if (DEBUG(MAKE)) { - if (gn->cmgn != NULL && gn->mtime < gn->cmgn->mtime) { - fprintf(debug_file, "modified before source %s...", - gn->cmgn->path); - } else if (gn->mtime == 0) { - fprintf(debug_file, "non-existent and no sources..."); - } else { - fprintf(debug_file, ":: operator and no sources..."); - } - } - oodate = TRUE; - } else { - /* - * When a non-existing child with no sources - * (such as a typically used FORCE source) has been made and - * the target of the child (usually a directory) has the same - * timestamp as the timestamp just given to the non-existing child - * after it was considered made. - */ - if (DEBUG(MAKE)) { - if (gn->flags & FORCE) - fprintf(debug_file, "non existing child..."); - } - oodate = (gn->flags & FORCE) ? TRUE : FALSE; - } - -#ifdef USE_META - if (useMeta) { - oodate = meta_oodate(gn, oodate); - } -#endif - - /* - * If the target isn't out-of-date, the parents need to know its - * modification time. Note that targets that appear to be out-of-date - * but aren't, because they have no commands and aren't of type OP_NOP, - * have their mtime stay below their children's mtime to keep parents from - * thinking they're out-of-date. - */ - if (!oodate) { - Lst_ForEach(gn->parents, MakeTimeStamp, gn); - } - - return (oodate); -} - -/*- - *----------------------------------------------------------------------- - * MakeAddChild -- - * Function used by Make_Run to add a child to the list l. - * It will only add the child if its make field is FALSE. - * - * Input: - * gnp the node to add - * lp the list to which to add it - * - * Results: - * Always returns 0 - * - * Side Effects: - * The given list is extended - *----------------------------------------------------------------------- - */ -static int -MakeAddChild(void *gnp, void *lp) -{ - GNode *gn = (GNode *)gnp; - Lst l = (Lst) lp; - - if ((gn->flags & REMAKE) == 0 && !(gn->type & (OP_USE|OP_USEBEFORE))) { - if (DEBUG(MAKE)) - fprintf(debug_file, "MakeAddChild: need to examine %s%s\n", - gn->name, gn->cohort_num); - (void)Lst_EnQueue(l, gn); - } - return (0); -} - -/*- - *----------------------------------------------------------------------- - * MakeFindChild -- - * Function used by Make_Run to find the pathname of a child - * that was already made. - * - * Input: - * gnp the node to find - * - * Results: - * Always returns 0 - * - * Side Effects: - * The path and mtime of the node and the cmgn of the parent are - * updated; the unmade children count of the parent is decremented. - *----------------------------------------------------------------------- - */ -static int -MakeFindChild(void *gnp, void *pgnp) -{ - GNode *gn = (GNode *)gnp; - GNode *pgn = (GNode *)pgnp; - - (void)Dir_MTime(gn, 0); - Make_TimeStamp(pgn, gn); - pgn->unmade--; - - return (0); -} - -/*- - *----------------------------------------------------------------------- - * Make_HandleUse -- - * Function called by Make_Run and SuffApplyTransform on the downward - * pass to handle .USE and transformation nodes. It implements the - * .USE and transformation functionality by copying the node's commands, - * type flags and children to the parent node. - * - * A .USE node is much like an explicit transformation rule, except - * its commands are always added to the target node, even if the - * target already has commands. - * - * Input: - * cgn The .USE node - * pgn The target of the .USE node - * - * Results: - * none - * - * Side Effects: - * Children and commands may be added to the parent and the parent's - * type may be changed. - * - *----------------------------------------------------------------------- - */ -void -Make_HandleUse(GNode *cgn, GNode *pgn) -{ - LstNode ln; /* An element in the children list */ - -#ifdef DEBUG_SRC - if ((cgn->type & (OP_USE|OP_USEBEFORE|OP_TRANSFORM)) == 0) { - fprintf(debug_file, "Make_HandleUse: called for plain node %s\n", cgn->name); - return; - } -#endif - - if ((cgn->type & (OP_USE|OP_USEBEFORE)) || Lst_IsEmpty(pgn->commands)) { - if (cgn->type & OP_USEBEFORE) { - /* - * .USEBEFORE -- - * prepend the child's commands to the parent. - */ - Lst cmds = pgn->commands; - pgn->commands = Lst_Duplicate(cgn->commands, NULL); - (void)Lst_Concat(pgn->commands, cmds, LST_CONCNEW); - Lst_Destroy(cmds, NULL); - } else { - /* - * .USE or target has no commands -- - * append the child's commands to the parent. - */ - (void)Lst_Concat(pgn->commands, cgn->commands, LST_CONCNEW); - } - } - - if (Lst_Open(cgn->children) == SUCCESS) { - while ((ln = Lst_Next(cgn->children)) != NULL) { - GNode *tgn, *gn = (GNode *)Lst_Datum(ln); - - /* - * Expand variables in the .USE node's name - * and save the unexpanded form. - * We don't need to do this for commands. - * They get expanded properly when we execute. - */ - if (gn->uname == NULL) { - gn->uname = gn->name; - } else { - if (gn->name) - free(gn->name); - } - gn->name = Var_Subst(NULL, gn->uname, pgn, FALSE); - if (gn->name && gn->uname && strcmp(gn->name, gn->uname) != 0) { - /* See if we have a target for this node. */ - tgn = Targ_FindNode(gn->name, TARG_NOCREATE); - if (tgn != NULL) - gn = tgn; - } - - (void)Lst_AtEnd(pgn->children, gn); - (void)Lst_AtEnd(gn->parents, pgn); - pgn->unmade += 1; - } - Lst_Close(cgn->children); - } - - pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_USEBEFORE|OP_TRANSFORM); -} - -/*- - *----------------------------------------------------------------------- - * MakeHandleUse -- - * Callback function for Lst_ForEach, used by Make_Run on the downward - * pass to handle .USE nodes. Should be called before the children - * are enqueued to be looked at by MakeAddChild. - * This function calls Make_HandleUse to copy the .USE node's commands, - * type flags and children to the parent node. - * - * Input: - * cgnp the child we've just examined - * pgnp the current parent - * - * Results: - * returns 0. - * - * Side Effects: - * After expansion, .USE child nodes are removed from the parent - * - *----------------------------------------------------------------------- - */ -static int -MakeHandleUse(void *cgnp, void *pgnp) -{ - GNode *cgn = (GNode *)cgnp; - GNode *pgn = (GNode *)pgnp; - LstNode ln; /* An element in the children list */ - int unmarked; - - unmarked = ((cgn->type & OP_MARK) == 0); - cgn->type |= OP_MARK; - - if ((cgn->type & (OP_USE|OP_USEBEFORE)) == 0) - return (0); - - if (unmarked) - Make_HandleUse(cgn, pgn); - - /* - * This child node is now "made", so we decrement the count of - * unmade children in the parent... We also remove the child - * from the parent's list to accurately reflect the number of decent - * children the parent has. This is used by Make_Run to decide - * whether to queue the parent or examine its children... - */ - if ((ln = Lst_Member(pgn->children, cgn)) != NULL) { - Lst_Remove(pgn->children, ln); - pgn->unmade--; - } - return (0); -} - - -/*- - *----------------------------------------------------------------------- - * Make_Recheck -- - * Check the modification time of a gnode, and update it as described - * in the comments below. - * - * Results: - * returns 0 if the gnode does not exist, or it's filesystem - * time if it does. - * - * Side Effects: - * the gnode's modification time and path name are affected. - * - *----------------------------------------------------------------------- - */ -time_t -Make_Recheck(GNode *gn) -{ - time_t mtime = Dir_MTime(gn, 1); - -#ifndef RECHECK - /* - * We can't re-stat the thing, but we can at least take care of rules - * where a target depends on a source that actually creates the - * target, but only if it has changed, e.g. - * - * parse.h : parse.o - * - * parse.o : parse.y - * yacc -d parse.y - * cc -c y.tab.c - * mv y.tab.o parse.o - * cmp -s y.tab.h parse.h || mv y.tab.h parse.h - * - * In this case, if the definitions produced by yacc haven't changed - * from before, parse.h won't have been updated and gn->mtime will - * reflect the current modification time for parse.h. This is - * something of a kludge, I admit, but it's a useful one.. - * XXX: People like to use a rule like - * - * FRC: - * - * To force things that depend on FRC to be made, so we have to - * check for gn->children being empty as well... - */ - if (!Lst_IsEmpty(gn->commands) || Lst_IsEmpty(gn->children)) { - gn->mtime = now; - } -#else - /* - * This is what Make does and it's actually a good thing, as it - * allows rules like - * - * cmp -s y.tab.h parse.h || cp y.tab.h parse.h - * - * to function as intended. Unfortunately, thanks to the stateless - * nature of NFS (by which I mean the loose coupling of two clients - * using the same file from a common server), there are times - * when the modification time of a file created on a remote - * machine will not be modified before the local stat() implied by - * the Dir_MTime occurs, thus leading us to believe that the file - * is unchanged, wreaking havoc with files that depend on this one. - * - * I have decided it is better to make too much than to make too - * little, so this stuff is commented out unless you're sure it's ok. - * -- ardeb 1/12/88 - */ - /* - * Christos, 4/9/92: If we are saving commands pretend that - * the target is made now. Otherwise archives with ... rules - * don't work! - */ - if (NoExecute(gn) || (gn->type & OP_SAVE_CMDS) || - (mtime == 0 && !(gn->type & OP_WAIT))) { - if (DEBUG(MAKE)) { - fprintf(debug_file, " recheck(%s): update time from %s to now\n", - gn->name, Targ_FmtTime(gn->mtime)); - } - gn->mtime = now; - } - else { - if (DEBUG(MAKE)) { - fprintf(debug_file, " recheck(%s): current update time: %s\n", - gn->name, Targ_FmtTime(gn->mtime)); - } - } -#endif - return mtime; -} - -/*- - *----------------------------------------------------------------------- - * Make_Update -- - * Perform update on the parents of a node. Used by JobFinish once - * a node has been dealt with and by MakeStartJobs if it finds an - * up-to-date node. - * - * Input: - * cgn the child node - * - * Results: - * Always returns 0 - * - * Side Effects: - * The unmade field of pgn is decremented and pgn may be placed on - * the toBeMade queue if this field becomes 0. - * - * If the child was made, the parent's flag CHILDMADE field will be - * set true. - * - * If the child is not up-to-date and still does not exist, - * set the FORCE flag on the parents. - * - * If the child wasn't made, the cmgn field of the parent will be - * altered if the child's mtime is big enough. - * - * Finally, if the child is the implied source for the parent, the - * parent's IMPSRC variable is set appropriately. - * - *----------------------------------------------------------------------- - */ -void -Make_Update(GNode *cgn) -{ - GNode *pgn; /* the parent node */ - char *cname; /* the child's name */ - LstNode ln; /* Element in parents and iParents lists */ - time_t mtime = -1; - char *p1; - Lst parents; - GNode *centurion; - - /* It is save to re-examine any nodes again */ - checked++; - - cname = Var_Value(TARGET, cgn, &p1); - if (p1) - free(p1); - - if (DEBUG(MAKE)) - fprintf(debug_file, "Make_Update: %s%s\n", cgn->name, cgn->cohort_num); - - /* - * If the child was actually made, see what its modification time is - * now -- some rules won't actually update the file. If the file still - * doesn't exist, make its mtime now. - */ - if (cgn->made != UPTODATE) { - mtime = Make_Recheck(cgn); - } - - /* - * If this is a `::' node, we must consult its first instance - * which is where all parents are linked. - */ - if ((centurion = cgn->centurion) != NULL) { - if (!Lst_IsEmpty(cgn->parents)) - Punt("%s%s: cohort has parents", cgn->name, cgn->cohort_num); - centurion->unmade_cohorts -= 1; - if (centurion->unmade_cohorts < 0) - Error("Graph cycles through centurion %s", centurion->name); - } else { - centurion = cgn; - } - parents = centurion->parents; - - /* If this was a .ORDER node, schedule the RHS */ - Lst_ForEach(centurion->order_succ, MakeBuildParent, Lst_First(toBeMade)); - - /* Now mark all the parents as having one less unmade child */ - if (Lst_Open(parents) == SUCCESS) { - while ((ln = Lst_Next(parents)) != NULL) { - pgn = (GNode *)Lst_Datum(ln); - if (DEBUG(MAKE)) - fprintf(debug_file, "inspect parent %s%s: flags %x, " - "type %x, made %d, unmade %d ", - pgn->name, pgn->cohort_num, pgn->flags, - pgn->type, pgn->made, pgn->unmade-1); - - if (!(pgn->flags & REMAKE)) { - /* This parent isn't needed */ - if (DEBUG(MAKE)) - fprintf(debug_file, "- not needed\n"); - continue; - } - if (mtime == 0 && !(cgn->type & OP_WAIT)) - pgn->flags |= FORCE; - - /* - * If the parent has the .MADE attribute, its timestamp got - * updated to that of its newest child, and its unmake - * child count got set to zero in Make_ExpandUse(). - * However other things might cause us to build one of its - * children - and so we mustn't do any processing here when - * the child build finishes. - */ - if (pgn->type & OP_MADE) { - if (DEBUG(MAKE)) - fprintf(debug_file, "- .MADE\n"); - continue; - } - - if ( ! (cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE))) { - if (cgn->made == MADE) - pgn->flags |= CHILDMADE; - (void)Make_TimeStamp(pgn, cgn); - } - - /* - * A parent must wait for the completion of all instances - * of a `::' dependency. - */ - if (centurion->unmade_cohorts != 0 || centurion->made < MADE) { - if (DEBUG(MAKE)) - fprintf(debug_file, - "- centurion made %d, %d unmade cohorts\n", - centurion->made, centurion->unmade_cohorts); - continue; - } - - /* One more child of this parent is now made */ - pgn->unmade -= 1; - if (pgn->unmade < 0) { - if (DEBUG(MAKE)) { - fprintf(debug_file, "Graph cycles through %s%s\n", - pgn->name, pgn->cohort_num); - Targ_PrintGraph(2); - } - Error("Graph cycles through %s%s", pgn->name, pgn->cohort_num); - } - - /* We must always rescan the parents of .WAIT and .ORDER nodes. */ - if (pgn->unmade != 0 && !(centurion->type & OP_WAIT) - && !(centurion->flags & DONE_ORDER)) { - if (DEBUG(MAKE)) - fprintf(debug_file, "- unmade children\n"); - continue; - } - if (pgn->made != DEFERRED) { - /* - * Either this parent is on a different branch of the tree, - * or it on the RHS of a .WAIT directive - * or it is already on the toBeMade list. - */ - if (DEBUG(MAKE)) - fprintf(debug_file, "- not deferred\n"); - continue; - } - if (pgn->order_pred - && Lst_ForEach(pgn->order_pred, MakeCheckOrder, 0)) { - /* A .ORDER rule stops us building this */ - continue; - } - if (DEBUG(MAKE)) { - static int two = 2; - fprintf(debug_file, "- %s%s made, schedule %s%s (made %d)\n", - cgn->name, cgn->cohort_num, - pgn->name, pgn->cohort_num, pgn->made); - Targ_PrintNode(pgn, &two); - } - /* Ok, we can schedule the parent again */ - pgn->made = REQUESTED; - (void)Lst_EnQueue(toBeMade, pgn); - } - Lst_Close(parents); - } - - /* - * Set the .PREFIX and .IMPSRC variables for all the implied parents - * of this node. - */ - if (Lst_Open(cgn->iParents) == SUCCESS) { - char *cpref = Var_Value(PREFIX, cgn, &p1); - - while ((ln = Lst_Next(cgn->iParents)) != NULL) { - pgn = (GNode *)Lst_Datum(ln); - if (pgn->flags & REMAKE) { - Var_Set(IMPSRC, cname, pgn, 0); - if (cpref != NULL) - Var_Set(PREFIX, cpref, pgn, 0); - } - } - if (p1) - free(p1); - Lst_Close(cgn->iParents); - } -} - -/*- - *----------------------------------------------------------------------- - * MakeAddAllSrc -- - * Add a child's name to the ALLSRC and OODATE variables of the given - * node. Called from Make_DoAllVar via Lst_ForEach. A child is added only - * if it has not been given the .EXEC, .USE or .INVISIBLE attributes. - * .EXEC and .USE children are very rarely going to be files, so... - * If the child is a .JOIN node, its ALLSRC is propagated to the parent. - * - * A child is added to the OODATE variable if its modification time is - * later than that of its parent, as defined by Make, except if the - * parent is a .JOIN node. In that case, it is only added to the OODATE - * variable if it was actually made (since .JOIN nodes don't have - * modification times, the comparison is rather unfair...).. - * - * Results: - * Always returns 0 - * - * Side Effects: - * The ALLSRC variable for the given node is extended. - *----------------------------------------------------------------------- - */ -static int -MakeUnmark(void *cgnp, void *pgnp MAKE_ATTR_UNUSED) -{ - GNode *cgn = (GNode *)cgnp; - - cgn->type &= ~OP_MARK; - return (0); -} - -/* - * Input: - * cgnp The child to add - * pgnp The parent to whose ALLSRC variable it should - * be added - * - */ -static int -MakeAddAllSrc(void *cgnp, void *pgnp) -{ - GNode *cgn = (GNode *)cgnp; - GNode *pgn = (GNode *)pgnp; - - if (cgn->type & OP_MARK) - return (0); - cgn->type |= OP_MARK; - - if ((cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE|OP_INVISIBLE)) == 0) { - char *child, *allsrc; - char *p1 = NULL, *p2 = NULL; - - if (cgn->type & OP_ARCHV) - child = Var_Value(MEMBER, cgn, &p1); - else - child = cgn->path ? cgn->path : cgn->name; - if (cgn->type & OP_JOIN) { - allsrc = Var_Value(ALLSRC, cgn, &p2); - } else { - allsrc = child; - } - if (allsrc != NULL) - Var_Append(ALLSRC, allsrc, pgn); - if (p2) - free(p2); - if (pgn->type & OP_JOIN) { - if (cgn->made == MADE) { - Var_Append(OODATE, child, pgn); - } - } else if ((pgn->mtime < cgn->mtime) || - (cgn->mtime >= now && cgn->made == MADE)) - { - /* - * It goes in the OODATE variable if the parent is younger than the - * child or if the child has been modified more recently than - * the start of the make. This is to keep pmake from getting - * confused if something else updates the parent after the - * make starts (shouldn't happen, I know, but sometimes it - * does). In such a case, if we've updated the kid, the parent - * is likely to have a modification time later than that of - * the kid and anything that relies on the OODATE variable will - * be hosed. - * - * XXX: This will cause all made children to go in the OODATE - * variable, even if they're not touched, if RECHECK isn't defined, - * since cgn->mtime is set to now in Make_Update. According to - * some people, this is good... - */ - Var_Append(OODATE, child, pgn); - } - if (p1) - free(p1); - } - return (0); -} - -/*- - *----------------------------------------------------------------------- - * Make_DoAllVar -- - * Set up the ALLSRC and OODATE variables. Sad to say, it must be - * done separately, rather than while traversing the graph. This is - * because Make defined OODATE to contain all sources whose modification - * times were later than that of the target, *not* those sources that - * were out-of-date. Since in both compatibility and native modes, - * the modification time of the parent isn't found until the child - * has been dealt with, we have to wait until now to fill in the - * variable. As for ALLSRC, the ordering is important and not - * guaranteed when in native mode, so it must be set here, too. - * - * Results: - * None - * - * Side Effects: - * The ALLSRC and OODATE variables of the given node is filled in. - * If the node is a .JOIN node, its TARGET variable will be set to - * match its ALLSRC variable. - *----------------------------------------------------------------------- - */ -void -Make_DoAllVar(GNode *gn) -{ - if (gn->flags & DONE_ALLSRC) - return; - - Lst_ForEach(gn->children, MakeUnmark, gn); - Lst_ForEach(gn->children, MakeAddAllSrc, gn); - - if (!Var_Exists (OODATE, gn)) { - Var_Set(OODATE, "", gn, 0); - } - if (!Var_Exists (ALLSRC, gn)) { - Var_Set(ALLSRC, "", gn, 0); - } - - if (gn->type & OP_JOIN) { - char *p1; - Var_Set(TARGET, Var_Value(ALLSRC, gn, &p1), gn, 0); - if (p1) - free(p1); - } - gn->flags |= DONE_ALLSRC; -} - -/*- - *----------------------------------------------------------------------- - * MakeStartJobs -- - * Start as many jobs as possible. - * - * Results: - * If the query flag was given to pmake, no job will be started, - * but as soon as an out-of-date target is found, this function - * returns TRUE. At all other times, this function returns FALSE. - * - * Side Effects: - * Nodes are removed from the toBeMade queue and job table slots - * are filled. - * - *----------------------------------------------------------------------- - */ - -static int -MakeCheckOrder(void *v_bn, void *ignore MAKE_ATTR_UNUSED) -{ - GNode *bn = v_bn; - - if (bn->made >= MADE || !(bn->flags & REMAKE)) - return 0; - if (DEBUG(MAKE)) - fprintf(debug_file, "MakeCheckOrder: Waiting for .ORDER node %s%s\n", - bn->name, bn->cohort_num); - return 1; -} - -static int -MakeBuildChild(void *v_cn, void *toBeMade_next) -{ - GNode *cn = v_cn; - - if (DEBUG(MAKE)) - fprintf(debug_file, "MakeBuildChild: inspect %s%s, made %d, type %x\n", - cn->name, cn->cohort_num, cn->made, cn->type); - if (cn->made > DEFERRED) - return 0; - - /* If this node is on the RHS of a .ORDER, check LHSs. */ - if (cn->order_pred && Lst_ForEach(cn->order_pred, MakeCheckOrder, 0)) { - /* Can't build this (or anything else in this child list) yet */ - cn->made = DEFERRED; - return 1; - } - - if (DEBUG(MAKE)) - fprintf(debug_file, "MakeBuildChild: schedule %s%s\n", - cn->name, cn->cohort_num); - - cn->made = REQUESTED; - if (toBeMade_next == NULL) - Lst_AtEnd(toBeMade, cn); - else - Lst_InsertBefore(toBeMade, toBeMade_next, cn); - - if (cn->unmade_cohorts != 0) - Lst_ForEach(cn->cohorts, MakeBuildChild, toBeMade_next); - - /* - * If this node is a .WAIT node with unmade chlidren - * then don't add the next sibling. - */ - return cn->type & OP_WAIT && cn->unmade > 0; -} - -/* When a .ORDER RHS node completes we do this on each LHS */ -static int -MakeBuildParent(void *v_pn, void *toBeMade_next) -{ - GNode *pn = v_pn; - - if (pn->made != DEFERRED) - return 0; - - if (MakeBuildChild(pn, toBeMade_next) == 0) { - /* Mark so that when this node is built we reschedule its parents */ - pn->flags |= DONE_ORDER; - } - - return 0; -} - -static Boolean -MakeStartJobs(void) -{ - GNode *gn; - int have_token = 0; - - while (!Lst_IsEmpty (toBeMade)) { - /* Get token now to avoid cycling job-list when we only have 1 token */ - if (!have_token && !Job_TokenWithdraw()) - break; - have_token = 1; - - gn = (GNode *)Lst_DeQueue(toBeMade); - if (DEBUG(MAKE)) - fprintf(debug_file, "Examining %s%s...\n", - gn->name, gn->cohort_num); - - if (gn->made != REQUESTED) { - if (DEBUG(MAKE)) - fprintf(debug_file, "state %d\n", gn->made); - - make_abort(gn, __LINE__); - } - - if (gn->checked == checked) { - /* We've already looked at this node since a job finished... */ - if (DEBUG(MAKE)) - fprintf(debug_file, "already checked %s%s\n", - gn->name, gn->cohort_num); - gn->made = DEFERRED; - continue; - } - gn->checked = checked; - - if (gn->unmade != 0) { - /* - * We can't build this yet, add all unmade children to toBeMade, - * just before the current first element. - */ - gn->made = DEFERRED; - Lst_ForEach(gn->children, MakeBuildChild, Lst_First(toBeMade)); - /* and drop this node on the floor */ - if (DEBUG(MAKE)) - fprintf(debug_file, "dropped %s%s\n", gn->name, gn->cohort_num); - continue; - } - - gn->made = BEINGMADE; - if (Make_OODate(gn)) { - if (DEBUG(MAKE)) { - fprintf(debug_file, "out-of-date\n"); - } - if (queryFlag) { - return (TRUE); - } - Make_DoAllVar(gn); - Job_Make(gn); - have_token = 0; - } else { - if (DEBUG(MAKE)) { - fprintf(debug_file, "up-to-date\n"); - } - gn->made = UPTODATE; - if (gn->type & OP_JOIN) { - /* - * Even for an up-to-date .JOIN node, we need it to have its - * context variables so references to it get the correct - * value for .TARGET when building up the context variables - * of its parent(s)... - */ - Make_DoAllVar(gn); - } - Make_Update(gn); - } - } - - if (have_token) - Job_TokenReturn(); - - return (FALSE); -} - -/*- - *----------------------------------------------------------------------- - * MakePrintStatus -- - * Print the status of a top-level node, viz. it being up-to-date - * already or not created due to an error in a lower level. - * Callback function for Make_Run via Lst_ForEach. - * - * Input: - * gnp Node to examine - * cyclep True if gn->unmade being non-zero implies a - * cycle in the graph, not an error in an - * inferior. - * - * Results: - * Always returns 0. - * - * Side Effects: - * A message may be printed. - * - *----------------------------------------------------------------------- - */ -static int -MakePrintStatusOrder(void *ognp, void *gnp) -{ - GNode *ogn = ognp; - GNode *gn = gnp; - - if (!(ogn->flags & REMAKE) || ogn->made > REQUESTED) - /* not waiting for this one */ - return 0; - - printf(" `%s%s' has .ORDER dependency against %s%s " - "(made %d, flags %x, type %x)\n", - gn->name, gn->cohort_num, - ogn->name, ogn->cohort_num, ogn->made, ogn->flags, ogn->type); - if (DEBUG(MAKE) && debug_file != stdout) - fprintf(debug_file, " `%s%s' has .ORDER dependency against %s%s " - "(made %d, flags %x, type %x)\n", - gn->name, gn->cohort_num, - ogn->name, ogn->cohort_num, ogn->made, ogn->flags, ogn->type); - return 0; -} - -static int -MakePrintStatus(void *gnp, void *v_errors) -{ - GNode *gn = (GNode *)gnp; - int *errors = v_errors; - - if (gn->flags & DONECYCLE) - /* We've completely processed this node before, don't do it again. */ - return 0; - - if (gn->unmade == 0) { - gn->flags |= DONECYCLE; - switch (gn->made) { - case UPTODATE: - printf("`%s%s' is up to date.\n", gn->name, gn->cohort_num); - break; - case MADE: - break; - case UNMADE: - case DEFERRED: - case REQUESTED: - case BEINGMADE: - (*errors)++; - printf("`%s%s' was not built (made %d, flags %x, type %x)!\n", - gn->name, gn->cohort_num, gn->made, gn->flags, gn->type); - if (DEBUG(MAKE) && debug_file != stdout) - fprintf(debug_file, - "`%s%s' was not built (made %d, flags %x, type %x)!\n", - gn->name, gn->cohort_num, gn->made, gn->flags, gn->type); - /* Most likely problem is actually caused by .ORDER */ - Lst_ForEach(gn->order_pred, MakePrintStatusOrder, gn); - break; - default: - /* Errors - already counted */ - printf("`%s%s' not remade because of errors.\n", - gn->name, gn->cohort_num); - if (DEBUG(MAKE) && debug_file != stdout) - fprintf(debug_file, "`%s%s' not remade because of errors.\n", - gn->name, gn->cohort_num); - break; - } - return 0; - } - - if (DEBUG(MAKE)) - fprintf(debug_file, "MakePrintStatus: %s%s has %d unmade children\n", - gn->name, gn->cohort_num, gn->unmade); - /* - * If printing cycles and came to one that has unmade children, - * print out the cycle by recursing on its children. - */ - if (!(gn->flags & CYCLE)) { - /* Fist time we've seen this node, check all children */ - gn->flags |= CYCLE; - Lst_ForEach(gn->children, MakePrintStatus, errors); - /* Mark that this node needn't be processed again */ - gn->flags |= DONECYCLE; - return 0; - } - - /* Only output the error once per node */ - gn->flags |= DONECYCLE; - Error("Graph cycles through `%s%s'", gn->name, gn->cohort_num); - if ((*errors)++ > 100) - /* Abandon the whole error report */ - return 1; - - /* Reporting for our children will give the rest of the loop */ - Lst_ForEach(gn->children, MakePrintStatus, errors); - return 0; -} - - -/*- - *----------------------------------------------------------------------- - * Make_ExpandUse -- - * Expand .USE nodes and create a new targets list - * - * Input: - * targs the initial list of targets - * - * Side Effects: - *----------------------------------------------------------------------- - */ -void -Make_ExpandUse(Lst targs) -{ - GNode *gn; /* a temporary pointer */ - Lst examine; /* List of targets to examine */ - - examine = Lst_Duplicate(targs, NULL); - - /* - * Make an initial downward pass over the graph, marking nodes to be made - * as we go down. We call Suff_FindDeps to find where a node is and - * to get some children for it if it has none and also has no commands. - * If the node is a leaf, we stick it on the toBeMade queue to - * be looked at in a minute, otherwise we add its children to our queue - * and go on about our business. - */ - while (!Lst_IsEmpty (examine)) { - gn = (GNode *)Lst_DeQueue(examine); - - if (gn->flags & REMAKE) - /* We've looked at this one already */ - continue; - gn->flags |= REMAKE; - if (DEBUG(MAKE)) - fprintf(debug_file, "Make_ExpandUse: examine %s%s\n", - gn->name, gn->cohort_num); - - if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) { - /* Append all the 'cohorts' to the list of things to examine */ - Lst new; - new = Lst_Duplicate(gn->cohorts, NULL); - Lst_Concat(new, examine, LST_CONCLINK); - examine = new; - } - - /* - * Apply any .USE rules before looking for implicit dependencies - * to make sure everything has commands that should... - * Make sure that the TARGET is set, so that we can make - * expansions. - */ - if (gn->type & OP_ARCHV) { - char *eoa, *eon; - eoa = strchr(gn->name, '('); - eon = strchr(gn->name, ')'); - if (eoa == NULL || eon == NULL) - continue; - *eoa = '\0'; - *eon = '\0'; - Var_Set(MEMBER, eoa + 1, gn, 0); - Var_Set(ARCHIVE, gn->name, gn, 0); - *eoa = '('; - *eon = ')'; - } - - (void)Dir_MTime(gn, 0); - Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0); - Lst_ForEach(gn->children, MakeUnmark, gn); - Lst_ForEach(gn->children, MakeHandleUse, gn); - - if ((gn->type & OP_MADE) == 0) - Suff_FindDeps(gn); - else { - /* Pretend we made all this node's children */ - Lst_ForEach(gn->children, MakeFindChild, gn); - if (gn->unmade != 0) - printf("Warning: %s%s still has %d unmade children\n", - gn->name, gn->cohort_num, gn->unmade); - } - - if (gn->unmade != 0) - Lst_ForEach(gn->children, MakeAddChild, examine); - } - - Lst_Destroy(examine, NULL); -} - -/*- - *----------------------------------------------------------------------- - * Make_ProcessWait -- - * Convert .WAIT nodes into dependencies - * - * Input: - * targs the initial list of targets - * - *----------------------------------------------------------------------- - */ - -static int -link_parent(void *cnp, void *pnp) -{ - GNode *cn = cnp; - GNode *pn = pnp; - - Lst_AtEnd(pn->children, cn); - Lst_AtEnd(cn->parents, pn); - pn->unmade++; - return 0; -} - -static int -add_wait_dep(void *v_cn, void *v_wn) -{ - GNode *cn = v_cn; - GNode *wn = v_wn; - - if (cn == wn) - return 1; - - if (cn == NULL || wn == NULL) { - printf("bad wait dep %p %p\n", cn, wn); - exit(4); - } - if (DEBUG(MAKE)) - fprintf(debug_file, ".WAIT: add dependency %s%s -> %s\n", - cn->name, cn->cohort_num, wn->name); - - Lst_AtEnd(wn->children, cn); - wn->unmade++; - Lst_AtEnd(cn->parents, wn); - return 0; -} - -static void -Make_ProcessWait(Lst targs) -{ - GNode *pgn; /* 'parent' node we are examining */ - GNode *cgn; /* Each child in turn */ - LstNode owln; /* Previous .WAIT node */ - Lst examine; /* List of targets to examine */ - LstNode ln; - - /* - * We need all the nodes to have a common parent in order for the - * .WAIT and .ORDER scheduling to work. - * Perhaps this should be done earlier... - */ - - pgn = Targ_NewGN(".MAIN"); - pgn->flags = REMAKE; - pgn->type = OP_PHONY | OP_DEPENDS; - /* Get it displayed in the diag dumps */ - Lst_AtFront(Targ_List(), pgn); - - Lst_ForEach(targs, link_parent, pgn); - - /* Start building with the 'dummy' .MAIN' node */ - MakeBuildChild(pgn, NULL); - - examine = Lst_Init(FALSE); - Lst_AtEnd(examine, pgn); - - while (!Lst_IsEmpty (examine)) { - pgn = Lst_DeQueue(examine); - - /* We only want to process each child-list once */ - if (pgn->flags & DONE_WAIT) - continue; - pgn->flags |= DONE_WAIT; - if (DEBUG(MAKE)) - fprintf(debug_file, "Make_ProcessWait: examine %s\n", pgn->name); - - if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (pgn->cohorts)) { - /* Append all the 'cohorts' to the list of things to examine */ - Lst new; - new = Lst_Duplicate(pgn->cohorts, NULL); - Lst_Concat(new, examine, LST_CONCLINK); - examine = new; - } - - owln = Lst_First(pgn->children); - Lst_Open(pgn->children); - for (; (ln = Lst_Next(pgn->children)) != NULL; ) { - cgn = Lst_Datum(ln); - if (cgn->type & OP_WAIT) { - /* Make the .WAIT node depend on the previous children */ - Lst_ForEachFrom(pgn->children, owln, add_wait_dep, cgn); - owln = ln; - } else { - Lst_AtEnd(examine, cgn); - } - } - Lst_Close(pgn->children); - } - - Lst_Destroy(examine, NULL); -} - -/*- - *----------------------------------------------------------------------- - * Make_Run -- - * Initialize the nodes to remake and the list of nodes which are - * ready to be made by doing a breadth-first traversal of the graph - * starting from the nodes in the given list. Once this traversal - * is finished, all the 'leaves' of the graph are in the toBeMade - * queue. - * Using this queue and the Job module, work back up the graph, - * calling on MakeStartJobs to keep the job table as full as - * possible. - * - * Input: - * targs the initial list of targets - * - * Results: - * TRUE if work was done. FALSE otherwise. - * - * Side Effects: - * The make field of all nodes involved in the creation of the given - * targets is set to 1. The toBeMade list is set to contain all the - * 'leaves' of these subgraphs. - *----------------------------------------------------------------------- - */ -Boolean -Make_Run(Lst targs) -{ - int errors; /* Number of errors the Job module reports */ - - /* Start trying to make the current targets... */ - toBeMade = Lst_Init(FALSE); - - Make_ExpandUse(targs); - Make_ProcessWait(targs); - - if (DEBUG(MAKE)) { - fprintf(debug_file, "#***# full graph\n"); - Targ_PrintGraph(1); - } - - if (queryFlag) { - /* - * We wouldn't do any work unless we could start some jobs in the - * next loop... (we won't actually start any, of course, this is just - * to see if any of the targets was out of date) - */ - return (MakeStartJobs()); - } - /* - * Initialization. At the moment, no jobs are running and until some - * get started, nothing will happen since the remaining upward - * traversal of the graph is performed by the routines in job.c upon - * the finishing of a job. So we fill the Job table as much as we can - * before going into our loop. - */ - (void)MakeStartJobs(); - - /* - * Main Loop: The idea here is that the ending of jobs will take - * care of the maintenance of data structures and the waiting for output - * will cause us to be idle most of the time while our children run as - * much as possible. Because the job table is kept as full as possible, - * the only time when it will be empty is when all the jobs which need - * running have been run, so that is the end condition of this loop. - * Note that the Job module will exit if there were any errors unless the - * keepgoing flag was given. - */ - while (!Lst_IsEmpty(toBeMade) || jobTokensRunning > 0) { - Job_CatchOutput(); - (void)MakeStartJobs(); - } - - errors = Job_Finish(); - - /* - * Print the final status of each target. E.g. if it wasn't made - * because some inferior reported an error. - */ - if (DEBUG(MAKE)) - fprintf(debug_file, "done: errors %d\n", errors); - if (errors == 0) { - Lst_ForEach(targs, MakePrintStatus, &errors); - if (DEBUG(MAKE)) { - fprintf(debug_file, "done: errors %d\n", errors); - if (errors) - Targ_PrintGraph(4); - } - } - return errors != 0; -} diff --git a/20120831/make.h b/20120831/make.h deleted file mode 100644 index 384d109..0000000 --- a/20120831/make.h +++ /dev/null @@ -1,518 +0,0 @@ -/* $NetBSD: make.h,v 1.89 2012/06/12 19:21:51 joerg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)make.h 8.3 (Berkeley) 6/13/95 - */ - -/* - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)make.h 8.3 (Berkeley) 6/13/95 - */ - -/*- - * make.h -- - * The global definitions for pmake - */ - -#ifndef _MAKE_H_ -#define _MAKE_H_ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <sys/types.h> -#include <sys/param.h> - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#ifdef HAVE_STRING_H -#include <string.h> -#else -#include <strings.h> -#endif -#include <unistd.h> -#include <sys/cdefs.h> - -#if defined(__GNUC__) -#define MAKE_GNUC_PREREQ(x, y) \ - ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \ - (__GNUC__ > (x))) -#else /* defined(__GNUC__) */ -#define MAKE_GNUC_PREREQx, y) 0 -#endif /* defined(__GNUC__) */ - -#if MAKE_GNUC_PREREQ(2, 7) -#define MAKE_ATTR_UNUSED __attribute__((__unused__)) -#else -#define MAKE_ATTR_UNUSED /* delete */ -#endif - -#if MAKE_GNUC_PREREQ(2, 5) -#define MAKE_ATTR_DEAD __attribute__((__noreturn__)) -#elif defined(__GNUC__) -#define MAKE_ATTR_DEAD __volatile -#else -#define MAKE_ATTR_DEAD /* delete */ -#endif - -#if MAKE_GNUC_PREREQ(2, 7) -#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) \ - __attribute__((__format__ (__printf__, fmtarg, firstvararg))) -#else -#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) /* delete */ -#endif - -#include "sprite.h" -#include "lst.h" -#include "hash.h" -#include "make-conf.h" -#include "buf.h" -#include "make_malloc.h" - -/* - * some vendors don't have this --sjg - */ -#if defined(S_IFDIR) && !defined(S_ISDIR) -# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif - -#if defined(sun) && (defined(__svr4__) || defined(__SVR4)) -#define POSIX_SIGNALS -#endif - -/*- - * The structure for an individual graph node. Each node has several - * pieces of data associated with it. - * 1) the name of the target it describes - * 2) the location of the target file in the file system. - * 3) the type of operator used to define its sources (qv. parse.c) - * 4) whether it is involved in this invocation of make - * 5) whether the target has been remade - * 6) whether any of its children has been remade - * 7) the number of its children that are, as yet, unmade - * 8) its modification time - * 9) the modification time of its youngest child (qv. make.c) - * 10) a list of nodes for which this is a source (parents) - * 11) a list of nodes on which this depends (children) - * 12) a list of nodes that depend on this, as gleaned from the - * transformation rules (iParents) - * 13) a list of ancestor nodes, which includes parents, iParents, - * and recursive parents of parents - * 14) a list of nodes of the same name created by the :: operator - * 15) a list of nodes that must be made (if they're made) before - * this node can be, but that do not enter into the datedness of - * this node. - * 16) a list of nodes that must be made (if they're made) before - * this node or any child of this node can be, but that do not - * enter into the datedness of this node. - * 17) a list of nodes that must be made (if they're made) after - * this node is, but that do not depend on this node, in the - * normal sense. - * 18) a Lst of ``local'' variables that are specific to this target - * and this target only (qv. var.c [$@ $< $?, etc.]) - * 19) a Lst of strings that are commands to be given to a shell - * to create this target. - */ -typedef struct GNode { - char *name; /* The target's name */ - char *uname; /* The unexpanded name of a .USE node */ - char *path; /* The full pathname of the file */ - int type; /* Its type (see the OP flags, below) */ - - int flags; -#define REMAKE 0x1 /* this target needs to be (re)made */ -#define CHILDMADE 0x2 /* children of this target were made */ -#define FORCE 0x4 /* children don't exist, and we pretend made */ -#define DONE_WAIT 0x8 /* Set by Make_ProcessWait() */ -#define DONE_ORDER 0x10 /* Build requested by .ORDER processing */ -#define FROM_DEPEND 0x20 /* Node created from .depend */ -#define DONE_ALLSRC 0x40 /* We do it once only */ -#define CYCLE 0x1000 /* Used by MakePrintStatus */ -#define DONECYCLE 0x2000 /* Used by MakePrintStatus */ - enum enum_made { - UNMADE, DEFERRED, REQUESTED, BEINGMADE, - MADE, UPTODATE, ERROR, ABORTED - } made; /* Set to reflect the state of processing - * on this node: - * UNMADE - Not examined yet - * DEFERRED - Examined once (building child) - * REQUESTED - on toBeMade list - * BEINGMADE - Target is already being made. - * Indicates a cycle in the graph. - * MADE - Was out-of-date and has been made - * UPTODATE - Was already up-to-date - * ERROR - An error occurred while it was being - * made (used only in compat mode) - * ABORTED - The target was aborted due to - * an error making an inferior (compat). - */ - int unmade; /* The number of unmade children */ - - time_t mtime; /* Its modification time */ - struct GNode *cmgn; /* The youngest child */ - - Lst iParents; /* Links to parents for which this is an - * implied source, if any */ - Lst cohorts; /* Other nodes for the :: operator */ - Lst parents; /* Nodes that depend on this one */ - Lst children; /* Nodes on which this one depends */ - Lst order_pred; /* .ORDER nodes we need made */ - Lst order_succ; /* .ORDER nodes who need us */ - - char cohort_num[8]; /* #n for this cohort */ - int unmade_cohorts;/* # of unmade instances on the - cohorts list */ - struct GNode *centurion; /* Pointer to the first instance of a :: - node; only set when on a cohorts list */ - unsigned int checked; /* Last time we tried to makle this node */ - - Hash_Table context; /* The local variables */ - Lst commands; /* Creation commands */ - - struct _Suff *suffix; /* Suffix for the node (determined by - * Suff_FindDeps and opaque to everyone - * but the Suff module) */ - const char *fname; /* filename where the GNode got defined */ - int lineno; /* line number where the GNode got defined */ -} GNode; - -/* - * The OP_ constants are used when parsing a dependency line as a way of - * communicating to other parts of the program the way in which a target - * should be made. These constants are bitwise-OR'ed together and - * placed in the 'type' field of each node. Any node that has - * a 'type' field which satisfies the OP_NOP function was never never on - * the lefthand side of an operator, though it may have been on the - * righthand side... - */ -#define OP_DEPENDS 0x00000001 /* Execution of commands depends on - * kids (:) */ -#define OP_FORCE 0x00000002 /* Always execute commands (!) */ -#define OP_DOUBLEDEP 0x00000004 /* Execution of commands depends on kids - * per line (::) */ -#define OP_OPMASK (OP_DEPENDS|OP_FORCE|OP_DOUBLEDEP) - -#define OP_OPTIONAL 0x00000008 /* Don't care if the target doesn't - * exist and can't be created */ -#define OP_USE 0x00000010 /* Use associated commands for parents */ -#define OP_EXEC 0x00000020 /* Target is never out of date, but always - * execute commands anyway. Its time - * doesn't matter, so it has none...sort - * of */ -#define OP_IGNORE 0x00000040 /* Ignore errors when creating the node */ -#define OP_PRECIOUS 0x00000080 /* Don't remove the target when - * interrupted */ -#define OP_SILENT 0x00000100 /* Don't echo commands when executed */ -#define OP_MAKE 0x00000200 /* Target is a recursive make so its - * commands should always be executed when - * it is out of date, regardless of the - * state of the -n or -t flags */ -#define OP_JOIN 0x00000400 /* Target is out-of-date only if any of its - * children was out-of-date */ -#define OP_MADE 0x00000800 /* Assume the children of the node have - * been already made */ -#define OP_SPECIAL 0x00001000 /* Special .BEGIN, .END, .INTERRUPT */ -#define OP_USEBEFORE 0x00002000 /* Like .USE, only prepend commands */ -#define OP_INVISIBLE 0x00004000 /* The node is invisible to its parents. - * I.e. it doesn't show up in the parents's - * local variables. */ -#define OP_NOTMAIN 0x00008000 /* The node is exempt from normal 'main - * target' processing in parse.c */ -#define OP_PHONY 0x00010000 /* Not a file target; run always */ -#define OP_NOPATH 0x00020000 /* Don't search for file in the path */ -#define OP_WAIT 0x00040000 /* .WAIT phony node */ -#define OP_NOMETA 0x00080000 /* .NOMETA do not create a .meta file */ -#define OP_META 0x00100000 /* .META we _do_ want a .meta file */ -#define OP_NOMETA_CMP 0x00200000 /* Do not compare commands in .meta file */ -/* Attributes applied by PMake */ -#define OP_TRANSFORM 0x80000000 /* The node is a transformation rule */ -#define OP_MEMBER 0x40000000 /* Target is a member of an archive */ -#define OP_LIB 0x20000000 /* Target is a library */ -#define OP_ARCHV 0x10000000 /* Target is an archive construct */ -#define OP_HAS_COMMANDS 0x08000000 /* Target has all the commands it should. - * Used when parsing to catch multiple - * commands for a target */ -#define OP_SAVE_CMDS 0x04000000 /* Saving commands on .END (Compat) */ -#define OP_DEPS_FOUND 0x02000000 /* Already processed by Suff_FindDeps */ -#define OP_MARK 0x01000000 /* Node found while expanding .ALLSRC */ - -#define NoExecute(gn) ((gn->type & OP_MAKE) ? noRecursiveExecute : noExecute) -/* - * OP_NOP will return TRUE if the node with the given type was not the - * object of a dependency operator - */ -#define OP_NOP(t) (((t) & OP_OPMASK) == 0x00000000) - -#define OP_NOTARGET (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM) - -/* - * The TARG_ constants are used when calling the Targ_FindNode and - * Targ_FindList functions in targ.c. They simply tell the functions what to - * do if the desired node(s) is (are) not found. If the TARG_CREATE constant - * is given, a new, empty node will be created for the target, placed in the - * table of all targets and its address returned. If TARG_NOCREATE is given, - * a NULL pointer will be returned. - */ -#define TARG_NOCREATE 0x00 /* don't create it */ -#define TARG_CREATE 0x01 /* create node if not found */ -#define TARG_NOHASH 0x02 /* don't look in/add to hash table */ - -/* - * These constants are all used by the Str_Concat function to decide how the - * final string should look. If STR_ADDSPACE is given, a space will be - * placed between the two strings. If STR_ADDSLASH is given, a '/' will - * be used instead of a space. If neither is given, no intervening characters - * will be placed between the two strings in the final output. If the - * STR_DOFREE bit is set, the two input strings will be freed before - * Str_Concat returns. - */ -#define STR_ADDSPACE 0x01 /* add a space when Str_Concat'ing */ -#define STR_ADDSLASH 0x02 /* add a slash when Str_Concat'ing */ - -/* - * Error levels for parsing. PARSE_FATAL means the process cannot continue - * once the makefile has been parsed. PARSE_WARNING means it can. Passed - * as the first argument to Parse_Error. - */ -#define PARSE_WARNING 2 -#define PARSE_FATAL 1 - -/* - * Values returned by Cond_Eval. - */ -#define COND_PARSE 0 /* Parse the next lines */ -#define COND_SKIP 1 /* Skip the next lines */ -#define COND_INVALID 2 /* Not a conditional statement */ - -/* - * Definitions for the "local" variables. Used only for clarity. - */ -#define TARGET "@" /* Target of dependency */ -#define OODATE "?" /* All out-of-date sources */ -#define ALLSRC ">" /* All sources */ -#define IMPSRC "<" /* Source implied by transformation */ -#define PREFIX "*" /* Common prefix */ -#define ARCHIVE "!" /* Archive in "archive(member)" syntax */ -#define MEMBER "%" /* Member in "archive(member)" syntax */ - -#define FTARGET "@F" /* file part of TARGET */ -#define DTARGET "@D" /* directory part of TARGET */ -#define FIMPSRC "<F" /* file part of IMPSRC */ -#define DIMPSRC "<D" /* directory part of IMPSRC */ -#define FPREFIX "*F" /* file part of PREFIX */ -#define DPREFIX "*D" /* directory part of PREFIX */ - -/* - * Global Variables - */ -extern Lst create; /* The list of target names specified on the - * command line. used to resolve #if - * make(...) statements */ -extern Lst dirSearchPath; /* The list of directories to search when - * looking for targets */ - -extern Boolean compatMake; /* True if we are make compatible */ -extern Boolean ignoreErrors; /* True if should ignore all errors */ -extern Boolean beSilent; /* True if should print no commands */ -extern Boolean noExecute; /* True if should execute nothing */ -extern Boolean noRecursiveExecute; /* True if should execute nothing */ -extern Boolean allPrecious; /* True if every target is precious */ -extern Boolean keepgoing; /* True if should continue on unaffected - * portions of the graph when have an error - * in one portion */ -extern Boolean touchFlag; /* TRUE if targets should just be 'touched' - * if out of date. Set by the -t flag */ -extern Boolean queryFlag; /* TRUE if we aren't supposed to really make - * anything, just see if the targets are out- - * of-date */ -extern Boolean doing_depend; /* TRUE if processing .depend */ - -extern Boolean checkEnvFirst; /* TRUE if environment should be searched for - * variables before the global context */ -extern Boolean jobServer; /* a jobServer already exists */ - -extern Boolean parseWarnFatal; /* TRUE if makefile parsing warnings are - * treated as errors */ - -extern Boolean varNoExportEnv; /* TRUE if we should not export variables - * set on the command line to the env. */ - -extern GNode *DEFAULT; /* .DEFAULT rule */ - -extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g - * in the Makefile itself */ -extern GNode *VAR_CMD; /* Variables defined on the command line */ -extern GNode *VAR_FOR; /* Iteration variables */ -extern char var_Error[]; /* Value returned by Var_Parse when an error - * is encountered. It actually points to - * an empty string, so naive callers needn't - * worry about it. */ - -extern time_t now; /* The time at the start of this whole - * process */ - -extern Boolean oldVars; /* Do old-style variable substitution */ - -extern Lst sysIncPath; /* The system include path. */ -extern Lst defIncPath; /* The default include path. */ - -extern char curdir[]; /* Startup directory */ -extern char *progname; /* The program name */ -extern char *makeDependfile; /* .depend */ -extern char **savedEnv; /* if we replaced environ this will be non-NULL */ - -/* - * We cannot vfork() in a child of vfork(). - * Most systems do not enforce this but some do. - */ -#define vFork() ((getpid() == myPid) ? vfork() : fork()) -extern pid_t myPid; - -#define MAKEFLAGS ".MAKEFLAGS" -#define MAKEOVERRIDES ".MAKEOVERRIDES" -#define MAKE_JOB_PREFIX ".MAKE.JOB.PREFIX" /* prefix for job target output */ -#define MAKE_EXPORTED ".MAKE.EXPORTED" /* variables we export */ -#define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all the makefiles we read */ -#define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */ -#define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE" -#define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */ -#define MAKE_MODE ".MAKE.MODE" - -#ifdef NEED_MAKE_LEVEL_SAFE -# define MAKE_LEVEL_SAFE "_MAKE_LEVEL" /* some shells will not pass .MAKE. */ -#endif - -/* - * debug control: - * There is one bit per module. It is up to the module what debug - * information to print. - */ -FILE *debug_file; /* Output written here - default stdout */ -extern int debug; -#define DEBUG_ARCH 0x00001 -#define DEBUG_COND 0x00002 -#define DEBUG_DIR 0x00004 -#define DEBUG_GRAPH1 0x00008 -#define DEBUG_GRAPH2 0x00010 -#define DEBUG_JOB 0x00020 -#define DEBUG_MAKE 0x00040 -#define DEBUG_SUFF 0x00080 -#define DEBUG_TARG 0x00100 -#define DEBUG_VAR 0x00200 -#define DEBUG_FOR 0x00400 -#define DEBUG_SHELL 0x00800 -#define DEBUG_ERROR 0x01000 -#define DEBUG_LOUD 0x02000 -#define DEBUG_META 0x04000 - -#define DEBUG_GRAPH3 0x10000 -#define DEBUG_SCRIPT 0x20000 -#define DEBUG_PARSE 0x40000 -#define DEBUG_CWD 0x80000 - -#define CONCAT(a,b) a##b - -#define DEBUG(module) (debug & CONCAT(DEBUG_,module)) - -#include "nonints.h" - -int Make_TimeStamp(GNode *, GNode *); -Boolean Make_OODate(GNode *); -void Make_ExpandUse(Lst); -time_t Make_Recheck(GNode *); -void Make_HandleUse(GNode *, GNode *); -void Make_Update(GNode *); -void Make_DoAllVar(GNode *); -Boolean Make_Run(Lst); -char * Check_Cwd_Cmd(const char *); -void Check_Cwd(const char **); -void PrintOnError(GNode *, const char *); -void Main_ExportMAKEFLAGS(Boolean); -Boolean Main_SetObjdir(const char *); -int mkTempFile(const char *, char **); -int str2Lst_Append(Lst, char *, const char *); - -#ifdef __GNUC__ -#define UNCONST(ptr) ({ \ - union __unconst { \ - const void *__cp; \ - void *__p; \ - } __d; \ - __d.__cp = ptr, __d.__p; }) -#else -#define UNCONST(ptr) (void *)(ptr) -#endif - -#ifndef MIN -#define MIN(a, b) ((a < b) ? a : b) -#endif -#ifndef MAX -#define MAX(a, b) ((a > b) ? a : b) -#endif - -#endif /* _MAKE_H_ */ diff --git a/20120831/make_malloc.c b/20120831/make_malloc.c deleted file mode 100644 index b8ac23f..0000000 --- a/20120831/make_malloc.c +++ /dev/null @@ -1,119 +0,0 @@ -/* $NetBSD: make_malloc.c,v 1.10 2012/06/20 17:46:28 sjg Exp $ */ - -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef MAKE_NATIVE -#include <sys/cdefs.h> -__RCSID("$NetBSD: make_malloc.c,v 1.10 2012/06/20 17:46:28 sjg Exp $"); -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include "make.h" - -#ifndef USE_EMALLOC -static void enomem(void) MAKE_ATTR_DEAD; - -/* - * enomem -- - * die when out of memory. - */ -static void -enomem(void) -{ - (void)fprintf(stderr, "%s: %s.\n", progname, strerror(ENOMEM)); - exit(2); -} - -/* - * bmake_malloc -- - * malloc, but die on error. - */ -void * -bmake_malloc(size_t len) -{ - void *p; - - if ((p = malloc(len)) == NULL) - enomem(); - return(p); -} - -/* - * bmake_strdup -- - * strdup, but die on error. - */ -char * -bmake_strdup(const char *str) -{ - size_t len; - char *p; - - len = strlen(str) + 1; - if ((p = malloc(len)) == NULL) - enomem(); - return memcpy(p, str, len); -} - -/* - * bmake_strndup -- - * strndup, but die on error. - */ -char * -bmake_strndup(const char *str, size_t max_len) -{ - size_t len; - char *p; - - if (str == NULL) - return NULL; - - len = strlen(str); - if (len > max_len) - len = max_len; - p = bmake_malloc(len + 1); - memcpy(p, str, len); - p[len] = '\0'; - - return(p); -} - -/* - * bmake_realloc -- - * realloc, but die on error. - */ -void * -bmake_realloc(void *ptr, size_t size) -{ - if ((ptr = realloc(ptr, size)) == NULL) - enomem(); - return(ptr); -} -#endif diff --git a/20120831/make_malloc.h b/20120831/make_malloc.h deleted file mode 100644 index 36d3eff..0000000 --- a/20120831/make_malloc.h +++ /dev/null @@ -1,41 +0,0 @@ -/* $NetBSD: make_malloc.h,v 1.4 2009/01/24 14:43:29 dsl Exp $ */ - -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef USE_EMALLOC -void *bmake_malloc(size_t); -void *bmake_realloc(void *, size_t); -char *bmake_strdup(const char *); -char *bmake_strndup(const char *, size_t); -#else -#include <util.h> -#define bmake_malloc(x) emalloc(x) -#define bmake_realloc(x,y) erealloc(x,y) -#define bmake_strdup(x) estrdup(x) -#define bmake_strndup(x,y) estrndup(x,y) -#endif - diff --git a/20120831/meta.c b/20120831/meta.c deleted file mode 100644 index 77af4e8..0000000 --- a/20120831/meta.c +++ /dev/null @@ -1,1346 +0,0 @@ -/* $NetBSD: meta.c,v 1.25 2012/06/27 17:22:58 sjg Exp $ */ - -/* - * Implement 'meta' mode. - * Adapted from John Birrell's patches to FreeBSD make. - * --sjg - */ -/* - * Copyright (c) 2009-2010, Juniper Networks, Inc. - * Portions Copyright (c) 2009, John Birrell. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#if defined(USE_META) - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <libgen.h> -#include <errno.h> -#if !defined(HAVE_CONFIG_H) || defined(HAVE_ERR_H) -#include <err.h> -#endif - -#include "make.h" -#include "job.h" - -#ifdef HAVE_FILEMON_H -# include <filemon.h> -#endif -#if !defined(USE_FILEMON) && defined(FILEMON_SET_FD) -# define USE_FILEMON -#endif - -static BuildMon Mybm; /* for compat */ -static Lst metaBailiwick; /* our scope of control */ - -Boolean useMeta = FALSE; -static Boolean useFilemon = FALSE; -static Boolean writeMeta = FALSE; -static Boolean metaEnv = FALSE; /* don't save env unless asked */ -static Boolean metaVerbose = FALSE; -static Boolean metaIgnoreCMDs = FALSE; /* ignore CMDs in .meta files */ -static Boolean metaCurdirOk = FALSE; /* write .meta in .CURDIR Ok? */ -static Boolean metaSilent = FALSE; /* if we have a .meta be SILENT */ - -extern Boolean forceJobs; -extern Boolean comatMake; -extern char **environ; - -#define MAKE_META_PREFIX ".MAKE.META.PREFIX" - -#ifndef N2U -# define N2U(n, u) (((n) + ((u) - 1)) / (u)) -#endif -#ifndef ROUNDUP -# define ROUNDUP(n, u) (N2U((n), (u)) * (u)) -#endif - -#if !defined(HAVE_STRSEP) -# define strsep(s, d) stresep((s), (d), 0) -#endif - -/* - * Filemon is a kernel module which snoops certain syscalls. - * - * C chdir - * E exec - * F [v]fork - * L [sym]link - * M rename - * R read - * W write - * S stat - * - * See meta_oodate below - we mainly care about 'E' and 'R'. - * - * We can still use meta mode without filemon, but - * the benefits are more limited. - */ -#ifdef USE_FILEMON -# ifndef _PATH_FILEMON -# define _PATH_FILEMON "/dev/filemon" -# endif - -/* - * Open the filemon device. - */ -static void -filemon_open(BuildMon *pbm) -{ - int retry; - - pbm->mon_fd = pbm->filemon_fd = -1; - if (!useFilemon) - return; - - for (retry = 5; retry >= 0; retry--) { - if ((pbm->filemon_fd = open(_PATH_FILEMON, O_RDWR)) >= 0) - break; - } - - if (pbm->filemon_fd < 0) { - useFilemon = FALSE; - warn("Could not open %s", _PATH_FILEMON); - return; - } - - /* - * We use a file outside of '.' - * to avoid a FreeBSD kernel bug where unlink invalidates - * cwd causing getcwd to do a lot more work. - * We only care about the descriptor. - */ - pbm->mon_fd = mkTempFile("filemon.XXXXXX", NULL); - if (ioctl(pbm->filemon_fd, FILEMON_SET_FD, &pbm->mon_fd) < 0) { - err(1, "Could not set filemon file descriptor!"); - } - /* we don't need these once we exec */ - (void)fcntl(pbm->mon_fd, F_SETFD, 1); - (void)fcntl(pbm->filemon_fd, F_SETFD, 1); -} - -/* - * Read the build monitor output file and write records to the target's - * metadata file. - */ -static void -filemon_read(FILE *mfp, int fd) -{ - FILE *fp; - char buf[BUFSIZ]; - - /* Check if we're not writing to a meta data file.*/ - if (mfp == NULL) { - if (fd >= 0) - close(fd); /* not interested */ - return; - } - /* rewind */ - (void)lseek(fd, (off_t)0, SEEK_SET); - if ((fp = fdopen(fd, "r")) == NULL) - err(1, "Could not read build monitor file '%d'", fd); - - fprintf(mfp, "-- filemon acquired metadata --\n"); - - while (fgets(buf, sizeof(buf), fp)) { - fprintf(mfp, "%s", buf); - } - fflush(mfp); - clearerr(fp); - fclose(fp); -} -#endif - -/* - * when realpath() fails, - * we use this, to clean up ./ and ../ - */ -static void -eat_dots(char *buf, size_t bufsz, int dots) -{ - char *cp; - char *cp2; - const char *eat; - size_t eatlen; - - switch (dots) { - case 1: - eat = "/./"; - eatlen = 2; - break; - case 2: - eat = "/../"; - eatlen = 3; - break; - default: - return; - } - - do { - cp = strstr(buf, eat); - if (cp) { - cp2 = cp + eatlen; - if (dots == 2 && cp > buf) { - do { - cp--; - } while (cp > buf && *cp != '/'); - } - if (*cp == '/') { - strlcpy(cp, cp2, bufsz - (cp - buf)); - } else { - return; /* can't happen? */ - } - } - } while (cp); -} - -static char * -meta_name(struct GNode *gn, char *mname, size_t mnamelen, - const char *dname, - const char *tname) -{ - char buf[MAXPATHLEN]; - char cwd[MAXPATHLEN]; - char *rp; - char *cp; - char *tp; - char *p[4]; /* >= number of possible uses */ - int i; - - i = 0; - if (!dname) - dname = Var_Value(".OBJDIR", gn, &p[i++]); - if (!tname) - tname = Var_Value(TARGET, gn, &p[i++]); - - if (realpath(dname, cwd)) - dname = cwd; - - /* - * Weed out relative paths from the target file name. - * We have to be careful though since if target is a - * symlink, the result will be unstable. - * So we use realpath() just to get the dirname, and leave the - * basename as given to us. - */ - if ((cp = strrchr(tname, '/'))) { - if (realpath(tname, buf)) { - if ((rp = strrchr(buf, '/'))) { - rp++; - cp++; - if (strcmp(cp, rp) != 0) - strlcpy(rp, cp, sizeof(buf) - (rp - buf)); - } - tname = buf; - } else { - /* - * We likely have a directory which is about to be made. - * We pretend realpath() succeeded, to have a chance - * of generating the same meta file name that we will - * next time through. - */ - if (tname[0] == '/') { - strlcpy(buf, tname, sizeof(buf)); - } else { - snprintf(buf, sizeof(buf), "%s/%s", cwd, tname); - } - eat_dots(buf, sizeof(buf), 1); /* ./ */ - eat_dots(buf, sizeof(buf), 2); /* ../ */ - tname = buf; - } - } - /* on some systems dirname may modify its arg */ - tp = bmake_strdup(tname); - if (strcmp(dname, dirname(tp)) == 0) - snprintf(mname, mnamelen, "%s.meta", tname); - else { - snprintf(mname, mnamelen, "%s/%s.meta", dname, tname); - - /* - * Replace path separators in the file name after the - * current object directory path. - */ - cp = mname + strlen(dname) + 1; - - while (*cp != '\0') { - if (*cp == '/') - *cp = '_'; - cp++; - } - } - free(tp); - for (i--; i >= 0; i--) { - if (p[i]) - free(p[i]); - } - return (mname); -} - -/* - * Return true if running ${.MAKE} - * Bypassed if target is flagged .MAKE - */ -static int -is_submake(void *cmdp, void *gnp) -{ - static char *p_make = NULL; - static int p_len; - char *cmd = cmdp; - GNode *gn = gnp; - char *mp = NULL; - char *cp; - char *cp2; - int rc = 0; /* keep looking */ - - if (!p_make) { - p_make = Var_Value(".MAKE", gn, &cp); - p_len = strlen(p_make); - } - cp = strchr(cmd, '$'); - if ((cp)) { - mp = Var_Subst(NULL, cmd, gn, FALSE); - cmd = mp; - } - cp2 = strstr(cmd, p_make); - if ((cp2)) { - switch (cp2[p_len]) { - case '\0': - case ' ': - case '\t': - case '\n': - rc = 1; - break; - } - if (cp2 > cmd && rc > 0) { - switch (cp2[-1]) { - case ' ': - case '\t': - case '\n': - break; - default: - rc = 0; /* no match */ - break; - } - } - } - if (mp) - free(mp); - return (rc); -} - -typedef struct meta_file_s { - FILE *fp; - GNode *gn; -} meta_file_t; - -static int -printCMD(void *cmdp, void *mfpp) -{ - meta_file_t *mfp = mfpp; - char *cmd = cmdp; - char *cp = NULL; - - if (strchr(cmd, '$')) { - cmd = cp = Var_Subst(NULL, cmd, mfp->gn, FALSE); - } - fprintf(mfp->fp, "CMD %s\n", cmd); - if (cp) - free(cp); - return 0; -} - -/* - * Certain node types never get a .meta file - */ -#define SKIP_META_TYPE(_type) do { \ - if ((gn->type & __CONCAT(OP_, _type))) { \ - if (DEBUG(META)) { \ - fprintf(debug_file, "Skipping meta for %s: .%s\n", \ - gn->name, __STRING(_type)); \ - } \ - return (NULL); \ - } \ -} while (0) - -static FILE * -meta_create(BuildMon *pbm, GNode *gn) -{ - meta_file_t mf; - char buf[MAXPATHLEN]; - char objdir[MAXPATHLEN]; - char **ptr; - const char *dname; - const char *tname; - char *fname; - const char *cp; - char *p[4]; /* >= possible uses */ - int i; - struct stat fs; - - - /* This may be a phony node which we don't want meta data for... */ - /* Skip .meta for .BEGIN, .END, .ERROR etc as well. */ - /* Or it may be explicitly flagged as .NOMETA */ - SKIP_META_TYPE(NOMETA); - /* Unless it is explicitly flagged as .META */ - if (!(gn->type & OP_META)) { - SKIP_META_TYPE(PHONY); - SKIP_META_TYPE(SPECIAL); - SKIP_META_TYPE(MAKE); - } - - mf.fp = NULL; - - i = 0; - - dname = Var_Value(".OBJDIR", gn, &p[i++]); - tname = Var_Value(TARGET, gn, &p[i++]); - - /* The object directory may not exist. Check it.. */ - if (stat(dname, &fs) != 0) { - if (DEBUG(META)) - fprintf(debug_file, "Skipping meta for %s: no .OBJDIR\n", - gn->name); - goto out; - } - /* Check if there are no commands to execute. */ - if (Lst_IsEmpty(gn->commands)) { - if (DEBUG(META)) - fprintf(debug_file, "Skipping meta for %s: no commands\n", - gn->name); - goto out; - } - - /* make sure these are canonical */ - if (realpath(dname, objdir)) - dname = objdir; - - /* If we aren't in the object directory, don't create a meta file. */ - if (!metaCurdirOk && strcmp(curdir, dname) == 0) { - if (DEBUG(META)) - fprintf(debug_file, "Skipping meta for %s: .OBJDIR == .CURDIR\n", - gn->name); - goto out; - } - if (!(gn->type & OP_META)) { - /* We do not generate .meta files for sub-makes */ - if (Lst_ForEach(gn->commands, is_submake, gn)) { - if (DEBUG(META)) - fprintf(debug_file, "Skipping meta for %s: .MAKE\n", - gn->name); - goto out; - } - } - - if (metaVerbose) { - char *mp; - - /* Describe the target we are building */ - mp = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", gn, 0); - if (*mp) - fprintf(stdout, "%s\n", mp); - free(mp); - } - /* Get the basename of the target */ - if ((cp = strrchr(tname, '/')) == NULL) { - cp = tname; - } else { - cp++; - } - - fflush(stdout); - - if (strcmp(cp, makeDependfile) == 0) - goto out; - - if (!writeMeta) - /* Don't create meta data. */ - goto out; - - fname = meta_name(gn, pbm->meta_fname, sizeof(pbm->meta_fname), - dname, tname); - -#ifdef DEBUG_META_MODE - if (DEBUG(META)) - fprintf(debug_file, "meta_create: %s\n", fname); -#endif - - if ((mf.fp = fopen(fname, "w")) == NULL) - err(1, "Could not open meta file '%s'", fname); - - fprintf(mf.fp, "# Meta data file %s\n", fname); - - mf.gn = gn; - - Lst_ForEach(gn->commands, printCMD, &mf); - - fprintf(mf.fp, "CWD %s\n", getcwd(buf, sizeof(buf))); - fprintf(mf.fp, "TARGET %s\n", tname); - - if (metaEnv) { - for (ptr = environ; *ptr != NULL; ptr++) - fprintf(mf.fp, "ENV %s\n", *ptr); - } - - fprintf(mf.fp, "-- command output --\n"); - fflush(mf.fp); - - Var_Append(".MAKE.META.FILES", fname, VAR_GLOBAL); - Var_Append(".MAKE.META.CREATED", fname, VAR_GLOBAL); - - gn->type |= OP_META; /* in case anyone wants to know */ - if (metaSilent) { - gn->type |= OP_SILENT; - } - out: - for (i--; i >= 0; i--) { - if (p[i]) - free(p[i]); - } - - return (mf.fp); -} - -static Boolean -boolValue(char *s) -{ - switch(*s) { - case '0': - case 'N': - case 'n': - case 'F': - case 'f': - return FALSE; - } - return TRUE; -} - -void -meta_init(const char *make_mode) -{ - static int once = 0; - char *cp; - - useMeta = TRUE; - useFilemon = TRUE; - writeMeta = TRUE; - - if (make_mode) { - if (strstr(make_mode, "env")) - metaEnv = TRUE; - if (strstr(make_mode, "verb")) - metaVerbose = TRUE; - if (strstr(make_mode, "read")) - writeMeta = FALSE; - if (strstr(make_mode, "nofilemon")) - useFilemon = FALSE; - if ((cp = strstr(make_mode, "curdirok="))) { - metaCurdirOk = boolValue(&cp[9]); - } - if ((cp = strstr(make_mode, "silent="))) { - metaSilent = boolValue(&cp[7]); - } - if (strstr(make_mode, "ignore-cmd")) - metaIgnoreCMDs = TRUE; - /* for backwards compatability */ - Var_Set(".MAKE.META_CREATED", "${.MAKE.META.CREATED}", VAR_GLOBAL, 0); - Var_Set(".MAKE.META_FILES", "${.MAKE.META.FILES}", VAR_GLOBAL, 0); - } - if (metaVerbose && !Var_Exists(MAKE_META_PREFIX, VAR_GLOBAL)) { - /* - * The default value for MAKE_META_PREFIX - * prints the absolute path of the target. - * This works be cause :H will generate '.' if there is no / - * and :tA will resolve that to cwd. - */ - Var_Set(MAKE_META_PREFIX, "Building ${.TARGET:H:tA}/${.TARGET:T}", VAR_GLOBAL, 0); - } - if (once) - return; - once = 1; - memset(&Mybm, 0, sizeof(Mybm)); - /* - * We consider ourselves master of all within ${.MAKE.META.BAILIWICK} - */ - metaBailiwick = Lst_Init(FALSE); - cp = Var_Subst(NULL, "${.MAKE.META.BAILIWICK:O:u:tA}", VAR_GLOBAL, 0); - if (cp) { - str2Lst_Append(metaBailiwick, cp, NULL); - } -} - -/* - * In each case below we allow for job==NULL - */ -void -meta_job_start(Job *job, GNode *gn) -{ - BuildMon *pbm; - - if (job != NULL) { - pbm = &job->bm; - } else { - pbm = &Mybm; - } - pbm->mfp = meta_create(pbm, gn); -#ifdef USE_FILEMON_ONCE - /* compat mode we open the filemon dev once per command */ - if (job == NULL) - return; -#endif -#ifdef USE_FILEMON - if (pbm->mfp != NULL && useFilemon) { - filemon_open(pbm); - } else { - pbm->mon_fd = pbm->filemon_fd = -1; - } -#endif -} - -/* - * The child calls this before doing anything. - * It does not disturb our state. - */ -void -meta_job_child(Job *job) -{ -#ifdef USE_FILEMON - BuildMon *pbm; - pid_t pid; - - if (job != NULL) { - pbm = &job->bm; - } else { - pbm = &Mybm; - } - pid = getpid(); - if (pbm->mfp != NULL && useFilemon) { - if (ioctl(pbm->filemon_fd, FILEMON_SET_PID, &pid) < 0) { - err(1, "Could not set filemon pid!"); - } - } -#endif -} - -void -meta_job_error(Job *job, GNode *gn, int flags, int status) -{ - char cwd[MAXPATHLEN]; - BuildMon *pbm; - - if (job != NULL) { - pbm = &job->bm; - } else { - if (!gn) - gn = job->node; - pbm = &Mybm; - } - if (pbm->mfp != NULL) { - fprintf(pbm->mfp, "*** Error code %d%s\n", - status, - (flags & JOB_IGNERR) ? - "(ignored)" : ""); - } - if (gn) { - Var_Set(".ERROR_TARGET", gn->path ? gn->path : gn->name, VAR_GLOBAL, 0); - } - getcwd(cwd, sizeof(cwd)); - Var_Set(".ERROR_CWD", cwd, VAR_GLOBAL, 0); - if (pbm && pbm->meta_fname[0]) { - Var_Set(".ERROR_META_FILE", pbm->meta_fname, VAR_GLOBAL, 0); - } - meta_job_finish(job); -} - -void -meta_job_output(Job *job, char *cp, const char *nl) -{ - BuildMon *pbm; - - if (job != NULL) { - pbm = &job->bm; - } else { - pbm = &Mybm; - } - if (pbm->mfp != NULL) { - if (metaVerbose) { - static char *meta_prefix = NULL; - static int meta_prefix_len; - - if (!meta_prefix) { - char *cp2; - - meta_prefix = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", VAR_GLOBAL, 0); - if ((cp2 = strchr(meta_prefix, '$'))) - meta_prefix_len = cp2 - meta_prefix; - else - meta_prefix_len = strlen(meta_prefix); - } - if (strncmp(cp, meta_prefix, meta_prefix_len) == 0) { - cp = strchr(cp+1, '\n'); - if (!cp++) - return; - } - } - fprintf(pbm->mfp, "%s%s", cp, nl); - } -} - -void -meta_cmd_finish(void *pbmp) -{ -#ifdef USE_FILEMON - BuildMon *pbm = pbmp; - - if (!pbm) - pbm = &Mybm; - - if (pbm->filemon_fd >= 0) { - close(pbm->filemon_fd); - filemon_read(pbm->mfp, pbm->mon_fd); - pbm->filemon_fd = pbm->mon_fd = -1; - } -#endif -} - -void -meta_job_finish(Job *job) -{ - BuildMon *pbm; - - if (job != NULL) { - pbm = &job->bm; - } else { - pbm = &Mybm; - } - if (pbm->mfp != NULL) { - meta_cmd_finish(pbm); - fclose(pbm->mfp); - pbm->mfp = NULL; - pbm->meta_fname[0] = '\0'; - } -} - -/* - * Fetch a full line from fp - growing bufp if needed - * Return length in bufp. - */ -static int -fgetLine(char **bufp, size_t *szp, int o, FILE *fp) -{ - char *buf = *bufp; - size_t bufsz = *szp; - struct stat fs; - int x; - - if (fgets(&buf[o], bufsz - o, fp) != NULL) { - check_newline: - x = o + strlen(&buf[o]); - if (buf[x - 1] == '\n') - return x; - /* - * We need to grow the buffer. - * The meta file can give us a clue. - */ - if (fstat(fileno(fp), &fs) == 0) { - size_t newsz; - char *p; - - newsz = ROUNDUP((fs.st_size / 2), BUFSIZ); - if (newsz <= bufsz) - newsz = ROUNDUP(fs.st_size, BUFSIZ); - if (DEBUG(META)) - fprintf(debug_file, "growing buffer %u -> %u\n", - (unsigned)bufsz, (unsigned)newsz); - p = bmake_realloc(buf, newsz); - if (p) { - *bufp = buf = p; - *szp = bufsz = newsz; - /* fetch the rest */ - if (!fgets(&buf[x], bufsz - x, fp)) - return x; /* truncated! */ - goto check_newline; - } - } - } - return 0; -} - -static int -prefix_match(void *p, void *q) -{ - const char *prefix = p; - const char *path = q; - size_t n = strlen(prefix); - - return (0 == strncmp(path, prefix, n)); -} - -static int -string_match(const void *p, const void *q) -{ - const char *p1 = p; - const char *p2 = q; - - return strcmp(p1, p2); -} - - -/* - * When running with 'meta' functionality, a target can be out-of-date - * if any of the references in it's meta data file is more recent. - * We have to track the latestdir on a per-process basis. - */ -#define LDIR_VNAME_FMT ".meta.%d.ldir" - -/* - * It is possible that a .meta file is corrupted, - * if we detect this we want to reproduce it. - * Setting oodate TRUE will have that effect. - */ -#define CHECK_VALID_META(p) if (!(p && *p)) { \ - warnx("%s: %d: malformed", fname, lineno); \ - oodate = TRUE; \ - continue; \ - } - -Boolean -meta_oodate(GNode *gn, Boolean oodate) -{ - static char *tmpdir = NULL; - static char cwd[MAXPATHLEN]; - char ldir_vname[64]; - char latestdir[MAXPATHLEN]; - char fname[MAXPATHLEN]; - char fname1[MAXPATHLEN]; - char fname2[MAXPATHLEN]; - char *p; - char *cp; - static size_t cwdlen = 0; - static size_t tmplen = 0; - FILE *fp; - Boolean ignoreOODATE = FALSE; - Lst missingFiles; - - if (oodate) - return oodate; /* we're done */ - - missingFiles = Lst_Init(FALSE); - - /* - * We need to check if the target is out-of-date. This includes - * checking if the expanded command has changed. This in turn - * requires that all variables are set in the same way that they - * would be if the target needs to be re-built. - */ - Make_DoAllVar(gn); - - meta_name(gn, fname, sizeof(fname), NULL, NULL); - -#ifdef DEBUG_META_MODE - if (DEBUG(META)) - fprintf(debug_file, "meta_oodate: %s\n", fname); -#endif - - if ((fp = fopen(fname, "r")) != NULL) { - static char *buf = NULL; - static size_t bufsz; - int lineno = 0; - int lastpid = 0; - int pid; - int f = 0; - int x; - LstNode ln; - struct stat fs; - - if (!buf) { - bufsz = 8 * BUFSIZ; - buf = bmake_malloc(bufsz); - } - - if (!cwdlen) { - if (getcwd(cwd, sizeof(cwd)) == NULL) - err(1, "Could not get current working directory"); - cwdlen = strlen(cwd); - } - - if (!tmpdir) { - tmpdir = getTmpdir(); - tmplen = strlen(tmpdir); - } - - /* we want to track all the .meta we read */ - Var_Append(".MAKE.META.FILES", fname, VAR_GLOBAL); - - ln = Lst_First(gn->commands); - while (!oodate && (x = fgetLine(&buf, &bufsz, 0, fp)) > 0) { - lineno++; - if (buf[x - 1] == '\n') - buf[x - 1] = '\0'; - else { - warnx("%s: %d: line truncated at %u", fname, lineno, x); - oodate = TRUE; - break; - } - /* Find the start of the build monitor section. */ - if (!f) { - if (strncmp(buf, "-- filemon", 10) == 0) { - f = 1; - continue; - } - if (strncmp(buf, "# buildmon", 10) == 0) { - f = 1; - continue; - } - } - - /* Delimit the record type. */ - p = buf; -#ifdef DEBUG_META_MODE - if (DEBUG(META)) - fprintf(debug_file, "%s: %d: %s\n", fname, lineno, buf); -#endif - strsep(&p, " "); - if (f) { - /* - * We are in the 'filemon' output section. - * Each record from filemon follows the general form: - * - * <key> <pid> <data> - * - * Where: - * <key> is a single letter, denoting the syscall. - * <pid> is the process that made the syscall. - * <data> is the arguments (of interest). - */ - switch(buf[0]) { - case '#': /* comment */ - case 'V': /* version */ - break; - default: - /* - * We need to track pathnames per-process. - * - * Each process run by make, starts off in the 'CWD' - * recorded in the .meta file, if it chdirs ('C') - * elsewhere we need to track that - but only for - * that process. If it forks ('F'), we initialize - * the child to have the same cwd as its parent. - * - * We also need to track the 'latestdir' of - * interest. This is usually the same as cwd, but - * not if a process is reading directories. - * - * Each time we spot a different process ('pid') - * we save the current value of 'latestdir' in a - * variable qualified by 'lastpid', and - * re-initialize 'latestdir' to any pre-saved - * value for the current 'pid' and 'CWD' if none. - */ - CHECK_VALID_META(p); - pid = atoi(p); - if (pid > 0 && pid != lastpid) { - char *ldir; - char *tp; - - if (lastpid > 0) { - /* We need to remember this. */ - Var_Set(ldir_vname, latestdir, VAR_GLOBAL, 0); - } - snprintf(ldir_vname, sizeof(ldir_vname), LDIR_VNAME_FMT, pid); - lastpid = pid; - ldir = Var_Value(ldir_vname, VAR_GLOBAL, &tp); - if (ldir) { - strlcpy(latestdir, ldir, sizeof(latestdir)); - if (tp) - free(tp); - } else - strlcpy(latestdir, cwd, sizeof(latestdir)); - } - /* Skip past the pid. */ - if (strsep(&p, " ") == NULL) - continue; -#ifdef DEBUG_META_MODE - if (DEBUG(META)) - fprintf(debug_file, "%s: %d: cwd=%s ldir=%s\n", fname, lineno, cwd, latestdir); -#endif - break; - } - - CHECK_VALID_META(p); - - /* Process according to record type. */ - switch (buf[0]) { - case 'X': /* eXit */ - Var_Delete(ldir_vname, VAR_GLOBAL); - lastpid = 0; /* no need to save ldir_vname */ - break; - - case 'F': /* [v]Fork */ - { - char cldir[64]; - int child; - - child = atoi(p); - if (child > 0) { - snprintf(cldir, sizeof(cldir), LDIR_VNAME_FMT, child); - Var_Set(cldir, latestdir, VAR_GLOBAL, 0); - } - } - break; - - case 'C': /* Chdir */ - /* Update the latest directory. */ - strlcpy(latestdir, p, sizeof(latestdir)); - break; - - case 'M': /* renaMe */ - if (Lst_IsEmpty(missingFiles)) - break; - /* 'L' and 'M' put single quotes around the args */ - if (*p == '\'') { - char *ep; - - p++; - if ((ep = strchr(p, '\''))) - *ep = '\0'; - } - /* FALLTHROUGH */ - case 'D': /* unlink */ - if (*p == '/' && !Lst_IsEmpty(missingFiles)) { - /* remove p from the missingFiles list if present */ - if ((ln = Lst_Find(missingFiles, p, string_match)) != NULL) { - char *tp = Lst_Datum(ln); - Lst_Remove(missingFiles, ln); - free(tp); - } - } - break; - case 'L': /* Link */ - /* we want the target */ - if (strsep(&p, " ") == NULL) - continue; - CHECK_VALID_META(p); - /* 'L' and 'M' put single quotes around the args */ - if (*p == '\'') { - char *ep; - - p++; - if ((ep = strchr(p, '\''))) - *ep = '\0'; - } - /* FALLTHROUGH */ - case 'W': /* Write */ - /* - * If a file we generated within our bailiwick - * but outside of .OBJDIR is missing, - * we need to do it again. - */ - /* ignore non-absolute paths */ - if (*p != '/') - break; - - if (Lst_IsEmpty(metaBailiwick)) - break; - - /* ignore cwd - normal dependencies handle those */ - if (strncmp(p, cwd, cwdlen) == 0) - break; - - if (!Lst_ForEach(metaBailiwick, prefix_match, p)) - break; - - /* tmpdir might be within */ - if (tmplen > 0 && strncmp(p, tmpdir, tmplen) == 0) - break; - - /* ignore anything containing the string "tmp" */ - if ((strstr("tmp", p))) - break; - - if (stat(p, &fs) < 0) { - Lst_AtEnd(missingFiles, bmake_strdup(p)); - } - break; - case 'R': /* Read */ - case 'E': /* Exec */ - /* - * Check for runtime files that can't - * be part of the dependencies because - * they are _expected_ to change. - */ - if (strncmp(p, "/tmp/", 5) == 0 || - (tmplen > 0 && strncmp(p, tmpdir, tmplen) == 0)) - break; - - if (strncmp(p, "/var/", 5) == 0) - break; - - /* Ignore device files. */ - if (strncmp(p, "/dev/", 5) == 0) - break; - - /* Ignore /etc/ files. */ - if (strncmp(p, "/etc/", 5) == 0) - break; - - if ((cp = strrchr(p, '/'))) { - cp++; - /* - * We don't normally expect to see this, - * but we do expect it to change. - */ - if (strcmp(cp, makeDependfile) == 0) - break; - } - - /* - * The rest of the record is the file name. - * Check if it's not an absolute path. - */ - { - char *sdirs[4]; - char **sdp; - int sdx = 0; - int found = 0; - - if (*p == '/') { - sdirs[sdx++] = p; /* done */ - } else { - if (strcmp(".", p) == 0) - continue; /* no point */ - - /* Check vs latestdir */ - snprintf(fname1, sizeof(fname1), "%s/%s", latestdir, p); - sdirs[sdx++] = fname1; - - if (strcmp(latestdir, cwd) != 0) { - /* Check vs cwd */ - snprintf(fname2, sizeof(fname2), "%s/%s", cwd, p); - sdirs[sdx++] = fname2; - } - } - sdirs[sdx++] = NULL; - - for (sdp = sdirs; *sdp && !found; sdp++) { -#ifdef DEBUG_META_MODE - if (DEBUG(META)) - fprintf(debug_file, "%s: %d: looking for: %s\n", fname, lineno, *sdp); -#endif - if (stat(*sdp, &fs) == 0) { - found = 1; - p = *sdp; - } - } - if (found) { -#ifdef DEBUG_META_MODE - if (DEBUG(META)) - fprintf(debug_file, "%s: %d: found: %s\n", fname, lineno, p); -#endif - if (!S_ISDIR(fs.st_mode) && - fs.st_mtime > gn->mtime) { - if (DEBUG(META)) - fprintf(debug_file, "%s: %d: file '%s' is newer than the target...\n", fname, lineno, p); - oodate = TRUE; - } else if (S_ISDIR(fs.st_mode)) { - /* Update the latest directory. */ - realpath(p, latestdir); - } - } else if (errno == ENOENT && *p == '/' && - strncmp(p, cwd, cwdlen) != 0) { - /* - * A referenced file outside of CWD is missing. - * We cannot catch every eventuality here... - */ - if (DEBUG(META)) - fprintf(debug_file, "%s: %d: file '%s' may have moved?...\n", fname, lineno, p); - oodate = TRUE; - } - } - break; - default: - break; - } - } else if (strcmp(buf, "CMD") == 0) { - /* - * Compare the current command with the one in the - * meta data file. - */ - if (ln == NULL) { - if (DEBUG(META)) - fprintf(debug_file, "%s: %d: there were more build commands in the meta data file than there are now...\n", fname, lineno); - oodate = TRUE; - } else { - char *cmd = (char *)Lst_Datum(ln); - - if (!ignoreOODATE) { - if (strstr(cmd, "$?")) - ignoreOODATE = TRUE; - else if ((cp = strstr(cmd, ".OODATE"))) { - /* check for $[{(].OODATE[)}] */ - if (cp > cmd + 2 && cp[-2] == '$') - ignoreOODATE = TRUE; - } - if (ignoreOODATE && DEBUG(META)) - fprintf(debug_file, "%s: %d: cannot compare commands using .OODATE\n", fname, lineno); - } - cmd = Var_Subst(NULL, cmd, gn, TRUE); - - if ((cp = strchr(cmd, '\n'))) { - int n; - - /* - * This command contains newlines, we need to - * fetch more from the .meta file before we - * attempt a comparison. - */ - /* first put the newline back at buf[x - 1] */ - buf[x - 1] = '\n'; - do { - /* now fetch the next line */ - if ((n = fgetLine(&buf, &bufsz, x, fp)) <= 0) - break; - x = n; - lineno++; - if (buf[x - 1] != '\n') { - warnx("%s: %d: line truncated at %u", fname, lineno, x); - break; - } - cp = strchr(++cp, '\n'); - } while (cp); - if (buf[x - 1] == '\n') - buf[x - 1] = '\0'; - } - if (!ignoreOODATE && - !(gn->type & OP_NOMETA_CMP) && - strcmp(p, cmd) != 0) { - if (DEBUG(META)) - fprintf(debug_file, "%s: %d: a build command has changed\n%s\nvs\n%s\n", fname, lineno, p, cmd); - if (!metaIgnoreCMDs) - oodate = TRUE; - } - free(cmd); - ln = Lst_Succ(ln); - } - } else if (strcmp(buf, "CWD") == 0) { - /* - * Check if there are extra commands now - * that weren't in the meta data file. - */ - if (!oodate && ln != NULL) { - if (DEBUG(META)) - fprintf(debug_file, "%s: %d: there are extra build commands now that weren't in the meta data file\n", fname, lineno); - oodate = TRUE; - } - if (strcmp(p, cwd) != 0) { - if (DEBUG(META)) - fprintf(debug_file, "%s: %d: the current working directory has changed from '%s' to '%s'\n", fname, lineno, p, curdir); - oodate = TRUE; - } - } - } - - fclose(fp); - if (!Lst_IsEmpty(missingFiles)) { - if (DEBUG(META)) - fprintf(debug_file, "%s: missing files: %s...\n", - fname, (char *)Lst_Datum(Lst_First(missingFiles))); - oodate = TRUE; - Lst_Destroy(missingFiles, (FreeProc *)free); - } - } else { - if ((gn->type & OP_META)) { - if (DEBUG(META)) - fprintf(debug_file, "%s: required but missing\n", fname); - oodate = TRUE; - } - } - if (oodate && ignoreOODATE) { - /* - * Target uses .OODATE, so we need to re-compute it. - * We need to clean up what Make_DoAllVar() did. - */ - Var_Delete(ALLSRC, gn); - Var_Delete(OODATE, gn); - gn->flags &= ~DONE_ALLSRC; - } - return oodate; -} - -/* support for compat mode */ - -static int childPipe[2]; - -void -meta_compat_start(void) -{ -#ifdef USE_FILEMON_ONCE - /* - * We need to re-open filemon for each cmd. - */ - BuildMon *pbm = &Mybm; - - if (pbm->mfp != NULL && useFilemon) { - filemon_open(pbm); - } else { - pbm->mon_fd = pbm->filemon_fd = -1; - } -#endif - if (pipe(childPipe) < 0) - Punt("Cannot create pipe: %s", strerror(errno)); - /* Set close-on-exec flag for both */ - (void)fcntl(childPipe[0], F_SETFD, 1); - (void)fcntl(childPipe[1], F_SETFD, 1); -} - -void -meta_compat_child(void) -{ - meta_job_child(NULL); - if (dup2(childPipe[1], 1) < 0 || - dup2(1, 2) < 0) { - execError("dup2", "pipe"); - _exit(1); - } -} - -void -meta_compat_parent(void) -{ - FILE *fp; - char buf[BUFSIZ]; - - close(childPipe[1]); /* child side */ - fp = fdopen(childPipe[0], "r"); - while (fgets(buf, sizeof(buf), fp)) { - meta_job_output(NULL, buf, ""); - printf("%s", buf); - } - fclose(fp); -} - -#endif /* USE_META */ diff --git a/20120831/meta.h b/20120831/meta.h deleted file mode 100644 index 1ce01ca..0000000 --- a/20120831/meta.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $NetBSD: meta.h,v 1.2 2011/03/30 22:03:49 sjg Exp $ */ - -/* - * Things needed for 'meta' mode. - */ -/* - * Copyright (c) 2009-2010, Juniper Networks, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -typedef struct BuildMon { - char meta_fname[MAXPATHLEN]; - int filemon_fd; - int mon_fd; - FILE *mfp; -} BuildMon; - -extern Boolean useMeta; - -struct Job; /* not defined yet */ -void meta_init(const char *); -void meta_job_start(struct Job *, GNode *); -void meta_job_child(struct Job *); -void meta_job_error(struct Job *, GNode *, int, int); -void meta_job_output(struct Job *, char *, const char *); -void meta_cmd_finish(void *); -void meta_job_finish(struct Job *); -Boolean meta_oodate(GNode *, Boolean); -void meta_compat_start(void); -void meta_compat_child(void); -void meta_compat_parent(void); diff --git a/20120831/mkdeps.sh b/20120831/mkdeps.sh deleted file mode 100755 index dd87c4f..0000000 --- a/20120831/mkdeps.sh +++ /dev/null @@ -1,314 +0,0 @@ -: -# NAME: -# mkdeps - generate dependencies -# -# SYNOPSIS: -# mkdeps [options] file ... -# -# DESCRIPTION: -# This script updates "makefile" with dependencies for -# "file"(s). It borrows ideas from various makedepend scripts -# and should be compatible with most. -# -# By default we use grep to extract include file names from -# source files. We source an "rc" file '$Mydir/.${Myname}rc' which -# can contain variable assignments such as: -#.nf -# -# cpp_c=/usr/lib/cpp -# cpp_cc=g++ -E -# ... -# -#.fi -# If the variable 'cpp_$suffix' is set, we use it as our cpp in -# place of grep. The program referenced by these variables are -# expected to produce output like: -#.nf -# -# # 10 \"/usr/include/stdio.h\" 1 -# -#.fi -# This allows us to skip most of our processing. For lex,yacc -# and other source files, grep is probably just as quick and -# certainly more portable. -# -# If the "rc" file does not exist, we create it and attempt to -# find cpp or an equivalent cc invocation to assign to 'cpp_c'. -# -# AUTHOR: -# Simon J. Gerraty <sjg@zen.void.oz.au> -# - -# RCSid: -# $Id: mkdeps.sh,v 1.23 2002/11/29 06:58:59 sjg Exp $ -# -# @(#) Copyright (c) 1993 Simon J. Gerraty -# -# This file is provided in the hope that it will -# be of use. There is absolutely NO WARRANTY. -# Permission to copy, redistribute or otherwise -# use this file is hereby granted provided that -# the above copyright notice and this notice are -# left intact. -# -# Please send copies of changes and bug-fixes to: -# sjg@zen.void.oz.au -# - -Myname=`basename $0 .sh` -Mydir=`dirname $0` - -case `echo -n .` in --n*) N=; C="\c";; -*) N=-n; C=;; -esac - -cc_include=-I/usr/include - -TF=/tmp/dep.$$ -EF=/tmp/deperr.$$ -> $EF - -case "$*" in -*-n*) # don't use rc file - rc=/dev/null - norc=yes;; -*) - rc=$Mydir/.${Myname}rc - ;; -esac - -update= -Include=include - -if [ x"$norc" = x -a -f $rc ]; then - . $rc -else - # if /usr/lib/cpp or equivalent is available it is better than - # grepping .c files. - # See what (if anything) works on this system... - echo : > $rc - echo "# pre-processor for .c files" >> $rc - # try a couple of sane places first - for d in /usr/libexec /usr/lib /usr/bin /lib /usr/ccs/bin - do - cpp_c=$d/cpp - [ -x $cpp_c ] && break - done - - if [ -x $cpp_c ]; then - echo cpp_c=$cpp_c >> $rc - else - cpp_c= - # rats see if cc can be used - echo "#include <stdio.h>" > /tmp/f$$.c - echo "main() { return 0; }" >> /tmp/f$$.c - # try some sensible args to cc - for arg in -E -P -M - do - ok=`${REALCC:-${CC:-cc}} $arg /tmp/f$$.c 2>/dev/null | grep '^#.*stdio.h' | tail -1` - case "$ok" in - "") ;; - *) - cpp_c="${REALCC:-${CC:-cc}} $arg" - echo cpp_c="'$cpp_c'" >> $rc - break;; - esac - done - rm -f /tmp/f$$.c - fi -fi - -clean_up() { - trap "" 2 3 - trap 0 - if [ -s $EF ]; then - egrep -vi "included from|warning" $EF > ${EF}2 - if [ -s ${EF}2 ]; then - cat $EF >&2 - rm -f .depend - ests=1 - fi - fi - rm -f $TF $EF* - exit ${ests:-0} -} - -# this lot does not work on HPsUX - complain to Hp. -trap clean_up 0 -trap exit 2 3 - -get_incs() { - case "$cpp" in - grep) - # set IGNORE="<" to skip system includes - egrep '^#[ ]*include' $* | egrep -v "$IGNORE" | \ - sed -e 's/^.*include[^"<]*["<]//' -e 's/[">].*//g';; - *) - # $cpp (eg. /usr/lib/cpp or cc -E) should produce output like: - # 1 "/usr/include/stdio.h" 2 - # set IGNORE=/usr/include to skip system includes - $cpp $cpp_opts $cc_include $* 2>> $EF | egrep '^#.*\.h"' | sed 's,^#.*"\(.*\)".*,\1,' | - egrep -v "$IGNORE" | sort -u;; - esac -} - -gen_deps() { - llen=$1 - shift - - for ifile in $* - do - case "$cpp" in - grep) - # this lot is not needed if not using grep. - for dir in $srcdir $dirlist /usr/include - do - [ -f "$dir/$ifile" ] && break - done - - if [ ! -f "$dir/$ifile" ]; then - # produce a useful error message (useful to emacs or error) - iline=`grep -n ".*include.*[\"<]$ifile[\">]" $file | cut -d: -f1` - echo "\"$file\", line $iline: cannot find include file \"$ifile\"" >> $EF - # no point adding to dependency list as the resulting makefile - # would not work anyway... - continue - fi - ifile=$dir/$ifile - - # check whether we have done it yet - case `grep "$ifile" $TF` in - "") echo "$ifile" >> $TF;; - *) continue;; # no repeats... - esac - ;; - esac - - len=`expr "$ifile " : '.*'` - if [ "`expr $llen + $len`" -gt ${width:-76} ]; then - echo "\\" >> .depend - echo $N " $C" >> .depend - llen=8 - fi - echo $N "$ifile $C" >> .depend - llen=`expr $llen + $len` - - case "$cpp" in - grep) - # this lot is not needed unless using grep. - ilist=`get_incs $ifile` # recurse needed? - [ "$ilist" ] && llen=`gen_deps $llen $ilist` - ;; - esac - done - echo $llen -} - -for f in makefile Makefile -do - test -s $f && { MAKEFILE=$f; break; } -done - -MAKEFILE=${MAKEFILE:-makefile} -IGNORE=${IGNORE:-"^-"} # won't happen -obj=o -cpp_opts= # incase cpp != grep -vpath= -append= -progDep= - -set -- `getopt "AanNV:s:w:o:I:D:b:f:i:p" "$@"` -for key in "$@" -do - case $key in - --) shift; break;; - -A) Include=;; # cat .depend >> $MAKEFILE - -a) append=yes; shift;; - -n) shift;; # ignore rc - -N) update=no; shift;; # don't update $MAKEFILE - -I) cpp_opts="$cpp_opts$1$2 "; dirlist="$dirlist $2"; shift 2;; - -o) obj=$2; shift 2;; - -s) shift 2;; # can't handle it anyway... - -w) width=$2; shift 2;; - -f) MAKEFILE=$2; shift 2;; - -b) BASEDIR=$2; shift 2;; - -i) IGNORE="$2"; shift 2;; # ignore headers matching this... - -D) cpp_opts="$cpp_opts$1$2 "; shift 2;; - -V) VPATH="$2"; shift 2;; # where to look for files - -p) progDep=yes; shift;; - esac -done - -[ "$VPATH" ] && vpath=`IFS=:; set -- $VPATH; echo $*` - -[ "$append" ] || > .depend - -for file in $* -do - cpp= - suffix=`expr $file : '.*\.\([^.]*\)'` - - eval cpp=\"\${cpp_${suffix}:-grep}\" - - if [ ! -f $file -a "$vpath" ]; then - for d in . $vpath - do - [ -f $d/$file ] && { file=$d/$file; break; } - done - fi - srcdir=`dirname $file` - base=`basename $file .$suffix` - - ilist=`get_incs $file` - - if [ "$ilist" ]; then - > $TF - if [ "$progDep" ]; then - echo "$base: $file \\" >> .depend - else - echo "$base.$obj: $file \\" >> .depend - fi - echo $N " $C" >> .depend - llen=8 - llen=`gen_deps $llen $ilist` - echo >> .depend - echo >> .depend - elif [ "$progDep" ]; then - echo "$base: $file" >> .depend - echo >> .depend - fi -done - -if [ -s .depend ]; then - # ./foo.h looks ugly - mv .depend $TF - { test "$BASEDIR" && sed -e "s;$BASEDIR;\$(BASEDIR);g" $TF || cat $TF; } | - sed 's;\([^.]\)\./;\1;g' > .depend - - # - # Save the manually updated section of the makefile - # - if [ x$update != xno ]; then - trap "" 2 # don't die if we got this far - - # if make doesn't support include, then append our deps... - depended=`grep 'include.*\.depend' $MAKEFILE` - test "$depended" && clean_up - - sed '/^# DO NOT DELETE.*depend.*$/,$d' < $MAKEFILE > $TF - mv $TF $MAKEFILE - cat <<! >> $MAKEFILE -# DO NOT DELETE THIS LINE -- make depend depends on it -# Do not edit anything below, it was added automagically by $Myname. - -! - - case "$Include" in - "") cat .depend >> $MAKEFILE;; - .include) echo '.include ".depend"' >> $MAKEFILE;; - include) echo include .depend >> $MAKEFILE;; - esac - fi -fi -clean_up diff --git a/20120831/nonints.h b/20120831/nonints.h deleted file mode 100644 index eeb197e..0000000 --- a/20120831/nonints.h +++ /dev/null @@ -1,198 +0,0 @@ -/* $NetBSD: nonints.h,v 1.64 2012/06/12 19:21:51 joerg Exp $ */ - -/*- - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)nonints.h 8.3 (Berkeley) 3/19/94 - */ - -/*- - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)nonints.h 8.3 (Berkeley) 3/19/94 - */ - -/* arch.c */ -ReturnStatus Arch_ParseArchive(char **, Lst, GNode *); -void Arch_Touch(GNode *); -void Arch_TouchLib(GNode *); -time_t Arch_MTime(GNode *); -time_t Arch_MemMTime(GNode *); -void Arch_FindLib(GNode *, Lst); -Boolean Arch_LibOODate(GNode *); -void Arch_Init(void); -void Arch_End(void); -int Arch_IsLib(GNode *); - -/* compat.c */ -int CompatRunCommand(void *, void *); -void Compat_Run(Lst); -int Compat_Make(void *, void *); - -/* cond.c */ -struct If; -int Cond_EvalExpression(const struct If *, char *, Boolean *, int); -int Cond_Eval(char *); -void Cond_restore_depth(unsigned int); -unsigned int Cond_save_depth(void); - -/* for.c */ -int For_Eval(char *); -int For_Accum(char *); -void For_Run(int); - -/* job.c */ -#ifdef WAIT_T -void JobReapChild(pid_t, WAIT_T, Boolean); -#endif - -/* main.c */ -void Main_ParseArgLine(const char *); -void MakeMode(const char *); -int main(int, char **); -char *Cmd_Exec(const char *, const char **); -void Error(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2); -void Fatal(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD; -void Punt(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD; -void DieHorribly(void) MAKE_ATTR_DEAD; -int PrintAddr(void *, void *); -void Finish(int) MAKE_ATTR_DEAD; -int eunlink(const char *); -void execError(const char *, const char *); -char *getTmpdir(void); - -/* parse.c */ -void Parse_Error(int, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3); -Boolean Parse_AnyExport(void); -Boolean Parse_IsVar(char *); -void Parse_DoVar(char *, GNode *); -void Parse_AddIncludeDir(char *); -void Parse_File(const char *, int); -void Parse_Init(void); -void Parse_End(void); -void Parse_SetInput(const char *, int, int, char *(*)(void *, size_t *), void *); -Lst Parse_MainName(void); - -/* str.c */ -char *str_concat(const char *, const char *, int); -char **brk_string(const char *, int *, Boolean, char **); -char *Str_FindSubstring(const char *, const char *); -int Str_Match(const char *, const char *); -char *Str_SYSVMatch(const char *, const char *, int *len); -void Str_SYSVSubst(Buffer *, char *, char *, int); - -/* suff.c */ -void Suff_ClearSuffixes(void); -Boolean Suff_IsTransform(char *); -GNode *Suff_AddTransform(char *); -int Suff_EndTransform(void *, void *); -void Suff_AddSuffix(char *, GNode **); -Lst Suff_GetPath(char *); -void Suff_DoPaths(void); -void Suff_AddInclude(char *); -void Suff_AddLib(char *); -void Suff_FindDeps(GNode *); -Lst Suff_FindPath(GNode *); -void Suff_SetNull(char *); -void Suff_Init(void); -void Suff_End(void); -void Suff_PrintAll(void); - -/* targ.c */ -void Targ_Init(void); -void Targ_End(void); -Lst Targ_List(void); -GNode *Targ_NewGN(const char *); -GNode *Targ_FindNode(const char *, int); -Lst Targ_FindList(Lst, int); -Boolean Targ_Ignore(GNode *); -Boolean Targ_Silent(GNode *); -Boolean Targ_Precious(GNode *); -void Targ_SetMain(GNode *); -int Targ_PrintCmd(void *, void *); -int Targ_PrintNode(void *, void *); -char *Targ_FmtTime(time_t); -void Targ_PrintType(int); -void Targ_PrintGraph(int); -void Targ_Propagate(void); -void Targ_Propagate_Wait(void); - -/* var.c */ -void Var_Delete(const char *, GNode *); -void Var_Set(const char *, const char *, GNode *, int); -void Var_Append(const char *, const char *, GNode *); -Boolean Var_Exists(const char *, GNode *); -char *Var_Value(const char *, GNode *, char **); -char *Var_Parse(const char *, GNode *, Boolean, int *, void **); -char *Var_Subst(const char *, const char *, GNode *, Boolean); -char *Var_GetTail(const char *); -char *Var_GetHead(const char *); -void Var_Init(void); -void Var_End(void); -void Var_Dump(GNode *); -void Var_ExportVars(void); -void Var_Export(char *, int); -void Var_UnExport(char *); - -/* util.c */ -void (*bmake_signal(int, void (*)(int)))(int); diff --git a/20120831/os.sh b/20120831/os.sh deleted file mode 100755 index 9e45f37..0000000 --- a/20120831/os.sh +++ /dev/null @@ -1,228 +0,0 @@ -: -# NAME: -# os.sh - operating system specifics -# -# DESCRIPTION: -# This file is included at the start of processing. Its role is -# to set the variables OS, OSREL, OSMAJOR, MACHINE and MACHINE_ARCH to -# reflect the current system. -# -# It also sets variables such as MAILER, LOCAL_FS, PS_AXC to hide -# certain aspects of different UNIX flavours. -# -# SEE ALSO: -# site.sh,funcs.sh -# -# AUTHOR: -# Simon J. Gerraty <sjg@crufty.net> - -# RCSid: -# $Id: os.sh,v 1.44 2010/06/29 15:37:21 sjg Exp $ -# -# @(#) Copyright (c) 1994 Simon J. Gerraty -# -# This file is provided in the hope that it will -# be of use. There is absolutely NO WARRANTY. -# Permission to copy, redistribute or otherwise -# use this file is hereby granted provided that -# the above copyright notice and this notice are -# left intact. -# -# Please send copies of changes and bug-fixes to: -# sjg@crufty.net -# - -# this lets us skip sourcing it again -_OS_SH=: - -OS=`uname` -OSREL=`uname -r` -OSMAJOR=`IFS=.; set $OSREL; echo $1` -MACHINE=`uname -m` -MACHINE_ARCH=`uname -p 2>/dev/null || echo $MACHINE` - -# there is at least one case of `uname -p` outputting -# a bunch of usless drivel -case "$MACHINE_ARCH" in -*[!A-Za-z0-9_-]*) MACHINE_ARCH="$MACHINE";; -esac - -# we need this here, and it is not always available... -Which() { - case "$1" in - -*) t=$1; shift;; - *) t=-x;; - esac - case "$1" in - /*) test $t $1 && echo $1;; - *) - # some shells cannot correctly handle `IFS` - # in conjunction with the for loop. - _dirs=`IFS=:; echo ${2:-$PATH}` - for d in $_dirs - do - test $t $d/$1 && { echo $d/$1; break; } - done - ;; - esac -} - -# tr is insanely non-portable wrt char classes, so we need to -# spell out the alphabet. sed y/// would work too. -toUpper() { - ${TR:-tr} abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ -} - -toLower() { - ${TR:-tr} ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz -} - -K= -case $OS in -AIX) # everyone loves to be different... - OSMAJOR=`uname -v` - OSREL="$OSMAJOR.`uname -r`" - LOCAL_FS=jfs - PS_AXC=-e - SHARE_ARCH=$OS/$OSMAJOR.X - ;; -SunOS) - CHOWN=`Which chown /usr/etc:/usr/bin` - export CHOWN - - # Great! Solaris keeps moving arch(1) - # should just bite the bullet and use uname -p - arch=`Which arch /usr/bin:/usr/ucb` - - MAILER=/usr/ucb/Mail - LOCAL_FS=4.2 - - case "$OSREL" in - 4.0*) - # uname -m just says sun which could be anything - # so use arch(1). - MACHINE_ARCH=`arch` - MACHINE=$MACHINE_ARCH - ;; - 4*) - MACHINE_ARCH=`arch` - ;; - 5*) - K=-k - LOCAL_FS=ufs - MAILER=mailx - PS_AXC=-e - # can you believe that ln on Solaris defaults to - # overwriting an existing file!!!!! We want one that works! - test -x /usr/xpg4/bin/ln && LN=${LN:-/usr/xpg4/bin/ln} - # wonderful, 5.8's tr again require's []'s - # but /usr/xpg4/bin/tr causes problems if LC_COLLATE is set! - # use toUpper/toLower instead. - ;; - esac - case "$OS/$MACHINE_ARCH" in - *sun386) SHARE_ARCH=$MACHINE_ARCH;; - esac - ;; -*BSD) - K=-k - MAILER=/usr/bin/Mail - LOCAL_FS=local - case "$-" in - *i*) ;; - *) ENV=;; - esac - # NetBSD at least has good backward compatability - # so NetBSD/i386 is good enough - case $OS in - NetBSD) SHARE_ARCH=$OS/${MACHINE_ARCH:-$MACHINE};; - OpenBSD) - arch=`Which arch /usr/bin:/usr/ucb:$PATH` - MACHINE_ARCH=`$arch -s` - ;; - esac - NAWK=awk - export NAWK - ;; -HP-UX) - TMP_DIRS="/tmp /usr/tmp" - LOCAL_FS=hfs - MAILER=mailx - # don't rely on /bin/sh, its broken - _shell=/bin/ksh; ENV= - # also, no one would be interested in OSMAJOR=A - case "$OSREL" in - ?.09*) OSMAJOR=9; PS_AXC=-e;; - ?.10*) OSMAJOR=10; PS_AXC=-e;; - esac - ;; -IRIX) - LOCAL_FS=efs - ;; -Interix) - MACHINE=i386 - MACHINE_ARCH=i386 - ;; -UnixWare) - OSREL=`uname -v` - OSMAJOR=`IFS=.; set $OSREL; echo $1` - MACHINE_ARCH=`uname -m` - ;; -Linux) - # Not really any such thing as Linux, but - # this covers red-hat and hopefully others. - case $MACHINE in - i?86) MACHINE_ARCH=i386;; # we don't care about i686 vs i586 - esac - LOCAL_FS=ext2 - PS_AXC=axc - [ -x /usr/bin/md5sum ] && { MD5=/usr/bin/md5sum; export MD5; } - ;; -QNX) - case $MACHINE in - x86pc) MACHINE_ARCH=i386;; - esac - ;; -Haiku) - case $MACHINE in - BeBox) MACHINE_ARCH=powerpc;; - BeMac) MACHINE_ARCH=powerpc;; - BePC) MACHINE_ARCH=i386;; - esac - ;; -esac - -HOSTNAME=${HOSTNAME:-`( hostname ) 2>/dev/null`} -HOSTNAME=${HOSTNAME:-`( uname -n ) 2>/dev/null`} -case "$HOSTNAME" in -*.*) HOST=`IFS=.; set -- $HOSTNAME; echo $1`;; -*) HOST=$HOSTNAME;; -esac - -TMP_DIRS=${TMP_DIRS:-"/tmp /var/tmp"} -MACHINE_ARCH=${MACHINE_ARCH:-$MACHINE} -# we mount server:/share/arch/$SHARE_ARCH as /usr/local -SHARE_ARCH=${SHARE_ARCH:-$OS/$OSMAJOR.X/$MACHINE_ARCH} -LN=${LN:-ln} -TR=${TR:-tr} - -# Some people like have /share/$HOST_TARGET/bin etc. -HOST_TARGET=`echo ${OS}${OSMAJOR}-${MACHINE_ARCH} | toLower` -export HOST_TARGET - -case `echo -n .` in -n*) N=; C="\c";; *) N=-n; C=;; esac - -export HOSTNAME HOST -export OS MACHINE MACHINE_ARCH OSREL OSMAJOR LOCAL_FS TMP_DIRS MAILER N C K PS_AXC -export LN SHARE_ARCH TR - -case /$0 in -*/os.sh) - for v in $* - do - eval vv=\$$v - echo "$v='$vv'" - done - ;; -esac - diff --git a/20120831/parse.c b/20120831/parse.c deleted file mode 100644 index 0b18f5d..0000000 --- a/20120831/parse.c +++ /dev/null @@ -1,3122 +0,0 @@ -/* $NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94"; -#else -__RCSID("$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * parse.c -- - * Functions to parse a makefile. - * - * One function, Parse_Init, must be called before any functions - * in this module are used. After that, the function Parse_File is the - * main entry point and controls most of the other functions in this - * module. - * - * Most important structures are kept in Lsts. Directories for - * the .include "..." function are kept in the 'parseIncPath' Lst, while - * those for the .include <...> are kept in the 'sysIncPath' Lst. The - * targets currently being defined are kept in the 'targets' Lst. - * - * The variables 'fname' and 'lineno' are used to track the name - * of the current file and the line number in that file so that error - * messages can be more meaningful. - * - * Interface: - * Parse_Init Initialization function which must be - * called before anything else in this module - * is used. - * - * Parse_End Cleanup the module - * - * Parse_File Function used to parse a makefile. It must - * be given the name of the file, which should - * already have been opened, and a function - * to call to read a character from the file. - * - * Parse_IsVar Returns TRUE if the given line is a - * variable assignment. Used by MainParseArgs - * to determine if an argument is a target - * or a variable assignment. Used internally - * for pretty much the same thing... - * - * Parse_Error Function called when an error occurs in - * parsing. Used by the variable and - * conditional modules. - * Parse_MainName Returns a Lst of the main target to create. - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <assert.h> -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <stdarg.h> -#include <stdio.h> - -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "job.h" -#include "buf.h" -#include "pathnames.h" - -#ifdef HAVE_MMAP -#include <sys/mman.h> - -#ifndef MAP_COPY -#define MAP_COPY MAP_PRIVATE -#endif -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif -#endif - -//////////////////////////////////////////////////////////// -// types and constants - -/* - * Structure for a file being read ("included file") - */ -typedef struct IFile { - const char *fname; /* name of file */ - int lineno; /* current line number in file */ - int first_lineno; /* line number of start of text */ - int cond_depth; /* 'if' nesting when file opened */ - char *P_str; /* point to base of string buffer */ - char *P_ptr; /* point to next char of string buffer */ - char *P_end; /* point to the end of string buffer */ - char *(*nextbuf)(void *, size_t *); /* Function to get more data */ - void *nextbuf_arg; /* Opaque arg for nextbuf() */ - struct loadedfile *lf; /* loadedfile object, if any */ -} IFile; - - -/* - * These values are returned by ParseEOF to tell Parse_File whether to - * CONTINUE parsing, i.e. it had only reached the end of an include file, - * or if it's DONE. - */ -#define CONTINUE 1 -#define DONE 0 - -/* - * Tokens for target attributes - */ -typedef enum { - Begin, /* .BEGIN */ - Default, /* .DEFAULT */ - End, /* .END */ - dotError, /* .ERROR */ - Ignore, /* .IGNORE */ - Includes, /* .INCLUDES */ - Interrupt, /* .INTERRUPT */ - Libs, /* .LIBS */ - Meta, /* .META */ - MFlags, /* .MFLAGS or .MAKEFLAGS */ - Main, /* .MAIN and we don't have anything user-specified to - * make */ - NoExport, /* .NOEXPORT */ - NoMeta, /* .NOMETA */ - NoMetaCmp, /* .NOMETA_CMP */ - NoPath, /* .NOPATH */ - Not, /* Not special */ - NotParallel, /* .NOTPARALLEL */ - Null, /* .NULL */ - ExObjdir, /* .OBJDIR */ - Order, /* .ORDER */ - Parallel, /* .PARALLEL */ - ExPath, /* .PATH */ - Phony, /* .PHONY */ -#ifdef POSIX - Posix, /* .POSIX */ -#endif - Precious, /* .PRECIOUS */ - ExShell, /* .SHELL */ - Silent, /* .SILENT */ - SingleShell, /* .SINGLESHELL */ - Suffixes, /* .SUFFIXES */ - Wait, /* .WAIT */ - Attribute /* Generic attribute */ -} ParseSpecial; - -/* - * Other tokens - */ -#define LPAREN '(' -#define RPAREN ')' - - -//////////////////////////////////////////////////////////// -// result data - -/* - * The main target to create. This is the first target on the first - * dependency line in the first makefile. - */ -static GNode *mainNode; - -//////////////////////////////////////////////////////////// -// eval state - -/* targets we're working on */ -static Lst targets; - -#ifdef CLEANUP -/* command lines for targets */ -static Lst targCmds; -#endif - -/* - * specType contains the SPECial TYPE of the current target. It is - * Not if the target is unspecial. If it *is* special, however, the children - * are linked as children of the parent but not vice versa. This variable is - * set in ParseDoDependency - */ -static ParseSpecial specType; - -/* - * Predecessor node for handling .ORDER. Initialized to NULL when .ORDER - * seen, then set to each successive source on the line. - */ -static GNode *predecessor; - -//////////////////////////////////////////////////////////// -// parser state - -/* true if currently in a dependency line or its commands */ -static Boolean inLine; - -/* number of fatal errors */ -static int fatals = 0; - -/* - * Variables for doing includes - */ - -/* current file being read */ -static IFile *curFile; - -/* stack of IFiles generated by .includes */ -static Lst includes; - -/* include paths (lists of directories) */ -Lst parseIncPath; /* dirs for "..." includes */ -Lst sysIncPath; /* dirs for <...> includes */ -Lst defIncPath; /* default for sysIncPath */ - -//////////////////////////////////////////////////////////// -// parser tables - -/* - * The parseKeywords table is searched using binary search when deciding - * if a target or source is special. The 'spec' field is the ParseSpecial - * type of the keyword ("Not" if the keyword isn't special as a target) while - * the 'op' field is the operator to apply to the list of targets if the - * keyword is used as a source ("0" if the keyword isn't special as a source) - */ -static const struct { - const char *name; /* Name of keyword */ - ParseSpecial spec; /* Type when used as a target */ - int op; /* Operator when used as a source */ -} parseKeywords[] = { -{ ".BEGIN", Begin, 0 }, -{ ".DEFAULT", Default, 0 }, -{ ".END", End, 0 }, -{ ".ERROR", dotError, 0 }, -{ ".EXEC", Attribute, OP_EXEC }, -{ ".IGNORE", Ignore, OP_IGNORE }, -{ ".INCLUDES", Includes, 0 }, -{ ".INTERRUPT", Interrupt, 0 }, -{ ".INVISIBLE", Attribute, OP_INVISIBLE }, -{ ".JOIN", Attribute, OP_JOIN }, -{ ".LIBS", Libs, 0 }, -{ ".MADE", Attribute, OP_MADE }, -{ ".MAIN", Main, 0 }, -{ ".MAKE", Attribute, OP_MAKE }, -{ ".MAKEFLAGS", MFlags, 0 }, -{ ".META", Meta, OP_META }, -{ ".MFLAGS", MFlags, 0 }, -{ ".NOMETA", NoMeta, OP_NOMETA }, -{ ".NOMETA_CMP", NoMetaCmp, OP_NOMETA_CMP }, -{ ".NOPATH", NoPath, OP_NOPATH }, -{ ".NOTMAIN", Attribute, OP_NOTMAIN }, -{ ".NOTPARALLEL", NotParallel, 0 }, -{ ".NO_PARALLEL", NotParallel, 0 }, -{ ".NULL", Null, 0 }, -{ ".OBJDIR", ExObjdir, 0 }, -{ ".OPTIONAL", Attribute, OP_OPTIONAL }, -{ ".ORDER", Order, 0 }, -{ ".PARALLEL", Parallel, 0 }, -{ ".PATH", ExPath, 0 }, -{ ".PHONY", Phony, OP_PHONY }, -#ifdef POSIX -{ ".POSIX", Posix, 0 }, -#endif -{ ".PRECIOUS", Precious, OP_PRECIOUS }, -{ ".RECURSIVE", Attribute, OP_MAKE }, -{ ".SHELL", ExShell, 0 }, -{ ".SILENT", Silent, OP_SILENT }, -{ ".SINGLESHELL", SingleShell, 0 }, -{ ".SUFFIXES", Suffixes, 0 }, -{ ".USE", Attribute, OP_USE }, -{ ".USEBEFORE", Attribute, OP_USEBEFORE }, -{ ".WAIT", Wait, 0 }, -}; - -//////////////////////////////////////////////////////////// -// local functions - -static int ParseIsEscaped(const char *, const char *); -static void ParseErrorInternal(const char *, size_t, int, const char *, ...) - MAKE_ATTR_PRINTFLIKE(4,5); -static void ParseVErrorInternal(FILE *, const char *, size_t, int, const char *, va_list) - MAKE_ATTR_PRINTFLIKE(5, 0); -static int ParseFindKeyword(const char *); -static int ParseLinkSrc(void *, void *); -static int ParseDoOp(void *, void *); -static void ParseDoSrc(int, const char *); -static int ParseFindMain(void *, void *); -static int ParseAddDir(void *, void *); -static int ParseClearPath(void *, void *); -static void ParseDoDependency(char *); -static int ParseAddCmd(void *, void *); -static void ParseHasCommands(void *); -static void ParseDoInclude(char *); -static void ParseSetParseFile(const char *); -#ifdef SYSVINCLUDE -static void ParseTraditionalInclude(char *); -#endif -#ifdef GMAKEEXPORT -static void ParseGmakeExport(char *); -#endif -static int ParseEOF(void); -static char *ParseReadLine(void); -static void ParseFinishLine(void); -static void ParseMark(GNode *); - -//////////////////////////////////////////////////////////// -// file loader - -struct loadedfile { - const char *path; /* name, for error reports */ - char *buf; /* contents buffer */ - size_t len; /* length of contents */ - size_t maplen; /* length of mmap area, or 0 */ - Boolean used; /* XXX: have we used the data yet */ -}; - -/* - * Constructor/destructor for loadedfile - */ -static struct loadedfile * -loadedfile_create(const char *path) -{ - struct loadedfile *lf; - - lf = bmake_malloc(sizeof(*lf)); - lf->path = (path == NULL ? "(stdin)" : path); - lf->buf = NULL; - lf->len = 0; - lf->maplen = 0; - lf->used = FALSE; - return lf; -} - -static void -loadedfile_destroy(struct loadedfile *lf) -{ - if (lf->buf != NULL) { - if (lf->maplen > 0) { -#ifdef HAVE_MMAP - munmap(lf->buf, lf->maplen); -#endif - } else { - free(lf->buf); - } - } - free(lf); -} - -/* - * nextbuf() operation for loadedfile, as needed by the weird and twisted - * logic below. Once that's cleaned up, we can get rid of lf->used... - */ -static char * -loadedfile_nextbuf(void *x, size_t *len) -{ - struct loadedfile *lf = x; - - if (lf->used) { - return NULL; - } - lf->used = TRUE; - *len = lf->len; - return lf->buf; -} - -/* - * Try to get the size of a file. - */ -static ReturnStatus -load_getsize(int fd, size_t *ret) -{ - struct stat st; - - if (fstat(fd, &st) < 0) { - return FAILURE; - } - - if (!S_ISREG(st.st_mode)) { - return FAILURE; - } - - /* - * st_size is an off_t, which is 64 bits signed; *ret is - * size_t, which might be 32 bits unsigned or 64 bits - * unsigned. Rather than being elaborate, just punt on - * files that are more than 2^31 bytes. We should never - * see a makefile that size in practice... - * - * While we're at it reject negative sizes too, just in case. - */ - if (st.st_size < 0 || st.st_size > 0x7fffffff) { - return FAILURE; - } - - *ret = (size_t) st.st_size; - return SUCCESS; -} - -/* - * Read in a file. - * - * Until the path search logic can be moved under here instead of - * being in the caller in another source file, we need to have the fd - * passed in already open. Bleh. - * - * If the path is NULL use stdin and (to insure against fd leaks) - * assert that the caller passed in -1. - */ -static struct loadedfile * -loadfile(const char *path, int fd) -{ - struct loadedfile *lf; -#ifdef HAVE_MMAP - long pagesize; -#endif - ssize_t result; - size_t bufpos; - - lf = loadedfile_create(path); - - if (path == NULL) { - assert(fd == -1); - fd = STDIN_FILENO; - } else { -#if 0 /* notyet */ - fd = open(path, O_RDONLY); - if (fd < 0) { - ... - Error("%s: %s", path, strerror(errno)); - exit(1); - } -#endif - } - -#ifdef HAVE_MMAP - if (load_getsize(fd, &lf->len) == SUCCESS) { - /* found a size, try mmap */ - pagesize = sysconf(_SC_PAGESIZE); - if (pagesize <= 0) { - pagesize = 0x1000; - } - /* round size up to a page */ - lf->maplen = pagesize * ((lf->len + pagesize - 1)/pagesize); - - /* - * XXX hack for dealing with empty files; remove when - * we're no longer limited by interfacing to the old - * logic elsewhere in this file. - */ - if (lf->maplen == 0) { - lf->maplen = pagesize; - } - - /* - * FUTURE: remove PROT_WRITE when the parser no longer - * needs to scribble on the input. - */ - lf->buf = mmap(NULL, lf->maplen, PROT_READ|PROT_WRITE, - MAP_FILE|MAP_COPY, fd, 0); - if (lf->buf != MAP_FAILED) { - /* succeeded */ - if (lf->len == lf->maplen && lf->buf[lf->len - 1] != '\n') { - char *b = malloc(lf->len + 1); - b[lf->len] = '\n'; - memcpy(b, lf->buf, lf->len++); - munmap(lf->buf, lf->maplen); - lf->maplen = 0; - lf->buf = b; - } - goto done; - } - } -#endif - /* cannot mmap; load the traditional way */ - - lf->maplen = 0; - lf->len = 1024; - lf->buf = bmake_malloc(lf->len); - - bufpos = 0; - while (1) { - assert(bufpos <= lf->len); - if (bufpos == lf->len) { - lf->len *= 2; - lf->buf = bmake_realloc(lf->buf, lf->len); - } - result = read(fd, lf->buf + bufpos, lf->len - bufpos); - if (result < 0) { - Error("%s: read error: %s", path, strerror(errno)); - exit(1); - } - if (result == 0) { - break; - } - bufpos += result; - } - assert(bufpos <= lf->len); - lf->len = bufpos; - - /* truncate malloc region to actual length (maybe not useful) */ - if (lf->len > 0) { - lf->buf = bmake_realloc(lf->buf, lf->len); - } - -#ifdef HAVE_MMAP -done: -#endif - if (path != NULL) { - close(fd); - } - return lf; -} - -//////////////////////////////////////////////////////////// -// old code - -/*- - *---------------------------------------------------------------------- - * ParseIsEscaped -- - * Check if the current character is escaped on the current line - * - * Results: - * 0 if the character is not backslash escaped, 1 otherwise - * - * Side Effects: - * None - *---------------------------------------------------------------------- - */ -static int -ParseIsEscaped(const char *line, const char *c) -{ - int active = 0; - for (;;) { - if (line == c) - return active; - if (*--c != '\\') - return active; - active = !active; - } -} - -/*- - *---------------------------------------------------------------------- - * ParseFindKeyword -- - * Look in the table of keywords for one matching the given string. - * - * Input: - * str String to find - * - * Results: - * The index of the keyword, or -1 if it isn't there. - * - * Side Effects: - * None - *---------------------------------------------------------------------- - */ -static int -ParseFindKeyword(const char *str) -{ - int start, end, cur; - int diff; - - start = 0; - end = (sizeof(parseKeywords)/sizeof(parseKeywords[0])) - 1; - - do { - cur = start + ((end - start) / 2); - diff = strcmp(str, parseKeywords[cur].name); - - if (diff == 0) { - return (cur); - } else if (diff < 0) { - end = cur - 1; - } else { - start = cur + 1; - } - } while (start <= end); - return (-1); -} - -/*- - * ParseVErrorInternal -- - * Error message abort function for parsing. Prints out the context - * of the error (line number and file) as well as the message with - * two optional arguments. - * - * Results: - * None - * - * Side Effects: - * "fatals" is incremented if the level is PARSE_FATAL. - */ -/* VARARGS */ -static void -ParseVErrorInternal(FILE *f, const char *cfname, size_t clineno, int type, - const char *fmt, va_list ap) -{ - static Boolean fatal_warning_error_printed = FALSE; - - (void)fprintf(f, "%s: ", progname); - - if (cfname != NULL) { - (void)fprintf(f, "\""); - if (*cfname != '/' && strcmp(cfname, "(stdin)") != 0) { - char *cp; - const char *dir; - - /* - * Nothing is more annoying than not knowing - * which Makefile is the culprit. - */ - dir = Var_Value(".PARSEDIR", VAR_GLOBAL, &cp); - if (dir == NULL || *dir == '\0' || - (*dir == '.' && dir[1] == '\0')) - dir = Var_Value(".CURDIR", VAR_GLOBAL, &cp); - if (dir == NULL) - dir = "."; - - (void)fprintf(f, "%s/%s", dir, cfname); - } else - (void)fprintf(f, "%s", cfname); - - (void)fprintf(f, "\" line %d: ", (int)clineno); - } - if (type == PARSE_WARNING) - (void)fprintf(f, "warning: "); - (void)vfprintf(f, fmt, ap); - (void)fprintf(f, "\n"); - (void)fflush(f); - if (type == PARSE_FATAL || parseWarnFatal) - fatals += 1; - if (parseWarnFatal && !fatal_warning_error_printed) { - Error("parsing warnings being treated as errors"); - fatal_warning_error_printed = TRUE; - } -} - -/*- - * ParseErrorInternal -- - * Error function - * - * Results: - * None - * - * Side Effects: - * None - */ -/* VARARGS */ -static void -ParseErrorInternal(const char *cfname, size_t clineno, int type, - const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - (void)fflush(stdout); - ParseVErrorInternal(stderr, cfname, clineno, type, fmt, ap); - va_end(ap); - - if (debug_file != stderr && debug_file != stdout) { - va_start(ap, fmt); - ParseVErrorInternal(debug_file, cfname, clineno, type, fmt, ap); - va_end(ap); - } -} - -/*- - * Parse_Error -- - * External interface to ParseErrorInternal; uses the default filename - * Line number. - * - * Results: - * None - * - * Side Effects: - * None - */ -/* VARARGS */ -void -Parse_Error(int type, const char *fmt, ...) -{ - va_list ap; - const char *fname; - size_t lineno; - - if (curFile == NULL) { - fname = NULL; - lineno = 0; - } else { - fname = curFile->fname; - lineno = curFile->lineno; - } - - va_start(ap, fmt); - (void)fflush(stdout); - ParseVErrorInternal(stderr, fname, lineno, type, fmt, ap); - va_end(ap); - - if (debug_file != stderr && debug_file != stdout) { - va_start(ap, fmt); - ParseVErrorInternal(debug_file, fname, lineno, type, fmt, ap); - va_end(ap); - } -} - - -/* - * ParseMessage - * Parse a .info .warning or .error directive - * - * The input is the line minus the ".". We substitute - * variables, print the message and exit(1) (for .error) or just print - * a warning if the directive is malformed. - */ -static Boolean -ParseMessage(char *line) -{ - int mtype; - - switch(*line) { - case 'i': - mtype = 0; - break; - case 'w': - mtype = PARSE_WARNING; - break; - case 'e': - mtype = PARSE_FATAL; - break; - default: - Parse_Error(PARSE_WARNING, "invalid syntax: \".%s\"", line); - return FALSE; - } - - while (isalpha((u_char)*line)) - line++; - if (!isspace((u_char)*line)) - return FALSE; /* not for us */ - while (isspace((u_char)*line)) - line++; - - line = Var_Subst(NULL, line, VAR_CMD, 0); - Parse_Error(mtype, "%s", line); - free(line); - - if (mtype == PARSE_FATAL) { - /* Terminate immediately. */ - exit(1); - } - return TRUE; -} - -/*- - *--------------------------------------------------------------------- - * ParseLinkSrc -- - * Link the parent node to its new child. Used in a Lst_ForEach by - * ParseDoDependency. If the specType isn't 'Not', the parent - * isn't linked as a parent of the child. - * - * Input: - * pgnp The parent node - * cgpn The child node - * - * Results: - * Always = 0 - * - * Side Effects: - * New elements are added to the parents list of cgn and the - * children list of cgn. the unmade field of pgn is updated - * to reflect the additional child. - *--------------------------------------------------------------------- - */ -static int -ParseLinkSrc(void *pgnp, void *cgnp) -{ - GNode *pgn = (GNode *)pgnp; - GNode *cgn = (GNode *)cgnp; - - if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (pgn->cohorts)) - pgn = (GNode *)Lst_Datum(Lst_Last(pgn->cohorts)); - (void)Lst_AtEnd(pgn->children, cgn); - if (specType == Not) - (void)Lst_AtEnd(cgn->parents, pgn); - pgn->unmade += 1; - if (DEBUG(PARSE)) { - fprintf(debug_file, "# ParseLinkSrc: added child %s - %s\n", pgn->name, cgn->name); - Targ_PrintNode(pgn, 0); - Targ_PrintNode(cgn, 0); - } - return (0); -} - -/*- - *--------------------------------------------------------------------- - * ParseDoOp -- - * Apply the parsed operator to the given target node. Used in a - * Lst_ForEach call by ParseDoDependency once all targets have - * been found and their operator parsed. If the previous and new - * operators are incompatible, a major error is taken. - * - * Input: - * gnp The node to which the operator is to be applied - * opp The operator to apply - * - * Results: - * Always 0 - * - * Side Effects: - * The type field of the node is altered to reflect any new bits in - * the op. - *--------------------------------------------------------------------- - */ -static int -ParseDoOp(void *gnp, void *opp) -{ - GNode *gn = (GNode *)gnp; - int op = *(int *)opp; - /* - * If the dependency mask of the operator and the node don't match and - * the node has actually had an operator applied to it before, and - * the operator actually has some dependency information in it, complain. - */ - if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) && - !OP_NOP(gn->type) && !OP_NOP(op)) - { - Parse_Error(PARSE_FATAL, "Inconsistent operator for %s", gn->name); - return (1); - } - - if ((op == OP_DOUBLEDEP) && ((gn->type & OP_OPMASK) == OP_DOUBLEDEP)) { - /* - * If the node was the object of a :: operator, we need to create a - * new instance of it for the children and commands on this dependency - * line. The new instance is placed on the 'cohorts' list of the - * initial one (note the initial one is not on its own cohorts list) - * and the new instance is linked to all parents of the initial - * instance. - */ - GNode *cohort; - - /* - * Propagate copied bits to the initial node. They'll be propagated - * back to the rest of the cohorts later. - */ - gn->type |= op & ~OP_OPMASK; - - cohort = Targ_FindNode(gn->name, TARG_NOHASH); - /* - * Make the cohort invisible as well to avoid duplicating it into - * other variables. True, parents of this target won't tend to do - * anything with their local variables, but better safe than - * sorry. (I think this is pointless now, since the relevant list - * traversals will no longer see this node anyway. -mycroft) - */ - cohort->type = op | OP_INVISIBLE; - (void)Lst_AtEnd(gn->cohorts, cohort); - cohort->centurion = gn; - gn->unmade_cohorts += 1; - snprintf(cohort->cohort_num, sizeof cohort->cohort_num, "#%d", - gn->unmade_cohorts); - } else { - /* - * We don't want to nuke any previous flags (whatever they were) so we - * just OR the new operator into the old - */ - gn->type |= op; - } - - return (0); -} - -/*- - *--------------------------------------------------------------------- - * ParseDoSrc -- - * Given the name of a source, figure out if it is an attribute - * and apply it to the targets if it is. Else decide if there is - * some attribute which should be applied *to* the source because - * of some special target and apply it if so. Otherwise, make the - * source be a child of the targets in the list 'targets' - * - * Input: - * tOp operator (if any) from special targets - * src name of the source to handle - * - * Results: - * None - * - * Side Effects: - * Operator bits may be added to the list of targets or to the source. - * The targets may have a new source added to their lists of children. - *--------------------------------------------------------------------- - */ -static void -ParseDoSrc(int tOp, const char *src) -{ - GNode *gn = NULL; - static int wait_number = 0; - char wait_src[16]; - - if (*src == '.' && isupper ((unsigned char)src[1])) { - int keywd = ParseFindKeyword(src); - if (keywd != -1) { - int op = parseKeywords[keywd].op; - if (op != 0) { - Lst_ForEach(targets, ParseDoOp, &op); - return; - } - if (parseKeywords[keywd].spec == Wait) { - /* - * We add a .WAIT node in the dependency list. - * After any dynamic dependencies (and filename globbing) - * have happened, it is given a dependency on the each - * previous child back to and previous .WAIT node. - * The next child won't be scheduled until the .WAIT node - * is built. - * We give each .WAIT node a unique name (mainly for diag). - */ - snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number); - gn = Targ_FindNode(wait_src, TARG_NOHASH); - gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN; - Lst_ForEach(targets, ParseLinkSrc, gn); - return; - } - } - } - - switch (specType) { - case Main: - /* - * If we have noted the existence of a .MAIN, it means we need - * to add the sources of said target to the list of things - * to create. The string 'src' is likely to be free, so we - * must make a new copy of it. Note that this will only be - * invoked if the user didn't specify a target on the command - * line. This is to allow #ifmake's to succeed, or something... - */ - (void)Lst_AtEnd(create, bmake_strdup(src)); - /* - * Add the name to the .TARGETS variable as well, so the user can - * employ that, if desired. - */ - Var_Append(".TARGETS", src, VAR_GLOBAL); - return; - - case Order: - /* - * Create proper predecessor/successor links between the previous - * source and the current one. - */ - gn = Targ_FindNode(src, TARG_CREATE); - if (predecessor != NULL) { - (void)Lst_AtEnd(predecessor->order_succ, gn); - (void)Lst_AtEnd(gn->order_pred, predecessor); - if (DEBUG(PARSE)) { - fprintf(debug_file, "# ParseDoSrc: added Order dependency %s - %s\n", - predecessor->name, gn->name); - Targ_PrintNode(predecessor, 0); - Targ_PrintNode(gn, 0); - } - } - /* - * The current source now becomes the predecessor for the next one. - */ - predecessor = gn; - break; - - default: - /* - * If the source is not an attribute, we need to find/create - * a node for it. After that we can apply any operator to it - * from a special target or link it to its parents, as - * appropriate. - * - * In the case of a source that was the object of a :: operator, - * the attribute is applied to all of its instances (as kept in - * the 'cohorts' list of the node) or all the cohorts are linked - * to all the targets. - */ - - /* Find/create the 'src' node and attach to all targets */ - gn = Targ_FindNode(src, TARG_CREATE); - if (tOp) { - gn->type |= tOp; - } else { - Lst_ForEach(targets, ParseLinkSrc, gn); - } - break; - } -} - -/*- - *----------------------------------------------------------------------- - * ParseFindMain -- - * Find a real target in the list and set it to be the main one. - * Called by ParseDoDependency when a main target hasn't been found - * yet. - * - * Input: - * gnp Node to examine - * - * Results: - * 0 if main not found yet, 1 if it is. - * - * Side Effects: - * mainNode is changed and Targ_SetMain is called. - * - *----------------------------------------------------------------------- - */ -static int -ParseFindMain(void *gnp, void *dummy) -{ - GNode *gn = (GNode *)gnp; - if ((gn->type & OP_NOTARGET) == 0) { - mainNode = gn; - Targ_SetMain(gn); - return (dummy ? 1 : 1); - } else { - return (dummy ? 0 : 0); - } -} - -/*- - *----------------------------------------------------------------------- - * ParseAddDir -- - * Front-end for Dir_AddDir to make sure Lst_ForEach keeps going - * - * Results: - * === 0 - * - * Side Effects: - * See Dir_AddDir. - * - *----------------------------------------------------------------------- - */ -static int -ParseAddDir(void *path, void *name) -{ - (void)Dir_AddDir((Lst) path, (char *)name); - return(0); -} - -/*- - *----------------------------------------------------------------------- - * ParseClearPath -- - * Front-end for Dir_ClearPath to make sure Lst_ForEach keeps going - * - * Results: - * === 0 - * - * Side Effects: - * See Dir_ClearPath - * - *----------------------------------------------------------------------- - */ -static int -ParseClearPath(void *path, void *dummy) -{ - Dir_ClearPath((Lst) path); - return(dummy ? 0 : 0); -} - -/*- - *--------------------------------------------------------------------- - * ParseDoDependency -- - * Parse the dependency line in line. - * - * Input: - * line the line to parse - * - * Results: - * None - * - * Side Effects: - * The nodes of the sources are linked as children to the nodes of the - * targets. Some nodes may be created. - * - * We parse a dependency line by first extracting words from the line and - * finding nodes in the list of all targets with that name. This is done - * until a character is encountered which is an operator character. Currently - * these are only ! and :. At this point the operator is parsed and the - * pointer into the line advanced until the first source is encountered. - * The parsed operator is applied to each node in the 'targets' list, - * which is where the nodes found for the targets are kept, by means of - * the ParseDoOp function. - * The sources are read in much the same way as the targets were except - * that now they are expanded using the wildcarding scheme of the C-Shell - * and all instances of the resulting words in the list of all targets - * are found. Each of the resulting nodes is then linked to each of the - * targets as one of its children. - * Certain targets are handled specially. These are the ones detailed - * by the specType variable. - * The storing of transformation rules is also taken care of here. - * A target is recognized as a transformation rule by calling - * Suff_IsTransform. If it is a transformation rule, its node is gotten - * from the suffix module via Suff_AddTransform rather than the standard - * Targ_FindNode in the target module. - *--------------------------------------------------------------------- - */ -static void -ParseDoDependency(char *line) -{ - char *cp; /* our current position */ - GNode *gn = NULL; /* a general purpose temporary node */ - int op; /* the operator on the line */ - char savec; /* a place to save a character */ - Lst paths; /* List of search paths to alter when parsing - * a list of .PATH targets */ - int tOp; /* operator from special target */ - Lst sources; /* list of archive source names after - * expansion */ - Lst curTargs; /* list of target names to be found and added - * to the targets list */ - char *lstart = line; - - if (DEBUG(PARSE)) - fprintf(debug_file, "ParseDoDependency(%s)\n", line); - tOp = 0; - - specType = Not; - paths = NULL; - - curTargs = Lst_Init(FALSE); - - do { - for (cp = line; *cp && (ParseIsEscaped(lstart, cp) || - !(isspace((unsigned char)*cp) || - *cp == '!' || *cp == ':' || *cp == LPAREN)); - cp++) { - if (*cp == '$') { - /* - * Must be a dynamic source (would have been expanded - * otherwise), so call the Var module to parse the puppy - * so we can safely advance beyond it...There should be - * no errors in this, as they would have been discovered - * in the initial Var_Subst and we wouldn't be here. - */ - int length; - void *freeIt; - char *result; - - result = Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt); - if (freeIt) - free(freeIt); - cp += length-1; - } - } - - if (!ParseIsEscaped(lstart, cp) && *cp == LPAREN) { - /* - * Archives must be handled specially to make sure the OP_ARCHV - * flag is set in their 'type' field, for one thing, and because - * things like "archive(file1.o file2.o file3.o)" are permissible. - * Arch_ParseArchive will set 'line' to be the first non-blank - * after the archive-spec. It creates/finds nodes for the members - * and places them on the given list, returning SUCCESS if all - * went well and FAILURE if there was an error in the - * specification. On error, line should remain untouched. - */ - if (Arch_ParseArchive(&line, targets, VAR_CMD) != SUCCESS) { - Parse_Error(PARSE_FATAL, - "Error in archive specification: \"%s\"", line); - goto out; - } else { - continue; - } - } - savec = *cp; - - if (!*cp) { - /* - * Ending a dependency line without an operator is a Bozo - * no-no. As a heuristic, this is also often triggered by - * undetected conflicts from cvs/rcs merges. - */ - if ((strncmp(line, "<<<<<<", 6) == 0) || - (strncmp(line, "======", 6) == 0) || - (strncmp(line, ">>>>>>", 6) == 0)) - Parse_Error(PARSE_FATAL, - "Makefile appears to contain unresolved cvs/rcs/??? merge conflicts"); - else - Parse_Error(PARSE_FATAL, lstart[0] == '.' ? "Unknown directive" - : "Need an operator"); - goto out; - } - *cp = '\0'; - - /* - * Have a word in line. See if it's a special target and set - * specType to match it. - */ - if (*line == '.' && isupper ((unsigned char)line[1])) { - /* - * See if the target is a special target that must have it - * or its sources handled specially. - */ - int keywd = ParseFindKeyword(line); - if (keywd != -1) { - if (specType == ExPath && parseKeywords[keywd].spec != ExPath) { - Parse_Error(PARSE_FATAL, "Mismatched special targets"); - goto out; - } - - specType = parseKeywords[keywd].spec; - tOp = parseKeywords[keywd].op; - - /* - * Certain special targets have special semantics: - * .PATH Have to set the dirSearchPath - * variable too - * .MAIN Its sources are only used if - * nothing has been specified to - * create. - * .DEFAULT Need to create a node to hang - * commands on, but we don't want - * it in the graph, nor do we want - * it to be the Main Target, so we - * create it, set OP_NOTMAIN and - * add it to the list, setting - * DEFAULT to the new node for - * later use. We claim the node is - * A transformation rule to make - * life easier later, when we'll - * use Make_HandleUse to actually - * apply the .DEFAULT commands. - * .PHONY The list of targets - * .NOPATH Don't search for file in the path - * .BEGIN - * .END - * .ERROR - * .INTERRUPT Are not to be considered the - * main target. - * .NOTPARALLEL Make only one target at a time. - * .SINGLESHELL Create a shell for each command. - * .ORDER Must set initial predecessor to NULL - */ - switch (specType) { - case ExPath: - if (paths == NULL) { - paths = Lst_Init(FALSE); - } - (void)Lst_AtEnd(paths, dirSearchPath); - break; - case Main: - if (!Lst_IsEmpty(create)) { - specType = Not; - } - break; - case Begin: - case End: - case dotError: - case Interrupt: - gn = Targ_FindNode(line, TARG_CREATE); - gn->type |= OP_NOTMAIN|OP_SPECIAL; - (void)Lst_AtEnd(targets, gn); - break; - case Default: - gn = Targ_NewGN(".DEFAULT"); - gn->type |= (OP_NOTMAIN|OP_TRANSFORM); - (void)Lst_AtEnd(targets, gn); - DEFAULT = gn; - break; - case NotParallel: - maxJobs = 1; - break; - case SingleShell: - compatMake = TRUE; - break; - case Order: - predecessor = NULL; - break; - default: - break; - } - } else if (strncmp(line, ".PATH", 5) == 0) { - /* - * .PATH<suffix> has to be handled specially. - * Call on the suffix module to give us a path to - * modify. - */ - Lst path; - - specType = ExPath; - path = Suff_GetPath(&line[5]); - if (path == NULL) { - Parse_Error(PARSE_FATAL, - "Suffix '%s' not defined (yet)", - &line[5]); - goto out; - } else { - if (paths == NULL) { - paths = Lst_Init(FALSE); - } - (void)Lst_AtEnd(paths, path); - } - } - } - - /* - * Have word in line. Get or create its node and stick it at - * the end of the targets list - */ - if ((specType == Not) && (*line != '\0')) { - if (Dir_HasWildcards(line)) { - /* - * Targets are to be sought only in the current directory, - * so create an empty path for the thing. Note we need to - * use Dir_Destroy in the destruction of the path as the - * Dir module could have added a directory to the path... - */ - Lst emptyPath = Lst_Init(FALSE); - - Dir_Expand(line, emptyPath, curTargs); - - Lst_Destroy(emptyPath, Dir_Destroy); - } else { - /* - * No wildcards, but we want to avoid code duplication, - * so create a list with the word on it. - */ - (void)Lst_AtEnd(curTargs, line); - } - - while(!Lst_IsEmpty(curTargs)) { - char *targName = (char *)Lst_DeQueue(curTargs); - - if (!Suff_IsTransform (targName)) { - gn = Targ_FindNode(targName, TARG_CREATE); - } else { - gn = Suff_AddTransform(targName); - } - - (void)Lst_AtEnd(targets, gn); - } - } else if (specType == ExPath && *line != '.' && *line != '\0') { - Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line); - } - - *cp = savec; - /* - * If it is a special type and not .PATH, it's the only target we - * allow on this line... - */ - if (specType != Not && specType != ExPath) { - Boolean warning = FALSE; - - while (*cp && (ParseIsEscaped(lstart, cp) || - ((*cp != '!') && (*cp != ':')))) { - if (ParseIsEscaped(lstart, cp) || - (*cp != ' ' && *cp != '\t')) { - warning = TRUE; - } - cp++; - } - if (warning) { - Parse_Error(PARSE_WARNING, "Extra target ignored"); - } - } else { - while (*cp && isspace ((unsigned char)*cp)) { - cp++; - } - } - line = cp; - } while (*line && (ParseIsEscaped(lstart, line) || - ((*line != '!') && (*line != ':')))); - - /* - * Don't need the list of target names anymore... - */ - Lst_Destroy(curTargs, NULL); - curTargs = NULL; - - if (!Lst_IsEmpty(targets)) { - switch(specType) { - default: - Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored"); - break; - case Default: - case Begin: - case End: - case dotError: - case Interrupt: - /* - * These four create nodes on which to hang commands, so - * targets shouldn't be empty... - */ - case Not: - /* - * Nothing special here -- targets can be empty if it wants. - */ - break; - } - } - - /* - * Have now parsed all the target names. Must parse the operator next. The - * result is left in op . - */ - if (*cp == '!') { - op = OP_FORCE; - } else if (*cp == ':') { - if (cp[1] == ':') { - op = OP_DOUBLEDEP; - cp++; - } else { - op = OP_DEPENDS; - } - } else { - Parse_Error(PARSE_FATAL, lstart[0] == '.' ? "Unknown directive" - : "Missing dependency operator"); - goto out; - } - - cp++; /* Advance beyond operator */ - - Lst_ForEach(targets, ParseDoOp, &op); - - /* - * Get to the first source - */ - while (*cp && isspace ((unsigned char)*cp)) { - cp++; - } - line = cp; - - /* - * Several special targets take different actions if present with no - * sources: - * a .SUFFIXES line with no sources clears out all old suffixes - * a .PRECIOUS line makes all targets precious - * a .IGNORE line ignores errors for all targets - * a .SILENT line creates silence when making all targets - * a .PATH removes all directories from the search path(s). - */ - if (!*line) { - switch (specType) { - case Suffixes: - Suff_ClearSuffixes(); - break; - case Precious: - allPrecious = TRUE; - break; - case Ignore: - ignoreErrors = TRUE; - break; - case Silent: - beSilent = TRUE; - break; - case ExPath: - Lst_ForEach(paths, ParseClearPath, NULL); - Dir_SetPATH(); - break; -#ifdef POSIX - case Posix: - Var_Set("%POSIX", "1003.2", VAR_GLOBAL, 0); - break; -#endif - default: - break; - } - } else if (specType == MFlags) { - /* - * Call on functions in main.c to deal with these arguments and - * set the initial character to a null-character so the loop to - * get sources won't get anything - */ - Main_ParseArgLine(line); - *line = '\0'; - } else if (specType == ExShell) { - if (Job_ParseShell(line) != SUCCESS) { - Parse_Error(PARSE_FATAL, "improper shell specification"); - goto out; - } - *line = '\0'; - } else if ((specType == NotParallel) || (specType == SingleShell)) { - *line = '\0'; - } - - /* - * NOW GO FOR THE SOURCES - */ - if ((specType == Suffixes) || (specType == ExPath) || - (specType == Includes) || (specType == Libs) || - (specType == Null) || (specType == ExObjdir)) - { - while (*line) { - /* - * If the target was one that doesn't take files as its sources - * but takes something like suffixes, we take each - * space-separated word on the line as a something and deal - * with it accordingly. - * - * If the target was .SUFFIXES, we take each source as a - * suffix and add it to the list of suffixes maintained by the - * Suff module. - * - * If the target was a .PATH, we add the source as a directory - * to search on the search path. - * - * If it was .INCLUDES, the source is taken to be the suffix of - * files which will be #included and whose search path should - * be present in the .INCLUDES variable. - * - * If it was .LIBS, the source is taken to be the suffix of - * files which are considered libraries and whose search path - * should be present in the .LIBS variable. - * - * If it was .NULL, the source is the suffix to use when a file - * has no valid suffix. - * - * If it was .OBJDIR, the source is a new definition for .OBJDIR, - * and will cause make to do a new chdir to that path. - */ - while (*cp && !isspace ((unsigned char)*cp)) { - cp++; - } - savec = *cp; - *cp = '\0'; - switch (specType) { - case Suffixes: - Suff_AddSuffix(line, &mainNode); - break; - case ExPath: - Lst_ForEach(paths, ParseAddDir, line); - break; - case Includes: - Suff_AddInclude(line); - break; - case Libs: - Suff_AddLib(line); - break; - case Null: - Suff_SetNull(line); - break; - case ExObjdir: - Main_SetObjdir(line); - break; - default: - break; - } - *cp = savec; - if (savec != '\0') { - cp++; - } - while (*cp && isspace ((unsigned char)*cp)) { - cp++; - } - line = cp; - } - if (paths) { - Lst_Destroy(paths, NULL); - } - if (specType == ExPath) - Dir_SetPATH(); - } else { - while (*line) { - /* - * The targets take real sources, so we must beware of archive - * specifications (i.e. things with left parentheses in them) - * and handle them accordingly. - */ - for (; *cp && !isspace ((unsigned char)*cp); cp++) { - if ((*cp == LPAREN) && (cp > line) && (cp[-1] != '$')) { - /* - * Only stop for a left parenthesis if it isn't at the - * start of a word (that'll be for variable changes - * later) and isn't preceded by a dollar sign (a dynamic - * source). - */ - break; - } - } - - if (*cp == LPAREN) { - sources = Lst_Init(FALSE); - if (Arch_ParseArchive(&line, sources, VAR_CMD) != SUCCESS) { - Parse_Error(PARSE_FATAL, - "Error in source archive spec \"%s\"", line); - goto out; - } - - while (!Lst_IsEmpty (sources)) { - gn = (GNode *)Lst_DeQueue(sources); - ParseDoSrc(tOp, gn->name); - } - Lst_Destroy(sources, NULL); - cp = line; - } else { - if (*cp) { - *cp = '\0'; - cp += 1; - } - - ParseDoSrc(tOp, line); - } - while (*cp && isspace ((unsigned char)*cp)) { - cp++; - } - line = cp; - } - } - - if (mainNode == NULL) { - /* - * If we have yet to decide on a main target to make, in the - * absence of any user input, we want the first target on - * the first dependency line that is actually a real target - * (i.e. isn't a .USE or .EXEC rule) to be made. - */ - Lst_ForEach(targets, ParseFindMain, NULL); - } - -out: - if (curTargs) - Lst_Destroy(curTargs, NULL); -} - -/*- - *--------------------------------------------------------------------- - * Parse_IsVar -- - * Return TRUE if the passed line is a variable assignment. A variable - * assignment consists of a single word followed by optional whitespace - * followed by either a += or an = operator. - * This function is used both by the Parse_File function and main when - * parsing the command-line arguments. - * - * Input: - * line the line to check - * - * Results: - * TRUE if it is. FALSE if it ain't - * - * Side Effects: - * none - *--------------------------------------------------------------------- - */ -Boolean -Parse_IsVar(char *line) -{ - Boolean wasSpace = FALSE; /* set TRUE if found a space */ - char ch; - int level = 0; -#define ISEQOPERATOR(c) \ - (((c) == '+') || ((c) == ':') || ((c) == '?') || ((c) == '!')) - - /* - * Skip to variable name - */ - for (;(*line == ' ') || (*line == '\t'); line++) - continue; - - /* Scan for one of the assignment operators outside a variable expansion */ - while ((ch = *line++) != 0) { - if (ch == '(' || ch == '{') { - level++; - continue; - } - if (ch == ')' || ch == '}') { - level--; - continue; - } - if (level != 0) - continue; - while (ch == ' ' || ch == '\t') { - ch = *line++; - wasSpace = TRUE; - } - if (ch == '=') - return TRUE; - if (*line == '=' && ISEQOPERATOR(ch)) - return TRUE; - if (wasSpace) - return FALSE; - } - - return FALSE; -} - -/*- - *--------------------------------------------------------------------- - * Parse_DoVar -- - * Take the variable assignment in the passed line and do it in the - * global context. - * - * Note: There is a lexical ambiguity with assignment modifier characters - * in variable names. This routine interprets the character before the = - * as a modifier. Therefore, an assignment like - * C++=/usr/bin/CC - * is interpreted as "C+ +=" instead of "C++ =". - * - * Input: - * line a line guaranteed to be a variable assignment. - * This reduces error checks - * ctxt Context in which to do the assignment - * - * Results: - * none - * - * Side Effects: - * the variable structure of the given variable name is altered in the - * global context. - *--------------------------------------------------------------------- - */ -void -Parse_DoVar(char *line, GNode *ctxt) -{ - char *cp; /* pointer into line */ - enum { - VAR_SUBST, VAR_APPEND, VAR_SHELL, VAR_NORMAL - } type; /* Type of assignment */ - char *opc; /* ptr to operator character to - * null-terminate the variable name */ - Boolean freeCp = FALSE; /* TRUE if cp needs to be freed, - * i.e. if any variable expansion was - * performed */ - int depth; - - /* - * Skip to variable name - */ - while ((*line == ' ') || (*line == '\t')) { - line++; - } - - /* - * Skip to operator character, nulling out whitespace as we go - * XXX Rather than counting () and {} we should look for $ and - * then expand the variable. - */ - for (depth = 0, cp = line + 1; depth != 0 || *cp != '='; cp++) { - if (*cp == '(' || *cp == '{') { - depth++; - continue; - } - if (*cp == ')' || *cp == '}') { - depth--; - continue; - } - if (depth == 0 && isspace ((unsigned char)*cp)) { - *cp = '\0'; - } - } - opc = cp-1; /* operator is the previous character */ - *cp++ = '\0'; /* nuke the = */ - - /* - * Check operator type - */ - switch (*opc) { - case '+': - type = VAR_APPEND; - *opc = '\0'; - break; - - case '?': - /* - * If the variable already has a value, we don't do anything. - */ - *opc = '\0'; - if (Var_Exists(line, ctxt)) { - return; - } else { - type = VAR_NORMAL; - } - break; - - case ':': - type = VAR_SUBST; - *opc = '\0'; - break; - - case '!': - type = VAR_SHELL; - *opc = '\0'; - break; - - default: -#ifdef SUNSHCMD - while (opc > line && *opc != ':') - opc--; - - if (strncmp(opc, ":sh", 3) == 0) { - type = VAR_SHELL; - *opc = '\0'; - break; - } -#endif - type = VAR_NORMAL; - break; - } - - while (isspace ((unsigned char)*cp)) { - cp++; - } - - if (type == VAR_APPEND) { - Var_Append(line, cp, ctxt); - } else if (type == VAR_SUBST) { - /* - * Allow variables in the old value to be undefined, but leave their - * invocation alone -- this is done by forcing oldVars to be false. - * XXX: This can cause recursive variables, but that's not hard to do, - * and this allows someone to do something like - * - * CFLAGS = $(.INCLUDES) - * CFLAGS := -I.. $(CFLAGS) - * - * And not get an error. - */ - Boolean oldOldVars = oldVars; - - oldVars = FALSE; - - /* - * make sure that we set the variable the first time to nothing - * so that it gets substituted! - */ - if (!Var_Exists(line, ctxt)) - Var_Set(line, "", ctxt, 0); - - cp = Var_Subst(NULL, cp, ctxt, FALSE); - oldVars = oldOldVars; - freeCp = TRUE; - - Var_Set(line, cp, ctxt, 0); - } else if (type == VAR_SHELL) { - char *res; - const char *error; - - if (strchr(cp, '$') != NULL) { - /* - * There's a dollar sign in the command, so perform variable - * expansion on the whole thing. The resulting string will need - * freeing when we're done, so set freeCmd to TRUE. - */ - cp = Var_Subst(NULL, cp, VAR_CMD, TRUE); - freeCp = TRUE; - } - - res = Cmd_Exec(cp, &error); - Var_Set(line, res, ctxt, 0); - free(res); - - if (error) - Parse_Error(PARSE_WARNING, error, cp); - } else { - /* - * Normal assignment -- just do it. - */ - Var_Set(line, cp, ctxt, 0); - } - if (strcmp(line, MAKEOVERRIDES) == 0) - Main_ExportMAKEFLAGS(FALSE); /* re-export MAKEFLAGS */ - else if (strcmp(line, ".CURDIR") == 0) { - /* - * Somone is being (too?) clever... - * Let's pretend they know what they are doing and - * re-initialize the 'cur' Path. - */ - Dir_InitCur(cp); - Dir_SetPATH(); - } else if (strcmp(line, MAKE_JOB_PREFIX) == 0) { - Job_SetPrefix(); - } else if (strcmp(line, MAKE_EXPORTED) == 0) { - Var_Export(cp, 0); - } - if (freeCp) - free(cp); -} - - -/*- - * ParseAddCmd -- - * Lst_ForEach function to add a command line to all targets - * - * Input: - * gnp the node to which the command is to be added - * cmd the command to add - * - * Results: - * Always 0 - * - * Side Effects: - * A new element is added to the commands list of the node. - */ -static int -ParseAddCmd(void *gnp, void *cmd) -{ - GNode *gn = (GNode *)gnp; - - /* Add to last (ie current) cohort for :: targets */ - if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) - gn = (GNode *)Lst_Datum(Lst_Last(gn->cohorts)); - - /* if target already supplied, ignore commands */ - if (!(gn->type & OP_HAS_COMMANDS)) { - (void)Lst_AtEnd(gn->commands, cmd); - ParseMark(gn); - } else { -#ifdef notyet - /* XXX: We cannot do this until we fix the tree */ - (void)Lst_AtEnd(gn->commands, cmd); - Parse_Error(PARSE_WARNING, - "overriding commands for target \"%s\"; " - "previous commands defined at %s: %d ignored", - gn->name, gn->fname, gn->lineno); -#else - Parse_Error(PARSE_WARNING, - "duplicate script for target \"%s\" ignored", - gn->name); - ParseErrorInternal(gn->fname, gn->lineno, PARSE_WARNING, - "using previous script for \"%s\" defined here", - gn->name); -#endif - } - return(0); -} - -/*- - *----------------------------------------------------------------------- - * ParseHasCommands -- - * Callback procedure for Parse_File when destroying the list of - * targets on the last dependency line. Marks a target as already - * having commands if it does, to keep from having shell commands - * on multiple dependency lines. - * - * Input: - * gnp Node to examine - * - * Results: - * None - * - * Side Effects: - * OP_HAS_COMMANDS may be set for the target. - * - *----------------------------------------------------------------------- - */ -static void -ParseHasCommands(void *gnp) -{ - GNode *gn = (GNode *)gnp; - if (!Lst_IsEmpty(gn->commands)) { - gn->type |= OP_HAS_COMMANDS; - } -} - -/*- - *----------------------------------------------------------------------- - * Parse_AddIncludeDir -- - * Add a directory to the path searched for included makefiles - * bracketed by double-quotes. Used by functions in main.c - * - * Input: - * dir The name of the directory to add - * - * Results: - * None. - * - * Side Effects: - * The directory is appended to the list. - * - *----------------------------------------------------------------------- - */ -void -Parse_AddIncludeDir(char *dir) -{ - (void)Dir_AddDir(parseIncPath, dir); -} - -/*- - *--------------------------------------------------------------------- - * ParseDoInclude -- - * Push to another file. - * - * The input is the line minus the `.'. A file spec is a string - * enclosed in <> or "". The former is looked for only in sysIncPath. - * The latter in . and the directories specified by -I command line - * options - * - * Results: - * None - * - * Side Effects: - * A structure is added to the includes Lst and readProc, lineno, - * fname and curFILE are altered for the new file - *--------------------------------------------------------------------- - */ - -static void -Parse_include_file(char *file, Boolean isSystem, int silent) -{ - struct loadedfile *lf; - char *fullname; /* full pathname of file */ - char *newName; - char *prefEnd, *incdir; - int fd; - int i; - - /* - * Now we know the file's name and its search path, we attempt to - * find the durn thing. A return of NULL indicates the file don't - * exist. - */ - fullname = file[0] == '/' ? bmake_strdup(file) : NULL; - - if (fullname == NULL && !isSystem) { - /* - * Include files contained in double-quotes are first searched for - * relative to the including file's location. We don't want to - * cd there, of course, so we just tack on the old file's - * leading path components and call Dir_FindFile to see if - * we can locate the beast. - */ - - incdir = bmake_strdup(curFile->fname); - prefEnd = strrchr(incdir, '/'); - if (prefEnd != NULL) { - *prefEnd = '\0'; - /* Now do lexical processing of leading "../" on the filename */ - for (i = 0; strncmp(file + i, "../", 3) == 0; i += 3) { - prefEnd = strrchr(incdir + 1, '/'); - if (prefEnd == NULL || strcmp(prefEnd, "/..") == 0) - break; - *prefEnd = '\0'; - } - newName = str_concat(incdir, file + i, STR_ADDSLASH); - fullname = Dir_FindFile(newName, parseIncPath); - if (fullname == NULL) - fullname = Dir_FindFile(newName, dirSearchPath); - free(newName); - } - free(incdir); - - if (fullname == NULL) { - /* - * Makefile wasn't found in same directory as included makefile. - * Search for it first on the -I search path, - * then on the .PATH search path, if not found in a -I directory. - * If we have a suffix specific path we should use that. - */ - char *suff; - Lst suffPath = NULL; - - if ((suff = strrchr(file, '.'))) { - suffPath = Suff_GetPath(suff); - if (suffPath != NULL) { - fullname = Dir_FindFile(file, suffPath); - } - } - if (fullname == NULL) { - fullname = Dir_FindFile(file, parseIncPath); - if (fullname == NULL) { - fullname = Dir_FindFile(file, dirSearchPath); - } - } - } - } - - /* Looking for a system file or file still not found */ - if (fullname == NULL) { - /* - * Look for it on the system path - */ - fullname = Dir_FindFile(file, - Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath); - } - - if (fullname == NULL) { - if (!silent) - Parse_Error(PARSE_FATAL, "Could not find %s", file); - return; - } - - /* Actually open the file... */ - fd = open(fullname, O_RDONLY); - if (fd == -1) { - if (!silent) - Parse_Error(PARSE_FATAL, "Cannot open %s", fullname); - free(fullname); - return; - } - - /* load it */ - lf = loadfile(fullname, fd); - - /* Start reading from this file next */ - Parse_SetInput(fullname, 0, -1, loadedfile_nextbuf, lf); - curFile->lf = lf; -} - -static void -ParseDoInclude(char *line) -{ - char endc; /* the character which ends the file spec */ - char *cp; /* current position in file spec */ - int silent = (*line != 'i') ? 1 : 0; - char *file = &line[7 + silent]; - - /* Skip to delimiter character so we know where to look */ - while (*file == ' ' || *file == '\t') - file++; - - if (*file != '"' && *file != '<') { - Parse_Error(PARSE_FATAL, - ".include filename must be delimited by '\"' or '<'"); - return; - } - - /* - * Set the search path on which to find the include file based on the - * characters which bracket its name. Angle-brackets imply it's - * a system Makefile while double-quotes imply it's a user makefile - */ - if (*file == '<') { - endc = '>'; - } else { - endc = '"'; - } - - /* Skip to matching delimiter */ - for (cp = ++file; *cp && *cp != endc; cp++) - continue; - - if (*cp != endc) { - Parse_Error(PARSE_FATAL, - "Unclosed %cinclude filename. '%c' expected", - '.', endc); - return; - } - *cp = '\0'; - - /* - * Substitute for any variables in the file name before trying to - * find the thing. - */ - file = Var_Subst(NULL, file, VAR_CMD, FALSE); - - Parse_include_file(file, endc == '>', silent); - free(file); -} - - -/*- - *--------------------------------------------------------------------- - * ParseSetParseFile -- - * Set the .PARSEDIR and .PARSEFILE variables to the dirname and - * basename of the given filename - * - * Results: - * None - * - * Side Effects: - * The .PARSEDIR and .PARSEFILE variables are overwritten by the - * dirname and basename of the given filename. - *--------------------------------------------------------------------- - */ -static void -ParseSetParseFile(const char *filename) -{ - char *slash, *dirname; - const char *pd, *pf; - int len; - - slash = strrchr(filename, '/'); - if (slash == NULL) { - Var_Set(".PARSEDIR", pd = curdir, VAR_GLOBAL, 0); - Var_Set(".PARSEFILE", pf = filename, VAR_GLOBAL, 0); - dirname= NULL; - } else { - len = slash - filename; - dirname = bmake_malloc(len + 1); - memcpy(dirname, filename, len); - dirname[len] = '\0'; - Var_Set(".PARSEDIR", pd = dirname, VAR_GLOBAL, 0); - Var_Set(".PARSEFILE", pf = slash + 1, VAR_GLOBAL, 0); - } - if (DEBUG(PARSE)) - fprintf(debug_file, "ParseSetParseFile: ${.PARSEDIR} = `%s' " - "${.PARSEFILE} = `%s'\n", pd, pf); - free(dirname); -} - -/* - * Track the makefiles we read - so makefiles can - * set dependencies on them. - * Avoid adding anything more than once. - */ - -static void -ParseTrackInput(const char *name) -{ - char *old; - char *fp = NULL; - size_t name_len = strlen(name); - - old = Var_Value(MAKE_MAKEFILES, VAR_GLOBAL, &fp); - if (old) { - /* does it contain name? */ - for (; old != NULL; old = strchr(old, ' ')) { - if (*old == ' ') - old++; - if (memcmp(old, name, name_len) == 0 - && (old[name_len] == 0 || old[name_len] == ' ')) - goto cleanup; - } - } - Var_Append (MAKE_MAKEFILES, name, VAR_GLOBAL); - cleanup: - if (fp) { - free(fp); - } -} - - -/*- - *--------------------------------------------------------------------- - * Parse_setInput -- - * Start Parsing from the given source - * - * Results: - * None - * - * Side Effects: - * A structure is added to the includes Lst and readProc, lineno, - * fname and curFile are altered for the new file - *--------------------------------------------------------------------- - */ -void -Parse_SetInput(const char *name, int line, int fd, - char *(*nextbuf)(void *, size_t *), void *arg) -{ - char *buf; - size_t len; - - if (name == NULL) - name = curFile->fname; - else - ParseTrackInput(name); - - if (DEBUG(PARSE)) - fprintf(debug_file, "Parse_SetInput: file %s, line %d, fd %d, nextbuf %p, arg %p\n", - name, line, fd, nextbuf, arg); - - if (fd == -1 && nextbuf == NULL) - /* sanity */ - return; - - if (curFile != NULL) - /* Save exiting file info */ - Lst_AtFront(includes, curFile); - - /* Allocate and fill in new structure */ - curFile = bmake_malloc(sizeof *curFile); - - /* - * Once the previous state has been saved, we can get down to reading - * the new file. We set up the name of the file to be the absolute - * name of the include file so error messages refer to the right - * place. - */ - curFile->fname = name; - curFile->lineno = line; - curFile->first_lineno = line; - curFile->nextbuf = nextbuf; - curFile->nextbuf_arg = arg; - curFile->lf = NULL; - - assert(nextbuf != NULL); - - /* Get first block of input data */ - buf = curFile->nextbuf(curFile->nextbuf_arg, &len); - if (buf == NULL) { - /* Was all a waste of time ... */ - free(curFile); - return; - } - curFile->P_str = buf; - curFile->P_ptr = buf; - curFile->P_end = buf+len; - - curFile->cond_depth = Cond_save_depth(); - ParseSetParseFile(name); -} - -#ifdef SYSVINCLUDE -/*- - *--------------------------------------------------------------------- - * ParseTraditionalInclude -- - * Push to another file. - * - * The input is the current line. The file name(s) are - * following the "include". - * - * Results: - * None - * - * Side Effects: - * A structure is added to the includes Lst and readProc, lineno, - * fname and curFILE are altered for the new file - *--------------------------------------------------------------------- - */ -static void -ParseTraditionalInclude(char *line) -{ - char *cp; /* current position in file spec */ - int done = 0; - int silent = (line[0] != 'i') ? 1 : 0; - char *file = &line[silent + 7]; - char *all_files; - - if (DEBUG(PARSE)) { - fprintf(debug_file, "ParseTraditionalInclude: %s\n", file); - } - - /* - * Skip over whitespace - */ - while (isspace((unsigned char)*file)) - file++; - - /* - * Substitute for any variables in the file name before trying to - * find the thing. - */ - all_files = Var_Subst(NULL, file, VAR_CMD, FALSE); - - if (*file == '\0') { - Parse_Error(PARSE_FATAL, - "Filename missing from \"include\""); - return; - } - - for (file = all_files; !done; file = cp + 1) { - /* Skip to end of line or next whitespace */ - for (cp = file; *cp && !isspace((unsigned char) *cp); cp++) - continue; - - if (*cp) - *cp = '\0'; - else - done = 1; - - Parse_include_file(file, FALSE, silent); - } - free(all_files); -} -#endif - -#ifdef GMAKEEXPORT -/*- - *--------------------------------------------------------------------- - * ParseGmakeExport -- - * Parse export <variable>=<value> - * - * And set the environment with it. - * - * Results: - * None - * - * Side Effects: - * None - *--------------------------------------------------------------------- - */ -static void -ParseGmakeExport(char *line) -{ - char *variable = &line[6]; - char *value; - - if (DEBUG(PARSE)) { - fprintf(debug_file, "ParseGmakeExport: %s\n", variable); - } - - /* - * Skip over whitespace - */ - while (isspace((unsigned char)*variable)) - variable++; - - for (value = variable; *value && *value != '='; value++) - continue; - - if (*value != '=') { - Parse_Error(PARSE_FATAL, - "Variable/Value missing from \"export\""); - return; - } - - /* - * Expand the value before putting it in the environment. - */ - value = Var_Subst(NULL, value, VAR_CMD, FALSE); - setenv(variable, value, 1); -} -#endif - -/*- - *--------------------------------------------------------------------- - * ParseEOF -- - * Called when EOF is reached in the current file. If we were reading - * an include file, the includes stack is popped and things set up - * to go back to reading the previous file at the previous location. - * - * Results: - * CONTINUE if there's more to do. DONE if not. - * - * Side Effects: - * The old curFILE, is closed. The includes list is shortened. - * lineno, curFILE, and fname are changed if CONTINUE is returned. - *--------------------------------------------------------------------- - */ -static int -ParseEOF(void) -{ - char *ptr; - size_t len; - - assert(curFile->nextbuf != NULL); - - /* get next input buffer, if any */ - ptr = curFile->nextbuf(curFile->nextbuf_arg, &len); - curFile->P_ptr = ptr; - curFile->P_str = ptr; - curFile->P_end = ptr + len; - curFile->lineno = curFile->first_lineno; - if (ptr != NULL) { - /* Iterate again */ - return CONTINUE; - } - - /* Ensure the makefile (or loop) didn't have mismatched conditionals */ - Cond_restore_depth(curFile->cond_depth); - - if (curFile->lf != NULL) { - loadedfile_destroy(curFile->lf); - curFile->lf = NULL; - } - - /* Dispose of curFile info */ - /* Leak curFile->fname because all the gnodes have pointers to it */ - free(curFile->P_str); - free(curFile); - - curFile = Lst_DeQueue(includes); - - if (curFile == NULL) { - /* We've run out of input */ - Var_Delete(".PARSEDIR", VAR_GLOBAL); - Var_Delete(".PARSEFILE", VAR_GLOBAL); - return DONE; - } - - if (DEBUG(PARSE)) - fprintf(debug_file, "ParseEOF: returning to file %s, line %d\n", - curFile->fname, curFile->lineno); - - /* Restore the PARSEDIR/PARSEFILE variables */ - ParseSetParseFile(curFile->fname); - return (CONTINUE); -} - -#define PARSE_RAW 1 -#define PARSE_SKIP 2 - -static char * -ParseGetLine(int flags, int *length) -{ - IFile *cf = curFile; - char *ptr; - char ch; - char *line; - char *line_end; - char *escaped; - char *comment; - char *tp; - - /* Loop through blank lines and comment lines */ - for (;;) { - cf->lineno++; - line = cf->P_ptr; - ptr = line; - line_end = line; - escaped = NULL; - comment = NULL; - for (;;) { - if (cf->P_end != NULL && ptr == cf->P_end) { - /* end of buffer */ - ch = 0; - break; - } - ch = *ptr; - if (ch == 0 || (ch == '\\' && ptr[1] == 0)) { - if (cf->P_end == NULL) - /* End of string (aka for loop) data */ - break; - if (cf->nextbuf != NULL) { - /* - * End of this buffer; return EOF and outer logic - * will get the next one. (eww) - */ - break; - } - Parse_Error(PARSE_FATAL, "Zero byte read from file"); - return NULL; - } - - if (ch == '\\') { - /* Don't treat next character as special, remember first one */ - if (escaped == NULL) - escaped = ptr; - if (ptr[1] == '\n') - cf->lineno++; - ptr += 2; - line_end = ptr; - continue; - } - if (ch == '#' && comment == NULL) { - /* Remember first '#' for comment stripping */ - /* Unless previous char was '[', as in modifier :[#] */ - if (!(ptr > line && ptr[-1] == '[')) - comment = line_end; - } - ptr++; - if (ch == '\n') - break; - if (!isspace((unsigned char)ch)) - /* We are not interested in trailing whitespace */ - line_end = ptr; - } - - /* Save next 'to be processed' location */ - cf->P_ptr = ptr; - - /* Check we have a non-comment, non-blank line */ - if (line_end == line || comment == line) { - if (ch == 0) - /* At end of file */ - return NULL; - /* Parse another line */ - continue; - } - - /* We now have a line of data */ - *line_end = 0; - - if (flags & PARSE_RAW) { - /* Leave '\' (etc) in line buffer (eg 'for' lines) */ - *length = line_end - line; - return line; - } - - if (flags & PARSE_SKIP) { - /* Completely ignore non-directives */ - if (line[0] != '.') - continue; - /* We could do more of the .else/.elif/.endif checks here */ - } - break; - } - - /* Brutally ignore anything after a non-escaped '#' in non-commands */ - if (comment != NULL && line[0] != '\t') { - line_end = comment; - *line_end = 0; - } - - /* If we didn't see a '\\' then the in-situ data is fine */ - if (escaped == NULL) { - *length = line_end - line; - return line; - } - - /* Remove escapes from '\n' and '#' */ - tp = ptr = escaped; - escaped = line; - for (; ; *tp++ = ch) { - ch = *ptr++; - if (ch != '\\') { - if (ch == 0) - break; - continue; - } - - ch = *ptr++; - if (ch == 0) { - /* Delete '\\' at end of buffer */ - tp--; - break; - } - - if (ch == '#' && line[0] != '\t') - /* Delete '\\' from before '#' on non-command lines */ - continue; - - if (ch != '\n') { - /* Leave '\\' in buffer for later */ - *tp++ = '\\'; - /* Make sure we don't delete an escaped ' ' from the line end */ - escaped = tp + 1; - continue; - } - - /* Escaped '\n' replace following whitespace with a single ' ' */ - while (ptr[0] == ' ' || ptr[0] == '\t') - ptr++; - ch = ' '; - } - - /* Delete any trailing spaces - eg from empty continuations */ - while (tp > escaped && isspace((unsigned char)tp[-1])) - tp--; - - *tp = 0; - *length = tp - line; - return line; -} - -/*- - *--------------------------------------------------------------------- - * ParseReadLine -- - * Read an entire line from the input file. Called only by Parse_File. - * - * Results: - * A line w/o its newline - * - * Side Effects: - * Only those associated with reading a character - *--------------------------------------------------------------------- - */ -static char * -ParseReadLine(void) -{ - char *line; /* Result */ - int lineLength; /* Length of result */ - int lineno; /* Saved line # */ - int rval; - - for (;;) { - line = ParseGetLine(0, &lineLength); - if (line == NULL) - return NULL; - - if (line[0] != '.') - return line; - - /* - * The line might be a conditional. Ask the conditional module - * about it and act accordingly - */ - switch (Cond_Eval(line)) { - case COND_SKIP: - /* Skip to next conditional that evaluates to COND_PARSE. */ - do { - line = ParseGetLine(PARSE_SKIP, &lineLength); - } while (line && Cond_Eval(line) != COND_PARSE); - if (line == NULL) - break; - continue; - case COND_PARSE: - continue; - case COND_INVALID: /* Not a conditional line */ - /* Check for .for loops */ - rval = For_Eval(line); - if (rval == 0) - /* Not a .for line */ - break; - if (rval < 0) - /* Syntax error - error printed, ignore line */ - continue; - /* Start of a .for loop */ - lineno = curFile->lineno; - /* Accumulate loop lines until matching .endfor */ - do { - line = ParseGetLine(PARSE_RAW, &lineLength); - if (line == NULL) { - Parse_Error(PARSE_FATAL, - "Unexpected end of file in for loop."); - break; - } - } while (For_Accum(line)); - /* Stash each iteration as a new 'input file' */ - For_Run(lineno); - /* Read next line from for-loop buffer */ - continue; - } - return (line); - } -} - -/*- - *----------------------------------------------------------------------- - * ParseFinishLine -- - * Handle the end of a dependency group. - * - * Results: - * Nothing. - * - * Side Effects: - * inLine set FALSE. 'targets' list destroyed. - * - *----------------------------------------------------------------------- - */ -static void -ParseFinishLine(void) -{ - if (inLine) { - Lst_ForEach(targets, Suff_EndTransform, NULL); - Lst_Destroy(targets, ParseHasCommands); - targets = NULL; - inLine = FALSE; - } -} - - -/*- - *--------------------------------------------------------------------- - * Parse_File -- - * Parse a file into its component parts, incorporating it into the - * current dependency graph. This is the main function and controls - * almost every other function in this module - * - * Input: - * name the name of the file being read - * fd Open file to makefile to parse - * - * Results: - * None - * - * Side Effects: - * closes fd. - * Loads. Nodes are added to the list of all targets, nodes and links - * are added to the dependency graph. etc. etc. etc. - *--------------------------------------------------------------------- - */ -void -Parse_File(const char *name, int fd) -{ - char *cp; /* pointer into the line */ - char *line; /* the line we're working on */ - struct loadedfile *lf; - - lf = loadfile(name, fd); - - inLine = FALSE; - fatals = 0; - - if (name == NULL) { - name = "(stdin)"; - } - - Parse_SetInput(name, 0, -1, loadedfile_nextbuf, lf); - curFile->lf = lf; - - do { - for (; (line = ParseReadLine()) != NULL; ) { - if (DEBUG(PARSE)) - fprintf(debug_file, "ParseReadLine (%d): '%s'\n", - curFile->lineno, line); - if (*line == '.') { - /* - * Lines that begin with the special character may be - * include or undef directives. - * On the other hand they can be suffix rules (.c.o: ...) - * or just dependencies for filenames that start '.'. - */ - for (cp = line + 1; isspace((unsigned char)*cp); cp++) { - continue; - } - if (strncmp(cp, "include", 7) == 0 || - ((cp[0] == 's' || cp[0] == '-') && - strncmp(&cp[1], "include", 7) == 0)) { - ParseDoInclude(cp); - continue; - } - if (strncmp(cp, "undef", 5) == 0) { - char *cp2; - for (cp += 5; isspace((unsigned char) *cp); cp++) - continue; - for (cp2 = cp; !isspace((unsigned char) *cp2) && - (*cp2 != '\0'); cp2++) - continue; - *cp2 = '\0'; - Var_Delete(cp, VAR_GLOBAL); - continue; - } else if (strncmp(cp, "export", 6) == 0) { - for (cp += 6; isspace((unsigned char) *cp); cp++) - continue; - Var_Export(cp, 1); - continue; - } else if (strncmp(cp, "unexport", 8) == 0) { - Var_UnExport(cp); - continue; - } else if (strncmp(cp, "info", 4) == 0 || - strncmp(cp, "error", 5) == 0 || - strncmp(cp, "warning", 7) == 0) { - if (ParseMessage(cp)) - continue; - } - } - - if (*line == '\t') { - /* - * If a line starts with a tab, it can only hope to be - * a creation command. - */ - cp = line + 1; - shellCommand: - for (; isspace ((unsigned char)*cp); cp++) { - continue; - } - if (*cp) { - if (!inLine) - Parse_Error(PARSE_FATAL, - "Unassociated shell command \"%s\"", - cp); - /* - * So long as it's not a blank line and we're actually - * in a dependency spec, add the command to the list of - * commands of all targets in the dependency spec - */ - if (targets) { - cp = bmake_strdup(cp); - Lst_ForEach(targets, ParseAddCmd, cp); -#ifdef CLEANUP - Lst_AtEnd(targCmds, cp); -#endif - } - } - continue; - } - -#ifdef SYSVINCLUDE - if (((strncmp(line, "include", 7) == 0 && - isspace((unsigned char) line[7])) || - ((line[0] == 's' || line[0] == '-') && - strncmp(&line[1], "include", 7) == 0 && - isspace((unsigned char) line[8]))) && - strchr(line, ':') == NULL) { - /* - * It's an S3/S5-style "include". - */ - ParseTraditionalInclude(line); - continue; - } -#endif -#ifdef GMAKEEXPORT - if (strncmp(line, "export", 6) == 0 && - isspace((unsigned char) line[6]) && - strchr(line, ':') == NULL) { - /* - * It's a Gmake "export". - */ - ParseGmakeExport(line); - continue; - } -#endif - if (Parse_IsVar(line)) { - ParseFinishLine(); - Parse_DoVar(line, VAR_GLOBAL); - continue; - } - -#ifndef POSIX - /* - * To make life easier on novices, if the line is indented we - * first make sure the line has a dependency operator in it. - * If it doesn't have an operator and we're in a dependency - * line's script, we assume it's actually a shell command - * and add it to the current list of targets. - */ - cp = line; - if (isspace((unsigned char) line[0])) { - while ((*cp != '\0') && isspace((unsigned char) *cp)) - cp++; - while (*cp && (ParseIsEscaped(line, cp) || - (*cp != ':') && (*cp != '!'))) { - cp++; - } - if (*cp == '\0') { - if (inLine) { - Parse_Error(PARSE_WARNING, - "Shell command needs a leading tab"); - goto shellCommand; - } - } - } -#endif - ParseFinishLine(); - - /* - * For some reason - probably to make the parser impossible - - * a ';' can be used to separate commands from dependencies. - * Attempt to avoid ';' inside substitution patterns. - */ - { - int level = 0; - - for (cp = line; *cp != 0; cp++) { - if (*cp == '\\' && cp[1] != 0) { - cp++; - continue; - } - if (*cp == '$' && - (cp[1] == '(' || cp[1] == '{')) { - level++; - continue; - } - if (level > 0) { - if (*cp == ')' || *cp == '}') { - level--; - continue; - } - } else if (*cp == ';') { - break; - } - } - } - if (*cp != 0) - /* Terminate the dependency list at the ';' */ - *cp++ = 0; - else - cp = NULL; - - /* - * We now know it's a dependency line so it needs to have all - * variables expanded before being parsed. Tell the variable - * module to complain if some variable is undefined... - */ - line = Var_Subst(NULL, line, VAR_CMD, TRUE); - - /* - * Need a non-circular list for the target nodes - */ - if (targets) - Lst_Destroy(targets, NULL); - - targets = Lst_Init(FALSE); - inLine = TRUE; - - ParseDoDependency(line); - free(line); - - /* If there were commands after a ';', add them now */ - if (cp != NULL) { - goto shellCommand; - } - } - /* - * Reached EOF, but it may be just EOF of an include file... - */ - } while (ParseEOF() == CONTINUE); - - if (fatals) { - (void)fflush(stdout); - (void)fprintf(stderr, - "%s: Fatal errors encountered -- cannot continue", - progname); - PrintOnError(NULL, NULL); - exit(1); - } -} - -/*- - *--------------------------------------------------------------------- - * Parse_Init -- - * initialize the parsing module - * - * Results: - * none - * - * Side Effects: - * the parseIncPath list is initialized... - *--------------------------------------------------------------------- - */ -void -Parse_Init(void) -{ - mainNode = NULL; - parseIncPath = Lst_Init(FALSE); - sysIncPath = Lst_Init(FALSE); - defIncPath = Lst_Init(FALSE); - includes = Lst_Init(FALSE); -#ifdef CLEANUP - targCmds = Lst_Init(FALSE); -#endif -} - -void -Parse_End(void) -{ -#ifdef CLEANUP - Lst_Destroy(targCmds, (FreeProc *)free); - if (targets) - Lst_Destroy(targets, NULL); - Lst_Destroy(defIncPath, Dir_Destroy); - Lst_Destroy(sysIncPath, Dir_Destroy); - Lst_Destroy(parseIncPath, Dir_Destroy); - Lst_Destroy(includes, NULL); /* Should be empty now */ -#endif -} - - -/*- - *----------------------------------------------------------------------- - * Parse_MainName -- - * Return a Lst of the main target to create for main()'s sake. If - * no such target exists, we Punt with an obnoxious error message. - * - * Results: - * A Lst of the single node to create. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -Lst -Parse_MainName(void) -{ - Lst mainList; /* result list */ - - mainList = Lst_Init(FALSE); - - if (mainNode == NULL) { - Punt("no target to make."); - /*NOTREACHED*/ - } else if (mainNode->type & OP_DOUBLEDEP) { - (void)Lst_AtEnd(mainList, mainNode); - Lst_Concat(mainList, mainNode->cohorts, LST_CONCNEW); - } - else - (void)Lst_AtEnd(mainList, mainNode); - Var_Append(".TARGETS", mainNode->name, VAR_GLOBAL); - return (mainList); -} - -/*- - *----------------------------------------------------------------------- - * ParseMark -- - * Add the filename and lineno to the GNode so that we remember - * where it was first defined. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static void -ParseMark(GNode *gn) -{ - gn->fname = curFile->fname; - gn->lineno = curFile->lineno; -} diff --git a/20120831/pathnames.h b/20120831/pathnames.h deleted file mode 100644 index 9c597b1..0000000 --- a/20120831/pathnames.h +++ /dev/null @@ -1,62 +0,0 @@ -/* $NetBSD: pathnames.h,v 1.17 2009/04/11 09:41:18 apb Exp $ */ - -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)pathnames.h 5.2 (Berkeley) 6/1/90 - * $Id: pathnames.h,v 1.13 2009/08/26 23:43:42 sjg Exp $ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif -#ifndef MAKE_NATIVE -#if HAVE_NBTOOL_CONFIG_H -#include "nbtool_config.h" -#endif -#endif -#ifdef HAVE_PATHS_H -#include <paths.h> -#endif -#define _PATH_OBJDIR "obj" -#define _PATH_OBJDIRPREFIX "/usr/obj" -#ifndef _PATH_DEFSHELLDIR -#define _PATH_DEFSHELLDIR "/bin" -#endif -#define _PATH_DEFSYSMK "sys.mk" -#define _path_defsyspath "/usr/share/mk:/usr/local/share/mk:/opt/share/mk" -#ifndef _PATH_DEFSYSPATH -# ifdef _PATH_PREFIX_SYSPATH -# define _PATH_DEFSYSPATH _PATH_PREFIX_SYSPATH ":" _path_defsyspath -# else -# define _PATH_DEFSYSPATH _path_defsyspath -# endif -#endif -#ifndef _PATH_TMP -#define _PATH_TMP "/tmp/" /* with trailing slash */ -#endif diff --git a/20120831/ranlib.h b/20120831/ranlib.h deleted file mode 100644 index 503c7c1..0000000 --- a/20120831/ranlib.h +++ /dev/null @@ -1,32 +0,0 @@ -/* @(#)ranlib.h 1.6 88/08/19 SMI; from UCB 4.1 83/05/03 */ -/* $Id: ranlib.h,v 1.5 2005/11/01 02:35:15 sjg Exp $ */ - -/* - * Structure of the __.SYMDEF table of contents for an archive. - * __.SYMDEF begins with a word giving the number of ranlib structures - * which immediately follow, and then continues with a string - * table consisting of a word giving the number of bytes of strings - * which follow and then the strings themselves. - * The ran_strx fields index the string table whose first byte is numbered 0. - */ - -#if !defined(IRIX) && !defined(__digital__) && !defined(__osf__) -#ifndef _ranlib_h -#define _ranlib_h - -#if 0 -#define RANLIBMAG "!<arch>\n__.SYMDEF" /* archive file name */ -#endif -#define RANLIBMAG "__.SYMDEF" /* archive file name */ -#define RANLIBSKEW 3 /* creation time offset */ - -struct ranlib { - union { - off_t ran_strx; /* string table index of */ - char *ran_name; /* symbol defined by */ - } ran_un; - off_t ran_off; /* library member at this offset */ -}; - -#endif /*!_ranlib_h*/ -#endif diff --git a/20120831/realpath.c b/20120831/realpath.c deleted file mode 100644 index 1ef2cd8..0000000 --- a/20120831/realpath.c +++ /dev/null @@ -1,196 +0,0 @@ -/* $Id: realpath.c,v 1.2 2010/04/21 17:47:49 sjg Exp $ */ -/* from: $NetBSD: getcwd.c,v 1.45 2007/10/26 19:48:14 christos Exp $ */ - -/* - * Copyright (c) 1989, 1991, 1993, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#ifndef HAVE_REALPATH - -#include <sys/cdefs.h> -#include <sys/param.h> -#include <sys/stat.h> - -#include <errno.h> -#ifdef HAVE_STDLIB_H -# include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -# include <string.h> -#endif -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif - -/* - * char *realpath(const char *path, char resolved[MAXPATHLEN]); - * - * Find the real name of path, by removing all ".", ".." and symlink - * components. Returns (resolved) on success, or (NULL) on failure, - * in which case the path which caused trouble is left in (resolved). - */ -char * -realpath(const char *path, char *resolved) -{ - struct stat sb; - int idx = 0, n, nlnk = 0; - const char *q; - char *p, wbuf[2][MAXPATHLEN]; - size_t len; - - if (!path || !resolved || path == resolved) - return (NULL); - - /* - * Build real path one by one with paying an attention to ., - * .. and symbolic link. - */ - - /* - * `p' is where we'll put a new component with prepending - * a delimiter. - */ - p = resolved; - - if (*path == 0) { - *p = 0; - errno = ENOENT; - return (NULL); - } - - /* If relative path, start from current working directory. */ - if (*path != '/') { - /* check for resolved pointer to appease coverity */ - if (resolved && getcwd(resolved, MAXPATHLEN) == NULL) { - p[0] = '.'; - p[1] = 0; - return (NULL); - } - len = strlen(resolved); - if (len > 1) - p += len; - } - -loop: - /* Skip any slash. */ - while (*path == '/') - path++; - - if (*path == 0) { - if (p == resolved) - *p++ = '/'; - *p = 0; - return (resolved); - } - - /* Find the end of this component. */ - q = path; - do - q++; - while (*q != '/' && *q != 0); - - /* Test . or .. */ - if (path[0] == '.') { - if (q - path == 1) { - path = q; - goto loop; - } - if (path[1] == '.' && q - path == 2) { - /* Trim the last component. */ - if (p != resolved) - while (*--p != '/') - ; - path = q; - goto loop; - } - } - - /* Append this component. */ - if (p - resolved + 1 + q - path + 1 > MAXPATHLEN) { - errno = ENAMETOOLONG; - if (p == resolved) - *p++ = '/'; - *p = 0; - return (NULL); - } - p[0] = '/'; - memcpy(&p[1], path, - /* LINTED We know q > path. */ - q - path); - p[1 + q - path] = 0; - - /* - * If this component is a symlink, toss it and prepend link - * target to unresolved path. - */ - if (lstat(resolved, &sb) == -1) { - return (NULL); - } - if (S_ISLNK(sb.st_mode)) { - if (nlnk++ >= MAXSYMLINKS) { - errno = ELOOP; - return (NULL); - } - n = readlink(resolved, wbuf[idx], sizeof(wbuf[0]) - 1); - if (n < 0) - return (NULL); - if (n == 0) { - errno = ENOENT; - return (NULL); - } - - /* Append unresolved path to link target and switch to it. */ - if (n + (len = strlen(q)) + 1 > sizeof(wbuf[0])) { - errno = ENAMETOOLONG; - return (NULL); - } - memcpy(&wbuf[idx][n], q, len + 1); - path = wbuf[idx]; - idx ^= 1; - - /* If absolute symlink, start from root. */ - if (*path == '/') - p = resolved; - goto loop; - } - if (*q == '/' && !S_ISDIR(sb.st_mode)) { - errno = ENOTDIR; - return (NULL); - } - - /* Advance both resolved and unresolved path. */ - p += 1 + q - path; - path = q; - goto loop; -} -#endif diff --git a/20120831/setenv.c b/20120831/setenv.c deleted file mode 100644 index efd0f74..0000000 --- a/20120831/setenv.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 1987 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifndef HAVE_SETENV - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)setenv.c 5.6 (Berkeley) 6/4/91";*/ -static char *rcsid = "$Id: setenv.c,v 1.5 1996/09/04 22:10:42 sjg Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - -/* - * __findenv -- - * Returns pointer to value associated with name, if any, else NULL. - * Sets offset to be the offset of the name/value combination in the - * environmental array, for use by setenv(3) and unsetenv(3). - * Explicitly removes '=' in argument name. - * - * This routine *should* be a static; don't use it. - */ -static char * -__findenv(name, offset) - register char *name; - int *offset; -{ - extern char **environ; - register int len; - register char **P, *C; - - for (C = name, len = 0; *C && *C != '='; ++C, ++len); - for (P = environ; *P; ++P) - if (!strncmp(*P, name, len)) - if (*(C = *P + len) == '=') { - *offset = P - environ; - return(++C); - } - return(NULL); -} - -/* - * setenv -- - * Set the value of the environmental variable "name" to be - * "value". If rewrite is set, replace any current value. - */ -setenv(name, value, rewrite) - register const char *name; - register const char *value; - int rewrite; -{ - extern char **environ; - static int alloced; /* if allocated space before */ - register char *C; - int l_value, offset; - char *__findenv(); - - if (*value == '=') /* no `=' in value */ - ++value; - l_value = strlen(value); - if ((C = __findenv(name, &offset))) { /* find if already exists */ - if (!rewrite) - return (0); - if (strlen(C) >= l_value) { /* old larger; copy over */ - while (*C++ = *value++); - return (0); - } - } else { /* create new slot */ - register int cnt; - register char **P; - - for (P = environ, cnt = 0; *P; ++P, ++cnt); - if (alloced) { /* just increase size */ - environ = (char **)realloc((char *)environ, - (size_t)(sizeof(char *) * (cnt + 2))); - if (!environ) - return (-1); - } - else { /* get new space */ - alloced = 1; /* copy old entries into it */ - P = (char **)malloc((size_t)(sizeof(char *) * - (cnt + 2))); - if (!P) - return (-1); - bcopy(environ, P, cnt * sizeof(char *)); - environ = P; - } - environ[cnt + 1] = NULL; - offset = cnt; - } - for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */ - if (!(environ[offset] = /* name + `=' + value */ - malloc((size_t)((int)(C - name) + l_value + 2)))) - return (-1); - for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) - ; - for (*C++ = '='; *C++ = *value++; ) - ; - return (0); -} - -/* - * unsetenv(name) -- - * Delete environmental variable "name". - */ -void -unsetenv(name) - const char *name; -{ - extern char **environ; - register char **P; - int offset; - char *__findenv(); - - while (__findenv(name, &offset)) /* if set multiple times */ - for (P = &environ[offset];; ++P) - if (!(*P = *(P + 1))) - break; -} -#endif diff --git a/20120831/sigcompat.c b/20120831/sigcompat.c deleted file mode 100644 index 608538d..0000000 --- a/20120831/sigcompat.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * NAME: - * sigcompat - BSD compat signals via POSIX - * - * SYNOPSIS: - * void (*signal(int "sig", void (*"handler")(int)))(int); - * int sigsetmask(int "mask"); - * int sigblock(int "mask"); - * int sigpause(int "mask"); - * int sigvec(int "signo", struct sigvec *"sv", struct sigvec *"osv"); - * - * DESCRIPTION: - * These implement the old BSD routines via the POSIX equivalents. - * This module can be used to provide the missing routines, or if - * 'FORCE_POSIX_SIGNALS' is defined, force use of these. - * - * Note that signal() is identical to my Signal() routine except - * for checking for recursion. Within libsig, signal() just - * calls Signal(). - * - * BUGS: - * This package assumes POSIX signal handling is available and - * NOT implemeneted using these routines. To be safe, we check - * for recursion and abort(3) if detected. - * - * Sadly, on some systems, sigset_t is an array, and we cannot - * test for this via #if sizeof(sigset_t) ..., so unless - * 'SIGSET_T_INT' is defined, we have to assume the worst and use - * memcpy(3) to handle args and return values. - * - * HISTORY: - * These routines originate from BSD, and are derrived from the - * NetBSD 1.1 implementation. They have been seriously hacked to - * make them portable to other systems. - * - * AUTHOR: - * Simon J. Gerraty <sjg@crufty.net> - */ -/* - * @(#)Copyright (c) 1994, Simon J. Gerraty. - * - * This is free software. It comes with NO WARRANTY. - * Permission to use, modify and distribute this source code - * is granted subject to the following conditions. - * 1/ that the above copyright notice and this notice - * are preserved in all copies and that due credit be given - * to the author. - * 2/ that any changes to this code are clearly commented - * as such so that the author does not get blamed for bugs - * other than his own. - * - * Please send copies of changes and bug-fixes to: - * sjg@crufty.net - */ - -/* - * Copyright (c) 1989 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include <signal.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#if defined(sun) && !(defined(__svr4__) || defined(__SVR4)) -# define NO_SIGCOMPAT -#endif -#if defined(__MINT__) -# define NO_SIGCOMPAT -#endif - -#if !defined(NO_SIGCOMPAT) && (defined(HAVE_SIGACTION) || defined(SA_NOCLDSTOP)) - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)sigcompat.c 5.3 (Berkeley) 2/24/91";*/ -static char *rcsid = "$Id: sigcompat.c,v 1.23 2011/02/14 00:07:11 sjg Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#undef signal -#include <stdio.h> -#include <string.h> -#include <sys/param.h> -#include <sys/cdefs.h> -#include "assert.h" - -#ifndef ASSERT -# define ASSERT assert -#endif - -#ifdef NDEBUG -# define _DBUG(x) -#else -# define _DBUG(x) x -#endif - -#ifndef SA_RESTART -# define SA_RESTART 2 -#endif -#ifndef SV_INTERRUPT -# define SV_INTERRUPT SA_RESTART -#endif - -#ifndef MASK_T -# if defined(__hpux__) || defined(__hpux) -# define MASK_T long -# else -# define MASK_T int -# endif -#endif -/* I just hate HPsUX */ -#if (defined(__HPUX_VERSION) && __HPUX_VERSION > 9) || defined(__hpux) -# define PAUSE_MASK_T int -#else -# define PAUSE_MASK_T MASK_T -#endif - -#ifndef SIG_HDLR -# define SIG_HDLR void -#endif - -#ifdef FORCE_POSIX_SIGNALS -#if !(defined(libsig) || defined(libsjg)) -/* - * This little block is almost identical to Signal(), - * and make this module standalone. - * We don't use it in libsig by default, as some apps might use both - * and expect _SignalFlags to be used by both. - */ - -#ifndef SIGNAL_FLAGS -# define SIGNAL_FLAGS 0 /* no auto-restart */ -#endif -int _signalFlags = SIGNAL_FLAGS; - -SIG_HDLR(*signal(int sig, SIG_HDLR(*handler)(int)))(int) -{ - _DBUG(static int depth_signal = 0); - struct sigaction act, oact; - int n; - - _DBUG(++depth_signal); - ASSERT(depth_signal < 2); - act.sa_handler = handler; - sigemptyset(&act.sa_mask); - act.sa_flags = _signalFlags; - n = sigaction(sig, &act, &oact); - _DBUG(--depth_signal); - if (n < 0) - return (SIG_ERR); - return (oact.sa_handler); -} -#else -SIG_HDLR(*signal(int sig, SIG_HDLR(*handler)(int)))(int) -{ - extern SIG_HDLR(*Signal(int, void (*)(int)))(int); - _DBUG(static int depth_signal = 0); - SIG_HDLR(*old) __P((int)); - - _DBUG(++depth_signal); - ASSERT(depth_signal < 2); - old = Signal(sig, handler); - _DBUG(--depth_signal); - return old; -} -#endif -#endif - -/* - * on some systems, sigset_t is an array... - * it would be nicer if we could do - * #if sizeof(sigset_t) > sizeof(MASK_T) - */ -#ifdef SIGSET_T_INT -# define ss2m(ss) (MASK_T) *(ss) -# define m2ss(ss, m) *ss = (sigset_t) *(m) -#else -static MASK_T -ss2m(sigset_t *ss) -{ - MASK_T ma[(sizeof(sigset_t) / sizeof(MASK_T)) + 1]; - - memcpy((char *) ma, (char *) ss, sizeof(sigset_t)); - return ma[0]; -} - -static void -m2ss(sigset_t *ss, MASK_T *m) -{ - if (sizeof(sigset_t) > sizeof(MASK_T)) - memset((char *) ss, 0, sizeof(sigset_t)); - - memcpy((char *) ss, (char *) m, sizeof(MASK_T)); -} -#endif - -#if !defined(HAVE_SIGSETMASK) || defined(FORCE_POSIX_SIGNALS) -MASK_T -sigsetmask(MASK_T mask) -{ - _DBUG(static int depth_sigsetmask = 0); - sigset_t m, omask; - int n; - - _DBUG(++depth_sigsetmask); - ASSERT(depth_sigsetmask < 2); - m2ss(&m, &mask); - n = sigprocmask(SIG_SETMASK, (sigset_t *) & m, (sigset_t *) & omask); - _DBUG(--depth_sigsetmask); - if (n) - return (n); - - return ss2m(&omask); -} - - -MASK_T -sigblock(MASK_T mask) -{ - _DBUG(static int depth_sigblock = 0); - sigset_t m, omask; - int n; - - _DBUG(++depth_sigblock); - ASSERT(depth_sigblock < 2); - if (mask) - m2ss(&m, &mask); - n = sigprocmask(SIG_BLOCK, (sigset_t *) ((mask) ? &m : 0), (sigset_t *) & omask); - _DBUG(--depth_sigblock); - if (n) - return (n); - return ss2m(&omask); -} - -#undef sigpause /* Linux at least */ - -PAUSE_MASK_T -sigpause(PAUSE_MASK_T mask) -{ - _DBUG(static int depth_sigpause = 0); - sigset_t m; - PAUSE_MASK_T n; - - _DBUG(++depth_sigpause); - ASSERT(depth_sigpause < 2); - m2ss(&m, &mask); - n = sigsuspend(&m); - _DBUG(--depth_sigpause); - return n; -} -#endif - -#if defined(HAVE_SIGVEC) && defined(FORCE_POSIX_SIGNALS) -int -sigvec(int signo, struct sigvec *sv, struct sigvec *osv) -{ - _DBUG(static int depth_sigvec = 0); - int ret; - struct sigvec nsv; - - _DBUG(++depth_sigvec); - ASSERT(depth_sigvec < 2); - if (sv) { - nsv = *sv; - nsv.sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */ - } - ret = sigaction(signo, sv ? (struct sigaction *) & nsv : NULL, - (struct sigaction *) osv); - _DBUG(--depth_sigvec); - if (ret == 0 && osv) - osv->sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */ - return (ret); -} -#endif - -#ifdef MAIN -# ifndef sigmask -# define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1))) -# endif - -int -main(int argc, char *argv[]) -{ - MASK_T old = 0; - - printf("expect: old=0,old=2\n"); - fflush(stdout); - signal(SIGQUIT, SIG_IGN); - old = sigblock(sigmask(SIGINT)); - printf("old=%d,", old); - old = sigsetmask(sigmask(SIGALRM)); - printf("old=%d\n", old); -} -#endif -#endif diff --git a/20120831/sprite.h b/20120831/sprite.h deleted file mode 100644 index 6ec4fe2..0000000 --- a/20120831/sprite.h +++ /dev/null @@ -1,116 +0,0 @@ -/* $NetBSD: sprite.h,v 1.11 2009/01/23 21:26:30 dsl Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)sprite.h 8.1 (Berkeley) 6/6/93 - */ - -/* - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)sprite.h 8.1 (Berkeley) 6/6/93 - */ - -/* - * sprite.h -- - * - * Common constants and type declarations for Sprite. - */ - -#ifndef _SPRITE -#define _SPRITE - - -/* - * A boolean type is defined as an integer, not an enum. This allows a - * boolean argument to be an expression that isn't strictly 0 or 1 valued. - */ - -typedef int Boolean; -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ -#ifndef FALSE -#define FALSE 0 -#endif /* FALSE */ - -/* - * Functions that must return a status can return a ReturnStatus to - * indicate success or type of failure. - */ - -typedef int ReturnStatus; - -/* - * The following statuses overlap with the first 2 generic statuses - * defined in status.h: - * - * SUCCESS There was no error. - * FAILURE There was a general error. - */ - -#define SUCCESS 0x00000000 -#define FAILURE 0x00000001 - -#endif /* _SPRITE */ diff --git a/20120831/str.c b/20120831/str.c deleted file mode 100644 index bc324b8..0000000 --- a/20120831/str.c +++ /dev/null @@ -1,508 +0,0 @@ -/* $NetBSD: str.c,v 1.34 2012/03/03 23:16:47 dholland Exp $ */ - -/*- - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/*- - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: str.c,v 1.34 2012/03/03 23:16:47 dholland Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90"; -#else -__RCSID("$NetBSD: str.c,v 1.34 2012/03/03 23:16:47 dholland Exp $"); -#endif -#endif /* not lint */ -#endif - -#include "make.h" - -/*- - * str_concat -- - * concatenate the two strings, inserting a space or slash between them, - * freeing them if requested. - * - * returns -- - * the resulting string in allocated space. - */ -char * -str_concat(const char *s1, const char *s2, int flags) -{ - int len1, len2; - char *result; - - /* get the length of both strings */ - len1 = strlen(s1); - len2 = strlen(s2); - - /* allocate length plus separator plus EOS */ - result = bmake_malloc((u_int)(len1 + len2 + 2)); - - /* copy first string into place */ - memcpy(result, s1, len1); - - /* add separator character */ - if (flags & STR_ADDSPACE) { - result[len1] = ' '; - ++len1; - } else if (flags & STR_ADDSLASH) { - result[len1] = '/'; - ++len1; - } - - /* copy second string plus EOS into place */ - memcpy(result + len1, s2, len2 + 1); - - return(result); -} - -/*- - * brk_string -- - * Fracture a string into an array of words (as delineated by tabs or - * spaces) taking quotation marks into account. Leading tabs/spaces - * are ignored. - * - * If expand is TRUE, quotes are removed and escape sequences - * such as \r, \t, etc... are expanded. - * - * returns -- - * Pointer to the array of pointers to the words. - * Memory containing the actual words in *buffer. - * Both of these must be free'd by the caller. - * Number of words in *store_argc. - */ -char ** -brk_string(const char *str, int *store_argc, Boolean expand, char **buffer) -{ - int argc, ch; - char inquote, *start, *t; - const char *p; - int len; - int argmax = 50, curlen = 0; - char **argv = bmake_malloc((argmax + 1) * sizeof(char *)); - - /* skip leading space chars. */ - for (; *str == ' ' || *str == '\t'; ++str) - continue; - - /* allocate room for a copy of the string */ - if ((len = strlen(str) + 1) > curlen) - *buffer = bmake_malloc(curlen = len); - - /* - * copy the string; at the same time, parse backslashes, - * quotes and build the argument list. - */ - argc = 0; - inquote = '\0'; - for (p = str, start = t = *buffer;; ++p) { - switch(ch = *p) { - case '"': - case '\'': - if (inquote) { - if (inquote == ch) - inquote = '\0'; - else - break; - } - else { - inquote = (char) ch; - /* Don't miss "" or '' */ - if (start == NULL && p[1] == inquote) { - if (!expand) { - start = t; - *t++ = ch; - } else - start = t + 1; - p++; - inquote = '\0'; - break; - } - } - if (!expand) { - if (!start) - start = t; - *t++ = ch; - } - continue; - case ' ': - case '\t': - case '\n': - if (inquote) - break; - if (!start) - continue; - /* FALLTHROUGH */ - case '\0': - /* - * end of a token -- make sure there's enough argv - * space and save off a pointer. - */ - if (!start) - goto done; - - *t++ = '\0'; - if (argc == argmax) { - argmax *= 2; /* ramp up fast */ - argv = (char **)bmake_realloc(argv, - (argmax + 1) * sizeof(char *)); - } - argv[argc++] = start; - start = NULL; - if (ch == '\n' || ch == '\0') { - if (expand && inquote) { - free(argv); - free(*buffer); - *buffer = NULL; - return NULL; - } - goto done; - } - continue; - case '\\': - if (!expand) { - if (!start) - start = t; - *t++ = '\\'; - if (*(p+1) == '\0') /* catch '\' at end of line */ - continue; - ch = *++p; - break; - } - - switch (ch = *++p) { - case '\0': - case '\n': - /* hmmm; fix it up as best we can */ - ch = '\\'; - --p; - break; - case 'b': - ch = '\b'; - break; - case 'f': - ch = '\f'; - break; - case 'n': - ch = '\n'; - break; - case 'r': - ch = '\r'; - break; - case 't': - ch = '\t'; - break; - } - break; - } - if (!start) - start = t; - *t++ = (char) ch; - } -done: argv[argc] = NULL; - *store_argc = argc; - return(argv); -} - -/* - * Str_FindSubstring -- See if a string contains a particular substring. - * - * Input: - * string String to search. - * substring Substring to find in string. - * - * Results: If string contains substring, the return value is the location of - * the first matching instance of substring in string. If string doesn't - * contain substring, the return value is NULL. Matching is done on an exact - * character-for-character basis with no wildcards or special characters. - * - * Side effects: None. - */ -char * -Str_FindSubstring(const char *string, const char *substring) -{ - const char *a, *b; - - /* - * First scan quickly through the two strings looking for a single- - * character match. When it's found, then compare the rest of the - * substring. - */ - - for (b = substring; *string != 0; string += 1) { - if (*string != *b) - continue; - a = string; - for (;;) { - if (*b == 0) - return UNCONST(string); - if (*a++ != *b++) - break; - } - b = substring; - } - return NULL; -} - -/* - * Str_Match -- - * - * See if a particular string matches a particular pattern. - * - * Results: Non-zero is returned if string matches pattern, 0 otherwise. The - * matching operation permits the following special characters in the - * pattern: *?\[] (see the man page for details on what these mean). - * - * XXX this function does not detect or report malformed patterns. - * - * Side effects: None. - */ -int -Str_Match(const char *string, const char *pattern) -{ - char c2; - - for (;;) { - /* - * See if we're at the end of both the pattern and the - * string. If, we succeeded. If we're at the end of the - * pattern but not at the end of the string, we failed. - */ - if (*pattern == 0) - return(!*string); - if (*string == 0 && *pattern != '*') - return(0); - /* - * Check for a "*" as the next pattern character. It matches - * any substring. We handle this by calling ourselves - * recursively for each postfix of string, until either we - * match or we reach the end of the string. - */ - if (*pattern == '*') { - pattern += 1; - if (*pattern == 0) - return(1); - while (*string != 0) { - if (Str_Match(string, pattern)) - return(1); - ++string; - } - return(0); - } - /* - * Check for a "?" as the next pattern character. It matches - * any single character. - */ - if (*pattern == '?') - goto thisCharOK; - /* - * Check for a "[" as the next pattern character. It is - * followed by a list of characters that are acceptable, or - * by a range (two characters separated by "-"). - */ - if (*pattern == '[') { - ++pattern; - for (;;) { - if ((*pattern == ']') || (*pattern == 0)) - return(0); - if (*pattern == *string) - break; - if (pattern[1] == '-') { - c2 = pattern[2]; - if (c2 == 0) - return(0); - if ((*pattern <= *string) && - (c2 >= *string)) - break; - if ((*pattern >= *string) && - (c2 <= *string)) - break; - pattern += 2; - } - ++pattern; - } - while ((*pattern != ']') && (*pattern != 0)) - ++pattern; - goto thisCharOK; - } - /* - * If the next pattern character is '/', just strip off the - * '/' so we do exact matching on the character that follows. - */ - if (*pattern == '\\') { - ++pattern; - if (*pattern == 0) - return(0); - } - /* - * There's no special character. Just make sure that the - * next characters of each string match. - */ - if (*pattern != *string) - return(0); -thisCharOK: ++pattern; - ++string; - } -} - - -/*- - *----------------------------------------------------------------------- - * Str_SYSVMatch -- - * Check word against pattern for a match (% is wild), - * - * Input: - * word Word to examine - * pattern Pattern to examine against - * len Number of characters to substitute - * - * Results: - * Returns the beginning position of a match or null. The number - * of characters matched is returned in len. - * - * Side Effects: - * None - * - *----------------------------------------------------------------------- - */ -char * -Str_SYSVMatch(const char *word, const char *pattern, int *len) -{ - const char *p = pattern; - const char *w = word; - const char *m; - - if (*p == '\0') { - /* Null pattern is the whole string */ - *len = strlen(w); - return UNCONST(w); - } - - if ((m = strchr(p, '%')) != NULL) { - /* check that the prefix matches */ - for (; p != m && *w && *w == *p; w++, p++) - continue; - - if (p != m) - return NULL; /* No match */ - - if (*++p == '\0') { - /* No more pattern, return the rest of the string */ - *len = strlen(w); - return UNCONST(w); - } - } - - m = w; - - /* Find a matching tail */ - do - if (strcmp(p, w) == 0) { - *len = w - m; - return UNCONST(m); - } - while (*w++ != '\0'); - - return NULL; -} - - -/*- - *----------------------------------------------------------------------- - * Str_SYSVSubst -- - * Substitute '%' on the pattern with len characters from src. - * If the pattern does not contain a '%' prepend len characters - * from src. - * - * Results: - * None - * - * Side Effects: - * Places result on buf - * - *----------------------------------------------------------------------- - */ -void -Str_SYSVSubst(Buffer *buf, char *pat, char *src, int len) -{ - char *m; - - if ((m = strchr(pat, '%')) != NULL) { - /* Copy the prefix */ - Buf_AddBytes(buf, m - pat, pat); - /* skip the % */ - pat = m + 1; - } - - /* Copy the pattern */ - Buf_AddBytes(buf, len, src); - - /* append the rest */ - Buf_AddBytes(buf, strlen(pat), pat); -} diff --git a/20120831/stresep.c b/20120831/stresep.c deleted file mode 100644 index b1b5714..0000000 --- a/20120831/stresep.c +++ /dev/null @@ -1,89 +0,0 @@ -/* $NetBSD: stresep.c,v 1.2 2007/12/06 22:07:07 seb Exp $ */ - -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <sys/cdefs.h> - -#include <assert.h> -#include <string.h> - -#if !defined(HAVE_STRESEP) -char * stresep(char **stringp, const char *delim, int esc); -/* - * Get next token from string *stringp, where tokens are possibly-empty - * strings separated by characters from delim. If esc is not NUL, then - * the characters followed by esc are ignored and are not taken into account - * when splitting the string. - * - * Writes NULs into the string at *stringp to end tokens. - * delim need not remain constant from call to call. - * On return, *stringp points past the last NUL written (if there might - * be further tokens), or is NULL (if there are definitely no more tokens). - * - * If *stringp is NULL, stresep returns NULL. - */ -char * -stresep(char **stringp, const char *delim, int esc) -{ - char *s; - const char *spanp; - int c, sc; - char *tok; - - if (stringp == NULL || delim == NULL) - return NULL; - - if ((s = *stringp) == NULL) - return NULL; - for (tok = s;;) { - c = *s++; - while (esc != '\0' && c == esc) { - (void)strcpy(s - 1, s); - c = *s++; - } - spanp = delim; - do { - if ((sc = *spanp++) == c) { - if (c == 0) - s = NULL; - else - s[-1] = 0; - *stringp = s; - return tok; - } - } while (sc != 0); - } -} -#endif - diff --git a/20120831/strlcpy.c b/20120831/strlcpy.c deleted file mode 100644 index b59b2f4..0000000 --- a/20120831/strlcpy.c +++ /dev/null @@ -1,63 +0,0 @@ -/* $NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */ -/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */ - -/* - * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE - * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#ifndef HAVE_STRLCPY - -#include <sys/cdefs.h> - -#include <sys/types.h> -#include <string.h> - -/* - * Copy src to string dst of size siz. At most siz-1 characters - * will be copied. Always NUL terminates (unless siz == 0). - * Returns strlen(src); if retval >= siz, truncation occurred. - */ -size_t -strlcpy(char *dst, const char *src, size_t siz) -{ - char *d = dst; - const char *s = src; - size_t n = siz; - - if (!dst || !src) - return 0; - - /* Copy as many bytes as will fit */ - if (n != 0 && --n != 0) { - do { - if ((*d++ = *s++) == 0) - break; - } while (--n != 0); - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; - } - - return(s - src - 1); /* count does not include NUL */ -} -#endif diff --git a/20120831/strlist.c b/20120831/strlist.c deleted file mode 100644 index 3fb2f7d..0000000 --- a/20120831/strlist.c +++ /dev/null @@ -1,93 +0,0 @@ -/* $NetBSD: strlist.c,v 1.4 2009/01/24 11:59:39 dsl Exp $ */ - -/*- - * Copyright (c) 2008 - 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by David Laight. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: strlist.c,v 1.4 2009/01/24 11:59:39 dsl Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -__RCSID("$NetBSD: strlist.c,v 1.4 2009/01/24 11:59:39 dsl Exp $"); -#endif /* not lint */ -#endif - -#include <stddef.h> -#include <stdlib.h> -#include "strlist.h" -#include "make_malloc.h" - -void -strlist_init(strlist_t *sl) -{ - sl->sl_num = 0; - sl->sl_max = 0; - sl->sl_items = NULL; -} - -void -strlist_clean(strlist_t *sl) -{ - char *str; - int i; - - STRLIST_FOREACH(str, sl, i) - free(str); - free(sl->sl_items); - - sl->sl_num = 0; - sl->sl_max = 0; - sl->sl_items = NULL; -} - -void -strlist_add_str(strlist_t *sl, char *str, unsigned int info) -{ - unsigned int n; - strlist_item_t *items; - - if (str == NULL) - return; - - n = sl->sl_num + 1; - sl->sl_num = n; - items = sl->sl_items; - if (n >= sl->sl_max) { - items = bmake_realloc(items, (n + 7) * sizeof *sl->sl_items); - sl->sl_items = items; - sl->sl_max = n + 6; - } - items += n - 1; - items->si_str = str; - items->si_info = info; - items[1].si_str = NULL; /* STRLIST_FOREACH() terminator */ -} diff --git a/20120831/strlist.h b/20120831/strlist.h deleted file mode 100644 index 2fc049e..0000000 --- a/20120831/strlist.h +++ /dev/null @@ -1,62 +0,0 @@ -/* $NetBSD: strlist.h,v 1.3 2009/01/16 21:15:34 dsl Exp $ */ - -/*- - * Copyright (c) 2008 - 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by David Laight. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _STRLIST_H -#define _STRLIST_H - -typedef struct { - char *si_str; - unsigned int si_info; -} strlist_item_t; - -typedef struct { - unsigned int sl_num; - unsigned int sl_max; - strlist_item_t *sl_items; -} strlist_t; - -void strlist_init(strlist_t *); -void strlist_clean(strlist_t *); -void strlist_add_str(strlist_t *, char *, unsigned int); - -#define strlist_num(sl) ((sl)->sl_num) -#define strlist_str(sl, n) ((sl)->sl_items[n].si_str) -#define strlist_info(sl, n) ((sl)->sl_items[n].si_info) -#define strlist_set_info(sl, n, v) ((void)((sl)->sl_items[n].si_info = (v))) - -#define STRLIST_FOREACH(v, sl, index) \ - if ((sl)->sl_items != NULL) \ - for (index = 0; (v = strlist_str(sl, index)) != NULL; index++) - -#endif /* _STRLIST_H */ diff --git a/20120831/suff.c b/20120831/suff.c deleted file mode 100644 index 6abdeb0..0000000 --- a/20120831/suff.c +++ /dev/null @@ -1,2653 +0,0 @@ -/* $NetBSD: suff.c,v 1.69 2011/09/29 23:38:04 sjg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: suff.c,v 1.69 2011/09/29 23:38:04 sjg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94"; -#else -__RCSID("$NetBSD: suff.c,v 1.69 2011/09/29 23:38:04 sjg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * suff.c -- - * Functions to maintain suffix lists and find implicit dependents - * using suffix transformation rules - * - * Interface: - * Suff_Init Initialize all things to do with suffixes. - * - * Suff_End Cleanup the module - * - * Suff_DoPaths This function is used to make life easier - * when searching for a file according to its - * suffix. It takes the global search path, - * as defined using the .PATH: target, and appends - * its directories to the path of each of the - * defined suffixes, as specified using - * .PATH<suffix>: targets. In addition, all - * directories given for suffixes labeled as - * include files or libraries, using the .INCLUDES - * or .LIBS targets, are played with using - * Dir_MakeFlags to create the .INCLUDES and - * .LIBS global variables. - * - * Suff_ClearSuffixes Clear out all the suffixes and defined - * transformations. - * - * Suff_IsTransform Return TRUE if the passed string is the lhs - * of a transformation rule. - * - * Suff_AddSuffix Add the passed string as another known suffix. - * - * Suff_GetPath Return the search path for the given suffix. - * - * Suff_AddInclude Mark the given suffix as denoting an include - * file. - * - * Suff_AddLib Mark the given suffix as denoting a library. - * - * Suff_AddTransform Add another transformation to the suffix - * graph. 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 - * if the target had no implicit sources. - * - * Suff_FindPath Return the appropriate path to search in - * order to find the node. - */ - -#include <stdio.h> -#include "make.h" -#include "hash.h" -#include "dir.h" - -static Lst sufflist; /* Lst of suffixes */ -#ifdef CLEANUP -static Lst suffClean; /* Lst of suffixes to be cleaned */ -#endif -static Lst srclist; /* Lst of sources */ -static Lst transforms; /* Lst of transformation rules */ - -static int sNum = 0; /* Counter for assigning suffix numbers */ - -/* - * Structure describing an individual suffix. - */ -typedef struct _Suff { - char *name; /* The suffix itself */ - int nameLen; /* Length of the suffix */ - short flags; /* Type of suffix */ -#define SUFF_INCLUDE 0x01 /* One which is #include'd */ -#define SUFF_LIBRARY 0x02 /* One which contains a library */ -#define SUFF_NULL 0x04 /* The empty suffix */ - Lst searchPath; /* The path along which files of this suffix - * may be found */ - int sNum; /* The suffix number */ - int refCount; /* Reference count of list membership */ - Lst parents; /* Suffixes we have a transformation to */ - Lst children; /* Suffixes we have a transformation from */ - Lst ref; /* List of lists this suffix is referenced */ -} Suff; - -/* - * for SuffSuffIsSuffix - */ -typedef struct { - char *ename; /* The end of the name */ - int len; /* Length of the name */ -} SuffixCmpData; - -/* - * Structure used in the search for implied sources. - */ -typedef struct _Src { - char *file; /* The file to look for */ - char *pref; /* Prefix from which file was formed */ - Suff *suff; /* The suffix on the file */ - struct _Src *parent; /* The Src for which this is a source */ - GNode *node; /* The node describing the file */ - int children; /* Count of existing children (so we don't free - * this thing too early or never nuke it) */ -#ifdef DEBUG_SRC - Lst cp; /* Debug; children list */ -#endif -} Src; - -/* - * A structure for passing more than one argument to the Lst-library-invoked - * function... - */ -typedef struct { - Lst l; - Src *s; -} LstSrc; - -typedef struct { - GNode **gn; - Suff *s; - Boolean r; -} GNodeSuff; - -static Suff *suffNull; /* The NULL suffix for this run */ -static Suff *emptySuff; /* The empty suffix required for POSIX - * single-suffix transformation rules */ - - -static const char *SuffStrIsPrefix(const char *, const char *); -static char *SuffSuffIsSuffix(const Suff *, const SuffixCmpData *); -static int SuffSuffIsSuffixP(const void *, const void *); -static int SuffSuffHasNameP(const void *, const void *); -static int SuffSuffIsPrefix(const void *, const void *); -static int SuffGNHasNameP(const void *, const void *); -static void SuffUnRef(void *, void *); -static void SuffFree(void *); -static void SuffInsert(Lst, Suff *); -static void SuffRemove(Lst, Suff *); -static Boolean SuffParseTransform(char *, Suff **, Suff **); -static int SuffRebuildGraph(void *, void *); -static int SuffScanTargets(void *, void *); -static int SuffAddSrc(void *, void *); -static int SuffRemoveSrc(Lst); -static void SuffAddLevel(Lst, Src *); -static Src *SuffFindThem(Lst, Lst); -static Src *SuffFindCmds(Src *, Lst); -static void SuffExpandChildren(LstNode, GNode *); -static void SuffExpandWildcards(LstNode, GNode *); -static Boolean SuffApplyTransform(GNode *, GNode *, Suff *, Suff *); -static void SuffFindDeps(GNode *, Lst); -static void SuffFindArchiveDeps(GNode *, Lst); -static void SuffFindNormalDeps(GNode *, Lst); -static int SuffPrintName(void *, void *); -static int SuffPrintSuff(void *, void *); -static int SuffPrintTrans(void *, void *); - - /*************** Lst Predicates ****************/ -/*- - *----------------------------------------------------------------------- - * SuffStrIsPrefix -- - * See if pref is a prefix of str. - * - * Input: - * pref possible prefix - * str string to check - * - * Results: - * NULL if it ain't, pointer to character in str after prefix if so - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static const char * -SuffStrIsPrefix(const char *pref, const char *str) -{ - while (*str && *pref == *str) { - pref++; - str++; - } - - return (*pref ? NULL : str); -} - -/*- - *----------------------------------------------------------------------- - * SuffSuffIsSuffix -- - * See if suff is a suffix of str. sd->ename should point to THE END - * of the string to check. (THE END == the null byte) - * - * Input: - * s possible suffix - * sd string to examine - * - * Results: - * NULL if it ain't, pointer to character in str before suffix if - * it is. - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static char * -SuffSuffIsSuffix(const Suff *s, const SuffixCmpData *sd) -{ - char *p1; /* Pointer into suffix name */ - char *p2; /* Pointer into string being examined */ - - if (sd->len < s->nameLen) - return NULL; /* this string is shorter than the suffix */ - - p1 = s->name + s->nameLen; - p2 = sd->ename; - - while (p1 >= s->name && *p1 == *p2) { - p1--; - p2--; - } - - return (p1 == s->name - 1 ? p2 : NULL); -} - -/*- - *----------------------------------------------------------------------- - * SuffSuffIsSuffixP -- - * Predicate form of SuffSuffIsSuffix. Passed as the callback function - * to Lst_Find. - * - * Results: - * 0 if the suffix is the one desired, non-zero if not. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static int -SuffSuffIsSuffixP(const void *s, const void *sd) -{ - return(!SuffSuffIsSuffix(s, sd)); -} - -/*- - *----------------------------------------------------------------------- - * SuffSuffHasNameP -- - * Callback procedure for finding a suffix based on its name. Used by - * Suff_GetPath. - * - * Input: - * s Suffix to check - * sd Desired name - * - * Results: - * 0 if the suffix is of the given name. non-zero otherwise. - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static int -SuffSuffHasNameP(const void *s, const void *sname) -{ - return (strcmp(sname, ((const Suff *)s)->name)); -} - -/*- - *----------------------------------------------------------------------- - * SuffSuffIsPrefix -- - * See if the suffix described by s is a prefix of the string. Care - * must be taken when using this to search for transformations and - * what-not, since there could well be two suffixes, one of which - * is a prefix of the other... - * - * Input: - * s suffix to compare - * str string to examine - * - * Results: - * 0 if s is a prefix of str. non-zero otherwise - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static int -SuffSuffIsPrefix(const void *s, const void *str) -{ - return SuffStrIsPrefix(((const Suff *)s)->name, str) == NULL; -} - -/*- - *----------------------------------------------------------------------- - * SuffGNHasNameP -- - * See if the graph node has the desired name - * - * Input: - * gn current node we're looking at - * name name we're looking for - * - * Results: - * 0 if it does. non-zero if it doesn't - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static int -SuffGNHasNameP(const void *gn, const void *name) -{ - return (strcmp(name, ((const GNode *)gn)->name)); -} - - /*********** Maintenance Functions ************/ - -static void -SuffUnRef(void *lp, void *sp) -{ - Lst l = (Lst) lp; - - LstNode ln = Lst_Member(l, sp); - if (ln != NULL) { - Lst_Remove(l, ln); - ((Suff *)sp)->refCount--; - } -} - -/*- - *----------------------------------------------------------------------- - * SuffFree -- - * Free up all memory associated with the given suffix structure. - * - * Results: - * none - * - * Side Effects: - * the suffix entry is detroyed - *----------------------------------------------------------------------- - */ -static void -SuffFree(void *sp) -{ - Suff *s = (Suff *)sp; - - if (s == suffNull) - suffNull = NULL; - - if (s == emptySuff) - emptySuff = NULL; - -#ifdef notdef - /* We don't delete suffixes in order, so we cannot use this */ - if (s->refCount) - Punt("Internal error deleting suffix `%s' with refcount = %d", s->name, - s->refCount); -#endif - - Lst_Destroy(s->ref, NULL); - Lst_Destroy(s->children, NULL); - Lst_Destroy(s->parents, NULL); - Lst_Destroy(s->searchPath, Dir_Destroy); - - free(s->name); - free(s); -} - -/*- - *----------------------------------------------------------------------- - * SuffRemove -- - * Remove the suffix into the list - * - * Results: - * None - * - * Side Effects: - * The reference count for the suffix is decremented and the - * suffix is possibly freed - *----------------------------------------------------------------------- - */ -static void -SuffRemove(Lst l, Suff *s) -{ - SuffUnRef(l, s); - if (s->refCount == 0) { - SuffUnRef(sufflist, s); - SuffFree(s); - } -} - -/*- - *----------------------------------------------------------------------- - * SuffInsert -- - * Insert the suffix into the list keeping the list ordered by suffix - * numbers. - * - * Input: - * l the list where in s should be inserted - * s the suffix to insert - * - * Results: - * None - * - * Side Effects: - * The reference count of the suffix is incremented - *----------------------------------------------------------------------- - */ -static void -SuffInsert(Lst l, Suff *s) -{ - LstNode ln; /* current element in l we're examining */ - Suff *s2 = NULL; /* the suffix descriptor in this element */ - - if (Lst_Open(l) == FAILURE) { - return; - } - while ((ln = Lst_Next(l)) != NULL) { - s2 = (Suff *)Lst_Datum(ln); - if (s2->sNum >= s->sNum) { - break; - } - } - - Lst_Close(l); - if (DEBUG(SUFF)) { - fprintf(debug_file, "inserting %s(%d)...", s->name, s->sNum); - } - if (ln == NULL) { - if (DEBUG(SUFF)) { - fprintf(debug_file, "at end of list\n"); - } - (void)Lst_AtEnd(l, s); - s->refCount++; - (void)Lst_AtEnd(s->ref, l); - } else if (s2->sNum != s->sNum) { - if (DEBUG(SUFF)) { - fprintf(debug_file, "before %s(%d)\n", s2->name, s2->sNum); - } - (void)Lst_InsertBefore(l, ln, s); - s->refCount++; - (void)Lst_AtEnd(s->ref, l); - } else if (DEBUG(SUFF)) { - fprintf(debug_file, "already there\n"); - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_ClearSuffixes -- - * This is gross. Nuke the list of suffixes but keep all transformation - * rules around. The transformation graph is destroyed in this process, - * but we leave the list of rules so when a new graph is formed the rules - * will remain. - * This function is called from the parse module when a - * .SUFFIXES:\n line is encountered. - * - * Results: - * none - * - * Side Effects: - * the sufflist and its graph nodes are destroyed - *----------------------------------------------------------------------- - */ -void -Suff_ClearSuffixes(void) -{ -#ifdef CLEANUP - Lst_Concat(suffClean, sufflist, LST_CONCLINK); -#endif - sufflist = Lst_Init(FALSE); - sNum = 0; - suffNull = emptySuff; -} - -/*- - *----------------------------------------------------------------------- - * SuffParseTransform -- - * Parse a transformation string to find its two component suffixes. - * - * Input: - * str String being parsed - * srcPtr Place to store source of trans. - * targPtr Place to store target of trans. - * - * Results: - * TRUE if the string is a valid transformation and FALSE otherwise. - * - * Side Effects: - * The passed pointers are overwritten. - * - *----------------------------------------------------------------------- - */ -static Boolean -SuffParseTransform(char *str, Suff **srcPtr, Suff **targPtr) -{ - LstNode srcLn; /* element in suffix list of trans source*/ - Suff *src; /* Source of transformation */ - LstNode targLn; /* element in suffix list of trans target*/ - char *str2; /* Extra pointer (maybe target suffix) */ - LstNode singleLn; /* element in suffix list of any suffix - * that exactly matches str */ - Suff *single = NULL;/* Source of possible transformation to - * null suffix */ - - srcLn = NULL; - singleLn = NULL; - - /* - * Loop looking first for a suffix that matches the start of the - * string and then for one that exactly matches the rest of it. If - * we can find two that meet these criteria, we've successfully - * parsed the string. - */ - for (;;) { - if (srcLn == NULL) { - srcLn = Lst_Find(sufflist, str, SuffSuffIsPrefix); - } else { - srcLn = Lst_FindFrom(sufflist, Lst_Succ(srcLn), str, - SuffSuffIsPrefix); - } - if (srcLn == NULL) { - /* - * Ran out of source suffixes -- no such rule - */ - if (singleLn != NULL) { - /* - * Not so fast Mr. Smith! There was a suffix that encompassed - * the entire string, so we assume it was a transformation - * to the null suffix (thank you POSIX). We still prefer to - * find a double rule over a singleton, hence we leave this - * check until the end. - * - * XXX: Use emptySuff over suffNull? - */ - *srcPtr = single; - *targPtr = suffNull; - return(TRUE); - } - return (FALSE); - } - src = (Suff *)Lst_Datum(srcLn); - str2 = str + src->nameLen; - if (*str2 == '\0') { - single = src; - singleLn = srcLn; - } else { - targLn = Lst_Find(sufflist, str2, SuffSuffHasNameP); - if (targLn != NULL) { - *srcPtr = src; - *targPtr = (Suff *)Lst_Datum(targLn); - return (TRUE); - } - } - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_IsTransform -- - * Return TRUE if the given string is a transformation rule - * - * - * Input: - * str string to check - * - * Results: - * TRUE if the string is a concatenation of two known suffixes. - * FALSE otherwise - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -Boolean -Suff_IsTransform(char *str) -{ - Suff *src, *targ; - - return (SuffParseTransform(str, &src, &targ)); -} - -/*- - *----------------------------------------------------------------------- - * Suff_AddTransform -- - * Add the transformation rule described by the line to the - * list of rules and place the transformation itself in the graph - * - * Input: - * line name of transformation to add - * - * Results: - * The node created for the transformation in the transforms list - * - * Side Effects: - * The node is placed on the end of the transforms Lst and links are - * made between the two suffixes mentioned in the target name - *----------------------------------------------------------------------- - */ -GNode * -Suff_AddTransform(char *line) -{ - GNode *gn; /* GNode of transformation rule */ - Suff *s, /* source suffix */ - *t; /* target suffix */ - LstNode ln; /* Node for existing transformation */ - - ln = Lst_Find(transforms, line, SuffGNHasNameP); - if (ln == NULL) { - /* - * Make a new graph node for the transformation. It will be filled in - * by the Parse module. - */ - gn = Targ_NewGN(line); - (void)Lst_AtEnd(transforms, gn); - } else { - /* - * New specification for transformation rule. Just nuke the old list - * of commands so they can be filled in again... We don't actually - * free the commands themselves, because a given command can be - * attached to several different transformations. - */ - gn = (GNode *)Lst_Datum(ln); - Lst_Destroy(gn->commands, NULL); - Lst_Destroy(gn->children, NULL); - gn->commands = Lst_Init(FALSE); - gn->children = Lst_Init(FALSE); - } - - gn->type = OP_TRANSFORM; - - (void)SuffParseTransform(line, &s, &t); - - /* - * link the two together in the proper relationship and order - */ - if (DEBUG(SUFF)) { - fprintf(debug_file, "defining transformation from `%s' to `%s'\n", - s->name, t->name); - } - SuffInsert(t->children, s); - SuffInsert(s->parents, t); - - return (gn); -} - -/*- - *----------------------------------------------------------------------- - * Suff_EndTransform -- - * Handle the finish of a transformation definition, removing the - * transformation from the graph if it has neither commands nor - * sources. This is a callback procedure for the Parse module via - * Lst_ForEach - * - * Input: - * gnp Node for transformation - * dummy Node for transformation - * - * Results: - * === 0 - * - * Side Effects: - * If the node has no commands or children, the children and parents - * lists of the affected suffixes are altered. - * - *----------------------------------------------------------------------- - */ -int -Suff_EndTransform(void *gnp, void *dummy) -{ - GNode *gn = (GNode *)gnp; - - if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) - gn = (GNode *)Lst_Datum(Lst_Last(gn->cohorts)); - if ((gn->type & OP_TRANSFORM) && Lst_IsEmpty(gn->commands) && - Lst_IsEmpty(gn->children)) - { - Suff *s, *t; - - /* - * SuffParseTransform() may fail for special rules which are not - * actual transformation rules. (e.g. .DEFAULT) - */ - if (SuffParseTransform(gn->name, &s, &t)) { - Lst p; - - if (DEBUG(SUFF)) { - fprintf(debug_file, "deleting transformation from `%s' to `%s'\n", - s->name, t->name); - } - - /* - * Store s->parents because s could be deleted in SuffRemove - */ - p = s->parents; - - /* - * Remove the source from the target's children list. We check for a - * nil return to handle a beanhead saying something like - * .c.o .c.o: - * - * We'll be called twice when the next target is seen, but .c and .o - * are only linked once... - */ - SuffRemove(t->children, s); - - /* - * Remove the target from the source's parents list - */ - SuffRemove(p, t); - } - } else if ((gn->type & OP_TRANSFORM) && DEBUG(SUFF)) { - fprintf(debug_file, "transformation %s complete\n", gn->name); - } - - return(dummy ? 0 : 0); -} - -/*- - *----------------------------------------------------------------------- - * SuffRebuildGraph -- - * Called from Suff_AddSuffix via Lst_ForEach to search through the - * list of existing transformation rules and rebuild the transformation - * graph when it has been destroyed by Suff_ClearSuffixes. If the - * given rule is a transformation involving this suffix and another, - * existing suffix, the proper relationship is established between - * the two. - * - * Input: - * transformp Transformation to test - * sp Suffix to rebuild - * - * Results: - * Always 0. - * - * Side Effects: - * The appropriate links will be made between this suffix and - * others if transformation rules exist for it. - * - *----------------------------------------------------------------------- - */ -static int -SuffRebuildGraph(void *transformp, void *sp) -{ - GNode *transform = (GNode *)transformp; - Suff *s = (Suff *)sp; - char *cp; - LstNode ln; - Suff *s2; - SuffixCmpData sd; - - /* - * First see if it is a transformation from this suffix. - */ - cp = UNCONST(SuffStrIsPrefix(s->name, transform->name)); - if (cp != NULL) { - ln = Lst_Find(sufflist, cp, SuffSuffHasNameP); - if (ln != NULL) { - /* - * Found target. Link in and return, since it can't be anything - * else. - */ - s2 = (Suff *)Lst_Datum(ln); - SuffInsert(s2->children, s); - SuffInsert(s->parents, s2); - return(0); - } - } - - /* - * Not from, maybe to? - */ - sd.len = strlen(transform->name); - sd.ename = transform->name + sd.len; - cp = SuffSuffIsSuffix(s, &sd); - if (cp != NULL) { - /* - * Null-terminate the source suffix in order to find it. - */ - cp[1] = '\0'; - ln = Lst_Find(sufflist, transform->name, SuffSuffHasNameP); - /* - * Replace the start of the target suffix - */ - cp[1] = s->name[0]; - if (ln != NULL) { - /* - * Found it -- establish the proper relationship - */ - s2 = (Suff *)Lst_Datum(ln); - SuffInsert(s->children, s2); - SuffInsert(s2->parents, s); - } - } - return(0); -} - -/*- - *----------------------------------------------------------------------- - * SuffScanTargets -- - * Called from Suff_AddSuffix via Lst_ForEach to search through the - * list of existing targets and find if any of the existing targets - * can be turned into a transformation rule. - * - * Results: - * 1 if a new main target has been selected, 0 otherwise. - * - * Side Effects: - * If such a target is found and the target is the current main - * target, the main target is set to NULL and the next target - * examined (if that exists) becomes the main target. - * - *----------------------------------------------------------------------- - */ -static int -SuffScanTargets(void *targetp, void *gsp) -{ - GNode *target = (GNode *)targetp; - GNodeSuff *gs = (GNodeSuff *)gsp; - Suff *s, *t; - char *ptr; - - if (*gs->gn == NULL && gs->r && (target->type & OP_NOTARGET) == 0) { - *gs->gn = target; - Targ_SetMain(target); - return 1; - } - - if ((unsigned int)target->type == OP_TRANSFORM) - return 0; - - if ((ptr = strstr(target->name, gs->s->name)) == NULL || - ptr == target->name) - return 0; - - if (SuffParseTransform(target->name, &s, &t)) { - if (*gs->gn == target) { - gs->r = TRUE; - *gs->gn = NULL; - Targ_SetMain(NULL); - } - Lst_Destroy(target->children, NULL); - target->children = Lst_Init(FALSE); - target->type = OP_TRANSFORM; - /* - * link the two together in the proper relationship and order - */ - if (DEBUG(SUFF)) { - fprintf(debug_file, "defining transformation from `%s' to `%s'\n", - s->name, t->name); - } - SuffInsert(t->children, s); - SuffInsert(s->parents, t); - } - return 0; -} - -/*- - *----------------------------------------------------------------------- - * Suff_AddSuffix -- - * Add the suffix in string to the end of the list of known suffixes. - * Should we restructure the suffix graph? Make doesn't... - * - * Input: - * str the name of the suffix to add - * - * Results: - * None - * - * Side Effects: - * A GNode is created for the suffix and a Suff structure is created and - * added to the suffixes list unless the suffix was already known. - * The mainNode passed can be modified if a target mutated into a - * transform and that target happened to be the main target. - *----------------------------------------------------------------------- - */ -void -Suff_AddSuffix(char *str, GNode **gn) -{ - Suff *s; /* new suffix descriptor */ - LstNode ln; - GNodeSuff gs; - - ln = Lst_Find(sufflist, str, SuffSuffHasNameP); - if (ln == NULL) { - s = bmake_malloc(sizeof(Suff)); - - s->name = bmake_strdup(str); - s->nameLen = strlen(s->name); - s->searchPath = Lst_Init(FALSE); - s->children = Lst_Init(FALSE); - s->parents = Lst_Init(FALSE); - s->ref = Lst_Init(FALSE); - s->sNum = sNum++; - s->flags = 0; - s->refCount = 1; - - (void)Lst_AtEnd(sufflist, s); - /* - * We also look at our existing targets list to see if adding - * this suffix will make one of our current targets mutate into - * a suffix rule. This is ugly, but other makes treat all targets - * that start with a . as suffix rules. - */ - gs.gn = gn; - gs.s = s; - gs.r = FALSE; - Lst_ForEach(Targ_List(), SuffScanTargets, &gs); - /* - * Look for any existing transformations from or to this suffix. - * XXX: Only do this after a Suff_ClearSuffixes? - */ - Lst_ForEach(transforms, SuffRebuildGraph, s); - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_GetPath -- - * Return the search path for the given suffix, if it's defined. - * - * Results: - * The searchPath for the desired suffix or NULL if the suffix isn't - * defined. - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -Lst -Suff_GetPath(char *sname) -{ - LstNode ln; - Suff *s; - - ln = Lst_Find(sufflist, sname, SuffSuffHasNameP); - if (ln == NULL) { - return NULL; - } else { - s = (Suff *)Lst_Datum(ln); - return (s->searchPath); - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_DoPaths -- - * Extend the search paths for all suffixes to include the default - * search path. - * - * Results: - * None. - * - * Side Effects: - * The searchPath field of all the suffixes is extended by the - * directories in dirSearchPath. If paths were specified for the - * ".h" suffix, the directories are stuffed into a global variable - * called ".INCLUDES" with each directory preceded by a -I. The same - * is done for the ".a" suffix, except the variable is called - * ".LIBS" and the flag is -L. - *----------------------------------------------------------------------- - */ -void -Suff_DoPaths(void) -{ - Suff *s; - LstNode ln; - char *ptr; - Lst inIncludes; /* Cumulative .INCLUDES path */ - Lst inLibs; /* Cumulative .LIBS path */ - - if (Lst_Open(sufflist) == FAILURE) { - return; - } - - inIncludes = Lst_Init(FALSE); - inLibs = Lst_Init(FALSE); - - while ((ln = Lst_Next(sufflist)) != NULL) { - s = (Suff *)Lst_Datum(ln); - if (!Lst_IsEmpty (s->searchPath)) { -#ifdef INCLUDES - if (s->flags & SUFF_INCLUDE) { - Dir_Concat(inIncludes, s->searchPath); - } -#endif /* INCLUDES */ -#ifdef LIBRARIES - if (s->flags & SUFF_LIBRARY) { - Dir_Concat(inLibs, s->searchPath); - } -#endif /* LIBRARIES */ - Dir_Concat(s->searchPath, dirSearchPath); - } else { - Lst_Destroy(s->searchPath, Dir_Destroy); - s->searchPath = Lst_Duplicate(dirSearchPath, Dir_CopyDir); - } - } - - Var_Set(".INCLUDES", ptr = Dir_MakeFlags("-I", inIncludes), VAR_GLOBAL, 0); - free(ptr); - Var_Set(".LIBS", ptr = Dir_MakeFlags("-L", inLibs), VAR_GLOBAL, 0); - free(ptr); - - Lst_Destroy(inIncludes, Dir_Destroy); - Lst_Destroy(inLibs, Dir_Destroy); - - Lst_Close(sufflist); -} - -/*- - *----------------------------------------------------------------------- - * Suff_AddInclude -- - * Add the given suffix as a type of file which gets included. - * Called from the parse module when a .INCLUDES line is parsed. - * The suffix must have already been defined. - * - * Input: - * sname Name of the suffix to mark - * - * Results: - * None. - * - * Side Effects: - * The SUFF_INCLUDE bit is set in the suffix's flags field - * - *----------------------------------------------------------------------- - */ -void -Suff_AddInclude(char *sname) -{ - LstNode ln; - Suff *s; - - ln = Lst_Find(sufflist, sname, SuffSuffHasNameP); - if (ln != NULL) { - s = (Suff *)Lst_Datum(ln); - s->flags |= SUFF_INCLUDE; - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_AddLib -- - * Add the given suffix as a type of file which is a library. - * Called from the parse module when parsing a .LIBS line. The - * suffix must have been defined via .SUFFIXES before this is - * called. - * - * Input: - * sname Name of the suffix to mark - * - * Results: - * None. - * - * Side Effects: - * The SUFF_LIBRARY bit is set in the suffix's flags field - * - *----------------------------------------------------------------------- - */ -void -Suff_AddLib(char *sname) -{ - LstNode ln; - Suff *s; - - ln = Lst_Find(sufflist, sname, SuffSuffHasNameP); - if (ln != NULL) { - s = (Suff *)Lst_Datum(ln); - s->flags |= SUFF_LIBRARY; - } -} - - /********** Implicit Source Search Functions *********/ - -/*- - *----------------------------------------------------------------------- - * SuffAddSrc -- - * Add a suffix as a Src structure to the given list with its parent - * being the given Src structure. If the suffix is the null suffix, - * the prefix is used unaltered as the file name in the Src structure. - * - * Input: - * sp suffix for which to create a Src structure - * lsp list and parent for the new Src - * - * Results: - * always returns 0 - * - * Side Effects: - * A Src structure is created and tacked onto the end of the list - *----------------------------------------------------------------------- - */ -static int -SuffAddSrc(void *sp, void *lsp) -{ - Suff *s = (Suff *)sp; - LstSrc *ls = (LstSrc *)lsp; - Src *s2; /* new Src structure */ - Src *targ; /* Target structure */ - - 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 = bmake_malloc(sizeof(Src)); - s2->file = bmake_strdup(targ->pref); - s2->pref = targ->pref; - s2->parent = targ; - s2->node = NULL; - s2->suff = s; - s->refCount++; - s2->children = 0; - targ->children += 1; - (void)Lst_AtEnd(ls->l, s2); -#ifdef DEBUG_SRC - s2->cp = Lst_Init(FALSE); - Lst_AtEnd(targ->cp, s2); - fprintf(debug_file, "1 add %x %x to %x:", targ, s2, ls->l); - Lst_ForEach(ls->l, PrintAddr, NULL); - fprintf(debug_file, "\n"); -#endif - } - s2 = bmake_malloc(sizeof(Src)); - s2->file = str_concat(targ->pref, s->name, 0); - s2->pref = targ->pref; - s2->parent = targ; - s2->node = NULL; - s2->suff = s; - s->refCount++; - s2->children = 0; - targ->children += 1; - (void)Lst_AtEnd(ls->l, s2); -#ifdef DEBUG_SRC - s2->cp = Lst_Init(FALSE); - Lst_AtEnd(targ->cp, s2); - fprintf(debug_file, "2 add %x %x to %x:", targ, s2, ls->l); - Lst_ForEach(ls->l, PrintAddr, NULL); - fprintf(debug_file, "\n"); -#endif - - return(0); -} - -/*- - *----------------------------------------------------------------------- - * SuffAddLevel -- - * Add all the children of targ as Src structures to the given list - * - * Input: - * l list to which to add the new level - * targ Src structure to use as the parent - * - * Results: - * None - * - * Side Effects: - * Lots of structures are created and added to the list - *----------------------------------------------------------------------- - */ -static void -SuffAddLevel(Lst l, Src *targ) -{ - LstSrc ls; - - ls.s = targ; - ls.l = l; - - Lst_ForEach(targ->suff->children, SuffAddSrc, &ls); -} - -/*- - *---------------------------------------------------------------------- - * SuffRemoveSrc -- - * Free all src structures in list that don't have a reference count - * - * Results: - * Ture if an src was removed - * - * Side Effects: - * The memory is free'd. - *---------------------------------------------------------------------- - */ -static int -SuffRemoveSrc(Lst l) -{ - LstNode ln; - Src *s; - int t = 0; - - if (Lst_Open(l) == FAILURE) { - return 0; - } -#ifdef DEBUG_SRC - fprintf(debug_file, "cleaning %lx: ", (unsigned long) l); - Lst_ForEach(l, PrintAddr, NULL); - fprintf(debug_file, "\n"); -#endif - - - while ((ln = Lst_Next(l)) != NULL) { - s = (Src *)Lst_Datum(ln); - if (s->children == 0) { - free(s->file); - if (!s->parent) - free(s->pref); - else { -#ifdef DEBUG_SRC - LstNode ln = Lst_Member(s->parent->cp, s); - if (ln != NULL) - Lst_Remove(s->parent->cp, ln); -#endif - --s->parent->children; - } -#ifdef DEBUG_SRC - fprintf(debug_file, "free: [l=%x] p=%x %d\n", l, s, s->children); - Lst_Destroy(s->cp, NULL); -#endif - Lst_Remove(l, ln); - free(s); - t |= 1; - Lst_Close(l); - return TRUE; - } -#ifdef DEBUG_SRC - else { - fprintf(debug_file, "keep: [l=%x] p=%x %d: ", l, s, s->children); - Lst_ForEach(s->cp, PrintAddr, NULL); - fprintf(debug_file, "\n"); - } -#endif - } - - Lst_Close(l); - - return t; -} - -/*- - *----------------------------------------------------------------------- - * SuffFindThem -- - * Find the first existing file/target in the list srcs - * - * Input: - * srcs list of Src structures to search through - * - * Results: - * The lowest structure in the chain of transformations - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static Src * -SuffFindThem(Lst srcs, Lst slst) -{ - Src *s; /* current Src */ - Src *rs; /* returned Src */ - char *ptr; - - rs = NULL; - - while (!Lst_IsEmpty (srcs)) { - s = (Src *)Lst_DeQueue(srcs); - - if (DEBUG(SUFF)) { - fprintf(debug_file, "\ttrying %s...", s->file); - } - - /* - * A file is considered to exist if either a node exists in the - * graph for it or the file actually exists. - */ - if (Targ_FindNode(s->file, TARG_NOCREATE) != NULL) { -#ifdef DEBUG_SRC - fprintf(debug_file, "remove %x from %x\n", s, srcs); -#endif - rs = s; - break; - } - - if ((ptr = Dir_FindFile(s->file, s->suff->searchPath)) != NULL) { - rs = s; -#ifdef DEBUG_SRC - fprintf(debug_file, "remove %x from %x\n", s, srcs); -#endif - free(ptr); - break; - } - - if (DEBUG(SUFF)) { - fprintf(debug_file, "not there\n"); - } - - SuffAddLevel(srcs, s); - Lst_AtEnd(slst, s); - } - - if (DEBUG(SUFF) && rs) { - fprintf(debug_file, "got it\n"); - } - return (rs); -} - -/*- - *----------------------------------------------------------------------- - * SuffFindCmds -- - * See if any of the children of the target in the Src structure is - * one from which the target can be transformed. If there is one, - * a Src structure is put together for it and returned. - * - * Input: - * targ Src structure to play with - * - * Results: - * The Src structure of the "winning" child, or NULL if no such beast. - * - * Side Effects: - * A Src structure may be allocated. - * - *----------------------------------------------------------------------- - */ -static Src * -SuffFindCmds(Src *targ, Lst slst) -{ - LstNode ln; /* General-purpose list node */ - GNode *t, /* Target GNode */ - *s; /* Source GNode */ - int prefLen;/* The length of the defined prefix */ - Suff *suff; /* Suffix on matching beastie */ - Src *ret; /* Return value */ - char *cp; - - t = targ->node; - (void)Lst_Open(t->children); - prefLen = strlen(targ->pref); - - for (;;) { - ln = Lst_Next(t->children); - if (ln == NULL) { - Lst_Close(t->children); - return NULL; - } - s = (GNode *)Lst_Datum(ln); - - if (s->type & OP_OPTIONAL && Lst_IsEmpty(t->commands)) { - /* - * We haven't looked to see if .OPTIONAL files exist yet, so - * don't use one as the implicit source. - * This allows us to use .OPTIONAL in .depend files so make won't - * complain "don't know how to make xxx.h' when a dependent file - * has been moved/deleted. - */ - continue; - } - - cp = strrchr(s->name, '/'); - if (cp == NULL) { - cp = s->name; - } else { - cp++; - } - if (strncmp(cp, targ->pref, prefLen) != 0) - continue; - /* - * The node matches the prefix ok, see if it has a known - * suffix. - */ - ln = Lst_Find(sufflist, &cp[prefLen], SuffSuffHasNameP); - if (ln == NULL) - continue; - /* - * It even has a known suffix, see if there's a transformation - * defined between the node's suffix and the target's suffix. - * - * XXX: Handle multi-stage transformations here, too. - */ - suff = (Suff *)Lst_Datum(ln); - - if (Lst_Member(suff->parents, targ->suff) != NULL) - break; - } - - /* - * Hot Damn! Create a new Src structure to describe - * this transformation (making sure to duplicate the - * source node's name so Suff_FindDeps can free it - * again (ick)), and return the new structure. - */ - ret = bmake_malloc(sizeof(Src)); - ret->file = bmake_strdup(s->name); - ret->pref = targ->pref; - ret->suff = suff; - suff->refCount++; - ret->parent = targ; - ret->node = s; - ret->children = 0; - targ->children += 1; -#ifdef DEBUG_SRC - ret->cp = Lst_Init(FALSE); - fprintf(debug_file, "3 add %x %x\n", targ, ret); - Lst_AtEnd(targ->cp, ret); -#endif - Lst_AtEnd(slst, ret); - if (DEBUG(SUFF)) { - fprintf(debug_file, "\tusing existing source %s\n", s->name); - } - return (ret); -} - -/*- - *----------------------------------------------------------------------- - * SuffExpandChildren -- - * Expand the names of any children of a given node that contain - * variable invocations or file wildcards into actual targets. - * - * Input: - * cln Child to examine - * pgn Parent node being processed - * - * Results: - * === 0 (continue) - * - * Side Effects: - * The expanded node is removed from the parent's list of children, - * and the parent's unmade counter is decremented, but other nodes - * may be added. - * - *----------------------------------------------------------------------- - */ -static void -SuffExpandChildren(LstNode cln, GNode *pgn) -{ - GNode *cgn = (GNode *)Lst_Datum(cln); - GNode *gn; /* New source 8) */ - char *cp; /* Expanded value */ - - if (!Lst_IsEmpty(cgn->order_pred) || !Lst_IsEmpty(cgn->order_succ)) - /* It is all too hard to process the result of .ORDER */ - return; - - if (cgn->type & OP_WAIT) - /* Ignore these (& OP_PHONY ?) */ - return; - - /* - * First do variable expansion -- this takes precedence over - * wildcard expansion. If the result contains wildcards, they'll be gotten - * to later since the resulting words are tacked on to the end of - * the children list. - */ - if (strchr(cgn->name, '$') == NULL) { - SuffExpandWildcards(cln, pgn); - return; - } - - if (DEBUG(SUFF)) { - fprintf(debug_file, "Expanding \"%s\"...", cgn->name); - } - cp = Var_Subst(NULL, cgn->name, pgn, TRUE); - - if (cp != NULL) { - Lst members = Lst_Init(FALSE); - - if (cgn->type & OP_ARCHV) { - /* - * Node was an archive(member) target, so we want to call - * on the Arch module to find the nodes for us, expanding - * variables in the parent's context. - */ - char *sacrifice = cp; - - (void)Arch_ParseArchive(&sacrifice, members, pgn); - } else { - /* - * Break the result into a vector of strings whose nodes - * we can find, then add those nodes to the members list. - * Unfortunately, we can't use brk_string b/c it - * doesn't understand about variable specifications with - * spaces in them... - */ - char *start; - char *initcp = cp; /* For freeing... */ - - for (start = cp; *start == ' ' || *start == '\t'; start++) - continue; - for (cp = start; *cp != '\0'; cp++) { - if (*cp == ' ' || *cp == '\t') { - /* - * White-space -- terminate element, find the node, - * add it, skip any further spaces. - */ - *cp++ = '\0'; - gn = Targ_FindNode(start, TARG_CREATE); - (void)Lst_AtEnd(members, gn); - while (*cp == ' ' || *cp == '\t') { - cp++; - } - /* - * Adjust cp for increment at start of loop, but - * set start to first non-space. - */ - start = cp--; - } else if (*cp == '$') { - /* - * Start of a variable spec -- contact variable module - * to find the end so we can skip over it. - */ - char *junk; - int len; - void *freeIt; - - junk = Var_Parse(cp, pgn, TRUE, &len, &freeIt); - if (junk != var_Error) { - cp += len - 1; - } - - if (freeIt) - free(freeIt); - } else if (*cp == '\\' && *cp != '\0') { - /* - * Escaped something -- skip over it - */ - cp++; - } - } - - if (cp != start) { - /* - * Stuff left over -- add it to the list too - */ - gn = Targ_FindNode(start, TARG_CREATE); - (void)Lst_AtEnd(members, gn); - } - /* - * Point cp back at the beginning again so the variable value - * can be freed. - */ - cp = initcp; - } - - /* - * Add all elements of the members list to the parent node. - */ - while(!Lst_IsEmpty(members)) { - gn = (GNode *)Lst_DeQueue(members); - - if (DEBUG(SUFF)) { - fprintf(debug_file, "%s...", gn->name); - } - /* Add gn to the parents child list before the original child */ - (void)Lst_InsertBefore(pgn->children, cln, gn); - (void)Lst_AtEnd(gn->parents, pgn); - pgn->unmade++; - /* Expand wildcards on new node */ - SuffExpandWildcards(Lst_Prev(cln), pgn); - } - Lst_Destroy(members, NULL); - - /* - * Free the result - */ - free(cp); - } - if (DEBUG(SUFF)) { - fprintf(debug_file, "\n"); - } - - /* - * Now the source is expanded, remove it from the list of children to - * keep it from being processed. - */ - pgn->unmade--; - Lst_Remove(pgn->children, cln); - Lst_Remove(cgn->parents, Lst_Member(cgn->parents, pgn)); -} - -static void -SuffExpandWildcards(LstNode cln, GNode *pgn) -{ - GNode *cgn = (GNode *)Lst_Datum(cln); - GNode *gn; /* New source 8) */ - char *cp; /* Expanded value */ - Lst explist; /* List of expansions */ - - if (!Dir_HasWildcards(cgn->name)) - return; - - /* - * Expand the word along the chosen path - */ - explist = Lst_Init(FALSE); - Dir_Expand(cgn->name, Suff_FindPath(cgn), explist); - - while (!Lst_IsEmpty(explist)) { - /* - * Fetch next expansion off the list and find its GNode - */ - cp = (char *)Lst_DeQueue(explist); - - if (DEBUG(SUFF)) { - fprintf(debug_file, "%s...", cp); - } - gn = Targ_FindNode(cp, TARG_CREATE); - - /* Add gn to the parents child list before the original child */ - (void)Lst_InsertBefore(pgn->children, cln, gn); - (void)Lst_AtEnd(gn->parents, pgn); - pgn->unmade++; - } - - /* - * Nuke what's left of the list - */ - Lst_Destroy(explist, NULL); - - if (DEBUG(SUFF)) { - fprintf(debug_file, "\n"); - } - - /* - * Now the source is expanded, remove it from the list of children to - * keep it from being processed. - */ - pgn->unmade--; - Lst_Remove(pgn->children, cln); - Lst_Remove(cgn->parents, Lst_Member(cgn->parents, pgn)); -} - -/*- - *----------------------------------------------------------------------- - * Suff_FindPath -- - * Find a path along which to expand the node. - * - * If the word has a known suffix, use that path. - * If it has no known suffix, use the default system search path. - * - * Input: - * gn Node being examined - * - * Results: - * The appropriate path to search for the GNode. - * - * Side Effects: - * XXX: We could set the suffix here so that we don't have to scan - * again. - * - *----------------------------------------------------------------------- - */ -Lst -Suff_FindPath(GNode* gn) -{ - Suff *suff = gn->suffix; - - if (suff == NULL) { - SuffixCmpData sd; /* Search string data */ - LstNode ln; - sd.len = strlen(gn->name); - sd.ename = gn->name + sd.len; - ln = Lst_Find(sufflist, &sd, SuffSuffIsSuffixP); - - if (DEBUG(SUFF)) { - fprintf(debug_file, "Wildcard expanding \"%s\"...", gn->name); - } - if (ln != NULL) - suff = (Suff *)Lst_Datum(ln); - /* XXX: Here we can save the suffix so we don't have to do this again */ - } - - if (suff != NULL) { - if (DEBUG(SUFF)) { - fprintf(debug_file, "suffix is \"%s\"...", suff->name); - } - return suff->searchPath; - } else { - /* - * Use default search path - */ - return dirSearchPath; - } -} - -/*- - *----------------------------------------------------------------------- - * SuffApplyTransform -- - * Apply a transformation rule, given the source and target nodes - * and suffixes. - * - * Input: - * tGn Target node - * sGn Source node - * t Target suffix - * s Source suffix - * - * Results: - * TRUE if successful, FALSE if not. - * - * Side Effects: - * The source and target are linked and the commands from the - * transformation are added to the target node's commands list. - * All attributes but OP_DEPMASK and OP_TRANSFORM are applied - * to the target. The target also inherits all the sources for - * the transformation rule. - * - *----------------------------------------------------------------------- - */ -static Boolean -SuffApplyTransform(GNode *tGn, GNode *sGn, Suff *t, Suff *s) -{ - LstNode ln, nln; /* General node */ - char *tname; /* Name of transformation rule */ - GNode *gn; /* Node for same */ - - /* - * Form the proper links between the target and source. - */ - (void)Lst_AtEnd(tGn->children, sGn); - (void)Lst_AtEnd(sGn->parents, tGn); - tGn->unmade += 1; - - /* - * Locate the transformation rule itself - */ - tname = str_concat(s->name, t->name, 0); - ln = Lst_Find(transforms, tname, SuffGNHasNameP); - free(tname); - - if (ln == NULL) { - /* - * Not really such a transformation rule (can happen when we're - * called to link an OP_MEMBER and OP_ARCHV node), so return - * FALSE. - */ - return(FALSE); - } - - gn = (GNode *)Lst_Datum(ln); - - if (DEBUG(SUFF)) { - fprintf(debug_file, "\tapplying %s -> %s to \"%s\"\n", s->name, t->name, tGn->name); - } - - /* - * Record last child for expansion purposes - */ - ln = Lst_Last(tGn->children); - - /* - * Pass the buck to Make_HandleUse to apply the rule - */ - (void)Make_HandleUse(gn, tGn); - - /* - * Deal with wildcards and variables in any acquired sources - */ - for (ln = Lst_Succ(ln); ln != NULL; ln = nln) { - nln = Lst_Succ(ln); - SuffExpandChildren(ln, tGn); - } - - /* - * Keep track of another parent to which this beast is transformed so - * the .IMPSRC variable can be set correctly for the parent. - */ - (void)Lst_AtEnd(sGn->iParents, tGn); - - return(TRUE); -} - - -/*- - *----------------------------------------------------------------------- - * SuffFindArchiveDeps -- - * Locate dependencies for an OP_ARCHV node. - * - * Input: - * gn Node for which to locate dependencies - * - * Results: - * None - * - * Side Effects: - * Same as Suff_FindDeps - * - *----------------------------------------------------------------------- - */ -static void -SuffFindArchiveDeps(GNode *gn, Lst slst) -{ - char *eoarch; /* End of archive portion */ - char *eoname; /* End of member portion */ - GNode *mem; /* Node for member */ - static const char *copy[] = { - /* Variables to be copied from the member node */ - TARGET, /* Must be first */ - PREFIX, /* Must be second */ - }; - int i; /* Index into copy and vals */ - Suff *ms; /* Suffix descriptor for member */ - char *name; /* Start of member's name */ - - /* - * The node is an archive(member) pair. so we must find a - * suffix for both of them. - */ - eoarch = strchr(gn->name, '('); - eoname = strchr(eoarch, ')'); - - *eoname = '\0'; /* Nuke parentheses during suffix search */ - *eoarch = '\0'; /* So a suffix can be found */ - - name = eoarch + 1; - - /* - * To simplify things, call Suff_FindDeps recursively on the member now, - * so we can simply compare the member's .PREFIX and .TARGET variables - * to locate its suffix. This allows us to figure out the suffix to - * use for the archive without having to do a quadratic search over the - * suffix list, backtracking for each one... - */ - mem = Targ_FindNode(name, TARG_CREATE); - SuffFindDeps(mem, slst); - - /* - * Create the link between the two nodes right off - */ - (void)Lst_AtEnd(gn->children, mem); - (void)Lst_AtEnd(mem->parents, gn); - gn->unmade += 1; - - /* - * Copy in the variables from the member node to this one. - */ - for (i = (sizeof(copy)/sizeof(copy[0]))-1; i >= 0; i--) { - char *p1; - Var_Set(copy[i], Var_Value(copy[i], mem, &p1), gn, 0); - if (p1) - free(p1); - - } - - ms = mem->suffix; - if (ms == NULL) { - /* - * Didn't know what it was -- use .NULL suffix if not in make mode - */ - if (DEBUG(SUFF)) { - fprintf(debug_file, "using null suffix\n"); - } - ms = suffNull; - } - - - /* - * Set the other two local variables required for this target. - */ - Var_Set(MEMBER, name, gn, 0); - Var_Set(ARCHIVE, gn->name, gn, 0); - - if (ms != NULL) { - /* - * Member has a known suffix, so look for a transformation rule from - * it to a possible suffix of the archive. Rather than searching - * through the entire list, we just look at suffixes to which the - * member's suffix may be transformed... - */ - LstNode ln; - SuffixCmpData sd; /* Search string data */ - - /* - * Use first matching suffix... - */ - sd.len = eoarch - gn->name; - sd.ename = eoarch; - ln = Lst_Find(ms->parents, &sd, SuffSuffIsSuffixP); - - if (ln != NULL) { - /* - * Got one -- apply it - */ - if (!SuffApplyTransform(gn, mem, (Suff *)Lst_Datum(ln), ms) && - DEBUG(SUFF)) - { - fprintf(debug_file, "\tNo transformation from %s -> %s\n", - ms->name, ((Suff *)Lst_Datum(ln))->name); - } - } - } - - /* - * Replace the opening and closing parens now we've no need of the separate - * pieces. - */ - *eoarch = '('; *eoname = ')'; - - /* - * Pretend gn appeared to the left of a dependency operator so - * the user needn't provide a transformation from the member to the - * archive. - */ - if (OP_NOP(gn->type)) { - gn->type |= OP_DEPENDS; - } - - /* - * Flag the member as such so we remember to look in the archive for - * its modification time. - */ - mem->type |= OP_MEMBER; -} - -/*- - *----------------------------------------------------------------------- - * SuffFindNormalDeps -- - * Locate implicit dependencies for regular targets. - * - * Input: - * gn Node for which to find sources - * - * Results: - * None. - * - * Side Effects: - * Same as Suff_FindDeps... - * - *----------------------------------------------------------------------- - */ -static void -SuffFindNormalDeps(GNode *gn, Lst slst) -{ - char *eoname; /* End of name */ - char *sopref; /* Start of prefix */ - LstNode ln, nln; /* Next suffix node to check */ - Lst srcs; /* List of sources at which to look */ - Lst targs; /* List of targets to which things can be - * transformed. They all have the same file, - * but different suff and pref fields */ - Src *bottom; /* Start of found transformation path */ - Src *src; /* General Src pointer */ - char *pref; /* Prefix to use */ - Src *targ; /* General Src target pointer */ - SuffixCmpData sd; /* Search string data */ - - - sd.len = strlen(gn->name); - sd.ename = eoname = gn->name + sd.len; - - sopref = gn->name; - - /* - * Begin at the beginning... - */ - ln = Lst_First(sufflist); - srcs = Lst_Init(FALSE); - targs = Lst_Init(FALSE); - - /* - * We're caught in a catch-22 here. On the one hand, we want to use any - * transformation implied by the target's sources, but we can't examine - * the sources until we've expanded any variables/wildcards they may hold, - * and we can't do that until we've set up the target's local variables - * and we can't do that until we know what the proper suffix for the - * target is (in case there are two suffixes one of which is a suffix of - * the other) and we can't know that until we've found its implied - * source, which we may not want to use if there's an existing source - * that implies a different transformation. - * - * In an attempt to get around this, which may not work all the time, - * but should work most of the time, we look for implied sources first, - * checking transformations to all possible suffixes of the target, - * use what we find to set the target's local variables, expand the - * children, then look for any overriding transformations they imply. - * Should we find one, we discard the one we found before. - */ - - while (ln != NULL) { - /* - * Look for next possible suffix... - */ - ln = Lst_FindFrom(sufflist, ln, &sd, SuffSuffIsSuffixP); - - if (ln != NULL) { - int prefLen; /* Length of the prefix */ - - /* - * Allocate a Src structure to which things can be transformed - */ - targ = bmake_malloc(sizeof(Src)); - targ->file = bmake_strdup(gn->name); - targ->suff = (Suff *)Lst_Datum(ln); - targ->suff->refCount++; - targ->node = gn; - targ->parent = NULL; - targ->children = 0; -#ifdef DEBUG_SRC - targ->cp = Lst_Init(FALSE); -#endif - - /* - * Allocate room for the prefix, whose end is found by subtracting - * the length of the suffix from the end of the name. - */ - prefLen = (eoname - targ->suff->nameLen) - sopref; - targ->pref = bmake_malloc(prefLen + 1); - memcpy(targ->pref, sopref, prefLen); - targ->pref[prefLen] = '\0'; - - /* - * Add nodes from which the target can be made - */ - SuffAddLevel(srcs, targ); - - /* - * Record the target so we can nuke it - */ - (void)Lst_AtEnd(targs, targ); - - /* - * Search from this suffix's successor... - */ - ln = Lst_Succ(ln); - } - } - - /* - * Handle target of unknown suffix... - */ - if (Lst_IsEmpty(targs) && suffNull != NULL) { - if (DEBUG(SUFF)) { - fprintf(debug_file, "\tNo known suffix on %s. Using .NULL suffix\n", gn->name); - } - - targ = bmake_malloc(sizeof(Src)); - targ->file = bmake_strdup(gn->name); - targ->suff = suffNull; - targ->suff->refCount++; - targ->node = gn; - targ->parent = NULL; - targ->children = 0; - targ->pref = bmake_strdup(sopref); -#ifdef DEBUG_SRC - targ->cp = Lst_Init(FALSE); -#endif - - /* - * Only use the default suffix rules if we don't have commands - * defined for this gnode; traditional make programs used to - * not define suffix rules if the gnode had children but we - * don't do this anymore. - */ - if (Lst_IsEmpty(gn->commands)) - SuffAddLevel(srcs, targ); - else { - if (DEBUG(SUFF)) - fprintf(debug_file, "not "); - } - - if (DEBUG(SUFF)) - fprintf(debug_file, "adding suffix rules\n"); - - (void)Lst_AtEnd(targs, targ); - } - - /* - * Using the list of possible sources built up from the target suffix(es), - * try and find an existing file/target that matches. - */ - bottom = SuffFindThem(srcs, slst); - - if (bottom == NULL) { - /* - * No known transformations -- use the first suffix found for setting - * the local variables. - */ - if (!Lst_IsEmpty(targs)) { - targ = (Src *)Lst_Datum(Lst_First(targs)); - } else { - targ = NULL; - } - } else { - /* - * Work up the transformation path to find the suffix of the - * target to which the transformation was made. - */ - for (targ = bottom; targ->parent != NULL; targ = targ->parent) - continue; - } - - Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0); - - pref = (targ != NULL) ? targ->pref : gn->name; - Var_Set(PREFIX, pref, gn, 0); - - /* - * Now we've got the important local variables set, expand any sources - * that still contain variables or wildcards in their names. - */ - for (ln = Lst_First(gn->children); ln != NULL; ln = nln) { - nln = Lst_Succ(ln); - SuffExpandChildren(ln, gn); - } - - if (targ == NULL) { - if (DEBUG(SUFF)) { - fprintf(debug_file, "\tNo valid suffix on %s\n", gn->name); - } - -sfnd_abort: - /* - * Deal with finding the thing on the default search path. We - * always do that, not only if the node is only a source (not - * on the lhs of a dependency operator or [XXX] it has neither - * children or commands) as the old pmake did. - */ - if ((gn->type & (OP_PHONY|OP_NOPATH)) == 0) { - free(gn->path); - gn->path = Dir_FindFile(gn->name, - (targ == NULL ? dirSearchPath : - targ->suff->searchPath)); - if (gn->path != NULL) { - char *ptr; - Var_Set(TARGET, gn->path, gn, 0); - - if (targ != NULL) { - /* - * Suffix known for the thing -- trim the suffix off - * the path to form the proper .PREFIX variable. - */ - int savep = strlen(gn->path) - targ->suff->nameLen; - char savec; - - if (gn->suffix) - gn->suffix->refCount--; - gn->suffix = targ->suff; - gn->suffix->refCount++; - - savec = gn->path[savep]; - gn->path[savep] = '\0'; - - if ((ptr = strrchr(gn->path, '/')) != NULL) - ptr++; - else - ptr = gn->path; - - Var_Set(PREFIX, ptr, gn, 0); - - gn->path[savep] = savec; - } else { - /* - * The .PREFIX gets the full path if the target has - * no known suffix. - */ - if (gn->suffix) - gn->suffix->refCount--; - gn->suffix = NULL; - - if ((ptr = strrchr(gn->path, '/')) != NULL) - ptr++; - else - ptr = gn->path; - - Var_Set(PREFIX, ptr, gn, 0); - } - } - } - - 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); - - if (src != NULL) { - /* - * Free up all the Src structures in the transformation path - * up to, but not including, the parent node. - */ - while (bottom && bottom->parent != NULL) { - if (Lst_Member(slst, bottom) == NULL) { - Lst_AtEnd(slst, bottom); - } - bottom = bottom->parent; - } - bottom = src; - } - } - - if (bottom == NULL) { - /* - * No idea from where it can come -- return now. - */ - goto sfnd_abort; - } - - /* - * We now have a list of Src structures headed by 'bottom' and linked via - * their 'parent' pointers. What we do next is create links between - * source and target nodes (which may or may not have been created) - * and set the necessary local variables in each target. The - * commands for each target are set from the commands of the - * transformation rule used to get from the src suffix to the targ - * suffix. Note that this causes the commands list of the original - * node, gn, to be replaced by the commands of the final - * transformation rule. Also, the unmade field of gn is incremented. - * Etc. - */ - if (bottom->node == NULL) { - bottom->node = Targ_FindNode(bottom->file, TARG_CREATE); - } - - for (src = bottom; src->parent != NULL; src = src->parent) { - targ = src->parent; - - if (src->node->suffix) - src->node->suffix->refCount--; - src->node->suffix = src->suff; - src->node->suffix->refCount++; - - if (targ->node == NULL) { - targ->node = Targ_FindNode(targ->file, TARG_CREATE); - } - - SuffApplyTransform(targ->node, src->node, - targ->suff, src->suff); - - if (targ->node != gn) { - /* - * Finish off the dependency-search process for any nodes - * between bottom and gn (no point in questing around the - * filesystem for their implicit source when it's already - * known). Note that the node can't have any sources that - * need expanding, since SuffFindThem will stop on an existing - * node, so all we need to do is set the standard and System V - * variables. - */ - targ->node->type |= OP_DEPS_FOUND; - - Var_Set(PREFIX, targ->pref, targ->node, 0); - - Var_Set(TARGET, targ->node->name, targ->node, 0); - } - } - - if (gn->suffix) - gn->suffix->refCount--; - gn->suffix = src->suff; - gn->suffix->refCount++; - - /* - * Nuke the transformation path and the Src structures left over in the - * two lists. - */ -sfnd_return: - if (bottom) - if (Lst_Member(slst, bottom) == NULL) - Lst_AtEnd(slst, bottom); - - while (SuffRemoveSrc(srcs) || SuffRemoveSrc(targs)) - continue; - - Lst_Concat(slst, srcs, LST_CONCLINK); - Lst_Concat(slst, targs, LST_CONCLINK); -} - - -/*- - *----------------------------------------------------------------------- - * Suff_FindDeps -- - * Find implicit sources for the target described by the graph node - * gn - * - * Results: - * Nothing. - * - * Side Effects: - * Nodes are added to the graph below the passed-in node. The nodes - * are marked to have their IMPSRC variable filled in. The - * PREFIX variable is set for the given node and all its - * implied children. - * - * Notes: - * The path found by this target is the shortest path in the - * transformation graph, which may pass through non-existent targets, - * to an existing target. The search continues on all paths from the - * root suffix until a file is found. I.e. if there's a path - * .o -> .c -> .l -> .l,v from the root and the .l,v file exists but - * the .c and .l files don't, the search will branch out in - * all directions from .o and again from all the nodes on the - * next level until the .l,v node is encountered. - * - *----------------------------------------------------------------------- - */ - -void -Suff_FindDeps(GNode *gn) -{ - - SuffFindDeps(gn, srclist); - while (SuffRemoveSrc(srclist)) - continue; -} - - -/* - * Input: - * gn node we're dealing with - * - */ -static void -SuffFindDeps(GNode *gn, Lst slst) -{ - if (gn->type & OP_DEPS_FOUND) { - /* - * If dependencies already found, no need to do it again... - */ - return; - } else { - gn->type |= OP_DEPS_FOUND; - } - /* - * Make sure we have these set, may get revised below. - */ - Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0); - Var_Set(PREFIX, gn->name, gn, 0); - if (gn->type & OP_PHONY) { - /* - * If this is a .PHONY target, we do not apply suffix rules. - */ - return; - } - if (DEBUG(SUFF)) { - fprintf(debug_file, "SuffFindDeps (%s)\n", gn->name); - } - - 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). - */ - LstNode ln; - Suff *s; - - ln = Lst_Find(sufflist, LIBSUFF, SuffSuffHasNameP); - if (gn->suffix) - gn->suffix->refCount--; - if (ln != NULL) { - gn->suffix = s = (Suff *)Lst_Datum(ln); - gn->suffix->refCount++; - Arch_FindLib(gn, s->searchPath); - } else { - gn->suffix = NULL; - Var_Set(TARGET, gn->name, gn, 0); - } - /* - * 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_Set(PREFIX, "", gn, 0); - } else { - SuffFindNormalDeps(gn, slst); - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_SetNull -- - * Define which suffix is the null suffix. - * - * Input: - * name Name of null suffix - * - * Results: - * None. - * - * Side Effects: - * 'suffNull' is altered. - * - * Notes: - * Need to handle the changing of the null suffix gracefully so the - * old transformation rules don't just go away. - * - *----------------------------------------------------------------------- - */ -void -Suff_SetNull(char *name) -{ - Suff *s; - LstNode ln; - - ln = Lst_Find(sufflist, name, SuffSuffHasNameP); - if (ln != NULL) { - s = (Suff *)Lst_Datum(ln); - if (suffNull != NULL) { - suffNull->flags &= ~SUFF_NULL; - } - s->flags |= SUFF_NULL; - /* - * XXX: Here's where the transformation mangling would take place - */ - suffNull = s; - } else { - Parse_Error(PARSE_WARNING, "Desired null suffix %s not defined.", - name); - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_Init -- - * Initialize suffixes module - * - * Results: - * None - * - * Side Effects: - * Many - *----------------------------------------------------------------------- - */ -void -Suff_Init(void) -{ - sufflist = Lst_Init(FALSE); -#ifdef CLEANUP - suffClean = Lst_Init(FALSE); -#endif - srclist = Lst_Init(FALSE); - transforms = Lst_Init(FALSE); - - sNum = 0; - /* - * Create null suffix for single-suffix rules (POSIX). The thing doesn't - * actually go on the suffix list or everyone will think that's its - * suffix. - */ - emptySuff = suffNull = bmake_malloc(sizeof(Suff)); - - suffNull->name = bmake_strdup(""); - suffNull->nameLen = 0; - suffNull->searchPath = Lst_Init(FALSE); - Dir_Concat(suffNull->searchPath, dirSearchPath); - suffNull->children = Lst_Init(FALSE); - suffNull->parents = Lst_Init(FALSE); - suffNull->ref = Lst_Init(FALSE); - suffNull->sNum = sNum++; - suffNull->flags = SUFF_NULL; - suffNull->refCount = 1; - -} - - -/*- - *---------------------------------------------------------------------- - * Suff_End -- - * Cleanup the this module - * - * Results: - * None - * - * Side Effects: - * The memory is free'd. - *---------------------------------------------------------------------- - */ - -void -Suff_End(void) -{ -#ifdef CLEANUP - Lst_Destroy(sufflist, SuffFree); - Lst_Destroy(suffClean, SuffFree); - if (suffNull) - SuffFree(suffNull); - Lst_Destroy(srclist, NULL); - Lst_Destroy(transforms, NULL); -#endif -} - - -/********************* DEBUGGING FUNCTIONS **********************/ - -static int SuffPrintName(void *s, void *dummy) -{ - fprintf(debug_file, "%s ", ((Suff *)s)->name); - return (dummy ? 0 : 0); -} - -static int -SuffPrintSuff(void *sp, void *dummy) -{ - Suff *s = (Suff *)sp; - int flags; - int flag; - - fprintf(debug_file, "# `%s' [%d] ", s->name, s->refCount); - - flags = s->flags; - if (flags) { - fputs(" (", debug_file); - while (flags) { - flag = 1 << (ffs(flags) - 1); - flags &= ~flag; - switch (flag) { - case SUFF_NULL: - fprintf(debug_file, "NULL"); - break; - case SUFF_INCLUDE: - fprintf(debug_file, "INCLUDE"); - break; - case SUFF_LIBRARY: - fprintf(debug_file, "LIBRARY"); - break; - } - fputc(flags ? '|' : ')', debug_file); - } - } - fputc('\n', debug_file); - fprintf(debug_file, "#\tTo: "); - Lst_ForEach(s->parents, SuffPrintName, NULL); - fputc('\n', debug_file); - fprintf(debug_file, "#\tFrom: "); - Lst_ForEach(s->children, SuffPrintName, NULL); - fputc('\n', debug_file); - fprintf(debug_file, "#\tSearch Path: "); - Dir_PrintPath(s->searchPath); - fputc('\n', debug_file); - return (dummy ? 0 : 0); -} - -static int -SuffPrintTrans(void *tp, void *dummy) -{ - GNode *t = (GNode *)tp; - - fprintf(debug_file, "%-16s: ", t->name); - Targ_PrintType(t->type); - fputc('\n', debug_file); - Lst_ForEach(t->commands, Targ_PrintCmd, NULL); - fputc('\n', debug_file); - return(dummy ? 0 : 0); -} - -void -Suff_PrintAll(void) -{ - fprintf(debug_file, "#*** Suffixes:\n"); - Lst_ForEach(sufflist, SuffPrintSuff, NULL); - - fprintf(debug_file, "#*** Transformations:\n"); - Lst_ForEach(transforms, SuffPrintTrans, NULL); -} diff --git a/20120831/targ.c b/20120831/targ.c deleted file mode 100644 index d26b845..0000000 --- a/20120831/targ.c +++ /dev/null @@ -1,848 +0,0 @@ -/* $NetBSD: targ.c,v 1.57 2012/06/12 19:21:51 joerg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: targ.c,v 1.57 2012/06/12 19:21:51 joerg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94"; -#else -__RCSID("$NetBSD: targ.c,v 1.57 2012/06/12 19:21:51 joerg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * targ.c -- - * Functions for maintaining the Lst allTargets. Target nodes are - * kept in two structures: a Lst, maintained by the list library, and a - * hash table, maintained by the hash library. - * - * Interface: - * Targ_Init Initialization procedure. - * - * Targ_End Cleanup the module - * - * Targ_List Return the list of all targets so far. - * - * 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 - * initialized. - * - * Targ_FindNode Find the node for a given target, creating - * and storing it if it doesn't exist and the - * flags are right (TARG_CREATE) - * - * Targ_FindList Given a list of names, find nodes for all - * of them. If a name doesn't exist and the - * TARG_NOCREATE flag was given, an error message - * is printed. Else, if a name doesn't exist, - * its node is created. - * - * Targ_Ignore Return TRUE if errors should be ignored when - * creating the given target. - * - * Targ_Silent Return TRUE if we should be silent when - * creating the given target. - * - * Targ_Precious Return TRUE if the target is precious and - * should not be removed if we are interrupted. - * - * Targ_Propagate Propagate information between related - * nodes. Should be called after the - * makefiles are parsed but before any - * action is taken. - * - * Debugging: - * Targ_PrintGraph Print out the entire graphm all variables - * and statistics for the directory cache. Should - * print something for suffixes, too, but... - */ - -#include <stdio.h> -#include <time.h> - -#include "make.h" -#include "hash.h" -#include "dir.h" - -static Lst allTargets; /* the list of all targets found so far */ -#ifdef CLEANUP -static Lst allGNs; /* List of all the GNodes */ -#endif -static Hash_Table targets; /* a hash table of same */ - -#define HTSIZE 191 /* initial size of hash table */ - -static int TargPrintOnlySrc(void *, void *); -static int TargPrintName(void *, void *); -#ifdef CLEANUP -static void TargFreeGN(void *); -#endif -static int TargPropagateCohort(void *, void *); -static int TargPropagateNode(void *, void *); - -/*- - *----------------------------------------------------------------------- - * Targ_Init -- - * Initialize this module - * - * Results: - * None - * - * Side Effects: - * The allTargets list and the targets hash table are initialized - *----------------------------------------------------------------------- - */ -void -Targ_Init(void) -{ - allTargets = Lst_Init(FALSE); - Hash_InitTable(&targets, HTSIZE); -} - -/*- - *----------------------------------------------------------------------- - * Targ_End -- - * Finalize this module - * - * Results: - * None - * - * Side Effects: - * All lists and gnodes are cleared - *----------------------------------------------------------------------- - */ -void -Targ_End(void) -{ -#ifdef CLEANUP - Lst_Destroy(allTargets, NULL); - if (allGNs) - Lst_Destroy(allGNs, TargFreeGN); - Hash_DeleteTable(&targets); -#endif -} - -/*- - *----------------------------------------------------------------------- - * Targ_List -- - * Return the list of all targets - * - * Results: - * The list of all targets. - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -Lst -Targ_List(void) -{ - return allTargets; -} - -/*- - *----------------------------------------------------------------------- - * Targ_NewGN -- - * Create and initialize a new graph node - * - * Input: - * name the name to stick in the new node - * - * Results: - * An initialized graph node with the name field filled with a copy - * of the passed name - * - * Side Effects: - * The gnode is added to the list of all gnodes. - *----------------------------------------------------------------------- - */ -GNode * -Targ_NewGN(const char *name) -{ - GNode *gn; - - gn = bmake_malloc(sizeof(GNode)); - gn->name = bmake_strdup(name); - gn->uname = NULL; - gn->path = NULL; - if (name[0] == '-' && name[1] == 'l') { - gn->type = OP_LIB; - } else { - gn->type = 0; - } - gn->unmade = 0; - gn->unmade_cohorts = 0; - gn->cohort_num[0] = 0; - gn->centurion = NULL; - gn->made = UNMADE; - gn->flags = 0; - gn->checked = 0; - gn->mtime = 0; - gn->cmgn = NULL; - gn->iParents = Lst_Init(FALSE); - gn->cohorts = Lst_Init(FALSE); - gn->parents = Lst_Init(FALSE); - gn->children = Lst_Init(FALSE); - gn->order_pred = Lst_Init(FALSE); - gn->order_succ = Lst_Init(FALSE); - Hash_InitTable(&gn->context, 0); - gn->commands = Lst_Init(FALSE); - gn->suffix = NULL; - gn->lineno = 0; - gn->fname = NULL; - -#ifdef CLEANUP - if (allGNs == NULL) - allGNs = Lst_Init(FALSE); - Lst_AtEnd(allGNs, gn); -#endif - - return (gn); -} - -#ifdef CLEANUP -/*- - *----------------------------------------------------------------------- - * TargFreeGN -- - * Destroy a GNode - * - * Results: - * None. - * - * Side Effects: - * None. - *----------------------------------------------------------------------- - */ -static void -TargFreeGN(void *gnp) -{ - GNode *gn = (GNode *)gnp; - - - free(gn->name); - if (gn->uname) - free(gn->uname); - if (gn->path) - free(gn->path); - /* gn->fname points to name allocated when file was opened, don't free */ - - Lst_Destroy(gn->iParents, NULL); - Lst_Destroy(gn->cohorts, NULL); - Lst_Destroy(gn->parents, NULL); - Lst_Destroy(gn->children, NULL); - Lst_Destroy(gn->order_succ, NULL); - Lst_Destroy(gn->order_pred, NULL); - Hash_DeleteTable(&gn->context); - Lst_Destroy(gn->commands, NULL); - free(gn); -} -#endif - - -/*- - *----------------------------------------------------------------------- - * Targ_FindNode -- - * Find a node in the list using the given name for matching - * - * Input: - * name the name to find - * flags flags governing events when target not - * found - * - * Results: - * The node in the list if it was. If it wasn't, return NULL of - * flags was TARG_NOCREATE or the newly created and initialized node - * if it was TARG_CREATE - * - * Side Effects: - * Sometimes a node is created and added to the list - *----------------------------------------------------------------------- - */ -GNode * -Targ_FindNode(const char *name, int flags) -{ - GNode *gn; /* node in that element */ - Hash_Entry *he = NULL; /* New or used hash entry for node */ - Boolean isNew; /* Set TRUE if Hash_CreateEntry had to create */ - /* an entry for the node */ - - if (!(flags & (TARG_CREATE | TARG_NOHASH))) { - he = Hash_FindEntry(&targets, name); - if (he == NULL) - return NULL; - return (GNode *)Hash_GetValue(he); - } - - if (!(flags & TARG_NOHASH)) { - he = Hash_CreateEntry(&targets, name, &isNew); - if (!isNew) - return (GNode *)Hash_GetValue(he); - } - - gn = Targ_NewGN(name); - if (!(flags & TARG_NOHASH)) - Hash_SetValue(he, gn); - Var_Append(".ALLTARGETS", name, VAR_GLOBAL); - (void)Lst_AtEnd(allTargets, gn); - if (doing_depend) - gn->flags |= FROM_DEPEND; - return gn; -} - -/*- - *----------------------------------------------------------------------- - * Targ_FindList -- - * Make a complete list of GNodes from the given list of names - * - * Input: - * name list of names to find - * flags flags used if no node is found for a given name - * - * Results: - * A complete list of graph nodes corresponding to all instances of all - * the names in names. - * - * Side Effects: - * If flags is TARG_CREATE, nodes will be created for all names in - * names which do not yet have graph nodes. If flags is TARG_NOCREATE, - * an error message will be printed for each name which can't be found. - * ----------------------------------------------------------------------- - */ -Lst -Targ_FindList(Lst names, int flags) -{ - Lst nodes; /* result list */ - LstNode ln; /* name list element */ - GNode *gn; /* node in tLn */ - char *name; - - nodes = Lst_Init(FALSE); - - if (Lst_Open(names) == FAILURE) { - return (nodes); - } - while ((ln = Lst_Next(names)) != NULL) { - name = (char *)Lst_Datum(ln); - gn = Targ_FindNode(name, flags); - if (gn != NULL) { - /* - * Note: Lst_AtEnd must come before the Lst_Concat so the nodes - * are added to the list in the order in which they were - * encountered in the makefile. - */ - (void)Lst_AtEnd(nodes, gn); - } else if (flags == TARG_NOCREATE) { - Error("\"%s\" -- target unknown.", name); - } - } - Lst_Close(names); - return (nodes); -} - -/*- - *----------------------------------------------------------------------- - * Targ_Ignore -- - * Return true if should ignore errors when creating gn - * - * Input: - * gn node to check for - * - * Results: - * TRUE if should ignore errors - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -Boolean -Targ_Ignore(GNode *gn) -{ - if (ignoreErrors || gn->type & OP_IGNORE) { - return (TRUE); - } else { - return (FALSE); - } -} - -/*- - *----------------------------------------------------------------------- - * Targ_Silent -- - * Return true if be silent when creating gn - * - * Input: - * gn node to check for - * - * Results: - * TRUE if should be silent - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -Boolean -Targ_Silent(GNode *gn) -{ - if (beSilent || gn->type & OP_SILENT) { - return (TRUE); - } else { - return (FALSE); - } -} - -/*- - *----------------------------------------------------------------------- - * Targ_Precious -- - * See if the given target is precious - * - * Input: - * gn the node to check - * - * Results: - * TRUE if it is precious. FALSE otherwise - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -Boolean -Targ_Precious(GNode *gn) -{ - if (allPrecious || (gn->type & (OP_PRECIOUS|OP_DOUBLEDEP))) { - return (TRUE); - } else { - return (FALSE); - } -} - -/******************* DEBUG INFO PRINTING ****************/ - -static GNode *mainTarg; /* the main target, as set by Targ_SetMain */ -/*- - *----------------------------------------------------------------------- - * Targ_SetMain -- - * Set our idea of the main target we'll be creating. Used for - * debugging output. - * - * Input: - * gn The main target we'll create - * - * Results: - * None. - * - * Side Effects: - * "mainTarg" is set to the main target's node. - *----------------------------------------------------------------------- - */ -void -Targ_SetMain(GNode *gn) -{ - mainTarg = gn; -} - -static int -TargPrintName(void *gnp, void *pflags MAKE_ATTR_UNUSED) -{ - GNode *gn = (GNode *)gnp; - - fprintf(debug_file, "%s%s ", gn->name, gn->cohort_num); - - return 0; -} - - -int -Targ_PrintCmd(void *cmd, void *dummy) -{ - fprintf(debug_file, "\t%s\n", (char *)cmd); - return (dummy ? 0 : 0); -} - -/*- - *----------------------------------------------------------------------- - * Targ_FmtTime -- - * Format a modification time in some reasonable way and return it. - * - * Results: - * The time reformatted. - * - * Side Effects: - * The time is placed in a static area, so it is overwritten - * with each call. - * - *----------------------------------------------------------------------- - */ -char * -Targ_FmtTime(time_t tm) -{ - struct tm *parts; - static char buf[128]; - - parts = localtime(&tm); - (void)strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts); - return(buf); -} - -/*- - *----------------------------------------------------------------------- - * Targ_PrintType -- - * Print out a type field giving only those attributes the user can - * set. - * - * Results: - * - * Side Effects: - * - *----------------------------------------------------------------------- - */ -void -Targ_PrintType(int type) -{ - int tbit; - -#define PRINTBIT(attr) case CONCAT(OP_,attr): fprintf(debug_file, "." #attr " "); break -#define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG))fprintf(debug_file, "." #attr " "); break - - type &= ~OP_OPMASK; - - while (type) { - tbit = 1 << (ffs(type) - 1); - type &= ~tbit; - - switch(tbit) { - PRINTBIT(OPTIONAL); - PRINTBIT(USE); - PRINTBIT(EXEC); - PRINTBIT(IGNORE); - PRINTBIT(PRECIOUS); - PRINTBIT(SILENT); - PRINTBIT(MAKE); - PRINTBIT(JOIN); - PRINTBIT(INVISIBLE); - PRINTBIT(NOTMAIN); - PRINTDBIT(LIB); - /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */ - case OP_MEMBER: if (DEBUG(TARG))fprintf(debug_file, ".MEMBER "); break; - PRINTDBIT(ARCHV); - PRINTDBIT(MADE); - PRINTDBIT(PHONY); - } - } -} - -static const char * -made_name(enum enum_made made) -{ - switch (made) { - case UNMADE: return "unmade"; - case DEFERRED: return "deferred"; - case REQUESTED: return "requested"; - case BEINGMADE: return "being made"; - case MADE: return "made"; - case UPTODATE: return "up-to-date"; - case ERROR: return "error when made"; - case ABORTED: return "aborted"; - default: return "unknown enum_made value"; - } -} - -/*- - *----------------------------------------------------------------------- - * TargPrintNode -- - * print the contents of a node - *----------------------------------------------------------------------- - */ -int -Targ_PrintNode(void *gnp, void *passp) -{ - GNode *gn = (GNode *)gnp; - int pass = passp ? *(int *)passp : 0; - - fprintf(debug_file, "# %s%s, flags %x, type %x, made %d\n", - gn->name, gn->cohort_num, gn->flags, gn->type, gn->made); - if (gn->flags == 0) - return 0; - - if (!OP_NOP(gn->type)) { - fprintf(debug_file, "#\n"); - if (gn == mainTarg) { - fprintf(debug_file, "# *** MAIN TARGET ***\n"); - } - if (pass >= 2) { - if (gn->unmade) { - fprintf(debug_file, "# %d unmade children\n", gn->unmade); - } else { - fprintf(debug_file, "# No unmade children\n"); - } - if (! (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC))) { - if (gn->mtime != 0) { - fprintf(debug_file, "# last modified %s: %s\n", - Targ_FmtTime(gn->mtime), - made_name(gn->made)); - } else if (gn->made != UNMADE) { - fprintf(debug_file, "# non-existent (maybe): %s\n", - made_name(gn->made)); - } else { - fprintf(debug_file, "# unmade\n"); - } - } - if (!Lst_IsEmpty (gn->iParents)) { - fprintf(debug_file, "# implicit parents: "); - Lst_ForEach(gn->iParents, TargPrintName, NULL); - fprintf(debug_file, "\n"); - } - } else { - if (gn->unmade) - fprintf(debug_file, "# %d unmade children\n", gn->unmade); - } - if (!Lst_IsEmpty (gn->parents)) { - fprintf(debug_file, "# parents: "); - Lst_ForEach(gn->parents, TargPrintName, NULL); - fprintf(debug_file, "\n"); - } - if (!Lst_IsEmpty (gn->order_pred)) { - fprintf(debug_file, "# order_pred: "); - Lst_ForEach(gn->order_pred, TargPrintName, NULL); - fprintf(debug_file, "\n"); - } - if (!Lst_IsEmpty (gn->order_succ)) { - fprintf(debug_file, "# order_succ: "); - Lst_ForEach(gn->order_succ, TargPrintName, NULL); - fprintf(debug_file, "\n"); - } - - fprintf(debug_file, "%-16s", gn->name); - switch (gn->type & OP_OPMASK) { - case OP_DEPENDS: - fprintf(debug_file, ": "); break; - case OP_FORCE: - fprintf(debug_file, "! "); break; - case OP_DOUBLEDEP: - fprintf(debug_file, ":: "); break; - } - Targ_PrintType(gn->type); - Lst_ForEach(gn->children, TargPrintName, NULL); - fprintf(debug_file, "\n"); - Lst_ForEach(gn->commands, Targ_PrintCmd, NULL); - fprintf(debug_file, "\n\n"); - if (gn->type & OP_DOUBLEDEP) { - Lst_ForEach(gn->cohorts, Targ_PrintNode, &pass); - } - } - return (0); -} - -/*- - *----------------------------------------------------------------------- - * TargPrintOnlySrc -- - * Print only those targets that are just a source. - * - * Results: - * 0. - * - * Side Effects: - * The name of each file is printed preceded by #\t - * - *----------------------------------------------------------------------- - */ -static int -TargPrintOnlySrc(void *gnp, void *dummy MAKE_ATTR_UNUSED) -{ - GNode *gn = (GNode *)gnp; - if (!OP_NOP(gn->type)) - return 0; - - fprintf(debug_file, "#\t%s [%s] ", - gn->name, gn->path ? gn->path : gn->name); - Targ_PrintType(gn->type); - fprintf(debug_file, "\n"); - - return 0; -} - -/*- - *----------------------------------------------------------------------- - * Targ_PrintGraph -- - * print the entire graph. heh heh - * - * Input: - * pass Which pass this is. 1 => no processing - * 2 => processing done - * - * Results: - * none - * - * Side Effects: - * lots o' output - *----------------------------------------------------------------------- - */ -void -Targ_PrintGraph(int pass) -{ - fprintf(debug_file, "#*** Input graph:\n"); - Lst_ForEach(allTargets, Targ_PrintNode, &pass); - fprintf(debug_file, "\n\n"); - fprintf(debug_file, "#\n# Files that are only sources:\n"); - Lst_ForEach(allTargets, TargPrintOnlySrc, NULL); - fprintf(debug_file, "#*** Global Variables:\n"); - Var_Dump(VAR_GLOBAL); - fprintf(debug_file, "#*** Command-line Variables:\n"); - Var_Dump(VAR_CMD); - fprintf(debug_file, "\n"); - Dir_PrintDirectories(); - fprintf(debug_file, "\n"); - Suff_PrintAll(); -} - -/*- - *----------------------------------------------------------------------- - * TargPropagateNode -- - * Propagate information from a single node to related nodes if - * appropriate. - * - * Input: - * gnp The node that we are processing. - * - * Results: - * Always returns 0, for the benefit of Lst_ForEach(). - * - * Side Effects: - * Information is propagated from this node to cohort or child - * nodes. - * - * If the node was defined with "::", then TargPropagateCohort() - * will be called for each cohort node. - * - * If the node has recursive predecessors, then - * TargPropagateRecpred() will be called for each recursive - * predecessor. - *----------------------------------------------------------------------- - */ -static int -TargPropagateNode(void *gnp, void *junk MAKE_ATTR_UNUSED) -{ - GNode *gn = (GNode *)gnp; - - if (gn->type & OP_DOUBLEDEP) - Lst_ForEach(gn->cohorts, TargPropagateCohort, gnp); - return (0); -} - -/*- - *----------------------------------------------------------------------- - * TargPropagateCohort -- - * Propagate some bits in the type mask from a node to - * a related cohort node. - * - * Input: - * cnp The node that we are processing. - * gnp Another node that has cnp as a cohort. - * - * Results: - * Always returns 0, for the benefit of Lst_ForEach(). - * - * Side Effects: - * cnp's type bitmask is modified to incorporate some of the - * bits from gnp's type bitmask. (XXX need a better explanation.) - *----------------------------------------------------------------------- - */ -static int -TargPropagateCohort(void *cgnp, void *pgnp) -{ - GNode *cgn = (GNode *)cgnp; - GNode *pgn = (GNode *)pgnp; - - cgn->type |= pgn->type & ~OP_OPMASK; - return (0); -} - -/*- - *----------------------------------------------------------------------- - * Targ_Propagate -- - * Propagate information between related nodes. Should be called - * after the makefiles are parsed but before any action is taken. - * - * Results: - * none - * - * Side Effects: - * Information is propagated between related nodes throughout the - * graph. - *----------------------------------------------------------------------- - */ -void -Targ_Propagate(void) -{ - Lst_ForEach(allTargets, TargPropagateNode, NULL); -} diff --git a/20120831/trace.c b/20120831/trace.c deleted file mode 100644 index 267177f..0000000 --- a/20120831/trace.c +++ /dev/null @@ -1,116 +0,0 @@ -/* $NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $ */ - -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Bill Sommerfeld - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -__RCSID("$NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $"); -#endif /* not lint */ -#endif - -/*- - * trace.c -- - * handle logging of trace events generated by various parts of make. - * - * Interface: - * Trace_Init Initialize tracing (called once during - * the lifetime of the process) - * - * Trace_End Finalize tracing (called before make exits) - * - * Trace_Log Log an event about a particular make job. - */ - -#include <sys/time.h> - -#include <stdio.h> -#include <unistd.h> - -#include "make.h" -#include "job.h" -#include "trace.h" - -static FILE *trfile; -static pid_t trpid; -char *trwd; - -static const char *evname[] = { - "BEG", - "END", - "ERR", - "JOB", - "DON", - "INT", -}; - -void -Trace_Init(const char *pathname) -{ - char *p1; - if (pathname != NULL) { - trpid = getpid(); - trwd = Var_Value(".CURDIR", VAR_GLOBAL, &p1); - - trfile = fopen(pathname, "a"); - } -} - -void -Trace_Log(TrEvent event, Job *job) -{ - struct timeval rightnow; - - if (trfile == NULL) - return; - - gettimeofday(&rightnow, NULL); - - fprintf(trfile, "%lld.%06ld %d %s %d %s", - (long long)rightnow.tv_sec, (long)rightnow.tv_usec, - jobTokensRunning, - evname[event], trpid, trwd); - if (job != NULL) { - fprintf(trfile, " %s %d %x %x", job->node->name, - job->pid, job->flags, job->node->type); - } - fputc('\n', trfile); - fflush(trfile); -} - -void -Trace_End(void) -{ - if (trfile != NULL) - fclose(trfile); -} diff --git a/20120831/trace.h b/20120831/trace.h deleted file mode 100644 index dc0fc6c..0000000 --- a/20120831/trace.h +++ /dev/null @@ -1,49 +0,0 @@ -/* $NetBSD: trace.h,v 1.3 2008/04/28 20:24:14 martin Exp $ */ - -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Bill Sommerfeld - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/*- - * trace.h -- - * Definitions pertaining to the tracing of jobs in parallel mode. - */ - -typedef enum { - MAKESTART, - MAKEEND, - MAKEERROR, - JOBSTART, - JOBEND, - MAKEINTR -} TrEvent; - -void Trace_Init(const char *); -void Trace_Log(TrEvent, Job *); -void Trace_End(void); - diff --git a/20120831/unit-tests/Makefile.in b/20120831/unit-tests/Makefile.in deleted file mode 100644 index 4e3592d..0000000 --- a/20120831/unit-tests/Makefile.in +++ /dev/null @@ -1,96 +0,0 @@ -# $Id: Makefile.in,v 1.38 2012/06/19 23:38:48 sjg Exp $ -# -# $NetBSD: Makefile,v 1.34 2012/06/19 23:25:53 sjg Exp $ -# -# Unit tests for make(1) -# The main targets are: -# -# all: run all the tests -# test: run 'all', capture output and compare to expected results -# accept: move generated output to expected results -# -# Adding a test case. -# Each feature should get its own set of tests in its own suitably -# named makefile which should be added to SUBFILES to hook it in. -# - -srcdir= @srcdir@ - -.MAIN: all - -UNIT_TESTS:= ${srcdir} - -# Simple sub-makefiles - we run them as a black box -# keep the list sorted. -SUBFILES= \ - comment \ - cond1 \ - error \ - export \ - export-all \ - doterror \ - dotwait \ - forloop \ - forsubst \ - hash \ - misc \ - moderrs \ - modmatch \ - modmisc \ - modorder \ - modts \ - modword \ - phony-end \ - posix \ - qequals \ - sysv \ - ternary \ - unexport \ - unexport-env \ - varcmd - -all: ${SUBFILES} - -flags.doterror= - -# the tests are actually done with sub-makes. -.PHONY: ${SUBFILES} -.PRECIOUS: ${SUBFILES} -${SUBFILES}: - -@${.MAKE} ${flags.$@:U-k} -f ${UNIT_TESTS}/$@ - -clean: - rm -f *.out *.fail *.core - -.-include <bsd.obj.mk> - -TEST_MAKE?= ${.MAKE} -TOOL_SED?= sed -TOOL_TR?= tr -TOOL_DIFF?= diff -DIFF_FLAGS?= @diff_u@ - -# ensure consistent results from sort(1) -LC_ALL= C -LANG= C -.export LANG LC_ALL - -# The driver. -# We always pretend .MAKE was called 'make' -# and strip ${.CURDIR}/ from the output -# and replace anything after 'stopped in' with unit-tests -# so the results can be compared. -test: - @echo "${TEST_MAKE} -f ${MAKEFILE} > ${.TARGET}.out 2>&1" - @cd ${.OBJDIR} && ${TEST_MAKE} -f ${MAKEFILE} 2>&1 | \ - ${TOOL_TR} -d '\015' | \ - ${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}:,make:,' \ - -e '/stopped/s, /.*, unit-tests,' \ - -e 's,${.CURDIR:C/\./\\\./g}/,,g' \ - -e 's,${UNIT_TESTS:C/\./\\\./g}/,,g' > ${.TARGET}.out || { \ - tail ${.TARGET}.out; mv ${.TARGET}.out ${.TARGET}.fail; exit 1; } - ${TOOL_DIFF} ${DIFF_FLAGS} ${UNIT_TESTS}/${.TARGET}.exp ${.TARGET}.out - -accept: - mv test.out ${srcdir}/test.exp - diff --git a/20120831/unit-tests/comment b/20120831/unit-tests/comment deleted file mode 100644 index 7dd7dbb..0000000 --- a/20120831/unit-tests/comment +++ /dev/null @@ -1,31 +0,0 @@ -# This is a comment -.if ${MACHINE_ARCH} == something -FOO=bar -.endif - -#\ - Multiline comment - -BAR=# defined -FOOBAR= # defined - -# This is an escaped comment \ -that keeps going until the end of this line - -# Another escaped comment \ -that \ -goes \ -on - -# This is NOT an escaped comment due to the double backslashes \\ -all: hi foo bar - @echo comment testing done - -hi: - @echo comment testing start - -foo: - @echo this is $@ - -bar: - @echo This is how a comment looks: '# comment' diff --git a/20120831/unit-tests/cond1 b/20120831/unit-tests/cond1 deleted file mode 100644 index c877c3d..0000000 --- a/20120831/unit-tests/cond1 +++ /dev/null @@ -1,109 +0,0 @@ -# $Id: cond1,v 1.1.1.3 2011/03/06 00:04:58 sjg Exp $ - -# hard code these! -TEST_UNAME_S= NetBSD -TEST_UNAME_M= sparc -TEST_MACHINE= i386 - -.if ${TEST_UNAME_S} -Ok=var, -.endif -.if ("${TEST_UNAME_S}") -Ok+=(\"var\"), -.endif -.if (${TEST_UNAME_M} != ${TEST_MACHINE}) -Ok+=(var != var), -.endif -.if ${TEST_UNAME_M} != ${TEST_MACHINE} -Ok+= var != var, -.endif -.if !((${TEST_UNAME_M} != ${TEST_MACHINE}) && defined(X)) -Ok+= !((var != var) && defined(name)), -.endif -# from bsd.obj.mk -MKOBJ?=no -.if ${MKOBJ} == "no" -o= no -Ok+= var == "quoted", -.else -.if defined(notMAKEOBJDIRPREFIX) || defined(norMAKEOBJDIR) -.if defined(notMAKEOBJDIRPREFIX) -o=${MAKEOBJDIRPREFIX}${__curdir} -.else -o= ${MAKEOBJDIR} -.endif -.endif -o= o -.endif - -# repeat the above to check we get the same result -.if ${MKOBJ} == "no" -o2= no -.else -.if defined(notMAKEOBJDIRPREFIX) || defined(norMAKEOBJDIR) -.if defined(notMAKEOBJDIRPREFIX) -o2=${MAKEOBJDIRPREFIX}${__curdir} -.else -o2= ${MAKEOBJDIR} -.endif -.endif -o2= o -.endif - -PRIMES=2 3 5 7 11 -NUMBERS=1 2 3 4 5 - -n=2 -.if ${PRIMES:M$n} == "" -X=not -.else -X= -.endif - -.if ${MACHINE_ARCH} == no-such -A=one -.else -.if ${MACHINE_ARCH} == not-this -.if ${MACHINE_ARCH} == something-else -A=unlikely -.else -A=no -.endif -.endif -A=other -# We expect an extra else warning - we're not skipping here -.else -A=this should be an error -.endif - -.if $X != "" -.if $X == not -B=one -.else -B=other -# We expect an extra else warning - we are skipping here -.else -B=this should be an error -.endif -.else -B=unknown -.endif - -.if "quoted" == quoted -C=clever -.else -C=dim -.endif - -.if defined(nosuch) && ${nosuch:Mx} != "" -# this should not happen -.info nosuch is x -.endif - -all: - @echo "$n is $X prime" - @echo "A='$A' B='$B' C='$C' o='$o,${o2}'" - @echo "Passed:${.newline} ${Ok:S/,/${.newline}/}" - @echo "${NUMBERS:@n@$n is ${("${PRIMES:M$n}" == ""):?not:} prime${.newline}@}" - @echo "${"${DoNotQuoteHere:U0}" > 0:?OK:No}" - @echo "${${NoSuchNumber:U42} > 0:?OK:No}" diff --git a/20120831/unit-tests/doterror b/20120831/unit-tests/doterror deleted file mode 100644 index 75d8920..0000000 --- a/20120831/unit-tests/doterror +++ /dev/null @@ -1,20 +0,0 @@ -# $Id: doterror,v 1.1.1.1 2010/04/08 17:43:00 sjg Exp $ - - -.BEGIN: - @echo At first, I am - -.END: - @echo not reached - -.ERROR: - @echo "$@: Looks like '${.ERROR_TARGET}' is upset." - -all: happy sad - -happy: - @echo $@ - -sad: - @echo and now: $@; exit 1 - diff --git a/20120831/unit-tests/dotwait b/20120831/unit-tests/dotwait deleted file mode 100644 index 43706af..0000000 --- a/20120831/unit-tests/dotwait +++ /dev/null @@ -1,61 +0,0 @@ -# $NetBSD: dotwait,v 1.1 2006/02/26 22:45:46 apb Exp $ - -THISMAKEFILE:= ${.PARSEDIR}/${.PARSEFILE} - -TESTS= simple recursive shared cycle -PAUSE= sleep 1 - -# Use a .for loop rather than dependencies here, to ensure -# that the tests are run one by one, with parallelism -# only within tests. -# Ignore "--- target ---" lines printed by parallel make. -all: -.for t in ${TESTS} - @${.MAKE} -f ${THISMAKEFILE} -j4 $t | grep -v "^--- " -.endfor - -# -# Within each test, the names of the sub-targets follow these -# conventions: -# * If it's expected that two or more targets may be made in parallel, -# then the target names will differ only in an alphabetic component -# such as ".a" or ".b". -# * If it's expected that two or more targets should be made in sequence -# then the target names will differ in numeric components, such that -# lexical ordering of the target names matches the expected order -# in which the targets should be made. -# -# Targets may echo ${PARALLEL_TARG} to print a modified version -# of their own name, in which alphabetic components like ".a" or ".b" -# are converted to ".*". Two targets that are expected to -# be made in parallel will thus print the same strings, so that the -# output is independent of the order in which these targets are made. -# -PARALLEL_TARG= ${.TARGET:C/\.[a-z]/.*/g:Q} -.DEFAULT: - @echo ${PARALLEL_TARG}; ${PAUSE}; echo ${PARALLEL_TARG} -_ECHOUSE: .USE - @echo ${PARALLEL_TARG}; ${PAUSE}; echo ${PARALLEL_TARG} - -# simple: no recursion, no cycles -simple: simple.1 .WAIT simple.2 - -# recursive: all children of the left hand side of the .WAIT -# must be made before any child of the right hand side. -recursive: recursive.1.99 .WAIT recursive.2.99 -recursive.1.99: recursive.1.1.a recursive.1.1.b _ECHOUSE -recursive.2.99: recursive.2.1.a recursive.2.1.b _ECHOUSE - -# shared: both shared.1.99 and shared.2.99 depend on shared.0. -# shared.0 must be made first, even though it is a child of -# the right hand side of the .WAIT. -shared: shared.1.99 .WAIT shared.2.99 -shared.1.99: shared.0 _ECHOUSE -shared.2.99: shared.2.1 shared.0 _ECHOUSE - -# cycle: the cyclic dependency must not cause infinite recursion -# leading to stack overflow and a crash. -cycle: cycle.1.99 .WAIT cycle.2.99 -cycle.2.99: cycle.2.98 _ECHOUSE -cycle.2.98: cycle.2.97 _ECHOUSE -cycle.2.97: cycle.2.99 _ECHOUSE diff --git a/20120831/unit-tests/error b/20120831/unit-tests/error deleted file mode 100644 index c0a1403..0000000 --- a/20120831/unit-tests/error +++ /dev/null @@ -1,10 +0,0 @@ -# $Id: error,v 1.1.1.2 2010/05/24 23:36:03 sjg Exp $ - -.info just FYI -.warning this could be serious -.error this is fatal - -all: - -.info.html: - @echo this should be ignored diff --git a/20120831/unit-tests/export b/20120831/unit-tests/export deleted file mode 100644 index 3e2ad95..0000000 --- a/20120831/unit-tests/export +++ /dev/null @@ -1,22 +0,0 @@ -# $Id: export,v 1.1.1.1 2007/10/08 20:30:12 sjg Exp $ - -UT_TEST=export -UT_FOO=foo${BAR} -UT_FU=fubar -UT_ZOO=hoopie -UT_NO=all -# belive it or not, we expect this one to come out with $UT_FU unexpanded. -UT_DOLLAR= This is $$UT_FU - -.export UT_FU UT_FOO -.export UT_DOLLAR -# this one will be ignored -.export .MAKE.PID - -BAR=bar is ${UT_FU} - -.MAKE.EXPORTED+= UT_ZOO UT_TEST - -all: - @env | grep '^UT_' | sort - diff --git a/20120831/unit-tests/export-all b/20120831/unit-tests/export-all deleted file mode 100644 index a243fe3..0000000 --- a/20120831/unit-tests/export-all +++ /dev/null @@ -1,23 +0,0 @@ -# $Id: export-all,v 1.1.1.2 2010/04/21 04:26:14 sjg Exp $ - -UT_OK=good -UT_F=fine - -# the old way to do :tA -M_tAbad = C,.*,cd & \&\& 'pwd',:sh -# the new -M_tA = tA - -here := ${.PARSEDIR} - -# this will cause trouble (recursing if we let it) -UT_BADDIR = ${${here}/../${here:T}:L:${M_tAbad}:T} -# this will be ok -UT_OKDIR = ${${here}/../${here:T}:L:${M_tA}:T} - -.export - -.include "export" - -UT_TEST=export-all -UT_ALL=even this gets exported diff --git a/20120831/unit-tests/forloop b/20120831/unit-tests/forloop deleted file mode 100644 index 0b50e66..0000000 --- a/20120831/unit-tests/forloop +++ /dev/null @@ -1,45 +0,0 @@ -# $Id: forloop,v 1.1.1.1 2012/06/19 23:30:49 sjg Exp $ - -all: for-loop - -LIST = one "two and three" four "five" - -.if make(for-fail) -for-fail: - -XTRA_LIST = xtra -.else - -.for x in ${LIST} -X!= echo 'x=$x' >&2; echo -.endfor - -CFL = -I/this -I"This or that" -Ithat "-DTHIS=\"this and that\"" -cfl= -.for x in ${CFL} -X!= echo 'x=$x' >&2; echo -.if empty(cfl) -cfl= $x -.else -cfl+= $x -.endif -.endfor -X!= echo 'cfl=${cfl}' >&2; echo - -.if ${cfl} != ${CFL} -.error ${.newline}'${cfl}' != ${.newline}'${CFL}' -.endif - -.for a b in ${EMPTY} -X!= echo 'a=$a b=$b' >&2; echo -.endfor -.endif - -.for a b in ${LIST} ${LIST:tu} ${XTRA_LIST} -X!= echo 'a=$a b=$b' >&2; echo -.endfor - -for-loop: - @echo We expect an error next: - @(cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} for-fail) && \ - { echo "Oops that should have failed!"; exit 1; } || echo OK diff --git a/20120831/unit-tests/forsubst b/20120831/unit-tests/forsubst deleted file mode 100644 index d3a7de1..0000000 --- a/20120831/unit-tests/forsubst +++ /dev/null @@ -1,10 +0,0 @@ -# $Id: forsubst,v 1.1.1.1 2009/10/07 18:53:35 sjg Exp $ - -all: for-subst - -here := ${.PARSEDIR} -# this should not run foul of the parser -.for file in ${.PARSEFILE} -for-subst: ${file:S;^;${here}/;g} - @echo ".for with :S;... OK" -.endfor diff --git a/20120831/unit-tests/hash b/20120831/unit-tests/hash deleted file mode 100644 index 1ed84e7..0000000 --- a/20120831/unit-tests/hash +++ /dev/null @@ -1,18 +0,0 @@ -STR1= -STR2= a -STR3= ab -STR4= abc -STR5= abcd -STR6= abcde -STR7= abcdef -STR8= abcdefghijklmnopqrstuvwxyz - -all: - @echo ${STR1:hash} - @echo ${STR2:hash} - @echo ${STR3:hash} - @echo ${STR4:hash} - @echo ${STR5:hash} - @echo ${STR6:hash} - @echo ${STR7:hash} - @echo ${STR8:hash} diff --git a/20120831/unit-tests/misc b/20120831/unit-tests/misc deleted file mode 100644 index 4ba3655..0000000 --- a/20120831/unit-tests/misc +++ /dev/null @@ -1,16 +0,0 @@ -# $Id: misc,v 1.1.1.1 2011/03/06 00:04:58 sjg Exp $ - -.if !exists(${.CURDIR}/) -.warning ${.CURDIR}/ doesn't exist ? -.endif - -.if !exists(${.CURDIR}/.) -.warning ${.CURDIR}/. doesn't exist ? -.endif - -.if !exists(${.CURDIR}/..) -.warning ${.CURDIR}/.. doesn't exist ? -.endif - -all: - @: all is well diff --git a/20120831/unit-tests/moderrs b/20120831/unit-tests/moderrs deleted file mode 100644 index b8f78ce..0000000 --- a/20120831/unit-tests/moderrs +++ /dev/null @@ -1,31 +0,0 @@ -# $Id: moderrs,v 1.2 2006/05/11 18:53:39 sjg Exp $ -# -# various modifier error tests - -VAR=TheVariable -# incase we have to change it ;-) -MOD_UNKN=Z -MOD_TERM=S,V,v -MOD_S:= ${MOD_TERM}, - -all: modunkn modunknV varterm vartermV modtermV - -modunkn: - @echo "Expect: Unknown modifier 'Z'" - @echo "VAR:Z=${VAR:Z}" - -modunknV: - @echo "Expect: Unknown modifier 'Z'" - @echo "VAR:${MOD_UNKN}=${VAR:${MOD_UNKN}}" - -varterm: - @echo "Expect: Unclosed variable specification for VAR" - @echo VAR:S,V,v,=${VAR:S,V,v, - -vartermV: - @echo "Expect: Unclosed variable specification for VAR" - @echo VAR:${MOD_TERM},=${VAR:${MOD_S} - -modtermV: - @echo "Expect: Unclosed substitution for VAR (, missing)" - -@echo "VAR:${MOD_TERM}=${VAR:${MOD_TERM}}" diff --git a/20120831/unit-tests/modmatch b/20120831/unit-tests/modmatch deleted file mode 100644 index 48a1bef..0000000 --- a/20120831/unit-tests/modmatch +++ /dev/null @@ -1,25 +0,0 @@ - -X=a b c d e - -.for x in $X -LIB${x:tu}=/tmp/lib$x.a -.endfor - -X_LIBS= ${LIBA} ${LIBD} ${LIBE} - -LIB?=a - -var = head -res = no -.if !empty(var:M${:Uhead\:tail:C/:.*//}) -res = OK -.endif - -all: - @for x in $X; do ${.MAKE} -f ${MAKEFILE} show LIB=$$x; done - @echo "Mscanner=${res}" - -show: - @echo 'LIB=${LIB} X_LIBS:M$${LIB$${LIB:tu}} is "${X_LIBS:M${LIB${LIB:tu}}}"' - @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a is "${X_LIBS:M*/lib${LIB}.a}"' - @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a:tu is "${X_LIBS:M*/lib${LIB}.a:tu}"' diff --git a/20120831/unit-tests/modmisc b/20120831/unit-tests/modmisc deleted file mode 100644 index d562e46..0000000 --- a/20120831/unit-tests/modmisc +++ /dev/null @@ -1,38 +0,0 @@ -# $Id: modmisc,v 1.1.1.5 2011/04/11 15:10:32 sjg Exp $ -# -# miscellaneous modifier tests - -# do not put any dirs in this list which exist on some -# but not all target systems - an exists() check is below. -path=:/bin:/tmp::/:.:/no/such/dir:. -# strip cwd from path. -MOD_NODOT=S/:/ /g:N.:ts: -# and decorate, note that $'s need to be doubled. Also note that -# the modifier_variable can be used with other modifiers. -MOD_NODOTX=S/:/ /g:N.:@d@'$$d'@ -# another mod - pretend it is more interesting -MOD_HOMES=S,/home/,/homes/, -MOD_OPT=@d@$${exists($$d):?$$d:$${d:S,/usr,/opt,}}@ -MOD_SEP=S,:, ,g - -all: modvar modvarloop modsysv - -modsysv: - @echo "The answer is ${libfoo.a:L:libfoo.a=42}" - -modvar: - @echo "path='${path}'" - @echo "path='${path:${MOD_NODOT}}'" - @echo "path='${path:S,home,homes,:${MOD_NODOT}}'" - @echo "path=${path:${MOD_NODOTX}:ts:}" - @echo "path=${path:${MOD_HOMES}:${MOD_NODOTX}:ts:}" - -.for d in ${path:${MOD_SEP}:N.} /usr/xbin -path_$d?= ${d:${MOD_OPT}:${MOD_HOMES}}/ -paths+= ${d:${MOD_OPT}:${MOD_HOMES}} -.endfor - -modvarloop: - @echo "path_/usr/xbin=${path_/usr/xbin}" - @echo "paths=${paths}" - @echo "PATHS=${paths:tu}" diff --git a/20120831/unit-tests/modorder b/20120831/unit-tests/modorder deleted file mode 100644 index 68b66fb..0000000 --- a/20120831/unit-tests/modorder +++ /dev/null @@ -1,22 +0,0 @@ -# $NetBSD: modorder,v 1.2 2007/10/05 15:27:46 sjg Exp $ - -LIST= one two three four five six seven eight nine ten -LISTX= ${LIST:Ox} -LISTSX:= ${LIST:Ox} -TEST_RESULT= && echo Ok || echo Failed - -# unit-tests have to produce the same results on each run -# so we cannot actually include :Ox output. -all: - @echo "LIST = ${LIST}" - @echo "LIST:O = ${LIST:O}" - # Note that 1 in every 10! trials two independently generated - # randomized orderings will be the same. The test framework doesn't - # support checking probabilistic output, so we accept that the test - # will incorrectly fail with probability 2.8E-7. - @echo "LIST:Ox = `test '${LIST:Ox}' != '${LIST:Ox}' ${TEST_RESULT}`" - @echo "LIST:O:Ox = `test '${LIST:O:Ox}' != '${LIST:O:Ox}' ${TEST_RESULT}`" - @echo "LISTX = `test '${LISTX}' != '${LISTX}' ${TEST_RESULT}`" - @echo "LISTSX = `test '${LISTSX}' = '${LISTSX}' ${TEST_RESULT}`" - @echo "BADMOD 1 = ${LIST:OX}" - @echo "BADMOD 2 = ${LIST:OxXX}" diff --git a/20120831/unit-tests/modts b/20120831/unit-tests/modts deleted file mode 100644 index 616bd89..0000000 --- a/20120831/unit-tests/modts +++ /dev/null @@ -1,43 +0,0 @@ - -LIST= one two three -LIST+= four five six - -FU_mod-ts = a / b / cool - -AAA= a a a -B.aaa= Baaa - -all: mod-ts - -# Use print or printf iff they are builtin. -# XXX note that this causes problems, when make decides -# there is no need to use a shell, so avoid where possible. -.if ${type print 2> /dev/null || echo:L:sh:Mbuiltin} != "" -PRINT= print -r -- -.elif ${type printf 2> /dev/null || echo:L:sh:Mbuiltin} != "" -PRINT= printf '%s\n' -.else -PRINT= echo -.endif - -mod-ts: - @echo 'LIST="${LIST}"' - @echo 'LIST:ts,="${LIST:ts,}"' - @echo 'LIST:ts/:tu="${LIST:ts/:tu}"' - @echo 'LIST:ts::tu="${LIST:ts::tu}"' - @echo 'LIST:ts:tu="${LIST:ts:tu}"' - @echo 'LIST:tu:ts/="${LIST:tu:ts/}"' - @echo 'LIST:ts:="${LIST:ts:}"' - @echo 'LIST:ts="${LIST:ts}"' - @echo 'LIST:ts:S/two/2/="${LIST:ts:S/two/2/}"' - @echo 'LIST:S/two/2/:ts="${LIST:S/two/2/:ts}"' - @echo 'LIST:ts/:S/two/2/="${LIST:ts/:S/two/2/}"' - @echo "Pretend the '/' in '/n' etc. below are back-slashes." - @${PRINT} 'LIST:ts/n="${LIST:ts\n}"' - @${PRINT} 'LIST:ts/t="${LIST:ts\t}"' - @${PRINT} 'LIST:ts/012:tu="${LIST:ts\012:tu}"' - @${PRINT} 'LIST:tx="${LIST:tx}"' - @${PRINT} 'LIST:ts/x:tu="${LIST:ts\x:tu}"' - @${PRINT} 'FU_$@="${FU_${@:ts}:ts}"' - @${PRINT} 'FU_$@:ts:T="${FU_${@:ts}:ts:T}" == cool?' - @${PRINT} 'B.$${AAA:ts}="${B.${AAA:ts}}" == Baaa?' diff --git a/20120831/unit-tests/modword b/20120831/unit-tests/modword deleted file mode 100644 index 39355d7..0000000 --- a/20120831/unit-tests/modword +++ /dev/null @@ -1,151 +0,0 @@ -# $Id: modword,v 1.1.1.1 2003/09/28 17:01:48 sjg Exp $ -# -# Test behaviour of new :[] modifier - -all: mod-squarebrackets mod-S-W mod-C-W mod-tW-tw - -LIST= one two three -LIST+= four five six -LONGLIST= 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 - -EMPTY= # the space should be ignored -ESCAPEDSPACE=\ # escaped space before the '#' -REALLYSPACE:=${EMPTY:C/^/ /W} -HASH= \# -AT= @ -STAR= * -ZERO= 0 -ONE= 1 -MINUSONE= -1 - -mod-squarebrackets: mod-squarebrackets-0-star-at \ - mod-squarebrackets-hash \ - mod-squarebrackets-n \ - mod-squarebrackets-start-end \ - mod-squarebrackets-nested - -mod-squarebrackets-0-star-at: - @echo 'LIST:[]="${LIST:[]}" is an error' - @echo 'LIST:[0]="${LIST:[0]}"' - @echo 'LIST:[0x0]="${LIST:[0x0]}"' - @echo 'LIST:[000]="${LIST:[000]}"' - @echo 'LIST:[*]="${LIST:[*]}"' - @echo 'LIST:[@]="${LIST:[@]}"' - @echo 'LIST:[0]:C/ /,/="${LIST:[0]:C/ /,/}"' - @echo 'LIST:[0]:C/ /,/g="${LIST:[0]:C/ /,/g}"' - @echo 'LIST:[0]:C/ /,/1g="${LIST:[0]:C/ /,/1g}"' - @echo 'LIST:[*]:C/ /,/="${LIST:[*]:C/ /,/}"' - @echo 'LIST:[*]:C/ /,/g="${LIST:[*]:C/ /,/g}"' - @echo 'LIST:[*]:C/ /,/1g="${LIST:[*]:C/ /,/1g}"' - @echo 'LIST:[@]:C/ /,/="${LIST:[@]:C/ /,/}"' - @echo 'LIST:[@]:C/ /,/g="${LIST:[@]:C/ /,/g}"' - @echo 'LIST:[@]:C/ /,/1g="${LIST:[@]:C/ /,/1g}"' - @echo 'LIST:[@]:[0]:C/ /,/="${LIST:[@]:[0]:C/ /,/}"' - @echo 'LIST:[0]:[@]:C/ /,/="${LIST:[0]:[@]:C/ /,/}"' - @echo 'LIST:[@]:[*]:C/ /,/="${LIST:[@]:[*]:C/ /,/}"' - @echo 'LIST:[*]:[@]:C/ /,/="${LIST:[*]:[@]:C/ /,/}"' - -mod-squarebrackets-hash: - @echo 'EMPTY="${EMPTY}"' - @echo 'EMPTY:[#]="${EMPTY:[#]}" == 1 ?' - @echo 'ESCAPEDSPACE="${ESCAPEDSPACE}"' - @echo 'ESCAPEDSPACE:[#]="${ESCAPEDSPACE:[#]}" == 1 ?' - @echo 'REALLYSPACE="${REALLYSPACE}"' - @echo 'REALLYSPACE:[#]="${REALLYSPACE:[#]}" == 1 ?' - @echo 'LIST:[#]="${LIST:[#]}"' - @echo 'LIST:[0]:[#]="${LIST:[0]:[#]}" == 1 ?' - @echo 'LIST:[*]:[#]="${LIST:[*]:[#]}" == 1 ?' - @echo 'LIST:[@]:[#]="${LIST:[@]:[#]}"' - @echo 'LIST:[1]:[#]="${LIST:[1]:[#]}"' - @echo 'LIST:[1..3]:[#]="${LIST:[1..3]:[#]}"' - -mod-squarebrackets-n: - @echo 'EMPTY:[1]="${EMPTY:[1]}"' - @echo 'ESCAPEDSPACE="${ESCAPEDSPACE}"' - @echo 'ESCAPEDSPACE:[1]="${ESCAPEDSPACE:[1]}"' - @echo 'REALLYSPACE="${REALLYSPACE}"' - @echo 'REALLYSPACE:[1]="${REALLYSPACE:[1]}" == "" ?' - @echo 'REALLYSPACE:[*]:[1]="${REALLYSPACE:[*]:[1]}" == " " ?' - @echo 'LIST:[1]="${LIST:[1]}"' - @echo 'LIST:[1.]="${LIST:[1.]}" is an error' - @echo 'LIST:[1].="${LIST:[1].}" is an error' - @echo 'LIST:[2]="${LIST:[2]}"' - @echo 'LIST:[6]="${LIST:[6]}"' - @echo 'LIST:[7]="${LIST:[7]}"' - @echo 'LIST:[999]="${LIST:[999]}"' - @echo 'LIST:[-]="${LIST:[-]}" is an error' - @echo 'LIST:[--]="${LIST:[--]}" is an error' - @echo 'LIST:[-1]="${LIST:[-1]}"' - @echo 'LIST:[-2]="${LIST:[-2]}"' - @echo 'LIST:[-6]="${LIST:[-6]}"' - @echo 'LIST:[-7]="${LIST:[-7]}"' - @echo 'LIST:[-999]="${LIST:[-999]}"' - @echo 'LONGLIST:[17]="${LONGLIST:[17]}"' - @echo 'LONGLIST:[0x11]="${LONGLIST:[0x11]}"' - @echo 'LONGLIST:[021]="${LONGLIST:[021]}"' - @echo 'LIST:[0]:[1]="${LIST:[0]:[1]}"' - @echo 'LIST:[*]:[1]="${LIST:[*]:[1]}"' - @echo 'LIST:[@]:[1]="${LIST:[@]:[1]}"' - @echo 'LIST:[0]:[2]="${LIST:[0]:[2]}"' - @echo 'LIST:[*]:[2]="${LIST:[*]:[2]}"' - @echo 'LIST:[@]:[2]="${LIST:[@]:[2]}"' - @echo 'LIST:[*]:C/ /,/:[2]="${LIST:[*]:C/ /,/:[2]}"' - @echo 'LIST:[*]:C/ /,/:[*]:[2]="${LIST:[*]:C/ /,/:[*]:[2]}"' - @echo 'LIST:[*]:C/ /,/:[@]:[2]="${LIST:[*]:C/ /,/:[@]:[2]}"' - -mod-squarebrackets-start-end: - @echo 'LIST:[1.]="${LIST:[1.]}" is an error' - @echo 'LIST:[1..]="${LIST:[1..]}" is an error' - @echo 'LIST:[1..1]="${LIST:[1..1]}"' - @echo 'LIST:[1..1.]="${LIST:[1..1.]}" is an error' - @echo 'LIST:[1..2]="${LIST:[1..2]}"' - @echo 'LIST:[2..1]="${LIST:[2..1]}"' - @echo 'LIST:[3..-2]="${LIST:[3..-2]}"' - @echo 'LIST:[-4..4]="${LIST:[-4..4]}"' - @echo 'LIST:[0..1]="${LIST:[0..1]}" is an error' - @echo 'LIST:[-1..0]="${LIST:[-1..0]}" is an error' - @echo 'LIST:[-1..1]="${LIST:[-1..1]}"' - @echo 'LIST:[0..0]="${LIST:[0..0]}"' - @echo 'LIST:[3..99]="${LIST:[3..99]}"' - @echo 'LIST:[-3..-99]="${LIST:[-3..-99]}"' - @echo 'LIST:[-99..-3]="${LIST:[-99..-3]}"' - -mod-squarebrackets-nested: - @echo 'HASH="${HASH}" == "#" ?' - @echo 'LIST:[$${HASH}]="${LIST:[${HASH}]}"' - @echo 'LIST:[$${ZERO}]="${LIST:[${ZERO}]}"' - @echo 'LIST:[$${ZERO}x$${ONE}]="${LIST:[${ZERO}x${ONE}]}"' - @echo 'LIST:[$${ONE}]="${LIST:[${ONE}]}"' - @echo 'LIST:[$${MINUSONE}]="${LIST:[${MINUSONE}]}"' - @echo 'LIST:[$${STAR}]="${LIST:[${STAR}]}"' - @echo 'LIST:[$${AT}]="${LIST:[${AT}]}"' - @echo 'LIST:[$${EMPTY}]="${LIST:[${EMPTY}]}" is an error' - @echo 'LIST:[$${LONGLIST:[21]:S/2//}]="${LIST:[${LONGLIST:[21]:S/2//}]}"' - @echo 'LIST:[$${LIST:[#]}]="${LIST:[${LIST:[#]}]}"' - @echo 'LIST:[$${LIST:[$${HASH}]}]="${LIST:[${LIST:[${HASH}]}]}"' - -mod-C-W: - @echo 'LIST:C/ /,/="${LIST:C/ /,/}"' - @echo 'LIST:C/ /,/W="${LIST:C/ /,/W}"' - @echo 'LIST:C/ /,/gW="${LIST:C/ /,/gW}"' - @echo 'EMPTY:C/^/,/="${EMPTY:C/^/,/}"' - @echo 'EMPTY:C/^/,/W="${EMPTY:C/^/,/W}"' - -mod-S-W: - @echo 'LIST:S/ /,/="${LIST:S/ /,/}"' - @echo 'LIST:S/ /,/W="${LIST:S/ /,/W}"' - @echo 'LIST:S/ /,/gW="${LIST:S/ /,/gW}"' - @echo 'EMPTY:S/^/,/="${EMPTY:S/^/,/}"' - @echo 'EMPTY:S/^/,/W="${EMPTY:S/^/,/W}"' - -mod-tW-tw: - @echo 'LIST:tW="${LIST:tW}"' - @echo 'LIST:tw="${LIST:tw}"' - @echo 'LIST:tW:C/ /,/="${LIST:tW:C/ /,/}"' - @echo 'LIST:tW:C/ /,/g="${LIST:tW:C/ /,/g}"' - @echo 'LIST:tW:C/ /,/1g="${LIST:tW:C/ /,/1g}"' - @echo 'LIST:tw:C/ /,/="${LIST:tw:C/ /,/}"' - @echo 'LIST:tw:C/ /,/g="${LIST:tw:C/ /,/g}"' - @echo 'LIST:tw:C/ /,/1g="${LIST:tw:C/ /,/1g}"' - @echo 'LIST:tw:tW:C/ /,/="${LIST:tw:tW:C/ /,/}"' - @echo 'LIST:tW:tw:C/ /,/="${LIST:tW:tw:C/ /,/}"' diff --git a/20120831/unit-tests/phony-end b/20120831/unit-tests/phony-end deleted file mode 100644 index d61884c..0000000 --- a/20120831/unit-tests/phony-end +++ /dev/null @@ -1,9 +0,0 @@ -# $Id: phony-end,v 1.1.1.1 2011/10/01 17:19:39 sjg Exp $ - -all ok also.ok bug phony: - @echo '${.TARGET .PREFIX .IMPSRC:L:@v@$v="${$v}"@}' - -.END: ok also.ok bug - -phony bug: .PHONY -all: phony diff --git a/20120831/unit-tests/posix b/20120831/unit-tests/posix deleted file mode 100644 index 48ed7a3..0000000 --- a/20120831/unit-tests/posix +++ /dev/null @@ -1,24 +0,0 @@ -# $Id: posix,v 1.1.1.1 2004/05/08 16:45:39 sjg Exp $ - -all: x plus subs err - -x: - @echo "Posix says we should execute the command as if run by system(3)" - @echo "Expect 'Hello,' and 'World!'" - @echo Hello,; false; echo "World!" - -plus: - @echo a command - +@echo "a command prefixed by '+' executes even with -n" - @echo another command - -subs: - @echo make -n - @${.MAKE} -f ${MAKEFILE} -n plus - @echo make -n -j1 - @${.MAKE} -f ${MAKEFILE} -n -j1 plus - -err: - @(echo Now we expect an error...; exit 1) - @echo "Oops! you shouldn't see this!" - diff --git a/20120831/unit-tests/qequals b/20120831/unit-tests/qequals deleted file mode 100644 index e23078e..0000000 --- a/20120831/unit-tests/qequals +++ /dev/null @@ -1,8 +0,0 @@ -# $Id: qequals,v 1.1.1.1 2008/03/31 00:13:05 sjg Exp $ - -M= i386 -V.i386= OK -V.$M ?= bug - -all: - @echo 'V.$M ?= ${V.$M}' diff --git a/20120831/unit-tests/sysv b/20120831/unit-tests/sysv deleted file mode 100644 index 9eedacb..0000000 --- a/20120831/unit-tests/sysv +++ /dev/null @@ -1,26 +0,0 @@ -# $Id: sysv,v 1.1.1.2 2011/06/05 04:23:49 sjg Exp $ - -FOO ?= -FOOBAR = $(FOO:=bar) - -_this := ${.PARSEDIR}/${.PARSEFILE} - -B = /b -S = / -FUN = ${B}${S}fun -SUN = the Sun - -# we expect nothing when FOO is empty -all: foo fun - -foo: - @echo FOOBAR = $(FOOBAR) -.if empty(FOO) - @FOO="foo fu" ${.MAKE} -f ${_this} foo -.endif - -fun: - @echo ${FUN:T} - @echo ${FUN:${B}${S}fun=fun} - @echo ${FUN:${B}${S}%=%} - @echo ${In:L:%=% ${SUN}} diff --git a/20120831/unit-tests/ternary b/20120831/unit-tests/ternary deleted file mode 100644 index 77f8349..0000000 --- a/20120831/unit-tests/ternary +++ /dev/null @@ -1,8 +0,0 @@ - -all: - @for x in "" A= A=42; do ${.MAKE} -f ${MAKEFILE} show $$x; done - -show: - @echo "The answer is ${A:?known:unknown}" - @echo "The answer is ${A:?$A:unknown}" - @echo "The answer is ${empty(A):?empty:$A}" diff --git a/20120831/unit-tests/test.exp b/20120831/unit-tests/test.exp deleted file mode 100644 index 932d84e..0000000 --- a/20120831/unit-tests/test.exp +++ /dev/null @@ -1,369 +0,0 @@ -comment testing start -this is foo -This is how a comment looks: # comment -comment testing done -make: "cond1" line 75: warning: extra else -make: "cond1" line 85: warning: extra else -2 is prime -A='other' B='unknown' C='clever' o='no,no' -Passed: - var - ("var") - (var != var) - var != var - !((var != var) && defined(name)) - var == quoted - -1 is not prime -2 is prime -3 is prime -4 is not prime -5 is prime - -make: warning: String comparison operator should be either == or != -make: Bad conditional expression `"0" > 0' in "0" > 0?OK:No - -OK -make: "error" line 3: just FYI -make: "error" line 4: warning: this could be serious -make: "error" line 5: this is fatal -UT_DOLLAR=This is $UT_FU -UT_FOO=foobar is fubar -UT_FU=fubar -UT_TEST=export -UT_ZOO=hoopie -UT_ALL=even this gets exported -UT_BADDIR=unit-tests -UT_DOLLAR=This is $UT_FU -UT_F=fine -UT_FOO=foobar is fubar -UT_FU=fubar -UT_NO=all -UT_OK=good -UT_OKDIR=unit-tests -UT_TEST=export-all -UT_ZOO=hoopie -At first, I am -happy -and now: sad -.ERROR: Looks like 'sad' is upset. -*** Error code 1 - -Stop. -make: stopped in unit-tests -simple.1 -simple.1 -simple.2 -simple.2 -recursive.1.1.* -recursive.1.1.* -recursive.1.1.* -recursive.1.1.* -recursive.1.99 -recursive.1.99 -recursive.2.1.* -recursive.2.1.* -recursive.2.1.* -recursive.2.1.* -recursive.2.99 -recursive.2.99 -shared.0 -shared.0 -shared.1.99 -shared.1.99 -shared.2.1 -shared.2.1 -shared.2.99 -shared.2.99 -make: Graph cycles through `cycle.2.99' -make: Graph cycles through `cycle.2.98' -make: Graph cycles through `cycle.2.97' -cycle.1.99 -cycle.1.99 -x=one -x="two and three" -x=four -x="five" -x=-I/this -x=-I"This or that" -x=-Ithat -x="-DTHIS=\"this and that\"" -cfl=-I/this -I"This or that" -Ithat "-DTHIS=\"this and that\"" -a=one b="two and three" -a=four b="five" -a=ONE b="TWO AND THREE" -a=FOUR b="FIVE" -We expect an error next: -make: "forloop" line 38: Wrong number of words (9) in .for substitution list with 2 vars -make: Fatal errors encountered -- cannot continue -make: stopped in unit-tests -OK -.for with :S;... OK -b2af338b -3360ac65 -7747f046 -9ca87054 -880fe816 -208fcbd3 -d5d376eb -de41416c -Expect: Unknown modifier 'Z' -make: Unknown modifier 'Z' -VAR:Z= -Expect: Unknown modifier 'Z' -make: Unknown modifier 'Z' -VAR:Z= -Expect: Unclosed variable specification for VAR -make: Unclosed variable specification (expecting '}') for "VAR" (value "Thevariable") modifier S -VAR:S,V,v,=Thevariable -Expect: Unclosed variable specification for VAR -make: Unclosed variable specification after complex modifier (expecting '}') for VAR -VAR:S,V,v,=Thevariable -Expect: Unclosed substitution for VAR (, missing) -make: Unclosed substitution for VAR (, missing) -VAR:S,V,v= -LIB=a X_LIBS:M${LIB${LIB:tu}} is "/tmp/liba.a" -LIB=a X_LIBS:M*/lib${LIB}.a is "/tmp/liba.a" -LIB=a X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBA.A" -LIB=b X_LIBS:M${LIB${LIB:tu}} is "" -LIB=b X_LIBS:M*/lib${LIB}.a is "" -LIB=b X_LIBS:M*/lib${LIB}.a:tu is "" -LIB=c X_LIBS:M${LIB${LIB:tu}} is "" -LIB=c X_LIBS:M*/lib${LIB}.a is "" -LIB=c X_LIBS:M*/lib${LIB}.a:tu is "" -LIB=d X_LIBS:M${LIB${LIB:tu}} is "/tmp/libd.a" -LIB=d X_LIBS:M*/lib${LIB}.a is "/tmp/libd.a" -LIB=d X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBD.A" -LIB=e X_LIBS:M${LIB${LIB:tu}} is "/tmp/libe.a" -LIB=e X_LIBS:M*/lib${LIB}.a is "/tmp/libe.a" -LIB=e X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBE.A" -Mscanner=OK -path=':/bin:/tmp::/:.:/no/such/dir:.' -path='/bin:/tmp:/:/no/such/dir' -path='/bin:/tmp:/:/no/such/dir' -path='/bin':'/tmp':'/':'/no/such/dir' -path='/bin':'/tmp':'/':'/no/such/dir' -path_/usr/xbin=/opt/xbin/ -paths=/bin /tmp / /no/such/dir /opt/xbin -PATHS=/BIN /TMP / /NO/SUCH/DIR /OPT/XBIN -The answer is 42 -LIST = one two three four five six seven eight nine ten -LIST:O = eight five four nine one seven six ten three two -LIST:Ox = Ok -LIST:O:Ox = Ok -LISTX = Ok -LISTSX = Ok -make: Bad modifier `:OX' for LIST -BADMOD 1 = } -make: Bad modifier `:OxXX' for LIST -BADMOD 2 = XX} -LIST="one two three four five six" -LIST:ts,="one,two,three,four,five,six" -LIST:ts/:tu="ONE/TWO/THREE/FOUR/FIVE/SIX" -LIST:ts::tu="ONE:TWO:THREE:FOUR:FIVE:SIX" -LIST:ts:tu="ONETWOTHREEFOURFIVESIX" -LIST:tu:ts/="ONE/TWO/THREE/FOUR/FIVE/SIX" -LIST:ts:="one:two:three:four:five:six" -LIST:ts="onetwothreefourfivesix" -LIST:ts:S/two/2/="one2threefourfivesix" -LIST:S/two/2/:ts="one2threefourfivesix" -LIST:ts/:S/two/2/="one/2/three/four/five/six" -Pretend the '/' in '/n' etc. below are back-slashes. -LIST:ts/n="one -two -three -four -five -six" -LIST:ts/t="one two three four five six" -LIST:ts/012:tu="ONE -TWO -THREE -FOUR -FIVE -SIX" -make: Bad modifier `:tx' for LIST -LIST:tx="}" -make: Bad modifier `:ts\x' for LIST -LIST:ts/x:tu="\x:tu}" -FU_mod-ts="a/b/cool" -FU_mod-ts:ts:T="cool" == cool? -B.${AAA:ts}="Baaa" == Baaa? -make: Bad modifier `:[]' for LIST -LIST:[]="" is an error -LIST:[0]="one two three four five six" -LIST:[0x0]="one two three four five six" -LIST:[000]="one two three four five six" -LIST:[*]="one two three four five six" -LIST:[@]="one two three four five six" -LIST:[0]:C/ /,/="one,two three four five six" -LIST:[0]:C/ /,/g="one,two,three,four,five,six" -LIST:[0]:C/ /,/1g="one,two,three,four,five,six" -LIST:[*]:C/ /,/="one,two three four five six" -LIST:[*]:C/ /,/g="one,two,three,four,five,six" -LIST:[*]:C/ /,/1g="one,two,three,four,five,six" -LIST:[@]:C/ /,/="one two three four five six" -LIST:[@]:C/ /,/g="one two three four five six" -LIST:[@]:C/ /,/1g="one two three four five six" -LIST:[@]:[0]:C/ /,/="one,two three four five six" -LIST:[0]:[@]:C/ /,/="one two three four five six" -LIST:[@]:[*]:C/ /,/="one,two three four five six" -LIST:[*]:[@]:C/ /,/="one two three four five six" -EMPTY="" -EMPTY:[#]="1" == 1 ? -ESCAPEDSPACE="\ " -ESCAPEDSPACE:[#]="1" == 1 ? -REALLYSPACE=" " -REALLYSPACE:[#]="1" == 1 ? -LIST:[#]="6" -LIST:[0]:[#]="1" == 1 ? -LIST:[*]:[#]="1" == 1 ? -LIST:[@]:[#]="6" -LIST:[1]:[#]="1" -LIST:[1..3]:[#]="3" -EMPTY:[1]="" -ESCAPEDSPACE="\ " -ESCAPEDSPACE:[1]="\ " -REALLYSPACE=" " -REALLYSPACE:[1]="" == "" ? -REALLYSPACE:[*]:[1]=" " == " " ? -LIST:[1]="one" -make: Bad modifier `:[1.]' for LIST -LIST:[1.]="" is an error -make: Bad modifier `:[1].' for LIST -LIST:[1].="}" is an error -LIST:[2]="two" -LIST:[6]="six" -LIST:[7]="" -LIST:[999]="" -make: Bad modifier `:[-]' for LIST -LIST:[-]="" is an error -make: Bad modifier `:[--]' for LIST -LIST:[--]="" is an error -LIST:[-1]="six" -LIST:[-2]="five" -LIST:[-6]="one" -LIST:[-7]="" -LIST:[-999]="" -LONGLIST:[17]="17" -LONGLIST:[0x11]="17" -LONGLIST:[021]="17" -LIST:[0]:[1]="one two three four five six" -LIST:[*]:[1]="one two three four five six" -LIST:[@]:[1]="one" -LIST:[0]:[2]="" -LIST:[*]:[2]="" -LIST:[@]:[2]="two" -LIST:[*]:C/ /,/:[2]="" -LIST:[*]:C/ /,/:[*]:[2]="" -LIST:[*]:C/ /,/:[@]:[2]="three" -make: Bad modifier `:[1.]' for LIST -LIST:[1.]="" is an error -make: Bad modifier `:[1..]' for LIST -LIST:[1..]="" is an error -LIST:[1..1]="one" -make: Bad modifier `:[1..1.]' for LIST -LIST:[1..1.]="" is an error -LIST:[1..2]="one two" -LIST:[2..1]="two one" -LIST:[3..-2]="three four five" -LIST:[-4..4]="three four" -make: Bad modifier `:[0..1]' for LIST -LIST:[0..1]="" is an error -make: Bad modifier `:[-1..0]' for LIST -LIST:[-1..0]="" is an error -LIST:[-1..1]="six five four three two one" -LIST:[0..0]="one two three four five six" -LIST:[3..99]="three four five six" -LIST:[-3..-99]="four three two one" -LIST:[-99..-3]="one two three four" -HASH="#" == "#" ? -LIST:[${HASH}]="6" -LIST:[${ZERO}]="one two three four five six" -LIST:[${ZERO}x${ONE}]="one" -LIST:[${ONE}]="one" -LIST:[${MINUSONE}]="six" -LIST:[${STAR}]="one two three four five six" -LIST:[${AT}]="one two three four five six" -make: Bad modifier `:[${EMPTY' for LIST -LIST:[${EMPTY}]="" is an error -LIST:[${LONGLIST:[21]:S/2//}]="one" -LIST:[${LIST:[#]}]="six" -LIST:[${LIST:[${HASH}]}]="six" -LIST:S/ /,/="one two three four five six" -LIST:S/ /,/W="one,two three four five six" -LIST:S/ /,/gW="one,two,three,four,five,six" -EMPTY:S/^/,/="," -EMPTY:S/^/,/W="," -LIST:C/ /,/="one two three four five six" -LIST:C/ /,/W="one,two three four five six" -LIST:C/ /,/gW="one,two,three,four,five,six" -EMPTY:C/^/,/="," -EMPTY:C/^/,/W="," -LIST:tW="one two three four five six" -LIST:tw="one two three four five six" -LIST:tW:C/ /,/="one,two three four five six" -LIST:tW:C/ /,/g="one,two,three,four,five,six" -LIST:tW:C/ /,/1g="one,two,three,four,five,six" -LIST:tw:C/ /,/="one two three four five six" -LIST:tw:C/ /,/g="one two three four five six" -LIST:tw:C/ /,/1g="one two three four five six" -LIST:tw:tW:C/ /,/="one,two three four five six" -LIST:tW:tw:C/ /,/="one two three four five six" -.TARGET="phony" .PREFIX="phony" .IMPSRC="" -.TARGET="all" .PREFIX="all" .IMPSRC="" -.TARGET="ok" .PREFIX="ok" .IMPSRC="" -.TARGET="also.ok" .PREFIX="also.ok" .IMPSRC="" -.TARGET="bug" .PREFIX="bug" .IMPSRC="" -Posix says we should execute the command as if run by system(3) -Expect 'Hello,' and 'World!' -Hello, -World! -a command -a command prefixed by '+' executes even with -n -another command -make -n -echo a command -echo "a command prefixed by '+' executes even with -n" -a command prefixed by '+' executes even with -n -echo another command -make -n -j1 -{ echo a command -} || exit $? -echo "a command prefixed by '+' executes even with -n" -a command prefixed by '+' executes even with -n -{ echo another command -} || exit $? -Now we expect an error... -*** Error code 1 (continuing) -`all' not remade because of errors. -V.i386 ?= OK -FOOBAR = -FOOBAR = foobar fubar -fun -fun -fun -In the Sun -The answer is unknown -The answer is unknown -The answer is empty -The answer is known -The answer is -The answer is empty -The answer is known -The answer is 42 -The answer is 42 -UT_DOLLAR=This is $UT_FU -UT_FU=fubar -UT_TEST=unexport -UT_TEST=unexport-env -default FU=<v>fu</v> FOO=<v>foo</v> VAR=<v></v> -two FU=<v>bar</v> FOO=<v>goo</v> VAR=<v></v> -three FU=<v>bar</v> FOO=<v>goo</v> VAR=<v></v> -four FU=<v>bar</v> FOO=<v>goo</v> VAR=<v>Internal</v> -five FU=<v>bar</v> FOO=<v>goo</v> VAR=<v>Internal</v> -five v=is x k=is x -six v=is y k=is y -show-v v=override k=override -*** Error code 1 (ignored) -*** Error code 1 (ignored) diff --git a/20120831/unit-tests/unexport b/20120831/unit-tests/unexport deleted file mode 100644 index fb40d0c..0000000 --- a/20120831/unit-tests/unexport +++ /dev/null @@ -1,8 +0,0 @@ -# $Id: unexport,v 1.1.1.1 2009/11/19 00:31:11 sjg Exp $ - -# pick up a bunch of exported vars -.include "export" - -.unexport UT_ZOO UT_FOO - -UT_TEST = unexport diff --git a/20120831/unit-tests/unexport-env b/20120831/unit-tests/unexport-env deleted file mode 100644 index f6a2ff9..0000000 --- a/20120831/unit-tests/unexport-env +++ /dev/null @@ -1,14 +0,0 @@ -# $Id: unexport-env,v 1.1.1.1 2009/11/19 00:31:11 sjg Exp $ - -# pick up a bunch of exported vars -.include "export" - -# an example of setting up a minimal environment. -PATH = /bin:/usr/bin:/sbin:/usr/sbin - -# now clobber the environment to just PATH and UT_TEST -UT_TEST = unexport-env - -# this removes everything -.unexport-env -.export PATH UT_TEST diff --git a/20120831/unit-tests/varcmd b/20120831/unit-tests/varcmd deleted file mode 100644 index a58e014..0000000 --- a/20120831/unit-tests/varcmd +++ /dev/null @@ -1,49 +0,0 @@ -# $Id: varcmd,v 1.3 2008/05/15 04:30:47 sjg Exp $ -# -# Test behaviour of recursive make and vars set on command line. - -FU=fu -FOO?=foo -.if !empty(.TARGETS) -TAG=${.TARGETS} -.endif -TAG?=default - -all: one - -show: - @echo "${TAG} FU=<v>${FU}</v> FOO=<v>${FOO}</v> VAR=<v>${VAR}</v>" - -one: show - @${.MAKE} -f ${MAKEFILE} FU=bar FOO=goo two - -two: show - @${.MAKE} -f ${MAKEFILE} three - -three: show - @${.MAKE} -f ${MAKEFILE} four - - -.ifmake four -VAR=Internal -.MAKEOVERRIDES+= VAR -.endif - -four: show - @${.MAKE} -f ${MAKEFILE} five - -M = x -V.y = is y -V.x = is x -V := ${V.$M} -K := ${V} - -show-v: - @echo '${TAG} v=${V} k=${K}' - -five: show show-v - @${.MAKE} -f ${MAKEFILE} M=y six - -six: show-v - @${.MAKE} -f ${MAKEFILE} V=override show-v - diff --git a/20120831/util.c b/20120831/util.c deleted file mode 100644 index a63fd33..0000000 --- a/20120831/util.c +++ /dev/null @@ -1,619 +0,0 @@ -/* $NetBSD: util.c,v 1.53 2012/06/04 22:45:05 sjg Exp $ */ - -/* - * Missing stuff from OS's - * - * $Id: util.c,v 1.32 2012/06/06 20:08:44 sjg Exp $ - */ - -#include "make.h" - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: util.c,v 1.53 2012/06/04 22:45:05 sjg Exp $"; -#else -#ifndef lint -__RCSID("$NetBSD: util.c,v 1.53 2012/06/04 22:45:05 sjg Exp $"); -#endif -#endif - -#include <errno.h> -#include <time.h> -#include <signal.h> - -#if !defined(HAVE_STRERROR) -extern int errno, sys_nerr; -extern char *sys_errlist[]; - -char * -strerror(int e) -{ - static char buf[100]; - if (e < 0 || e >= sys_nerr) { - snprintf(buf, sizeof(buf), "Unknown error %d", e); - return buf; - } - else - return sys_errlist[e]; -} -#endif - -#if !defined(HAVE_GETENV) || !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV) -extern char **environ; - -static char * -findenv(const char *name, int *offset) -{ - size_t i, len; - char *p, *q; - - len = strlen(name); - for (i = 0; (q = environ[i]); i++) { - p = strchr(q, '='); - if (p == NULL || p - q != len) - continue; - if (strncmp(name, q, len) == 0) { - *offset = i; - return q + len + 1; - } - } - *offset = i; - return NULL; -} - -char * -getenv(const char *name) -{ - int offset; - - return(findenv(name, &offset)); -} - -int -unsetenv(const char *name) -{ - char **p; - int offset; - - if (name == NULL || *name == '\0' || strchr(name, '=') != NULL) { - errno = EINVAL; - return -1; - } - - while (findenv(name, &offset)) { /* if set multiple times */ - for (p = &environ[offset];; ++p) - if (!(*p = *(p + 1))) - break; - } - return 0; -} - -int -setenv(const char *name, const char *value, int rewrite) -{ - char *c, **newenv; - const char *cc; - size_t l_value, size; - int offset; - - if (name == NULL || value == NULL) { - errno = EINVAL; - return -1; - } - - if (*value == '=') /* no `=' in value */ - ++value; - l_value = strlen(value); - - /* find if already exists */ - if ((c = findenv(name, &offset))) { - if (!rewrite) - return 0; - if (strlen(c) >= l_value) /* old larger; copy over */ - goto copy; - } else { /* create new slot */ - size = sizeof(char *) * (offset + 2); - if (savedEnv == environ) { /* just increase size */ - if ((newenv = realloc(savedEnv, size)) == NULL) - return -1; - savedEnv = newenv; - } else { /* get new space */ - /* - * We don't free here because we don't know if - * the first allocation is valid on all OS's - */ - if ((savedEnv = malloc(size)) == NULL) - return -1; - (void)memcpy(savedEnv, environ, size - sizeof(char *)); - } - environ = savedEnv; - environ[offset + 1] = NULL; - } - for (cc = name; *cc && *cc != '='; ++cc) /* no `=' in name */ - continue; - size = cc - name; - /* name + `=' + value */ - if ((environ[offset] = malloc(size + l_value + 2)) == NULL) - return -1; - c = environ[offset]; - (void)memcpy(c, name, size); - c += size; - *c++ = '='; -copy: - (void)memcpy(c, value, l_value + 1); - return 0; -} - -#ifdef TEST -int -main(int argc, char *argv[]) -{ - setenv(argv[1], argv[2], 0); - printf("%s\n", getenv(argv[1])); - unsetenv(argv[1]); - printf("%s\n", getenv(argv[1])); - return 0; -} -#endif - -#endif - - -#if defined(__hpux__) || defined(__hpux) -/* strrcpy(): - * Like strcpy, going backwards and returning the new pointer - */ -static char * -strrcpy(char *ptr, char *str) -{ - int len = strlen(str); - - while (len) - *--ptr = str[--len]; - - return (ptr); -} /* end strrcpy */ - - -char *sys_siglist[] = { - "Signal 0", - "Hangup", /* SIGHUP */ - "Interrupt", /* SIGINT */ - "Quit", /* SIGQUIT */ - "Illegal instruction", /* SIGILL */ - "Trace/BPT trap", /* SIGTRAP */ - "IOT trap", /* SIGIOT */ - "EMT trap", /* SIGEMT */ - "Floating point exception", /* SIGFPE */ - "Killed", /* SIGKILL */ - "Bus error", /* SIGBUS */ - "Segmentation fault", /* SIGSEGV */ - "Bad system call", /* SIGSYS */ - "Broken pipe", /* SIGPIPE */ - "Alarm clock", /* SIGALRM */ - "Terminated", /* SIGTERM */ - "User defined signal 1", /* SIGUSR1 */ - "User defined signal 2", /* SIGUSR2 */ - "Child exited", /* SIGCLD */ - "Power-fail restart", /* SIGPWR */ - "Virtual timer expired", /* SIGVTALRM */ - "Profiling timer expired", /* SIGPROF */ - "I/O possible", /* SIGIO */ - "Window size changes", /* SIGWINDOW */ - "Stopped (signal)", /* SIGSTOP */ - "Stopped", /* SIGTSTP */ - "Continued", /* SIGCONT */ - "Stopped (tty input)", /* SIGTTIN */ - "Stopped (tty output)", /* SIGTTOU */ - "Urgent I/O condition", /* SIGURG */ - "Remote lock lost (NFS)", /* SIGLOST */ - "Signal 31", /* reserved */ - "DIL signal" /* SIGDIL */ -}; -#endif /* __hpux__ || __hpux */ - -#if defined(__hpux__) || defined(__hpux) -#include <sys/types.h> -#include <sys/syscall.h> -#include <sys/signal.h> -#include <sys/stat.h> -#include <dirent.h> -#include <sys/time.h> -#include <unistd.h> - -int -killpg(int pid, int sig) -{ - return kill(-pid, sig); -} - -#if !defined(__hpux__) && !defined(__hpux) -void -srandom(long seed) -{ - srand48(seed); -} - -long -random(void) -{ - return lrand48(); -} -#endif - -#if !defined(__hpux__) && !defined(__hpux) -int -utimes(char *file, struct timeval tvp[2]) -{ - struct utimbuf t; - - t.actime = tvp[0].tv_sec; - t.modtime = tvp[1].tv_sec; - return(utime(file, &t)); -} -#endif - -#if !defined(BSD) && !defined(d_fileno) -# define d_fileno d_ino -#endif - -#ifndef DEV_DEV_COMPARE -# define DEV_DEV_COMPARE(a, b) ((a) == (b)) -#endif -#define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/'))) -#define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1]))) - -char * -getwd(char *pathname) -{ - DIR *dp; - struct dirent *d; - extern int errno; - - struct stat st_root, st_cur, st_next, st_dotdot; - char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2]; - char *pathptr, *nextpathptr, *cur_name_add; - - /* find the inode of root */ - if (stat("/", &st_root) == -1) { - (void)sprintf(pathname, - "getwd: Cannot stat \"/\" (%s)", strerror(errno)); - return NULL; - } - pathbuf[MAXPATHLEN - 1] = '\0'; - pathptr = &pathbuf[MAXPATHLEN - 1]; - nextpathbuf[MAXPATHLEN - 1] = '\0'; - cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1]; - - /* find the inode of the current directory */ - if (lstat(".", &st_cur) == -1) { - (void)sprintf(pathname, - "getwd: Cannot stat \".\" (%s)", strerror(errno)); - return NULL; - } - nextpathptr = strrcpy(nextpathptr, "../"); - - /* Descend to root */ - for (;;) { - - /* look if we found root yet */ - if (st_cur.st_ino == st_root.st_ino && - DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) { - (void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr); - return (pathname); - } - - /* open the parent directory */ - if (stat(nextpathptr, &st_dotdot) == -1) { - (void)sprintf(pathname, - "getwd: Cannot stat directory \"%s\" (%s)", - nextpathptr, strerror(errno)); - return NULL; - } - if ((dp = opendir(nextpathptr)) == NULL) { - (void)sprintf(pathname, - "getwd: Cannot open directory \"%s\" (%s)", - nextpathptr, strerror(errno)); - return NULL; - } - - /* look in the parent for the entry with the same inode */ - if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) { - /* Parent has same device. No need to stat every member */ - for (d = readdir(dp); d != NULL; d = readdir(dp)) - if (d->d_fileno == st_cur.st_ino) - break; - } - else { - /* - * Parent has a different device. This is a mount point so we - * need to stat every member - */ - for (d = readdir(dp); d != NULL; d = readdir(dp)) { - if (ISDOT(d->d_name) || ISDOTDOT(d->d_name)) - continue; - (void)strcpy(cur_name_add, d->d_name); - if (lstat(nextpathptr, &st_next) == -1) { - (void)sprintf(pathname, - "getwd: Cannot stat \"%s\" (%s)", - d->d_name, strerror(errno)); - (void)closedir(dp); - return NULL; - } - /* check if we found it yet */ - if (st_next.st_ino == st_cur.st_ino && - DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev)) - break; - } - } - if (d == NULL) { - (void)sprintf(pathname, - "getwd: Cannot find \".\" in \"..\""); - (void)closedir(dp); - return NULL; - } - st_cur = st_dotdot; - pathptr = strrcpy(pathptr, d->d_name); - pathptr = strrcpy(pathptr, "/"); - nextpathptr = strrcpy(nextpathptr, "../"); - (void)closedir(dp); - *cur_name_add = '\0'; - } -} /* end getwd */ - -#endif /* __hpux */ - -#if !defined(HAVE_GETCWD) -char * -getcwd(path, sz) - char *path; - int sz; -{ - return getwd(path); -} -#endif - -/* force posix signals */ -void (* -bmake_signal(int s, void (*a)(int)))(int) -{ - struct sigaction sa, osa; - - sa.sa_handler = a; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - - if (sigaction(s, &sa, &osa) == -1) - return SIG_ERR; - else - return osa.sa_handler; -} - -#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_VASPRINTF) -#include <stdarg.h> -#endif - -#if !defined(HAVE_VSNPRINTF) -#if !defined(__osf__) -#ifdef _IOSTRG -#define STRFLAG (_IOSTRG|_IOWRT) /* no _IOWRT: avoid stdio bug */ -#else -#if 0 -#define STRFLAG (_IOREAD) /* XXX: Assume svr4 stdio */ -#endif -#endif /* _IOSTRG */ -#endif /* __osf__ */ - -int -vsnprintf(char *s, size_t n, const char *fmt, va_list args) -{ -#ifdef STRFLAG - FILE fakebuf; - - fakebuf._flag = STRFLAG; - /* - * Some os's are char * _ptr, others are unsigned char *_ptr... - * We cast to void * to make everyone happy. - */ - fakebuf._ptr = (void *)s; - fakebuf._cnt = n-1; - fakebuf._file = -1; - _doprnt(fmt, args, &fakebuf); - fakebuf._cnt++; - putc('\0', &fakebuf); - if (fakebuf._cnt<0) - fakebuf._cnt = 0; - return (n-fakebuf._cnt-1); -#else -#ifndef _PATH_DEVNULL -# define _PATH_DEVNULL "/dev/null" -#endif - /* - * Rats... we don't want to clobber anything... - * do a printf to /dev/null to see how much space we need. - */ - static FILE *nullfp; - int need = 0; /* XXX what's a useful error return? */ - - if (!nullfp) - nullfp = fopen(_PATH_DEVNULL, "w"); - if (nullfp) { - need = vfprintf(nullfp, fmt, args); - if (need < n) - (void)vsprintf(s, fmt, args); - } - return need; -#endif -} -#endif - -#if !defined(HAVE_SNPRINTF) -int -snprintf(char *s, size_t n, const char *fmt, ...) -{ - va_list ap; - int rv; - - va_start(ap, fmt); - rv = vsnprintf(s, n, fmt, ap); - va_end(ap); - return rv; -} -#endif - -#if !defined(HAVE_STRFTIME) -size_t -strftime(char *buf, size_t len, const char *fmt, const struct tm *tm) -{ - static char months[][4] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; - - size_t s; - char *b = buf; - - while (*fmt) { - if (len == 0) - return buf - b; - if (*fmt != '%') { - *buf++ = *fmt++; - len--; - continue; - } - switch (*fmt++) { - case '%': - *buf++ = '%'; - len--; - if (len == 0) return buf - b; - /*FALLTHROUGH*/ - case '\0': - *buf = '%'; - s = 1; - break; - case 'k': - s = snprintf(buf, len, "%d", tm->tm_hour); - break; - case 'M': - s = snprintf(buf, len, "%02d", tm->tm_min); - break; - case 'S': - s = snprintf(buf, len, "%02d", tm->tm_sec); - break; - case 'b': - if (tm->tm_mon >= 12) - return buf - b; - s = snprintf(buf, len, "%s", months[tm->tm_mon]); - break; - case 'd': - s = snprintf(buf, len, "%02d", tm->tm_mday); - break; - case 'Y': - s = snprintf(buf, len, "%d", 1900 + tm->tm_year); - break; - default: - s = snprintf(buf, len, "Unsupported format %c", - fmt[-1]); - break; - } - buf += s; - len -= s; - } -} -#endif - -#if !defined(HAVE_KILLPG) -#if !defined(__hpux__) && !defined(__hpux) -int -killpg(int pid, int sig) -{ - return kill(-pid, sig); -} -#endif -#endif - -#if !defined(HAVE_WARNX) -static void -vwarnx(const char *fmt, va_list args) -{ - fprintf(stderr, "%s: ", progname); - if ((fmt)) { - vfprintf(stderr, fmt, args); - fprintf(stderr, ": "); - } -} -#endif - -#if !defined(HAVE_WARN) -static void -vwarn(const char *fmt, va_list args) -{ - vwarnx(fmt, args); - fprintf(stderr, "%s\n", strerror(errno)); -} -#endif - -#if !defined(HAVE_ERR) -static void -verr(int eval, const char *fmt, va_list args) -{ - vwarn(fmt, args); - exit(eval); -} -#endif - -#if !defined(HAVE_ERRX) -static void -verrx(int eval, const char *fmt, va_list args) -{ - vwarnx(fmt, args); - exit(eval); -} -#endif - -#if !defined(HAVE_ERR) -void -err(int eval, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - verr(eval, fmt, ap); - va_end(ap); -} -#endif - -#if !defined(HAVE_ERRX) -void -errx(int eval, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - verrx(eval, fmt, ap); - va_end(ap); -} -#endif - -#if !defined(HAVE_WARN) -void -warn(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vwarn(fmt, ap); - va_end(ap); -} -#endif - -#if !defined(HAVE_WARNX) -void -warnx(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vwarnx(fmt, ap); - va_end(ap); -} -#endif diff --git a/20120831/var.c b/20120831/var.c deleted file mode 100644 index e958a36..0000000 --- a/20120831/var.c +++ /dev/null @@ -1,4196 +0,0 @@ -/* $NetBSD: var.c,v 1.171 2012/06/12 19:21:51 joerg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: var.c,v 1.171 2012/06/12 19:21:51 joerg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; -#else -__RCSID("$NetBSD: var.c,v 1.171 2012/06/12 19:21:51 joerg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * var.c -- - * Variable-handling functions - * - * Interface: - * Var_Set Set the value of a variable in the given - * context. The variable is created if it doesn't - * yet exist. The value and variable name need not - * be preserved. - * - * Var_Append Append more characters to an existing variable - * in the given context. The variable needn't - * exist already -- it will be created if it doesn't. - * A space is placed between the old value and the - * new one. - * - * Var_Exists See if a variable exists. - * - * Var_Value Return the value of a variable in a context or - * NULL if the variable is undefined. - * - * Var_Subst Substitute named variable, or all variables if - * NULL in a string using - * the given context as the top-most one. If the - * third argument is non-zero, Parse_Error is - * called if any variables are undefined. - * - * Var_Parse Parse a variable expansion from a string and - * return the result and the number of characters - * consumed. - * - * Var_Delete Delete a variable in a context. - * - * Var_Init Initialize this module. - * - * Debugging: - * Var_Dump Print out all variables defined in the given - * context. - * - * XXX: There's a lot of duplication in these functions. - */ - -#include <sys/stat.h> -#ifndef NO_REGEX -#include <sys/types.h> -#include <regex.h> -#endif -#include <ctype.h> -#include <inttypes.h> -#include <stdlib.h> -#include <limits.h> -#include <time.h> - -#include "make.h" -#include "buf.h" -#include "dir.h" -#include "job.h" - -/* - * This lets us tell if we have replaced the original environ - * (which we cannot free). - */ -char **savedEnv = NULL; - -/* - * This is a harmless return value for Var_Parse that can be used by Var_Subst - * to determine if there was an error in parsing -- easier than returning - * a flag, as things outside this module don't give a hoot. - */ -char var_Error[] = ""; - -/* - * Similar to var_Error, but returned when the 'errnum' flag for Var_Parse is - * set false. Why not just use a constant? Well, gcc likes to condense - * identical string instances... - */ -static char varNoError[] = ""; - -/* - * Internally, variables are contained in four different contexts. - * 1) the environment. They may not be changed. If an environment - * variable is appended-to, the result is placed in the global - * context. - * 2) the global context. Variables set in the Makefile are located in - * the global context. It is the penultimate context searched when - * substituting. - * 3) the command-line context. All variables set on the command line - * are placed in this context. They are UNALTERABLE once placed here. - * 4) the local context. Each target has associated with it a context - * list. On this list are located the structures describing such - * local variables as $(@) and $(*) - * The four contexts are searched in the reverse order from which they are - * listed. - */ -GNode *VAR_GLOBAL; /* variables from the makefile */ -GNode *VAR_CMD; /* variables defined on the command-line */ - -#define FIND_CMD 0x1 /* look in VAR_CMD when searching */ -#define FIND_GLOBAL 0x2 /* look in VAR_GLOBAL as well */ -#define FIND_ENV 0x4 /* look in the environment also */ - -typedef struct Var { - char *name; /* the variable's name */ - Buffer val; /* its value */ - int flags; /* miscellaneous status flags */ -#define VAR_IN_USE 1 /* Variable's value currently being used. - * Used to avoid recursion */ -#define VAR_FROM_ENV 2 /* Variable comes from the environment */ -#define VAR_JUNK 4 /* Variable is a junk variable that - * should be destroyed when done with - * it. Used by Var_Parse for undefined, - * modified variables */ -#define VAR_KEEP 8 /* Variable is VAR_JUNK, but we found - * a use for it in some modifier and - * the value is therefore valid */ -#define VAR_EXPORTED 16 /* Variable is exported */ -#define VAR_REEXPORT 32 /* Indicate if var needs re-export. - * This would be true if it contains $'s - */ -#define VAR_FROM_CMD 64 /* Variable came from command line */ -} Var; - -/* - * Exporting vars is expensive so skip it if we can - */ -#define VAR_EXPORTED_NONE 0 -#define VAR_EXPORTED_YES 1 -#define VAR_EXPORTED_ALL 2 -static int var_exportedVars = VAR_EXPORTED_NONE; -/* - * We pass this to Var_Export when doing the initial export - * or after updating an exported var. - */ -#define VAR_EXPORT_PARENT 1 - -/* Var*Pattern flags */ -#define VAR_SUB_GLOBAL 0x01 /* Apply substitution globally */ -#define VAR_SUB_ONE 0x02 /* Apply substitution to one word */ -#define VAR_SUB_MATCHED 0x04 /* There was a match */ -#define VAR_MATCH_START 0x08 /* Match at start of word */ -#define VAR_MATCH_END 0x10 /* Match at end of word */ -#define VAR_NOSUBST 0x20 /* don't expand vars in VarGetPattern */ - -/* Var_Set flags */ -#define VAR_NO_EXPORT 0x01 /* do not export */ - -typedef struct { - /* - * The following fields are set by Var_Parse() when it - * encounters modifiers that need to keep state for use by - * subsequent modifiers within the same variable expansion. - */ - Byte varSpace; /* Word separator in expansions */ - Boolean oneBigWord; /* TRUE if we will treat the variable as a - * single big word, even if it contains - * embedded spaces (as opposed to the - * usual behaviour of treating it as - * several space-separated words). */ -} Var_Parse_State; - -/* struct passed as 'void *' to VarSubstitute() for ":S/lhs/rhs/", - * to VarSYSVMatch() for ":lhs=rhs". */ -typedef struct { - const char *lhs; /* String to match */ - int leftLen; /* Length of string */ - const char *rhs; /* Replacement string (w/ &'s removed) */ - int rightLen; /* Length of replacement */ - int flags; -} VarPattern; - -/* struct passed as 'void *' to VarLoopExpand() for ":@tvar@str@" */ -typedef struct { - GNode *ctxt; /* variable context */ - char *tvar; /* name of temp var */ - int tvarLen; - char *str; /* string to expand */ - int strLen; - int errnum; /* errnum for not defined */ -} VarLoop_t; - -#ifndef NO_REGEX -/* struct passed as 'void *' to VarRESubstitute() for ":C///" */ -typedef struct { - regex_t re; - int nsub; - regmatch_t *matches; - char *replace; - int flags; -} VarREPattern; -#endif - -/* struct passed to VarSelectWords() for ":[start..end]" */ -typedef struct { - int start; /* first word to select */ - int end; /* last word to select */ -} VarSelectWords_t; - -static Var *VarFind(const char *, GNode *, int); -static void VarAdd(const char *, const char *, GNode *); -static Boolean VarHead(GNode *, Var_Parse_State *, - char *, Boolean, Buffer *, void *); -static Boolean VarTail(GNode *, Var_Parse_State *, - char *, Boolean, Buffer *, void *); -static Boolean VarSuffix(GNode *, Var_Parse_State *, - char *, Boolean, Buffer *, void *); -static Boolean VarRoot(GNode *, Var_Parse_State *, - char *, Boolean, Buffer *, void *); -static Boolean VarMatch(GNode *, Var_Parse_State *, - char *, Boolean, Buffer *, void *); -#ifdef SYSVVARSUB -static Boolean VarSYSVMatch(GNode *, Var_Parse_State *, - char *, Boolean, Buffer *, void *); -#endif -static Boolean VarNoMatch(GNode *, Var_Parse_State *, - char *, Boolean, Buffer *, void *); -#ifndef NO_REGEX -static void VarREError(int, regex_t *, const char *); -static Boolean VarRESubstitute(GNode *, Var_Parse_State *, - char *, Boolean, Buffer *, void *); -#endif -static Boolean VarSubstitute(GNode *, Var_Parse_State *, - char *, Boolean, Buffer *, void *); -static Boolean VarLoopExpand(GNode *, Var_Parse_State *, - char *, Boolean, Buffer *, void *); -static char *VarGetPattern(GNode *, Var_Parse_State *, - int, const char **, int, int *, int *, - VarPattern *); -static char *VarQuote(char *); -static char *VarChangeCase(char *, int); -static char *VarHash(char *); -static char *VarModify(GNode *, Var_Parse_State *, - const char *, - Boolean (*)(GNode *, Var_Parse_State *, char *, Boolean, Buffer *, void *), - void *); -static char *VarOrder(const char *, const char); -static char *VarUniq(const char *); -static int VarWordCompare(const void *, const void *); -static void VarPrintVar(void *); - -#define BROPEN '{' -#define BRCLOSE '}' -#define PROPEN '(' -#define PRCLOSE ')' - -/*- - *----------------------------------------------------------------------- - * VarFind -- - * Find the given variable in the given context and any other contexts - * indicated. - * - * Input: - * name name to find - * ctxt context in which to find it - * flags FIND_GLOBAL set means to look in the - * VAR_GLOBAL context as well. FIND_CMD set means - * to look in the VAR_CMD context also. FIND_ENV - * set means to look in the environment - * - * Results: - * A pointer to the structure describing the desired variable or - * NULL if the variable does not exist. - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static Var * -VarFind(const char *name, GNode *ctxt, int flags) -{ - Hash_Entry *var; - Var *v; - - /* - * If the variable name begins with a '.', it could very well be one of - * the local ones. We check the name against all the local variables - * and substitute the short version in for 'name' if it matches one of - * them. - */ - if (*name == '.' && isupper((unsigned char) name[1])) - switch (name[1]) { - case 'A': - if (!strcmp(name, ".ALLSRC")) - name = ALLSRC; - if (!strcmp(name, ".ARCHIVE")) - name = ARCHIVE; - break; - case 'I': - if (!strcmp(name, ".IMPSRC")) - name = IMPSRC; - break; - case 'M': - if (!strcmp(name, ".MEMBER")) - name = MEMBER; - break; - case 'O': - if (!strcmp(name, ".OODATE")) - name = OODATE; - break; - case 'P': - if (!strcmp(name, ".PREFIX")) - name = PREFIX; - break; - case 'T': - if (!strcmp(name, ".TARGET")) - name = TARGET; - break; - } -#ifdef notyet - /* for compatibility with gmake */ - if (name[0] == '^' && name[1] == '\0') - name = ALLSRC; -#endif - - /* - * First look for the variable in the given context. If it's not there, - * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order, - * depending on the FIND_* flags in 'flags' - */ - var = Hash_FindEntry(&ctxt->context, name); - - if ((var == NULL) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) { - var = Hash_FindEntry(&VAR_CMD->context, name); - } - if (!checkEnvFirst && (var == NULL) && (flags & FIND_GLOBAL) && - (ctxt != VAR_GLOBAL)) - { - var = Hash_FindEntry(&VAR_GLOBAL->context, name); - } - if ((var == NULL) && (flags & FIND_ENV)) { - char *env; - - if ((env = getenv(name)) != NULL) { - int len; - - v = bmake_malloc(sizeof(Var)); - v->name = bmake_strdup(name); - - len = strlen(env); - - Buf_Init(&v->val, len + 1); - Buf_AddBytes(&v->val, len, env); - - v->flags = VAR_FROM_ENV; - return (v); - } else if (checkEnvFirst && (flags & FIND_GLOBAL) && - (ctxt != VAR_GLOBAL)) - { - var = Hash_FindEntry(&VAR_GLOBAL->context, name); - if (var == NULL) { - return NULL; - } else { - return ((Var *)Hash_GetValue(var)); - } - } else { - return NULL; - } - } else if (var == NULL) { - return NULL; - } else { - return ((Var *)Hash_GetValue(var)); - } -} - -/*- - *----------------------------------------------------------------------- - * VarFreeEnv -- - * If the variable is an environment variable, free it - * - * Input: - * v the variable - * destroy true if the value buffer should be destroyed. - * - * Results: - * 1 if it is an environment variable 0 ow. - * - * Side Effects: - * The variable is free'ed if it is an environent variable. - *----------------------------------------------------------------------- - */ -static Boolean -VarFreeEnv(Var *v, Boolean destroy) -{ - if ((v->flags & VAR_FROM_ENV) == 0) - return FALSE; - free(v->name); - Buf_Destroy(&v->val, destroy); - free(v); - return TRUE; -} - -/*- - *----------------------------------------------------------------------- - * VarAdd -- - * Add a new variable of name name and value val to the given context - * - * Input: - * name name of variable to add - * val value to set it to - * ctxt context in which to set it - * - * Results: - * None - * - * Side Effects: - * The new variable is placed at the front of the given context - * The name and val arguments are duplicated so they may - * safely be freed. - *----------------------------------------------------------------------- - */ -static void -VarAdd(const char *name, const char *val, GNode *ctxt) -{ - Var *v; - int len; - Hash_Entry *h; - - v = bmake_malloc(sizeof(Var)); - - len = val ? strlen(val) : 0; - Buf_Init(&v->val, len+1); - Buf_AddBytes(&v->val, len, val); - - v->flags = 0; - - h = Hash_CreateEntry(&ctxt->context, name, NULL); - Hash_SetValue(h, v); - v->name = h->name; - if (DEBUG(VAR)) { - fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val); - } -} - -/*- - *----------------------------------------------------------------------- - * Var_Delete -- - * Remove a variable from a context. - * - * Results: - * None. - * - * Side Effects: - * The Var structure is removed and freed. - * - *----------------------------------------------------------------------- - */ -void -Var_Delete(const char *name, GNode *ctxt) -{ - Hash_Entry *ln; - - ln = Hash_FindEntry(&ctxt->context, name); - if (DEBUG(VAR)) { - fprintf(debug_file, "%s:delete %s%s\n", - ctxt->name, name, ln ? "" : " (not found)"); - } - if (ln != NULL) { - Var *v; - - v = (Var *)Hash_GetValue(ln); - if ((v->flags & VAR_EXPORTED)) { - unsetenv(v->name); - } - if (strcmp(MAKE_EXPORTED, v->name) == 0) { - var_exportedVars = VAR_EXPORTED_NONE; - } - if (v->name != ln->name) - free(v->name); - Hash_DeleteEntry(&ctxt->context, ln); - Buf_Destroy(&v->val, TRUE); - free(v); - } -} - - -/* - * Export a var. - * We ignore make internal variables (those which start with '.') - * Also we jump through some hoops to avoid calling setenv - * more than necessary since it can leak. - * We only manipulate flags of vars if 'parent' is set. - */ -static int -Var_Export1(const char *name, int parent) -{ - char tmp[BUFSIZ]; - Var *v; - char *val = NULL; - int n; - - if (*name == '.') - return 0; /* skip internals */ - if (!name[1]) { - /* - * A single char. - * If it is one of the vars that should only appear in - * local context, skip it, else we can get Var_Subst - * into a loop. - */ - switch (name[0]) { - case '@': - case '%': - case '*': - case '!': - return 0; - } - } - v = VarFind(name, VAR_GLOBAL, 0); - if (v == NULL) { - return 0; - } - if (!parent && - (v->flags & (VAR_EXPORTED|VAR_REEXPORT)) == VAR_EXPORTED) { - return 0; /* nothing to do */ - } - val = Buf_GetAll(&v->val, NULL); - if (strchr(val, '$')) { - if (parent) { - /* - * Flag this as something we need to re-export. - * No point actually exporting it now though, - * the child can do it at the last minute. - */ - v->flags |= (VAR_EXPORTED|VAR_REEXPORT); - return 1; - } - if (v->flags & VAR_IN_USE) { - /* - * We recursed while exporting in a child. - * This isn't going to end well, just skip it. - */ - return 0; - } - n = snprintf(tmp, sizeof(tmp), "${%s}", name); - if (n < (int)sizeof(tmp)) { - val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); - setenv(name, val, 1); - free(val); - } - } else { - if (parent) { - v->flags &= ~VAR_REEXPORT; /* once will do */ - } - if (parent || !(v->flags & VAR_EXPORTED)) { - setenv(name, val, 1); - } - } - /* - * This is so Var_Set knows to call Var_Export again... - */ - if (parent) { - v->flags |= VAR_EXPORTED; - } - return 1; -} - -/* - * This gets called from our children. - */ -void -Var_ExportVars(void) -{ - char tmp[BUFSIZ]; - Hash_Entry *var; - Hash_Search state; - Var *v; - char *val; - int n; - - if (VAR_EXPORTED_NONE == var_exportedVars) - return; - - if (VAR_EXPORTED_ALL == var_exportedVars) { - /* - * Ouch! This is crazy... - */ - for (var = Hash_EnumFirst(&VAR_GLOBAL->context, &state); - var != NULL; - var = Hash_EnumNext(&state)) { - v = (Var *)Hash_GetValue(var); - Var_Export1(v->name, 0); - } - return; - } - /* - * We have a number of exported vars, - */ - n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}"); - if (n < (int)sizeof(tmp)) { - char **av; - char *as; - int ac; - int i; - - val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); - av = brk_string(val, &ac, FALSE, &as); - for (i = 0; i < ac; i++) { - Var_Export1(av[i], 0); - } - free(val); - free(as); - free(av); - } -} - -/* - * This is called when .export is seen or - * .MAKE.EXPORTED is modified. - * It is also called when any exported var is modified. - */ -void -Var_Export(char *str, int isExport) -{ - char *name; - char *val; - char **av; - char *as; - int track; - int ac; - int i; - - if (isExport && (!str || !str[0])) { - var_exportedVars = VAR_EXPORTED_ALL; /* use with caution! */ - return; - } - - if (strncmp(str, "-env", 4) == 0) { - track = 0; - str += 4; - } else { - track = VAR_EXPORT_PARENT; - } - val = Var_Subst(NULL, str, VAR_GLOBAL, 0); - av = brk_string(val, &ac, FALSE, &as); - for (i = 0; i < ac; i++) { - name = av[i]; - if (!name[1]) { - /* - * A single char. - * If it is one of the vars that should only appear in - * local context, skip it, else we can get Var_Subst - * into a loop. - */ - switch (name[0]) { - case '@': - case '%': - case '*': - case '!': - continue; - } - } - if (Var_Export1(name, track)) { - if (VAR_EXPORTED_ALL != var_exportedVars) - var_exportedVars = VAR_EXPORTED_YES; - if (isExport && track) { - Var_Append(MAKE_EXPORTED, name, VAR_GLOBAL); - } - } - } - free(val); - free(as); - free(av); -} - - -/* - * This is called when .unexport[-env] is seen. - */ -extern char **environ; - -void -Var_UnExport(char *str) -{ - char tmp[BUFSIZ]; - char *vlist; - char *cp; - Boolean unexport_env; - int n; - - if (!str || !str[0]) { - return; /* assert? */ - } - - vlist = NULL; - - str += 8; - unexport_env = (strncmp(str, "-env", 4) == 0); - if (unexport_env) { - char **newenv; - - cp = getenv(MAKE_LEVEL); /* we should preserve this */ - if (environ == savedEnv) { - /* we have been here before! */ - newenv = bmake_realloc(environ, 2 * sizeof(char *)); - } else { - if (savedEnv) { - free(savedEnv); - savedEnv = NULL; - } - newenv = bmake_malloc(2 * sizeof(char *)); - } - if (!newenv) - return; - /* Note: we cannot safely free() the original environ. */ - environ = savedEnv = newenv; - newenv[0] = NULL; - newenv[1] = NULL; - setenv(MAKE_LEVEL, cp, 1); -#ifdef MAKE_LEVEL_SAFE - setenv(MAKE_LEVEL_SAFE, cp, 1); -#endif - } else { - for (; *str != '\n' && isspace((unsigned char) *str); str++) - continue; - if (str[0] && str[0] != '\n') { - vlist = str; - } - } - - if (!vlist) { - /* Using .MAKE.EXPORTED */ - n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}"); - if (n < (int)sizeof(tmp)) { - vlist = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); - } - } - if (vlist) { - Var *v; - char **av; - char *as; - int ac; - int i; - - av = brk_string(vlist, &ac, FALSE, &as); - for (i = 0; i < ac; i++) { - v = VarFind(av[i], VAR_GLOBAL, 0); - if (!v) - continue; - if (!unexport_env && - (v->flags & (VAR_EXPORTED|VAR_REEXPORT)) == VAR_EXPORTED) { - unsetenv(v->name); - } - v->flags &= ~(VAR_EXPORTED|VAR_REEXPORT); - /* - * If we are unexporting a list, - * remove each one from .MAKE.EXPORTED. - * If we are removing them all, - * just delete .MAKE.EXPORTED below. - */ - if (vlist == str) { - n = snprintf(tmp, sizeof(tmp), - "${" MAKE_EXPORTED ":N%s}", v->name); - if (n < (int)sizeof(tmp)) { - cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); - Var_Set(MAKE_EXPORTED, cp, VAR_GLOBAL, 0); - free(cp); - } - } - } - free(as); - free(av); - if (vlist != str) { - Var_Delete(MAKE_EXPORTED, VAR_GLOBAL); - free(vlist); - } - } -} - -/*- - *----------------------------------------------------------------------- - * Var_Set -- - * Set the variable name to the value val in the given context. - * - * Input: - * name name of variable to set - * val value to give to the variable - * ctxt context in which to set it - * - * Results: - * None. - * - * Side Effects: - * If the variable doesn't yet exist, a new record is created for it. - * Else the old value is freed and the new one stuck in its place - * - * Notes: - * The variable is searched for only in its context before being - * created in that context. I.e. if the context is VAR_GLOBAL, - * only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only - * VAR_CMD->context is searched. This is done to avoid the literally - * thousands of unnecessary strcmp's that used to be done to - * set, say, $(@) or $(<). - * If the context is VAR_GLOBAL though, we check if the variable - * was set in VAR_CMD from the command line and skip it if so. - *----------------------------------------------------------------------- - */ -void -Var_Set(const char *name, const char *val, GNode *ctxt, int flags) -{ - Var *v; - char *expanded_name = NULL; - - /* - * We only look for a variable in the given context since anything set - * here will override anything in a lower context, so there's not much - * point in searching them all just to save a bit of memory... - */ - if (strchr(name, '$') != NULL) { - expanded_name = Var_Subst(NULL, name, ctxt, 0); - if (expanded_name[0] == 0) { - if (DEBUG(VAR)) { - fprintf(debug_file, "Var_Set(\"%s\", \"%s\", ...) " - "name expands to empty string - ignored\n", - name, val); - } - free(expanded_name); - return; - } - name = expanded_name; - } - if (ctxt == VAR_GLOBAL) { - v = VarFind(name, VAR_CMD, 0); - if (v != NULL) { - if ((v->flags & VAR_FROM_CMD)) { - if (DEBUG(VAR)) { - fprintf(debug_file, "%s:%s = %s ignored!\n", ctxt->name, name, val); - } - goto out; - } - VarFreeEnv(v, TRUE); - } - } - v = VarFind(name, ctxt, 0); - if (v == NULL) { - VarAdd(name, val, ctxt); - } else { - Buf_Empty(&v->val); - Buf_AddBytes(&v->val, strlen(val), val); - - if (DEBUG(VAR)) { - fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val); - } - if ((v->flags & VAR_EXPORTED)) { - Var_Export1(name, VAR_EXPORT_PARENT); - } - } - /* - * Any variables given on the command line are automatically exported - * to the environment (as per POSIX standard) - */ - if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) { - if (v == NULL) { - /* we just added it */ - v = VarFind(name, ctxt, 0); - } - if (v != NULL) - v->flags |= VAR_FROM_CMD; - /* - * If requested, don't export these in the environment - * individually. We still put them in MAKEOVERRIDES so - * that the command-line settings continue to override - * Makefile settings. - */ - if (varNoExportEnv != TRUE) - setenv(name, val, 1); - - Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL); - } - /* - * Another special case. - * Several make's support this sort of mechanism for tracking - * recursion - but each uses a different name. - * We allow the makefiles to update .MAKE.LEVEL and ensure - * children see a correctly incremented value. - */ - if (ctxt == VAR_GLOBAL && strcmp(MAKE_LEVEL, name) == 0) { - char tmp[64]; - int level; - - level = atoi(val); - snprintf(tmp, sizeof(tmp), "%u", level + 1); - setenv(MAKE_LEVEL, tmp, 1); -#ifdef MAKE_LEVEL_SAFE - setenv(MAKE_LEVEL_SAFE, tmp, 1); -#endif - } - - - out: - if (expanded_name != NULL) - free(expanded_name); - if (v != NULL) - VarFreeEnv(v, TRUE); -} - -/*- - *----------------------------------------------------------------------- - * Var_Append -- - * The variable of the given name has the given value appended to it in - * the given context. - * - * Input: - * name name of variable to modify - * val String to append to it - * ctxt Context in which this should occur - * - * Results: - * None - * - * Side Effects: - * If the variable doesn't exist, it is created. Else the strings - * are concatenated (with a space in between). - * - * Notes: - * Only if the variable is being sought in the global context is the - * environment searched. - * XXX: Knows its calling circumstances in that if called with ctxt - * an actual target, it will only search that context since only - * a local variable could be being appended to. This is actually - * a big win and must be tolerated. - *----------------------------------------------------------------------- - */ -void -Var_Append(const char *name, const char *val, GNode *ctxt) -{ - Var *v; - Hash_Entry *h; - char *expanded_name = NULL; - - if (strchr(name, '$') != NULL) { - expanded_name = Var_Subst(NULL, name, ctxt, 0); - if (expanded_name[0] == 0) { - if (DEBUG(VAR)) { - fprintf(debug_file, "Var_Append(\"%s\", \"%s\", ...) " - "name expands to empty string - ignored\n", - name, val); - } - free(expanded_name); - return; - } - name = expanded_name; - } - - v = VarFind(name, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0); - - if (v == NULL) { - VarAdd(name, val, ctxt); - } else { - Buf_AddByte(&v->val, ' '); - Buf_AddBytes(&v->val, strlen(val), val); - - if (DEBUG(VAR)) { - fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, - Buf_GetAll(&v->val, NULL)); - } - - if (v->flags & VAR_FROM_ENV) { - /* - * If the original variable came from the environment, we - * have to install it in the global context (we could place - * it in the environment, but then we should provide a way to - * export other variables...) - */ - v->flags &= ~VAR_FROM_ENV; - h = Hash_CreateEntry(&ctxt->context, name, NULL); - Hash_SetValue(h, v); - } - } - if (expanded_name != NULL) - free(expanded_name); -} - -/*- - *----------------------------------------------------------------------- - * Var_Exists -- - * See if the given variable exists. - * - * Input: - * name Variable to find - * ctxt Context in which to start search - * - * Results: - * TRUE if it does, FALSE if it doesn't - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -Boolean -Var_Exists(const char *name, GNode *ctxt) -{ - Var *v; - char *cp; - - if ((cp = strchr(name, '$')) != NULL) { - cp = Var_Subst(NULL, name, ctxt, FALSE); - } - v = VarFind(cp ? cp : name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV); - if (cp != NULL) { - free(cp); - } - if (v == NULL) { - return(FALSE); - } else { - (void)VarFreeEnv(v, TRUE); - } - return(TRUE); -} - -/*- - *----------------------------------------------------------------------- - * Var_Value -- - * Return the value of the named variable in the given context - * - * Input: - * name name to find - * ctxt context in which to search for it - * - * Results: - * The value if the variable exists, NULL if it doesn't - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -char * -Var_Value(const char *name, GNode *ctxt, char **frp) -{ - Var *v; - - v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); - *frp = NULL; - if (v != NULL) { - char *p = (Buf_GetAll(&v->val, NULL)); - if (VarFreeEnv(v, FALSE)) - *frp = p; - return p; - } else { - return NULL; - } -} - -/*- - *----------------------------------------------------------------------- - * VarHead -- - * Remove the tail of the given word and place the result in the given - * buffer. - * - * Input: - * word Word to trim - * addSpace True if need to add a space to the buffer - * before sticking in the head - * buf Buffer in which to store it - * - * Results: - * TRUE if characters were added to the buffer (a space needs to be - * added to the buffer before the next word). - * - * Side Effects: - * The trimmed word is added to the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarHead(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate, - char *word, Boolean addSpace, Buffer *buf, - void *dummy) -{ - char *slash; - - slash = strrchr(word, '/'); - if (slash != NULL) { - if (addSpace && vpstate->varSpace) { - Buf_AddByte(buf, vpstate->varSpace); - } - *slash = '\0'; - Buf_AddBytes(buf, strlen(word), word); - *slash = '/'; - return (TRUE); - } else { - /* - * If no directory part, give . (q.v. the POSIX standard) - */ - if (addSpace && vpstate->varSpace) - Buf_AddByte(buf, vpstate->varSpace); - Buf_AddByte(buf, '.'); - } - return(dummy ? TRUE : TRUE); -} - -/*- - *----------------------------------------------------------------------- - * VarTail -- - * Remove the head of the given word and place the result in the given - * buffer. - * - * Input: - * word Word to trim - * addSpace True if need to add a space to the buffer - * before adding the tail - * buf Buffer in which to store it - * - * Results: - * TRUE if characters were added to the buffer (a space needs to be - * added to the buffer before the next word). - * - * Side Effects: - * The trimmed word is added to the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarTail(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate, - char *word, Boolean addSpace, Buffer *buf, - void *dummy) -{ - char *slash; - - if (addSpace && vpstate->varSpace) { - Buf_AddByte(buf, vpstate->varSpace); - } - - slash = strrchr(word, '/'); - if (slash != NULL) { - *slash++ = '\0'; - Buf_AddBytes(buf, strlen(slash), slash); - slash[-1] = '/'; - } else { - Buf_AddBytes(buf, strlen(word), word); - } - return (dummy ? TRUE : TRUE); -} - -/*- - *----------------------------------------------------------------------- - * VarSuffix -- - * Place the suffix of the given word in the given buffer. - * - * Input: - * word Word to trim - * addSpace TRUE if need to add a space before placing the - * suffix in the buffer - * buf Buffer in which to store it - * - * Results: - * TRUE if characters were added to the buffer (a space needs to be - * added to the buffer before the next word). - * - * Side Effects: - * The suffix from the word is placed in the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarSuffix(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate, - char *word, Boolean addSpace, Buffer *buf, - void *dummy) -{ - char *dot; - - dot = strrchr(word, '.'); - if (dot != NULL) { - if (addSpace && vpstate->varSpace) { - Buf_AddByte(buf, vpstate->varSpace); - } - *dot++ = '\0'; - Buf_AddBytes(buf, strlen(dot), dot); - dot[-1] = '.'; - addSpace = TRUE; - } - return (dummy ? addSpace : addSpace); -} - -/*- - *----------------------------------------------------------------------- - * VarRoot -- - * Remove the suffix of the given word and place the result in the - * buffer. - * - * Input: - * word Word to trim - * addSpace TRUE if need to add a space to the buffer - * before placing the root in it - * buf Buffer in which to store it - * - * Results: - * TRUE if characters were added to the buffer (a space needs to be - * added to the buffer before the next word). - * - * Side Effects: - * The trimmed word is added to the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarRoot(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate, - char *word, Boolean addSpace, Buffer *buf, - void *dummy) -{ - char *dot; - - if (addSpace && vpstate->varSpace) { - Buf_AddByte(buf, vpstate->varSpace); - } - - dot = strrchr(word, '.'); - if (dot != NULL) { - *dot = '\0'; - Buf_AddBytes(buf, strlen(word), word); - *dot = '.'; - } else { - Buf_AddBytes(buf, strlen(word), word); - } - return (dummy ? TRUE : TRUE); -} - -/*- - *----------------------------------------------------------------------- - * VarMatch -- - * Place the word in the buffer if it matches the given pattern. - * Callback function for VarModify to implement the :M modifier. - * - * Input: - * word Word to examine - * addSpace TRUE if need to add a space to the buffer - * before adding the word, if it matches - * buf Buffer in which to store it - * pattern Pattern the word must match - * - * Results: - * TRUE if a space should be placed in the buffer before the next - * word. - * - * Side Effects: - * The word may be copied to the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarMatch(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate, - char *word, Boolean addSpace, Buffer *buf, - void *pattern) -{ - if (DEBUG(VAR)) - fprintf(debug_file, "VarMatch [%s] [%s]\n", word, (char *)pattern); - if (Str_Match(word, (char *)pattern)) { - if (addSpace && vpstate->varSpace) { - Buf_AddByte(buf, vpstate->varSpace); - } - addSpace = TRUE; - Buf_AddBytes(buf, strlen(word), word); - } - return(addSpace); -} - -#ifdef SYSVVARSUB -/*- - *----------------------------------------------------------------------- - * VarSYSVMatch -- - * Place the word in the buffer if it matches the given pattern. - * Callback function for VarModify to implement the System V % - * modifiers. - * - * Input: - * word Word to examine - * addSpace TRUE if need to add a space to the buffer - * before adding the word, if it matches - * buf Buffer in which to store it - * patp Pattern the word must match - * - * Results: - * TRUE if a space should be placed in the buffer before the next - * word. - * - * Side Effects: - * The word may be copied to the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate, - char *word, Boolean addSpace, Buffer *buf, - void *patp) -{ - int len; - char *ptr; - VarPattern *pat = (VarPattern *)patp; - char *varexp; - - if (addSpace && vpstate->varSpace) - Buf_AddByte(buf, vpstate->varSpace); - - addSpace = TRUE; - - if ((ptr = Str_SYSVMatch(word, pat->lhs, &len)) != NULL) { - varexp = Var_Subst(NULL, pat->rhs, ctx, 0); - Str_SYSVSubst(buf, varexp, ptr, len); - free(varexp); - } else { - Buf_AddBytes(buf, strlen(word), word); - } - - return(addSpace); -} -#endif - - -/*- - *----------------------------------------------------------------------- - * VarNoMatch -- - * Place the word in the buffer if it doesn't match the given pattern. - * Callback function for VarModify to implement the :N modifier. - * - * Input: - * word Word to examine - * addSpace TRUE if need to add a space to the buffer - * before adding the word, if it matches - * buf Buffer in which to store it - * pattern Pattern the word must match - * - * Results: - * TRUE if a space should be placed in the buffer before the next - * word. - * - * Side Effects: - * The word may be copied to the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarNoMatch(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate, - char *word, Boolean addSpace, Buffer *buf, - void *pattern) -{ - if (!Str_Match(word, (char *)pattern)) { - if (addSpace && vpstate->varSpace) { - Buf_AddByte(buf, vpstate->varSpace); - } - addSpace = TRUE; - Buf_AddBytes(buf, strlen(word), word); - } - return(addSpace); -} - - -/*- - *----------------------------------------------------------------------- - * VarSubstitute -- - * Perform a string-substitution on the given word, placing the - * result in the passed buffer. - * - * Input: - * word Word to modify - * addSpace True if space should be added before - * other characters - * buf Buffer for result - * patternp Pattern for substitution - * - * Results: - * TRUE if a space is needed before more characters are added. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate, - char *word, Boolean addSpace, Buffer *buf, - void *patternp) -{ - int wordLen; /* Length of word */ - char *cp; /* General pointer */ - VarPattern *pattern = (VarPattern *)patternp; - - wordLen = strlen(word); - if ((pattern->flags & (VAR_SUB_ONE|VAR_SUB_MATCHED)) != - (VAR_SUB_ONE|VAR_SUB_MATCHED)) { - /* - * Still substituting -- break it down into simple anchored cases - * and if none of them fits, perform the general substitution case. - */ - if ((pattern->flags & VAR_MATCH_START) && - (strncmp(word, pattern->lhs, pattern->leftLen) == 0)) { - /* - * Anchored at start and beginning of word matches pattern - */ - if ((pattern->flags & VAR_MATCH_END) && - (wordLen == pattern->leftLen)) { - /* - * Also anchored at end and matches to the end (word - * is same length as pattern) add space and rhs only - * if rhs is non-null. - */ - if (pattern->rightLen != 0) { - if (addSpace && vpstate->varSpace) { - Buf_AddByte(buf, vpstate->varSpace); - } - addSpace = TRUE; - Buf_AddBytes(buf, pattern->rightLen, pattern->rhs); - } - pattern->flags |= VAR_SUB_MATCHED; - } else if (pattern->flags & VAR_MATCH_END) { - /* - * Doesn't match to end -- copy word wholesale - */ - goto nosub; - } else { - /* - * Matches at start but need to copy in trailing characters - */ - if ((pattern->rightLen + wordLen - pattern->leftLen) != 0){ - if (addSpace && vpstate->varSpace) { - Buf_AddByte(buf, vpstate->varSpace); - } - addSpace = TRUE; - } - Buf_AddBytes(buf, pattern->rightLen, pattern->rhs); - Buf_AddBytes(buf, wordLen - pattern->leftLen, - (word + pattern->leftLen)); - pattern->flags |= VAR_SUB_MATCHED; - } - } else if (pattern->flags & VAR_MATCH_START) { - /* - * Had to match at start of word and didn't -- copy whole word. - */ - goto nosub; - } else if (pattern->flags & VAR_MATCH_END) { - /* - * Anchored at end, Find only place match could occur (leftLen - * characters from the end of the word) and see if it does. Note - * that because the $ will be left at the end of the lhs, we have - * to use strncmp. - */ - cp = word + (wordLen - pattern->leftLen); - if ((cp >= word) && - (strncmp(cp, pattern->lhs, pattern->leftLen) == 0)) { - /* - * Match found. If we will place characters in the buffer, - * add a space before hand as indicated by addSpace, then - * stuff in the initial, unmatched part of the word followed - * by the right-hand-side. - */ - if (((cp - word) + pattern->rightLen) != 0) { - if (addSpace && vpstate->varSpace) { - Buf_AddByte(buf, vpstate->varSpace); - } - addSpace = TRUE; - } - Buf_AddBytes(buf, cp - word, word); - Buf_AddBytes(buf, pattern->rightLen, pattern->rhs); - pattern->flags |= VAR_SUB_MATCHED; - } else { - /* - * Had to match at end and didn't. Copy entire word. - */ - goto nosub; - } - } else { - /* - * Pattern is unanchored: search for the pattern in the word using - * String_FindSubstring, copying unmatched portions and the - * right-hand-side for each match found, handling non-global - * substitutions correctly, etc. When the loop is done, any - * remaining part of the word (word and wordLen are adjusted - * accordingly through the loop) is copied straight into the - * buffer. - * addSpace is set FALSE as soon as a space is added to the - * buffer. - */ - Boolean done; - int origSize; - - done = FALSE; - origSize = Buf_Size(buf); - while (!done) { - cp = Str_FindSubstring(word, pattern->lhs); - if (cp != NULL) { - if (addSpace && (((cp - word) + pattern->rightLen) != 0)){ - Buf_AddByte(buf, vpstate->varSpace); - addSpace = FALSE; - } - Buf_AddBytes(buf, cp-word, word); - Buf_AddBytes(buf, pattern->rightLen, pattern->rhs); - wordLen -= (cp - word) + pattern->leftLen; - word = cp + pattern->leftLen; - if (wordLen == 0) { - done = TRUE; - } - if ((pattern->flags & VAR_SUB_GLOBAL) == 0) { - done = TRUE; - } - pattern->flags |= VAR_SUB_MATCHED; - } else { - done = TRUE; - } - } - if (wordLen != 0) { - if (addSpace && vpstate->varSpace) { - Buf_AddByte(buf, vpstate->varSpace); - } - Buf_AddBytes(buf, wordLen, word); - } - /* - * If added characters to the buffer, need to add a space - * before we add any more. If we didn't add any, just return - * the previous value of addSpace. - */ - return ((Buf_Size(buf) != origSize) || addSpace); - } - return (addSpace); - } - nosub: - if (addSpace && vpstate->varSpace) { - Buf_AddByte(buf, vpstate->varSpace); - } - Buf_AddBytes(buf, wordLen, word); - return(TRUE); -} - -#ifndef NO_REGEX -/*- - *----------------------------------------------------------------------- - * VarREError -- - * Print the error caused by a regcomp or regexec call. - * - * Results: - * None. - * - * Side Effects: - * An error gets printed. - * - *----------------------------------------------------------------------- - */ -static void -VarREError(int errnum, regex_t *pat, const char *str) -{ - char *errbuf; - int errlen; - - errlen = regerror(errnum, pat, 0, 0); - errbuf = bmake_malloc(errlen); - regerror(errnum, pat, errbuf, errlen); - Error("%s: %s", str, errbuf); - free(errbuf); -} - - -/*- - *----------------------------------------------------------------------- - * VarRESubstitute -- - * Perform a regex substitution on the given word, placing the - * result in the passed buffer. - * - * Results: - * TRUE if a space is needed before more characters are added. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarRESubstitute(GNode *ctx MAKE_ATTR_UNUSED, - Var_Parse_State *vpstate MAKE_ATTR_UNUSED, - char *word, Boolean addSpace, Buffer *buf, - void *patternp) -{ - VarREPattern *pat; - int xrv; - char *wp; - char *rp; - int added; - int flags = 0; - -#define MAYBE_ADD_SPACE() \ - if (addSpace && !added) \ - Buf_AddByte(buf, ' '); \ - added = 1 - - added = 0; - wp = word; - pat = patternp; - - if ((pat->flags & (VAR_SUB_ONE|VAR_SUB_MATCHED)) == - (VAR_SUB_ONE|VAR_SUB_MATCHED)) - xrv = REG_NOMATCH; - else { - tryagain: - xrv = regexec(&pat->re, wp, pat->nsub, pat->matches, flags); - } - - switch (xrv) { - case 0: - pat->flags |= VAR_SUB_MATCHED; - if (pat->matches[0].rm_so > 0) { - MAYBE_ADD_SPACE(); - Buf_AddBytes(buf, pat->matches[0].rm_so, wp); - } - - for (rp = pat->replace; *rp; rp++) { - if ((*rp == '\\') && ((rp[1] == '&') || (rp[1] == '\\'))) { - MAYBE_ADD_SPACE(); - Buf_AddByte(buf,rp[1]); - rp++; - } - else if ((*rp == '&') || - ((*rp == '\\') && isdigit((unsigned char)rp[1]))) { - int n; - const char *subbuf; - int sublen; - char errstr[3]; - - if (*rp == '&') { - n = 0; - errstr[0] = '&'; - errstr[1] = '\0'; - } else { - n = rp[1] - '0'; - errstr[0] = '\\'; - errstr[1] = rp[1]; - errstr[2] = '\0'; - rp++; - } - - if (n > pat->nsub) { - Error("No subexpression %s", &errstr[0]); - subbuf = ""; - sublen = 0; - } else if ((pat->matches[n].rm_so == -1) && - (pat->matches[n].rm_eo == -1)) { - Error("No match for subexpression %s", &errstr[0]); - subbuf = ""; - sublen = 0; - } else { - subbuf = wp + pat->matches[n].rm_so; - sublen = pat->matches[n].rm_eo - pat->matches[n].rm_so; - } - - if (sublen > 0) { - MAYBE_ADD_SPACE(); - Buf_AddBytes(buf, sublen, subbuf); - } - } else { - MAYBE_ADD_SPACE(); - Buf_AddByte(buf, *rp); - } - } - wp += pat->matches[0].rm_eo; - if (pat->flags & VAR_SUB_GLOBAL) { - flags |= REG_NOTBOL; - if (pat->matches[0].rm_so == 0 && pat->matches[0].rm_eo == 0) { - MAYBE_ADD_SPACE(); - Buf_AddByte(buf, *wp); - wp++; - - } - if (*wp) - goto tryagain; - } - if (*wp) { - MAYBE_ADD_SPACE(); - Buf_AddBytes(buf, strlen(wp), wp); - } - break; - default: - VarREError(xrv, &pat->re, "Unexpected regex error"); - /* fall through */ - case REG_NOMATCH: - if (*wp) { - MAYBE_ADD_SPACE(); - Buf_AddBytes(buf,strlen(wp),wp); - } - break; - } - return(addSpace||added); -} -#endif - - - -/*- - *----------------------------------------------------------------------- - * VarLoopExpand -- - * Implements the :@<temp>@<string>@ modifier of ODE make. - * We set the temp variable named in pattern.lhs to word and expand - * pattern.rhs storing the result in the passed buffer. - * - * Input: - * word Word to modify - * addSpace True if space should be added before - * other characters - * buf Buffer for result - * pattern Datafor substitution - * - * Results: - * TRUE if a space is needed before more characters are added. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarLoopExpand(GNode *ctx MAKE_ATTR_UNUSED, - Var_Parse_State *vpstate MAKE_ATTR_UNUSED, - char *word, Boolean addSpace, Buffer *buf, - void *loopp) -{ - VarLoop_t *loop = (VarLoop_t *)loopp; - char *s; - int slen; - - if (word && *word) { - Var_Set(loop->tvar, word, loop->ctxt, VAR_NO_EXPORT); - s = Var_Subst(NULL, loop->str, loop->ctxt, loop->errnum); - if (s != NULL && *s != '\0') { - if (addSpace && *s != '\n') - Buf_AddByte(buf, ' '); - Buf_AddBytes(buf, (slen = strlen(s)), s); - addSpace = (slen > 0 && s[slen - 1] != '\n'); - free(s); - } - } - return addSpace; -} - - -/*- - *----------------------------------------------------------------------- - * VarSelectWords -- - * Implements the :[start..end] modifier. - * This is a special case of VarModify since we want to be able - * to scan the list backwards if start > end. - * - * Input: - * str String whose words should be trimmed - * seldata words to select - * - * Results: - * A string of all the words selected. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static char * -VarSelectWords(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate, - const char *str, VarSelectWords_t *seldata) -{ - Buffer buf; /* Buffer for the new string */ - Boolean addSpace; /* TRUE if need to add a space to the - * buffer before adding the trimmed - * word */ - char **av; /* word list */ - char *as; /* word list memory */ - int ac, i; - int start, end, step; - - Buf_Init(&buf, 0); - addSpace = FALSE; - - if (vpstate->oneBigWord) { - /* fake what brk_string() would do if there were only one word */ - ac = 1; - av = bmake_malloc((ac + 1) * sizeof(char *)); - as = bmake_strdup(str); - av[0] = as; - av[1] = NULL; - } else { - av = brk_string(str, &ac, FALSE, &as); - } - - /* - * Now sanitize seldata. - * If seldata->start or seldata->end are negative, convert them to - * the positive equivalents (-1 gets converted to argc, -2 gets - * converted to (argc-1), etc.). - */ - if (seldata->start < 0) - seldata->start = ac + seldata->start + 1; - if (seldata->end < 0) - seldata->end = ac + seldata->end + 1; - - /* - * We avoid scanning more of the list than we need to. - */ - if (seldata->start > seldata->end) { - start = MIN(ac, seldata->start) - 1; - end = MAX(0, seldata->end - 1); - step = -1; - } else { - start = MAX(0, seldata->start - 1); - end = MIN(ac, seldata->end); - step = 1; - } - - for (i = start; - (step < 0 && i >= end) || (step > 0 && i < end); - i += step) { - if (av[i] && *av[i]) { - if (addSpace && vpstate->varSpace) { - Buf_AddByte(&buf, vpstate->varSpace); - } - Buf_AddBytes(&buf, strlen(av[i]), av[i]); - addSpace = TRUE; - } - } - - free(as); - free(av); - - return Buf_Destroy(&buf, FALSE); -} - - -/*- - * VarRealpath -- - * Replace each word with the result of realpath() - * if successful. - */ -static Boolean -VarRealpath(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate, - char *word, Boolean addSpace, Buffer *buf, - void *patternp MAKE_ATTR_UNUSED) -{ - struct stat st; - char rbuf[MAXPATHLEN]; - char *rp; - - if (addSpace && vpstate->varSpace) { - Buf_AddByte(buf, vpstate->varSpace); - } - addSpace = TRUE; - rp = realpath(word, rbuf); - if (rp && *rp == '/' && stat(rp, &st) == 0) - word = rp; - - Buf_AddBytes(buf, strlen(word), word); - return(addSpace); -} - -/*- - *----------------------------------------------------------------------- - * VarModify -- - * Modify each of the words of the passed string using the given - * function. Used to implement all modifiers. - * - * Input: - * str String whose words should be trimmed - * modProc Function to use to modify them - * datum Datum to pass it - * - * Results: - * A string of all the words modified appropriately. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static char * -VarModify(GNode *ctx, Var_Parse_State *vpstate, - const char *str, - Boolean (*modProc)(GNode *, Var_Parse_State *, char *, - Boolean, Buffer *, void *), - void *datum) -{ - Buffer buf; /* Buffer for the new string */ - Boolean addSpace; /* TRUE if need to add a space to the - * buffer before adding the trimmed - * word */ - char **av; /* word list */ - char *as; /* word list memory */ - int ac, i; - - Buf_Init(&buf, 0); - addSpace = FALSE; - - if (vpstate->oneBigWord) { - /* fake what brk_string() would do if there were only one word */ - ac = 1; - av = bmake_malloc((ac + 1) * sizeof(char *)); - as = bmake_strdup(str); - av[0] = as; - av[1] = NULL; - } else { - av = brk_string(str, &ac, FALSE, &as); - } - - for (i = 0; i < ac; i++) { - addSpace = (*modProc)(ctx, vpstate, av[i], addSpace, &buf, datum); - } - - free(as); - free(av); - - return Buf_Destroy(&buf, FALSE); -} - - -static int -VarWordCompare(const void *a, const void *b) -{ - int r = strcmp(*(const char * const *)a, *(const char * const *)b); - return r; -} - -/*- - *----------------------------------------------------------------------- - * VarOrder -- - * Order the words in the string. - * - * Input: - * str String whose words should be sorted. - * otype How to order: s - sort, x - random. - * - * Results: - * A string containing the words ordered. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static char * -VarOrder(const char *str, const char otype) -{ - Buffer buf; /* Buffer for the new string */ - char **av; /* word list [first word does not count] */ - char *as; /* word list memory */ - int ac, i; - - Buf_Init(&buf, 0); - - av = brk_string(str, &ac, FALSE, &as); - - if (ac > 0) - switch (otype) { - case 's': /* sort alphabetically */ - qsort(av, ac, sizeof(char *), VarWordCompare); - break; - case 'x': /* randomize */ - { - int rndidx; - char *t; - - /* - * We will use [ac..2] range for mod factors. This will produce - * random numbers in [(ac-1)..0] interval, and minimal - * reasonable value for mod factor is 2 (the mod 1 will produce - * 0 with probability 1). - */ - for (i = ac-1; i > 0; i--) { - rndidx = random() % (i + 1); - if (i != rndidx) { - t = av[i]; - av[i] = av[rndidx]; - av[rndidx] = t; - } - } - } - } /* end of switch */ - - for (i = 0; i < ac; i++) { - Buf_AddBytes(&buf, strlen(av[i]), av[i]); - if (i != ac - 1) - Buf_AddByte(&buf, ' '); - } - - free(as); - free(av); - - return Buf_Destroy(&buf, FALSE); -} - - -/*- - *----------------------------------------------------------------------- - * VarUniq -- - * Remove adjacent duplicate words. - * - * Input: - * str String whose words should be sorted - * - * Results: - * A string containing the resulting words. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static char * -VarUniq(const char *str) -{ - Buffer buf; /* Buffer for new string */ - char **av; /* List of words to affect */ - char *as; /* Word list memory */ - int ac, i, j; - - Buf_Init(&buf, 0); - av = brk_string(str, &ac, FALSE, &as); - - if (ac > 1) { - for (j = 0, i = 1; i < ac; i++) - if (strcmp(av[i], av[j]) != 0 && (++j != i)) - av[j] = av[i]; - ac = j + 1; - } - - for (i = 0; i < ac; i++) { - Buf_AddBytes(&buf, strlen(av[i]), av[i]); - if (i != ac - 1) - Buf_AddByte(&buf, ' '); - } - - free(as); - free(av); - - return Buf_Destroy(&buf, FALSE); -} - - -/*- - *----------------------------------------------------------------------- - * VarGetPattern -- - * Pass through the tstr looking for 1) escaped delimiters, - * '$'s and backslashes (place the escaped character in - * uninterpreted) and 2) unescaped $'s that aren't before - * the delimiter (expand the variable substitution unless flags - * has VAR_NOSUBST set). - * Return the expanded string or NULL if the delimiter was missing - * If pattern is specified, handle escaped ampersands, and replace - * unescaped ampersands with the lhs of the pattern. - * - * Results: - * A string of all the words modified appropriately. - * If length is specified, return the string length of the buffer - * If flags is specified and the last character of the pattern is a - * $ set the VAR_MATCH_END bit of flags. - * - * Side Effects: - * None. - *----------------------------------------------------------------------- - */ -static char * -VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED, - int errnum, const char **tstr, int delim, int *flags, - int *length, VarPattern *pattern) -{ - const char *cp; - char *rstr; - Buffer buf; - int junk; - - Buf_Init(&buf, 0); - if (length == NULL) - length = &junk; - -#define IS_A_MATCH(cp, delim) \ - ((cp[0] == '\\') && ((cp[1] == delim) || \ - (cp[1] == '\\') || (cp[1] == '$') || (pattern && (cp[1] == '&')))) - - /* - * Skim through until the matching delimiter is found; - * pick up variable substitutions on the way. Also allow - * backslashes to quote the delimiter, $, and \, but don't - * touch other backslashes. - */ - for (cp = *tstr; *cp && (*cp != delim); cp++) { - if (IS_A_MATCH(cp, delim)) { - Buf_AddByte(&buf, cp[1]); - cp++; - } else if (*cp == '$') { - if (cp[1] == delim) { - if (flags == NULL) - Buf_AddByte(&buf, *cp); - else - /* - * Unescaped $ at end of pattern => anchor - * pattern at end. - */ - *flags |= VAR_MATCH_END; - } else { - if (flags == NULL || (*flags & VAR_NOSUBST) == 0) { - char *cp2; - int len; - void *freeIt; - - /* - * If unescaped dollar sign not before the - * delimiter, assume it's a variable - * substitution and recurse. - */ - cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt); - Buf_AddBytes(&buf, strlen(cp2), cp2); - if (freeIt) - free(freeIt); - cp += len - 1; - } else { - const char *cp2 = &cp[1]; - - if (*cp2 == PROPEN || *cp2 == BROPEN) { - /* - * Find the end of this variable reference - * and suck it in without further ado. - * It will be interperated later. - */ - int have = *cp2; - int want = (*cp2 == PROPEN) ? PRCLOSE : BRCLOSE; - int depth = 1; - - for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) { - if (cp2[-1] != '\\') { - if (*cp2 == have) - ++depth; - if (*cp2 == want) - --depth; - } - } - Buf_AddBytes(&buf, cp2 - cp, cp); - cp = --cp2; - } else - Buf_AddByte(&buf, *cp); - } - } - } - else if (pattern && *cp == '&') - Buf_AddBytes(&buf, pattern->leftLen, pattern->lhs); - else - Buf_AddByte(&buf, *cp); - } - - if (*cp != delim) { - *tstr = cp; - *length = 0; - return NULL; - } - - *tstr = ++cp; - *length = Buf_Size(&buf); - rstr = Buf_Destroy(&buf, FALSE); - if (DEBUG(VAR)) - fprintf(debug_file, "Modifier pattern: \"%s\"\n", rstr); - return rstr; -} - -/*- - *----------------------------------------------------------------------- - * VarQuote -- - * Quote shell meta-characters in the string - * - * Results: - * The quoted string - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static char * -VarQuote(char *str) -{ - - Buffer buf; - /* This should cover most shells :-( */ - static const char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~"; - const char *newline; - size_t len, nlen; - - if ((newline = Shell_GetNewline()) == NULL) - newline = "\\\n"; - nlen = strlen(newline); - - Buf_Init(&buf, 0); - while (*str != '\0') { - if ((len = strcspn(str, meta)) != 0) { - Buf_AddBytes(&buf, len, str); - str += len; - } else if (*str == '\n') { - Buf_AddBytes(&buf, nlen, newline); - ++str; - } else { - Buf_AddByte(&buf, '\\'); - Buf_AddByte(&buf, *str); - ++str; - } - } - str = Buf_Destroy(&buf, FALSE); - if (DEBUG(VAR)) - fprintf(debug_file, "QuoteMeta: [%s]\n", str); - return str; -} - -/*- - *----------------------------------------------------------------------- - * VarHash -- - * Hash the string using the MurmurHash3 algorithm. - * Output is computed using 32bit Little Endian arithmetic. - * - * Input: - * str String to modify - * - * Results: - * Hash value of str, encoded as 8 hex digits. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static char * -VarHash(char *str) -{ - static const char hexdigits[16] = "0123456789abcdef"; - Buffer buf; - size_t len, len2; - unsigned char *ustr = (unsigned char *)str; - uint32_t h, k, c1, c2; - int done; - - done = 1; - h = 0x971e137bU; - c1 = 0x95543787U; - c2 = 0x2ad7eb25U; - len2 = strlen(str); - - for (len = len2; len; ) { - k = 0; - switch (len) { - default: - k = (ustr[3] << 24) | (ustr[2] << 16) | (ustr[1] << 8) | ustr[0]; - len -= 4; - ustr += 4; - break; - case 3: - k |= (ustr[2] << 16); - case 2: - k |= (ustr[1] << 8); - case 1: - k |= ustr[0]; - len = 0; - } - c1 = c1 * 5 + 0x7b7d159cU; - c2 = c2 * 5 + 0x6bce6396U; - k *= c1; - k = (k << 11) ^ (k >> 21); - k *= c2; - h = (h << 13) ^ (h >> 19); - h = h * 5 + 0x52dce729U; - h ^= k; - } while (!done); - h ^= len2; - h *= 0x85ebca6b; - h ^= h >> 13; - h *= 0xc2b2ae35; - h ^= h >> 16; - - Buf_Init(&buf, 0); - for (len = 0; len < 8; ++len) { - Buf_AddByte(&buf, hexdigits[h & 15]); - h >>= 4; - } - - return Buf_Destroy(&buf, FALSE); -} - -/*- - *----------------------------------------------------------------------- - * VarChangeCase -- - * Change the string to all uppercase or all lowercase - * - * Input: - * str String to modify - * upper TRUE -> uppercase, else lowercase - * - * Results: - * The string with case changed - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static char * -VarChangeCase(char *str, int upper) -{ - Buffer buf; - int (*modProc)(int); - - modProc = (upper ? toupper : tolower); - Buf_Init(&buf, 0); - for (; *str ; str++) { - Buf_AddByte(&buf, modProc(*str)); - } - return Buf_Destroy(&buf, FALSE); -} - -static char * -VarStrftime(const char *fmt, int zulu) -{ - char buf[BUFSIZ]; - time_t utc; - - time(&utc); - if (!*fmt) - fmt = "%c"; - strftime(buf, sizeof(buf), fmt, zulu ? gmtime(&utc) : localtime(&utc)); - - buf[sizeof(buf) - 1] = '\0'; - return bmake_strdup(buf); -} - -/* - * Now we need to apply any modifiers the user wants applied. - * These are: - * :M<pattern> words which match the given <pattern>. - * <pattern> is of the standard file - * wildcarding form. - * :N<pattern> words which do not match the given <pattern>. - * :S<d><pat1><d><pat2><d>[1gW] - * Substitute <pat2> for <pat1> in the value - * :C<d><pat1><d><pat2><d>[1gW] - * Substitute <pat2> for regex <pat1> in the value - * :H Substitute the head of each word - * :T Substitute the tail of each word - * :E Substitute the extension (minus '.') of - * each word - * :R Substitute the root of each word - * (pathname minus the suffix). - * :O ("Order") Alphabeticaly sort words in variable. - * :Ox ("intermiX") Randomize words in variable. - * :u ("uniq") Remove adjacent duplicate words. - * :tu Converts the variable contents to uppercase. - * :tl Converts the variable contents to lowercase. - * :ts[c] Sets varSpace - the char used to - * separate words to 'c'. If 'c' is - * omitted then no separation is used. - * :tW Treat the variable contents as a single - * word, even if it contains spaces. - * (Mnemonic: one big 'W'ord.) - * :tw Treat the variable contents as multiple - * space-separated words. - * (Mnemonic: many small 'w'ords.) - * :[index] Select a single word from the value. - * :[start..end] Select multiple words from the value. - * :[*] or :[0] Select the entire value, as a single - * word. Equivalent to :tW. - * :[@] Select the entire value, as multiple - * words. Undoes the effect of :[*]. - * Equivalent to :tw. - * :[#] Returns the number of words in the value. - * - * :?<true-value>:<false-value> - * If the variable evaluates to true, return - * true value, else return the second value. - * :lhs=rhs Like :S, but the rhs goes to the end of - * the invocation. - * :sh Treat the current value as a command - * to be run, new value is its output. - * The following added so we can handle ODE makefiles. - * :@<tmpvar>@<newval>@ - * Assign a temporary local variable <tmpvar> - * to the current value of each word in turn - * and replace each word with the result of - * evaluating <newval> - * :D<newval> Use <newval> as value if variable defined - * :U<newval> Use <newval> as value if variable undefined - * :L Use the name of the variable as the value. - * :P Use the path of the node that has the same - * name as the variable as the value. This - * basically includes an implied :L so that - * the common method of refering to the path - * of your dependent 'x' in a rule is to use - * the form '${x:P}'. - * :!<cmd>! Run cmd much the same as :sh run's the - * current value of the variable. - * The ::= modifiers, actually assign a value to the variable. - * Their main purpose is in supporting modifiers of .for loop - * iterators and other obscure uses. They always expand to - * nothing. In a target rule that would otherwise expand to an - * empty line they can be preceded with @: to keep make happy. - * Eg. - * - * foo: .USE - * .for i in ${.TARGET} ${.TARGET:R}.gz - * @: ${t::=$i} - * @echo blah ${t:T} - * .endfor - * - * ::=<str> Assigns <str> as the new value of variable. - * ::?=<str> Assigns <str> as value of variable if - * it was not already set. - * ::+=<str> Appends <str> to variable. - * ::!=<cmd> Assigns output of <cmd> as the new value of - * variable. - */ - -/* we now have some modifiers with long names */ -#define STRMOD_MATCH(s, want, n) \ - (strncmp(s, want, n) == 0 && (s[n] == endc || s[n] == ':')) - -static char * -ApplyModifiers(char *nstr, const char *tstr, - int startc, int endc, - Var *v, GNode *ctxt, Boolean errnum, - int *lengthPtr, void **freePtr) -{ - const char *start; - const char *cp; /* Secondary pointer into str (place marker - * for tstr) */ - char *newStr; /* New value to return */ - char termc; /* Character which terminated scan */ - int cnt; /* Used to count brace pairs when variable in - * in parens or braces */ - char delim; - int modifier; /* that we are processing */ - Var_Parse_State parsestate; /* Flags passed to helper functions */ - - delim = '\0'; - parsestate.oneBigWord = FALSE; - parsestate.varSpace = ' '; /* word separator */ - - start = cp = tstr; - - while (*tstr && *tstr != endc) { - - if (*tstr == '$') { - /* - * We may have some complex modifiers in a variable. - */ - void *freeIt; - char *rval; - int rlen; - int c; - - rval = Var_Parse(tstr, ctxt, errnum, &rlen, &freeIt); - - /* - * If we have not parsed up to endc or ':', - * we are not interested. - */ - if (rval != NULL && *rval && - (c = tstr[rlen]) != '\0' && - c != ':' && - c != endc) { - if (freeIt) - free(freeIt); - goto apply_mods; - } - - if (DEBUG(VAR)) { - fprintf(debug_file, "Got '%s' from '%.*s'%.*s\n", - rval, rlen, tstr, rlen, tstr + rlen); - } - - tstr += rlen; - - if (rval != NULL && *rval) { - int used; - - nstr = ApplyModifiers(nstr, rval, - 0, 0, - v, ctxt, errnum, &used, freePtr); - if (nstr == var_Error - || (nstr == varNoError && errnum == 0) - || strlen(rval) != (size_t) used) { - if (freeIt) - free(freeIt); - goto out; /* error already reported */ - } - } - if (freeIt) - free(freeIt); - if (*tstr == ':') - tstr++; - else if (!*tstr && endc) { - Error("Unclosed variable specification after complex modifier (expecting '%c') for %s", endc, v->name); - goto out; - } - continue; - } - apply_mods: - if (DEBUG(VAR)) { - fprintf(debug_file, "Applying :%c to \"%s\"\n", *tstr, nstr); - } - newStr = var_Error; - switch ((modifier = *tstr)) { - case ':': - { - if (tstr[1] == '=' || - (tstr[2] == '=' && - (tstr[1] == '!' || tstr[1] == '+' || tstr[1] == '?'))) { - /* - * "::=", "::!=", "::+=", or "::?=" - */ - GNode *v_ctxt; /* context where v belongs */ - const char *emsg; - char *sv_name; - VarPattern pattern; - int how; - - if (v->name[0] == 0) - goto bad_modifier; - - v_ctxt = ctxt; - sv_name = NULL; - ++tstr; - if (v->flags & VAR_JUNK) { - /* - * We need to bmake_strdup() it incase - * VarGetPattern() recurses. - */ - sv_name = v->name; - v->name = bmake_strdup(v->name); - } else if (ctxt != VAR_GLOBAL) { - Var *gv = VarFind(v->name, ctxt, 0); - if (gv == NULL) - v_ctxt = VAR_GLOBAL; - else - VarFreeEnv(gv, TRUE); - } - - switch ((how = *tstr)) { - case '+': - case '?': - case '!': - cp = &tstr[2]; - break; - default: - cp = ++tstr; - break; - } - delim = startc == PROPEN ? PRCLOSE : BRCLOSE; - pattern.flags = 0; - - pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, NULL, - &pattern.rightLen, - NULL); - if (v->flags & VAR_JUNK) { - /* restore original name */ - free(v->name); - v->name = sv_name; - } - if (pattern.rhs == NULL) - goto cleanup; - - termc = *--cp; - delim = '\0'; - - switch (how) { - case '+': - Var_Append(v->name, pattern.rhs, v_ctxt); - break; - case '!': - newStr = Cmd_Exec(pattern.rhs, &emsg); - if (emsg) - Error(emsg, nstr); - else - Var_Set(v->name, newStr, v_ctxt, 0); - if (newStr) - free(newStr); - break; - case '?': - if ((v->flags & VAR_JUNK) == 0) - break; - /* FALLTHROUGH */ - default: - Var_Set(v->name, pattern.rhs, v_ctxt, 0); - break; - } - free(UNCONST(pattern.rhs)); - newStr = var_Error; - break; - } - goto default_case; /* "::<unrecognised>" */ - } - case '@': - { - VarLoop_t loop; - int flags = VAR_NOSUBST; - - cp = ++tstr; - delim = '@'; - if ((loop.tvar = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, - &flags, &loop.tvarLen, - NULL)) == NULL) - goto cleanup; - - if ((loop.str = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, - &flags, &loop.strLen, - NULL)) == NULL) - goto cleanup; - - termc = *cp; - delim = '\0'; - - loop.errnum = errnum; - loop.ctxt = ctxt; - newStr = VarModify(ctxt, &parsestate, nstr, VarLoopExpand, - &loop); - free(loop.tvar); - free(loop.str); - break; - } - case 'D': - case 'U': - { - Buffer buf; /* Buffer for patterns */ - int wantit; /* want data in buffer */ - - /* - * Pass through tstr looking for 1) escaped delimiters, - * '$'s and backslashes (place the escaped character in - * uninterpreted) and 2) unescaped $'s that aren't before - * the delimiter (expand the variable substitution). - * The result is left in the Buffer buf. - */ - Buf_Init(&buf, 0); - for (cp = tstr + 1; - *cp != endc && *cp != ':' && *cp != '\0'; - cp++) { - if ((*cp == '\\') && - ((cp[1] == ':') || - (cp[1] == '$') || - (cp[1] == endc) || - (cp[1] == '\\'))) - { - Buf_AddByte(&buf, cp[1]); - cp++; - } else if (*cp == '$') { - /* - * If unescaped dollar sign, assume it's a - * variable substitution and recurse. - */ - char *cp2; - int len; - void *freeIt; - - cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt); - Buf_AddBytes(&buf, strlen(cp2), cp2); - if (freeIt) - free(freeIt); - cp += len - 1; - } else { - Buf_AddByte(&buf, *cp); - } - } - - termc = *cp; - - if (*tstr == 'U') - wantit = ((v->flags & VAR_JUNK) != 0); - else - wantit = ((v->flags & VAR_JUNK) == 0); - if ((v->flags & VAR_JUNK) != 0) - v->flags |= VAR_KEEP; - if (wantit) { - newStr = Buf_Destroy(&buf, FALSE); - } else { - newStr = nstr; - Buf_Destroy(&buf, TRUE); - } - break; - } - case 'L': - { - if ((v->flags & VAR_JUNK) != 0) - v->flags |= VAR_KEEP; - newStr = bmake_strdup(v->name); - cp = ++tstr; - termc = *tstr; - break; - } - case 'P': - { - GNode *gn; - - if ((v->flags & VAR_JUNK) != 0) - v->flags |= VAR_KEEP; - gn = Targ_FindNode(v->name, TARG_NOCREATE); - if (gn == NULL || gn->type & OP_NOPATH) { - newStr = NULL; - } else if (gn->path) { - newStr = bmake_strdup(gn->path); - } else { - newStr = Dir_FindFile(v->name, Suff_FindPath(gn)); - } - if (!newStr) { - newStr = bmake_strdup(v->name); - } - cp = ++tstr; - termc = *tstr; - break; - } - case '!': - { - const char *emsg; - VarPattern pattern; - pattern.flags = 0; - - delim = '!'; - - cp = ++tstr; - if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, - NULL, &pattern.rightLen, - NULL)) == NULL) - goto cleanup; - newStr = Cmd_Exec(pattern.rhs, &emsg); - free(UNCONST(pattern.rhs)); - if (emsg) - Error(emsg, nstr); - termc = *cp; - delim = '\0'; - if (v->flags & VAR_JUNK) { - v->flags |= VAR_KEEP; - } - break; - } - case '[': - { - /* - * Look for the closing ']', recursively - * expanding any embedded variables. - * - * estr is a pointer to the expanded result, - * which we must free(). - */ - char *estr; - - cp = tstr+1; /* point to char after '[' */ - delim = ']'; /* look for closing ']' */ - estr = VarGetPattern(ctxt, &parsestate, - errnum, &cp, delim, - NULL, NULL, NULL); - if (estr == NULL) - goto cleanup; /* report missing ']' */ - /* now cp points just after the closing ']' */ - delim = '\0'; - if (cp[0] != ':' && cp[0] != endc) { - /* Found junk after ']' */ - free(estr); - goto bad_modifier; - } - if (estr[0] == '\0') { - /* Found empty square brackets in ":[]". */ - free(estr); - goto bad_modifier; - } else if (estr[0] == '#' && estr[1] == '\0') { - /* Found ":[#]" */ - - /* - * We will need enough space for the decimal - * representation of an int. We calculate the - * space needed for the octal representation, - * and add enough slop to cope with a '-' sign - * (which should never be needed) and a '\0' - * string terminator. - */ - int newStrSize = - (sizeof(int) * CHAR_BIT + 2) / 3 + 2; - - newStr = bmake_malloc(newStrSize); - if (parsestate.oneBigWord) { - strncpy(newStr, "1", newStrSize); - } else { - /* XXX: brk_string() is a rather expensive - * way of counting words. */ - char **av; - char *as; - int ac; - - av = brk_string(nstr, &ac, FALSE, &as); - snprintf(newStr, newStrSize, "%d", ac); - free(as); - free(av); - } - termc = *cp; - free(estr); - break; - } else if (estr[0] == '*' && estr[1] == '\0') { - /* Found ":[*]" */ - parsestate.oneBigWord = TRUE; - newStr = nstr; - termc = *cp; - free(estr); - break; - } else if (estr[0] == '@' && estr[1] == '\0') { - /* Found ":[@]" */ - parsestate.oneBigWord = FALSE; - newStr = nstr; - termc = *cp; - free(estr); - break; - } else { - /* - * We expect estr to contain a single - * integer for :[N], or two integers - * separated by ".." for :[start..end]. - */ - char *ep; - - VarSelectWords_t seldata = { 0, 0 }; - - seldata.start = strtol(estr, &ep, 0); - if (ep == estr) { - /* Found junk instead of a number */ - free(estr); - goto bad_modifier; - } else if (ep[0] == '\0') { - /* Found only one integer in :[N] */ - seldata.end = seldata.start; - } else if (ep[0] == '.' && ep[1] == '.' && - ep[2] != '\0') { - /* Expecting another integer after ".." */ - ep += 2; - seldata.end = strtol(ep, &ep, 0); - if (ep[0] != '\0') { - /* Found junk after ".." */ - free(estr); - goto bad_modifier; - } - } else { - /* Found junk instead of ".." */ - free(estr); - goto bad_modifier; - } - /* - * Now seldata is properly filled in, - * but we still have to check for 0 as - * a special case. - */ - if (seldata.start == 0 && seldata.end == 0) { - /* ":[0]" or perhaps ":[0..0]" */ - parsestate.oneBigWord = TRUE; - newStr = nstr; - termc = *cp; - free(estr); - break; - } else if (seldata.start == 0 || - seldata.end == 0) { - /* ":[0..N]" or ":[N..0]" */ - free(estr); - goto bad_modifier; - } - /* - * Normal case: select the words - * described by seldata. - */ - newStr = VarSelectWords(ctxt, &parsestate, - nstr, &seldata); - - termc = *cp; - free(estr); - break; - } - - } - case 'g': - cp = tstr + 1; /* make sure it is set */ - if (STRMOD_MATCH(tstr, "gmtime", 6)) { - newStr = VarStrftime(nstr, 1); - cp = tstr + 6; - termc = *cp; - } else { - goto default_case; - } - break; - case 'h': - cp = tstr + 1; /* make sure it is set */ - if (STRMOD_MATCH(tstr, "hash", 4)) { - newStr = VarHash(nstr); - cp = tstr + 4; - termc = *cp; - } else { - goto default_case; - } - break; - case 'l': - cp = tstr + 1; /* make sure it is set */ - if (STRMOD_MATCH(tstr, "localtime", 9)) { - newStr = VarStrftime(nstr, 0); - cp = tstr + 9; - termc = *cp; - } else { - goto default_case; - } - break; - case 't': - { - cp = tstr + 1; /* make sure it is set */ - if (tstr[1] != endc && tstr[1] != ':') { - if (tstr[1] == 's') { - /* - * Use the char (if any) at tstr[2] - * as the word separator. - */ - VarPattern pattern; - - if (tstr[2] != endc && - (tstr[3] == endc || tstr[3] == ':')) { - /* ":ts<unrecognised><endc>" or - * ":ts<unrecognised>:" */ - parsestate.varSpace = tstr[2]; - cp = tstr + 3; - } else if (tstr[2] == endc || tstr[2] == ':') { - /* ":ts<endc>" or ":ts:" */ - parsestate.varSpace = 0; /* no separator */ - cp = tstr + 2; - } else if (tstr[2] == '\\') { - switch (tstr[3]) { - case 'n': - parsestate.varSpace = '\n'; - cp = tstr + 4; - break; - case 't': - parsestate.varSpace = '\t'; - cp = tstr + 4; - break; - default: - if (isdigit((unsigned char)tstr[3])) { - char *ep; - - parsestate.varSpace = - strtoul(&tstr[3], &ep, 0); - if (*ep != ':' && *ep != endc) - goto bad_modifier; - cp = ep; - } else { - /* - * ":ts<backslash><unrecognised>". - */ - goto bad_modifier; - } - break; - } - } else { - /* - * Found ":ts<unrecognised><unrecognised>". - */ - goto bad_modifier; - } - - termc = *cp; - - /* - * We cannot be certain that VarModify - * will be used - even if there is a - * subsequent modifier, so do a no-op - * VarSubstitute now to for str to be - * re-expanded without the spaces. - */ - pattern.flags = VAR_SUB_ONE; - pattern.lhs = pattern.rhs = "\032"; - pattern.leftLen = pattern.rightLen = 1; - - newStr = VarModify(ctxt, &parsestate, nstr, - VarSubstitute, - &pattern); - } else if (tstr[2] == endc || tstr[2] == ':') { - /* - * Check for two-character options: - * ":tu", ":tl" - */ - if (tstr[1] == 'A') { /* absolute path */ - newStr = VarModify(ctxt, &parsestate, nstr, - VarRealpath, NULL); - cp = tstr + 2; - termc = *cp; - } else if (tstr[1] == 'u' || tstr[1] == 'l') { - newStr = VarChangeCase(nstr, (tstr[1] == 'u')); - cp = tstr + 2; - termc = *cp; - } else if (tstr[1] == 'W' || tstr[1] == 'w') { - parsestate.oneBigWord = (tstr[1] == 'W'); - newStr = nstr; - cp = tstr + 2; - termc = *cp; - } else { - /* Found ":t<unrecognised>:" or - * ":t<unrecognised><endc>". */ - goto bad_modifier; - } - } else { - /* - * Found ":t<unrecognised><unrecognised>". - */ - goto bad_modifier; - } - } else { - /* - * Found ":t<endc>" or ":t:". - */ - goto bad_modifier; - } - break; - } - case 'N': - case 'M': - { - char *pattern; - const char *endpat; /* points just after end of pattern */ - char *cp2; - Boolean copy; /* pattern should be, or has been, copied */ - Boolean needSubst; - int nest; - - copy = FALSE; - needSubst = FALSE; - nest = 1; - /* - * In the loop below, ignore ':' unless we are at - * (or back to) the original brace level. - * XXX This will likely not work right if $() and ${} - * are intermixed. - */ - for (cp = tstr + 1; - *cp != '\0' && !(*cp == ':' && nest == 1); - cp++) - { - if (*cp == '\\' && - (cp[1] == ':' || - cp[1] == endc || cp[1] == startc)) { - if (!needSubst) { - copy = TRUE; - } - cp++; - continue; - } - if (*cp == '$') { - needSubst = TRUE; - } - if (*cp == '(' || *cp == '{') - ++nest; - if (*cp == ')' || *cp == '}') { - --nest; - if (nest == 0) - break; - } - } - termc = *cp; - endpat = cp; - if (copy) { - /* - * Need to compress the \:'s out of the pattern, so - * allocate enough room to hold the uncompressed - * pattern (note that cp started at tstr+1, so - * cp - tstr takes the null byte into account) and - * compress the pattern into the space. - */ - pattern = bmake_malloc(cp - tstr); - for (cp2 = pattern, cp = tstr + 1; - cp < endpat; - cp++, cp2++) - { - if ((*cp == '\\') && (cp+1 < endpat) && - (cp[1] == ':' || cp[1] == endc)) { - cp++; - } - *cp2 = *cp; - } - *cp2 = '\0'; - endpat = cp2; - } else { - /* - * Either Var_Subst or VarModify will need a - * nul-terminated string soon, so construct one now. - */ - pattern = bmake_strndup(tstr+1, endpat - (tstr + 1)); - } - if (needSubst) { - /* - * pattern contains embedded '$', so use Var_Subst to - * expand it. - */ - cp2 = pattern; - pattern = Var_Subst(NULL, cp2, ctxt, errnum); - free(cp2); - } - if (DEBUG(VAR)) - fprintf(debug_file, "Pattern for [%s] is [%s]\n", nstr, - pattern); - if (*tstr == 'M') { - newStr = VarModify(ctxt, &parsestate, nstr, VarMatch, - pattern); - } else { - newStr = VarModify(ctxt, &parsestate, nstr, VarNoMatch, - pattern); - } - free(pattern); - break; - } - case 'S': - { - VarPattern pattern; - Var_Parse_State tmpparsestate; - - pattern.flags = 0; - tmpparsestate = parsestate; - delim = tstr[1]; - tstr += 2; - - /* - * If pattern begins with '^', it is anchored to the - * start of the word -- skip over it and flag pattern. - */ - if (*tstr == '^') { - pattern.flags |= VAR_MATCH_START; - tstr += 1; - } - - cp = tstr; - if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, - &pattern.flags, - &pattern.leftLen, - NULL)) == NULL) - goto cleanup; - - if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, NULL, - &pattern.rightLen, - &pattern)) == NULL) - goto cleanup; - - /* - * Check for global substitution. If 'g' after the final - * delimiter, substitution is global and is marked that - * way. - */ - for (;; cp++) { - switch (*cp) { - case 'g': - pattern.flags |= VAR_SUB_GLOBAL; - continue; - case '1': - pattern.flags |= VAR_SUB_ONE; - continue; - case 'W': - tmpparsestate.oneBigWord = TRUE; - continue; - } - break; - } - - termc = *cp; - newStr = VarModify(ctxt, &tmpparsestate, nstr, - VarSubstitute, - &pattern); - - /* - * Free the two strings. - */ - free(UNCONST(pattern.lhs)); - free(UNCONST(pattern.rhs)); - delim = '\0'; - break; - } - case '?': - { - VarPattern pattern; - Boolean value; - - /* find ':', and then substitute accordingly */ - - pattern.flags = 0; - - cp = ++tstr; - delim = ':'; - if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, NULL, - &pattern.leftLen, - NULL)) == NULL) - goto cleanup; - - /* BROPEN or PROPEN */ - delim = endc; - if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, NULL, - &pattern.rightLen, - NULL)) == NULL) - goto cleanup; - - termc = *--cp; - delim = '\0'; - if (Cond_EvalExpression(NULL, v->name, &value, 0) - == COND_INVALID) { - Error("Bad conditional expression `%s' in %s?%s:%s", - v->name, v->name, pattern.lhs, pattern.rhs); - goto cleanup; - } - - if (value) { - newStr = UNCONST(pattern.lhs); - free(UNCONST(pattern.rhs)); - } else { - newStr = UNCONST(pattern.rhs); - free(UNCONST(pattern.lhs)); - } - if (v->flags & VAR_JUNK) { - v->flags |= VAR_KEEP; - } - break; - } -#ifndef NO_REGEX - case 'C': - { - VarREPattern pattern; - char *re; - int error; - Var_Parse_State tmpparsestate; - - pattern.flags = 0; - tmpparsestate = parsestate; - delim = tstr[1]; - tstr += 2; - - cp = tstr; - - if ((re = VarGetPattern(ctxt, &parsestate, errnum, &cp, delim, - NULL, NULL, NULL)) == NULL) - goto cleanup; - - if ((pattern.replace = VarGetPattern(ctxt, &parsestate, - errnum, &cp, delim, NULL, - NULL, NULL)) == NULL){ - free(re); - goto cleanup; - } - - for (;; cp++) { - switch (*cp) { - case 'g': - pattern.flags |= VAR_SUB_GLOBAL; - continue; - case '1': - pattern.flags |= VAR_SUB_ONE; - continue; - case 'W': - tmpparsestate.oneBigWord = TRUE; - continue; - } - break; - } - - termc = *cp; - - error = regcomp(&pattern.re, re, REG_EXTENDED); - free(re); - if (error) { - *lengthPtr = cp - start + 1; - VarREError(error, &pattern.re, "RE substitution error"); - free(pattern.replace); - goto cleanup; - } - - pattern.nsub = pattern.re.re_nsub + 1; - if (pattern.nsub < 1) - pattern.nsub = 1; - if (pattern.nsub > 10) - pattern.nsub = 10; - pattern.matches = bmake_malloc(pattern.nsub * - sizeof(regmatch_t)); - newStr = VarModify(ctxt, &tmpparsestate, nstr, - VarRESubstitute, - &pattern); - regfree(&pattern.re); - free(pattern.replace); - free(pattern.matches); - delim = '\0'; - break; - } -#endif - case 'Q': - if (tstr[1] == endc || tstr[1] == ':') { - newStr = VarQuote(nstr); - cp = tstr + 1; - termc = *cp; - break; - } - goto default_case; - case 'T': - if (tstr[1] == endc || tstr[1] == ':') { - newStr = VarModify(ctxt, &parsestate, nstr, VarTail, - NULL); - cp = tstr + 1; - termc = *cp; - break; - } - goto default_case; - case 'H': - if (tstr[1] == endc || tstr[1] == ':') { - newStr = VarModify(ctxt, &parsestate, nstr, VarHead, - NULL); - cp = tstr + 1; - termc = *cp; - break; - } - goto default_case; - case 'E': - if (tstr[1] == endc || tstr[1] == ':') { - newStr = VarModify(ctxt, &parsestate, nstr, VarSuffix, - NULL); - cp = tstr + 1; - termc = *cp; - break; - } - goto default_case; - case 'R': - if (tstr[1] == endc || tstr[1] == ':') { - newStr = VarModify(ctxt, &parsestate, nstr, VarRoot, - NULL); - cp = tstr + 1; - termc = *cp; - break; - } - goto default_case; - case 'O': - { - char otype; - - cp = tstr + 1; /* skip to the rest in any case */ - if (tstr[1] == endc || tstr[1] == ':') { - otype = 's'; - termc = *cp; - } else if ( (tstr[1] == 'x') && - (tstr[2] == endc || tstr[2] == ':') ) { - otype = tstr[1]; - cp = tstr + 2; - termc = *cp; - } else { - goto bad_modifier; - } - newStr = VarOrder(nstr, otype); - break; - } - case 'u': - if (tstr[1] == endc || tstr[1] == ':') { - newStr = VarUniq(nstr); - cp = tstr + 1; - termc = *cp; - break; - } - goto default_case; -#ifdef SUNSHCMD - case 's': - if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) { - const char *emsg; - newStr = Cmd_Exec(nstr, &emsg); - if (emsg) - Error(emsg, nstr); - cp = tstr + 2; - termc = *cp; - break; - } - goto default_case; -#endif - default: - default_case: - { -#ifdef SYSVVARSUB - /* - * This can either be a bogus modifier or a System-V - * substitution command. - */ - VarPattern pattern; - Boolean eqFound; - - pattern.flags = 0; - eqFound = FALSE; - /* - * First we make a pass through the string trying - * to verify it is a SYSV-make-style translation: - * it must be: <string1>=<string2>) - */ - cp = tstr; - cnt = 1; - while (*cp != '\0' && cnt) { - if (*cp == '=') { - eqFound = TRUE; - /* continue looking for endc */ - } - else if (*cp == endc) - cnt--; - else if (*cp == startc) - cnt++; - if (cnt) - cp++; - } - if (*cp == endc && eqFound) { - - /* - * Now we break this sucker into the lhs and - * rhs. We must null terminate them of course. - */ - delim='='; - cp = tstr; - if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, - errnum, &cp, delim, &pattern.flags, - &pattern.leftLen, NULL)) == NULL) - goto cleanup; - delim = endc; - if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, - errnum, &cp, delim, NULL, &pattern.rightLen, - &pattern)) == NULL) - goto cleanup; - - /* - * SYSV modifications happen through the whole - * string. Note the pattern is anchored at the end. - */ - termc = *--cp; - delim = '\0'; - if (pattern.leftLen == 0 && *nstr == '\0') { - newStr = nstr; /* special case */ - } else { - newStr = VarModify(ctxt, &parsestate, nstr, - VarSYSVMatch, - &pattern); - } - free(UNCONST(pattern.lhs)); - free(UNCONST(pattern.rhs)); - } else -#endif - { - Error("Unknown modifier '%c'", *tstr); - for (cp = tstr+1; - *cp != ':' && *cp != endc && *cp != '\0'; - cp++) - continue; - termc = *cp; - newStr = var_Error; - } - } - } - if (DEBUG(VAR)) { - fprintf(debug_file, "Result of :%c is \"%s\"\n", modifier, newStr); - } - - if (newStr != nstr) { - if (*freePtr) { - free(nstr); - *freePtr = NULL; - } - nstr = newStr; - if (nstr != var_Error && nstr != varNoError) { - *freePtr = nstr; - } - } - if (termc == '\0' && endc != '\0') { - Error("Unclosed variable specification (expecting '%c') for \"%s\" (value \"%s\") modifier %c", endc, v->name, nstr, modifier); - } else if (termc == ':') { - cp++; - } - tstr = cp; - } - out: - *lengthPtr = tstr - start; - return (nstr); - - bad_modifier: - /* "{(" */ - Error("Bad modifier `:%.*s' for %s", (int)strcspn(tstr, ":)}"), tstr, - v->name); - - cleanup: - *lengthPtr = cp - start; - if (delim != '\0') - Error("Unclosed substitution for %s (%c missing)", - v->name, delim); - if (*freePtr) { - free(*freePtr); - *freePtr = NULL; - } - return (var_Error); -} - -/*- - *----------------------------------------------------------------------- - * Var_Parse -- - * Given the start of a variable invocation, extract the variable - * name and find its value, then modify it according to the - * specification. - * - * Input: - * str The string to parse - * ctxt The context for the variable - * errnum TRUE if undefined variables are an error - * lengthPtr OUT: The length of the specification - * freePtr OUT: Non-NULL if caller should free *freePtr - * - * Results: - * The (possibly-modified) value of the variable or var_Error if the - * specification is invalid. The length of the specification is - * placed in *lengthPtr (for invalid specifications, this is just - * 2...?). - * If *freePtr is non-NULL then it's a pointer that the caller - * should pass to free() to free memory used by the result. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -/* coverity[+alloc : arg-*4] */ -char * -Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, - void **freePtr) -{ - const char *tstr; /* Pointer into str */ - Var *v; /* Variable in invocation */ - Boolean haveModifier;/* TRUE if have modifiers for the variable */ - char endc; /* Ending character when variable in parens - * or braces */ - char startc; /* Starting character when variable in parens - * or braces */ - int vlen; /* Length of variable name */ - const char *start; /* Points to original start of str */ - char *nstr; /* New string, used during expansion */ - Boolean dynamic; /* TRUE if the variable is local and we're - * expanding it in a non-local context. This - * is done to support dynamic sources. The - * result is just the invocation, unaltered */ - Var_Parse_State parsestate; /* Flags passed to helper functions */ - char name[2]; - - *freePtr = NULL; - dynamic = FALSE; - start = str; - parsestate.oneBigWord = FALSE; - parsestate.varSpace = ' '; /* word separator */ - - startc = str[1]; - if (startc != PROPEN && startc != BROPEN) { - /* - * If it's not bounded by braces of some sort, life is much simpler. - * We just need to check for the first character and return the - * value if it exists. - */ - - /* Error out some really stupid names */ - if (startc == '\0' || strchr(")}:$", startc)) { - *lengthPtr = 1; - return var_Error; - } - name[0] = startc; - name[1] = '\0'; - - v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); - if (v == NULL) { - *lengthPtr = 2; - - if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) { - /* - * If substituting a local variable in a non-local context, - * assume it's for dynamic source stuff. We have to handle - * this specially and return the longhand for the variable - * with the dollar sign escaped so it makes it back to the - * caller. Only four of the local variables are treated - * specially as they are the only four that will be set - * when dynamic sources are expanded. - */ - switch (str[1]) { - case '@': - return UNCONST("$(.TARGET)"); - case '%': - return UNCONST("$(.ARCHIVE)"); - case '*': - return UNCONST("$(.PREFIX)"); - case '!': - return UNCONST("$(.MEMBER)"); - } - } - /* - * Error - */ - return (errnum ? var_Error : varNoError); - } else { - haveModifier = FALSE; - tstr = &str[1]; - endc = str[1]; - } - } else { - Buffer buf; /* Holds the variable name */ - - endc = startc == PROPEN ? PRCLOSE : BRCLOSE; - Buf_Init(&buf, 0); - - /* - * Skip to the end character or a colon, whichever comes first. - */ - for (tstr = str + 2; - *tstr != '\0' && *tstr != endc && *tstr != ':'; - tstr++) - { - /* - * A variable inside a variable, expand - */ - if (*tstr == '$') { - int rlen; - void *freeIt; - char *rval = Var_Parse(tstr, ctxt, errnum, &rlen, &freeIt); - if (rval != NULL) { - Buf_AddBytes(&buf, strlen(rval), rval); - } - if (freeIt) - free(freeIt); - tstr += rlen - 1; - } - else - Buf_AddByte(&buf, *tstr); - } - if (*tstr == ':') { - haveModifier = TRUE; - } else if (*tstr != '\0') { - haveModifier = FALSE; - } else { - /* - * If we never did find the end character, return NULL - * right now, setting the length to be the distance to - * the end of the string, since that's what make does. - */ - *lengthPtr = tstr - str; - Buf_Destroy(&buf, TRUE); - return (var_Error); - } - str = Buf_GetAll(&buf, &vlen); - - /* - * At this point, str points into newly allocated memory from - * buf, containing only the name of the variable. - * - * start and tstr point into the const string that was pointed - * to by the original value of the str parameter. start points - * to the '$' at the beginning of the string, while tstr points - * to the char just after the end of the variable name -- this - * will be '\0', ':', PRCLOSE, or BRCLOSE. - */ - - v = VarFind(str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); - /* - * Check also for bogus D and F forms of local variables since we're - * in a local context and the name is the right length. - */ - if ((v == NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) && - (vlen == 2) && (str[1] == 'F' || str[1] == 'D') && - strchr("@%*!<>", str[0]) != NULL) { - /* - * Well, it's local -- go look for it. - */ - name[0] = *str; - name[1] = '\0'; - v = VarFind(name, ctxt, 0); - - if (v != NULL) { - /* - * No need for nested expansion or anything, as we're - * the only one who sets these things and we sure don't - * but nested invocations in them... - */ - nstr = Buf_GetAll(&v->val, NULL); - - if (str[1] == 'D') { - nstr = VarModify(ctxt, &parsestate, nstr, VarHead, - NULL); - } else { - nstr = VarModify(ctxt, &parsestate, nstr, VarTail, - NULL); - } - /* - * Resulting string is dynamically allocated, so - * tell caller to free it. - */ - *freePtr = nstr; - *lengthPtr = tstr-start+1; - Buf_Destroy(&buf, TRUE); - VarFreeEnv(v, TRUE); - return nstr; - } - } - - if (v == NULL) { - if (((vlen == 1) || - (((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) && - ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) - { - /* - * If substituting a local variable in a non-local context, - * assume it's for dynamic source stuff. We have to handle - * this specially and return the longhand for the variable - * with the dollar sign escaped so it makes it back to the - * caller. Only four of the local variables are treated - * specially as they are the only four that will be set - * when dynamic sources are expanded. - */ - switch (*str) { - case '@': - case '%': - case '*': - case '!': - dynamic = TRUE; - break; - } - } else if ((vlen > 2) && (*str == '.') && - isupper((unsigned char) str[1]) && - ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) - { - int len; - - len = vlen - 1; - if ((strncmp(str, ".TARGET", len) == 0) || - (strncmp(str, ".ARCHIVE", len) == 0) || - (strncmp(str, ".PREFIX", len) == 0) || - (strncmp(str, ".MEMBER", len) == 0)) - { - dynamic = TRUE; - } - } - - if (!haveModifier) { - /* - * No modifiers -- have specification length so we can return - * now. - */ - *lengthPtr = tstr - start + 1; - if (dynamic) { - char *pstr = bmake_strndup(start, *lengthPtr); - *freePtr = pstr; - Buf_Destroy(&buf, TRUE); - return(pstr); - } else { - Buf_Destroy(&buf, TRUE); - return (errnum ? var_Error : varNoError); - } - } else { - /* - * Still need to get to the end of the variable specification, - * so kludge up a Var structure for the modifications - */ - v = bmake_malloc(sizeof(Var)); - v->name = UNCONST(str); - Buf_Init(&v->val, 1); - v->flags = VAR_JUNK; - Buf_Destroy(&buf, FALSE); - } - } else - Buf_Destroy(&buf, TRUE); - } - - if (v->flags & VAR_IN_USE) { - Fatal("Variable %s is recursive.", v->name); - /*NOTREACHED*/ - } else { - v->flags |= VAR_IN_USE; - } - /* - * Before doing any modification, we have to make sure the value - * has been fully expanded. If it looks like recursion might be - * necessary (there's a dollar sign somewhere in the variable's value) - * we just call Var_Subst to do any other substitutions that are - * necessary. Note that the value returned by Var_Subst will have - * been dynamically-allocated, so it will need freeing when we - * return. - */ - nstr = Buf_GetAll(&v->val, NULL); - if (strchr(nstr, '$') != NULL) { - nstr = Var_Subst(NULL, nstr, ctxt, errnum); - *freePtr = nstr; - } - - v->flags &= ~VAR_IN_USE; - - if ((nstr != NULL) && haveModifier) { - int used; - /* - * Skip initial colon. - */ - tstr++; - - nstr = ApplyModifiers(nstr, tstr, startc, endc, - v, ctxt, errnum, &used, freePtr); - tstr += used; - } - if (*tstr) { - *lengthPtr = tstr - start + 1; - } else { - *lengthPtr = tstr - start; - } - - if (v->flags & VAR_FROM_ENV) { - Boolean destroy = FALSE; - - if (nstr != Buf_GetAll(&v->val, NULL)) { - destroy = TRUE; - } else { - /* - * Returning the value unmodified, so tell the caller to free - * the thing. - */ - *freePtr = nstr; - } - VarFreeEnv(v, destroy); - } else if (v->flags & VAR_JUNK) { - /* - * Perform any free'ing needed and set *freePtr to NULL so the caller - * doesn't try to free a static pointer. - * If VAR_KEEP is also set then we want to keep str as is. - */ - if (!(v->flags & VAR_KEEP)) { - if (*freePtr) { - free(nstr); - *freePtr = NULL; - } - if (dynamic) { - nstr = bmake_strndup(start, *lengthPtr); - *freePtr = nstr; - } else { - nstr = errnum ? var_Error : varNoError; - } - } - if (nstr != Buf_GetAll(&v->val, NULL)) - Buf_Destroy(&v->val, TRUE); - free(v->name); - free(v); - } - return (nstr); -} - -/*- - *----------------------------------------------------------------------- - * Var_Subst -- - * Substitute for all variables in the given string in the given context - * If undefErr is TRUE, Parse_Error will be called when an undefined - * variable is encountered. - * - * Input: - * var Named variable || NULL for all - * str the string which to substitute - * ctxt the context wherein to find variables - * undefErr TRUE if undefineds are an error - * - * Results: - * The resulting string. - * - * Side Effects: - * None. The old string must be freed by the caller - *----------------------------------------------------------------------- - */ -char * -Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr) -{ - Buffer buf; /* Buffer for forming things */ - char *val; /* Value to substitute for a variable */ - int length; /* Length of the variable invocation */ - Boolean trailingBslash; /* variable ends in \ */ - void *freeIt = NULL; /* Set if it should be freed */ - static Boolean errorReported; /* Set true if an error has already - * been reported to prevent a plethora - * of messages when recursing */ - - Buf_Init(&buf, 0); - errorReported = FALSE; - trailingBslash = FALSE; - - while (*str) { - if (*str == '\n' && trailingBslash) - Buf_AddByte(&buf, ' '); - if (var == NULL && (*str == '$') && (str[1] == '$')) { - /* - * A dollar sign may be escaped either with another dollar sign. - * In such a case, we skip over the escape character and store the - * dollar sign into the buffer directly. - */ - str++; - Buf_AddByte(&buf, *str); - str++; - } else if (*str != '$') { - /* - * Skip as many characters as possible -- either to the end of - * the string or to the next dollar sign (variable invocation). - */ - const char *cp; - - for (cp = str++; *str != '$' && *str != '\0'; str++) - continue; - Buf_AddBytes(&buf, str - cp, cp); - } else { - if (var != NULL) { - int expand; - for (;;) { - if (str[1] == '\0') { - /* A trailing $ is kind of a special case */ - Buf_AddByte(&buf, str[0]); - str++; - expand = FALSE; - } else if (str[1] != PROPEN && str[1] != BROPEN) { - if (str[1] != *var || strlen(var) > 1) { - Buf_AddBytes(&buf, 2, str); - str += 2; - expand = FALSE; - } - else - expand = TRUE; - break; - } - else { - const char *p; - - /* - * Scan up to the end of the variable name. - */ - for (p = &str[2]; *p && - *p != ':' && *p != PRCLOSE && *p != BRCLOSE; p++) - if (*p == '$') - break; - /* - * A variable inside the variable. We cannot expand - * the external variable yet, so we try again with - * the nested one - */ - if (*p == '$') { - Buf_AddBytes(&buf, p - str, str); - str = p; - continue; - } - - if (strncmp(var, str + 2, p - str - 2) != 0 || - var[p - str - 2] != '\0') { - /* - * Not the variable we want to expand, scan - * until the next variable - */ - for (;*p != '$' && *p != '\0'; p++) - continue; - Buf_AddBytes(&buf, p - str, str); - str = p; - expand = FALSE; - } - else - expand = TRUE; - break; - } - } - if (!expand) - continue; - } - - val = Var_Parse(str, ctxt, undefErr, &length, &freeIt); - - /* - * When we come down here, val should either point to the - * value of this variable, suitably modified, or be NULL. - * Length should be the total length of the potential - * variable invocation (from $ to end character...) - */ - if (val == var_Error || val == varNoError) { - /* - * If performing old-time variable substitution, skip over - * the variable and continue with the substitution. Otherwise, - * store the dollar sign and advance str so we continue with - * the string... - */ - if (oldVars) { - str += length; - } else if (undefErr) { - /* - * If variable is undefined, complain and skip the - * variable. The complaint will stop us from doing anything - * when the file is parsed. - */ - if (!errorReported) { - Parse_Error(PARSE_FATAL, - "Undefined variable \"%.*s\"",length,str); - } - str += length; - errorReported = TRUE; - } else { - Buf_AddByte(&buf, *str); - str += 1; - } - } else { - /* - * We've now got a variable structure to store in. But first, - * advance the string pointer. - */ - str += length; - - /* - * Copy all the characters from the variable value straight - * into the new string. - */ - length = strlen(val); - Buf_AddBytes(&buf, length, val); - trailingBslash = length > 0 && val[length - 1] == '\\'; - } - if (freeIt) { - free(freeIt); - freeIt = NULL; - } - } - } - - return Buf_DestroyCompact(&buf); -} - -/*- - *----------------------------------------------------------------------- - * Var_GetTail -- - * Return the tail from each of a list of words. Used to set the - * System V local variables. - * - * Input: - * file Filename to modify - * - * Results: - * The resulting string. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -#if 0 -char * -Var_GetTail(char *file) -{ - return(VarModify(file, VarTail, NULL)); -} - -/*- - *----------------------------------------------------------------------- - * Var_GetHead -- - * Find the leading components of a (list of) filename(s). - * XXX: VarHead does not replace foo by ., as (sun) System V make - * does. - * - * Input: - * file Filename to manipulate - * - * Results: - * The leading components. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -char * -Var_GetHead(char *file) -{ - return(VarModify(file, VarHead, NULL)); -} -#endif - -/*- - *----------------------------------------------------------------------- - * Var_Init -- - * Initialize the module - * - * Results: - * None - * - * Side Effects: - * The VAR_CMD and VAR_GLOBAL contexts are created - *----------------------------------------------------------------------- - */ -void -Var_Init(void) -{ - VAR_GLOBAL = Targ_NewGN("Global"); - VAR_CMD = Targ_NewGN("Command"); - -} - - -void -Var_End(void) -{ -} - - -/****************** PRINT DEBUGGING INFO *****************/ -static void -VarPrintVar(void *vp) -{ - Var *v = (Var *)vp; - fprintf(debug_file, "%-16s = %s\n", v->name, Buf_GetAll(&v->val, NULL)); -} - -/*- - *----------------------------------------------------------------------- - * Var_Dump -- - * print all variables in a context - *----------------------------------------------------------------------- - */ -void -Var_Dump(GNode *ctxt) -{ - Hash_Search search; - Hash_Entry *h; - - for (h = Hash_EnumFirst(&ctxt->context, &search); - h != NULL; - h = Hash_EnumNext(&search)) { - VarPrintVar(Hash_GetValue(h)); - } -} diff --git a/20120831/wait.h b/20120831/wait.h deleted file mode 100644 index 7408d15..0000000 --- a/20120831/wait.h +++ /dev/null @@ -1,81 +0,0 @@ -/* NAME: - * wait.h - compensate for what vendors leave out - * - * AUTHOR: - * Simon J. Gerraty <sjg@crufty.net> - */ -/* - * RCSid: - * $Id: wait.h,v 1.6 2002/11/26 07:53:06 sjg Exp $ - * - * @(#)Copyright (c) 1994, Simon J. Gerraty. - * - * This is free software. It comes with NO WARRANTY. - * Permission to use, modify and distribute this source code - * is granted subject to the following conditions. - * 1/ that the above copyright notice and this notice - * are preserved in all copies and that due credit be given - * to the author. - * 2/ that any changes to this code are clearly commented - * as such so that the author does not get blamed for bugs - * other than his own. - * - * Please send copies of changes and bug-fixes to: - * sjg@crufty.net - */ - -#include <sys/wait.h> - -#ifdef sun386 -# define UNION_WAIT -# define WEXITSTATUS(x) ((&x)->w_retcode) -# define WTERMSIG(x) ((&x)->w_termsig) -# define WSTOPSIG(x) ((&x)->w_stopsig) -# define HAVE_WAIT4 -#endif - -#ifndef WAIT_T -# ifdef UNION_WAIT -# define WAIT_T union wait -# define WAIT_STATUS(x) (x).w_status -# else -# define WAIT_T int -# define WAIT_STATUS(x) x -# endif -#endif - -#ifndef WEXITSTATUS -# define WEXITSTATUS(_X) (((int)(_X)>>8)&0377) -#endif -#ifndef WSTOPPED -# define WSTOPPED 0177 -#endif -#ifndef WSTOPSIG -# define WSTOPSIG(x) WSTOPPED -#endif - -#ifdef UNION_WAIT -#ifndef WSET_STOPCODE -#define WSET_STOPCODE(x, sig) ((&x)->w_stopsig = (sig)) -#endif -#ifndef WSET_EXITCODE -#define WSET_EXITCODE(x, ret, sig) ((&x)->w_termsig = (sig), (&x)->w_retcode = (ret)) -#endif -#else -#ifndef WSET_STOPCODE -#define WSET_STOPCODE(x, sig) ((x) = ((sig) << 8) | 0177) -#endif -#ifndef WSET_EXITCODE -#define WSET_EXITCODE(x, ret, sig) ((x) = (ret << 8) | (sig)) -#endif -#endif - -#ifndef HAVE_WAITPID -# ifdef HAVE_WAIT4 -# define waitpid(pid, statusp, flags) wait4(pid, statusp, flags, (char *)0) -# else -# ifdef HAVE_WAIT3 -# define waitpid(pid, statusp, flags) wait3(statusp, flags, (char *)0) -# endif -# endif -#endif |