Import bmake-20200902
Lots of code refactoring, simplification and cleanup. Lots of new unit-tests providing much higher code coverage. All courtesy of rillig at netbsd. Other significant changes: o new read-only variable .SHELL which provides the path of the shell used to run scripts (as defined by the .SHELL target). o new debug option -dl: LINT mode, does the equivalent of := for all variable assignments so that file and line number are reported for variable parse errors.
This commit is contained in:
parent
367d32e2b1
commit
6bbc783f48
240
ChangeLog
240
ChangeLog
@ -1,3 +1,243 @@
|
||||
2020-09-02 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200902
|
||||
Merge with NetBSD make, pick up
|
||||
o use make_stat to ensure no confusion over valid fields
|
||||
returned by cached_stat
|
||||
o var.c: make VarQuote const-correct
|
||||
o add unit tests for .for
|
||||
|
||||
2020-09-01 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200901
|
||||
Merge with NetBSD make, pick up
|
||||
o rename Hash_Table fields
|
||||
o make data types in Dir_HasWildcards more precise
|
||||
|
||||
2020-08-31 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200831
|
||||
Merge with NetBSD make, pick up
|
||||
o suff.c: fix unbalanced Lst_Open/Lst_Close in SuffFindCmds
|
||||
o lst.c: Lst_Open renable assert that list isn't open
|
||||
o unit test for .TARGET dependent flags
|
||||
o var.c: fix aliasing bug in VarUniq
|
||||
o more unit tests for :u
|
||||
|
||||
2020-08-30 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200830
|
||||
Merge with NetBSD make, pick up
|
||||
o allow for strict type checking for Boolean
|
||||
o Var_Parse never returns NULL
|
||||
o Var_Subst never returns NULL
|
||||
o Lst_Find now takes boolean match function
|
||||
o rename Lst_Memeber to Lst_FindDatum
|
||||
o rename LstNode functions to match their type
|
||||
o rename GNode.iParents to implicitParents
|
||||
o fix assertion failure for .SUFFIXES in archives
|
||||
o compat.c: clean up documentation for CompatInterrupt and Compat_Run
|
||||
remove unreachable code from CompatRunCommand
|
||||
o main.c: simplify getBoolean
|
||||
o stc.c: replace brk_string with simpler Str_Words
|
||||
o suff.c: add debug macros
|
||||
|
||||
2020-08-28 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200828
|
||||
Merge with NetBSD make, pick up
|
||||
o lst.c: inline LstIsValid and LstNodeIsValid
|
||||
o remove trailing S from Lst function names after migration complete
|
||||
o more comment cleanup/clarification
|
||||
o suff.c: clean up suffix handling
|
||||
o more unit tests
|
||||
|
||||
2020-08-26 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200826
|
||||
Merge with NetBSD make, pick up
|
||||
o enum.c: distinguish between bitsets containing flags and
|
||||
ordinary enums
|
||||
o var.c: fix error message for ::!= modifier with shell error
|
||||
o fix bugs in -DCLEANUP mode
|
||||
|
||||
2020-08-24 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200824
|
||||
Merge with NetBSD make, pick up
|
||||
o in debug mode, print GNode details in symbols
|
||||
|
||||
2020-08-23 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200823
|
||||
Merge with NetBSD make, pick up
|
||||
o lst.c: more asserts,
|
||||
make args to Lst_Find match others.
|
||||
o var.c: pass flags to VarAdd
|
||||
o arch.c: use Buffer
|
||||
o str.c: brk_string return size_t for nwords
|
||||
o more unit tests
|
||||
|
||||
2020-08-22 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION):
|
||||
Merge with NetBSD make, pick up
|
||||
o var.c: support for read-only variables eg .SHELL
|
||||
being the shell used to run scripts.
|
||||
o lst.c: more simplification
|
||||
o more documentation and style cleanup
|
||||
o more unit tests
|
||||
o ensure unit-test/Makefile is run by TEST_MAKE
|
||||
o reduce duplication of header inclusion
|
||||
|
||||
2020-08-21 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200821
|
||||
Merge with NetBSD make, pick up
|
||||
o lst.c: revert invalid assertion - but document it
|
||||
o dir.c: split Dir_Init into two functions
|
||||
|
||||
2020-08-20 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* lst.c: needs inttypes.h on Linux
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200820
|
||||
Merge with NetBSD make, pick up
|
||||
o make.1: clarify some passages
|
||||
o var.c: more cleanup, clarify comments
|
||||
o make_malloc.c: remove unreachable code
|
||||
o cond.c: make CondGetString easier to debug
|
||||
o simplify list usage
|
||||
o unit-tests: more
|
||||
|
||||
2020-08-16 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200816
|
||||
Merge with NetBSD make, pick up
|
||||
o refactor unit-tests to be more fine grained
|
||||
not all tests moved yet
|
||||
|
||||
2020-08-14 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200814
|
||||
Merge with NetBSD make, pick up
|
||||
o more str_concat variants
|
||||
o more enums for flags
|
||||
o var.c: cleanup for higher warnings level
|
||||
|
||||
2020-08-10 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200810
|
||||
Merge with NetBSD make, pick up
|
||||
o more unit tests
|
||||
o general comment and style cleanup
|
||||
|
||||
2020-08-08 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200808
|
||||
Merge with NetBSD make, pick up
|
||||
o enum.[ch]: streamline, enums for use in flags and debug output
|
||||
o cond.c: cleanup
|
||||
o var.c: reduce duplicate code for modifiers
|
||||
debug logging for Var_Parse
|
||||
more detailed debug output
|
||||
o more unit tests
|
||||
|
||||
2020-08-06 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* unit-tests/Makefile: -r for recursive and include Makefile.inc
|
||||
so I can run tests in meta mode
|
||||
supress extra noise if in meta mode
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200806
|
||||
Merge with NetBSD make, pick up
|
||||
o parse.c: remove VARE_WANTRES for LINT
|
||||
we just want to check parsing (for now).
|
||||
|
||||
2020-08-05 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200805
|
||||
Merge with NetBSD make, pick up
|
||||
o make.1: Rework the description of dependence operators
|
||||
|
||||
2020-08-03 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200803
|
||||
Merge with NetBSD make, pick up
|
||||
o revert some C99 usage, for max portability
|
||||
o unit-tests/lint
|
||||
|
||||
2020-08-02 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200802
|
||||
Merge with NetBSD make, pick up
|
||||
o more unit tests
|
||||
|
||||
2020-08-01 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* Remove NetBSD specific plumbing from unit-tests/Makefile
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200801
|
||||
Merge with NetBSD make, pick up
|
||||
o make Var_Value return const
|
||||
o size_t for buf sizes
|
||||
o optimize some buffer operations - avoid strlen
|
||||
|
||||
2020-07-31 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200731
|
||||
Merge with NetBSD make, pick up
|
||||
o var.c: fix undefinded behavior for incomplete :t modifier
|
||||
fixes unit-test/moderrs on Ubuntu
|
||||
o parse.c: When parsing variable assignments other than :=
|
||||
if DEBUG(LINT) test substition of value, so we get a file and
|
||||
line number in the resulting error.
|
||||
o dir.c: fix parsing of nested braces in dependency lines
|
||||
add unit-tests
|
||||
|
||||
2020-07-30 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200730
|
||||
Merge with NetBSD make, pick up
|
||||
o var.c: minor cleanup
|
||||
o unit-tests: more tests to improve code coverage
|
||||
|
||||
2020-07-28 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200728
|
||||
Merge with NetBSD make, pick up
|
||||
o var.c: more optimizations
|
||||
|
||||
2020-07-26 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200726
|
||||
Merge with NetBSD make, pick up
|
||||
o collapse lsd.lib into lst.c - reduce code size and allow inlining
|
||||
o lots of function comment updates
|
||||
o var.c: more optimizations
|
||||
o make return of Var_Parse const
|
||||
|
||||
2020-07-20 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200720
|
||||
Merge with NetBSD make, pick up
|
||||
o DEBUG_HASH report stats at end and tone down the noise
|
||||
o var.c: each flag type gets its own prefix.
|
||||
move SysV string matching to var.c
|
||||
make ampersand in ${VAR:from=to&} an ordinary character
|
||||
cleanup and simplify implementation of modifiers
|
||||
o make.1: move documentation for assignment modifiers
|
||||
|
||||
2020-07-18 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* VERSION (_MAKE_VERSION): 20200718
|
||||
Merge with NetBSD make, pick up
|
||||
o DEBUG_HASH to see how well the hash tables are working
|
||||
|
||||
2020-07-11 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* bsd.after-import.mk: make sure we update unit-tests/Makefile
|
||||
|
||||
2020-07-10 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* configure.in: use AC_INCLUDES_DEFAULT rather than AC_HEADER_STDC
|
||||
|
527
FILES
527
FILES
@ -23,6 +23,8 @@ configure.in
|
||||
dir.c
|
||||
dir.h
|
||||
dirname.c
|
||||
enum.c
|
||||
enum.h
|
||||
filemon/filemon.h
|
||||
filemon/filemon_dev.c
|
||||
filemon/filemon_ktrace.c
|
||||
@ -34,36 +36,8 @@ hash.h
|
||||
install-sh
|
||||
job.c
|
||||
job.h
|
||||
lst.c
|
||||
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-bootstrap.sh.in
|
||||
@ -88,7 +62,6 @@ ranlib.h
|
||||
realpath.c
|
||||
setenv.c
|
||||
sigcompat.c
|
||||
sprite.h
|
||||
str.c
|
||||
stresep.c
|
||||
strlcpy.c
|
||||
@ -100,22 +73,234 @@ trace.c
|
||||
trace.h
|
||||
unit-tests/Makefile
|
||||
unit-tests/Makefile.config.in
|
||||
unit-tests/archive.exp
|
||||
unit-tests/archive.mk
|
||||
unit-tests/archive-suffix.exp
|
||||
unit-tests/archive-suffix.mk
|
||||
unit-tests/cmd-interrupt.exp
|
||||
unit-tests/cmd-interrupt.mk
|
||||
unit-tests/cmdline.exp
|
||||
unit-tests/cmdline.mk
|
||||
unit-tests/comment.exp
|
||||
unit-tests/comment.mk
|
||||
unit-tests/cond-cmp-numeric-eq.exp
|
||||
unit-tests/cond-cmp-numeric-eq.mk
|
||||
unit-tests/cond-cmp-numeric-ge.exp
|
||||
unit-tests/cond-cmp-numeric-ge.mk
|
||||
unit-tests/cond-cmp-numeric-gt.exp
|
||||
unit-tests/cond-cmp-numeric-gt.mk
|
||||
unit-tests/cond-cmp-numeric-le.exp
|
||||
unit-tests/cond-cmp-numeric-le.mk
|
||||
unit-tests/cond-cmp-numeric-lt.exp
|
||||
unit-tests/cond-cmp-numeric-lt.mk
|
||||
unit-tests/cond-cmp-numeric-ne.exp
|
||||
unit-tests/cond-cmp-numeric-ne.mk
|
||||
unit-tests/cond-cmp-numeric.exp
|
||||
unit-tests/cond-cmp-numeric.mk
|
||||
unit-tests/cond-cmp-string.exp
|
||||
unit-tests/cond-cmp-string.mk
|
||||
unit-tests/cond-func.exp
|
||||
unit-tests/cond-func.mk
|
||||
unit-tests/cond-func-commands.exp
|
||||
unit-tests/cond-func-commands.mk
|
||||
unit-tests/cond-func-defined.exp
|
||||
unit-tests/cond-func-defined.mk
|
||||
unit-tests/cond-func-empty.exp
|
||||
unit-tests/cond-func-empty.mk
|
||||
unit-tests/cond-func-exists.exp
|
||||
unit-tests/cond-func-exists.mk
|
||||
unit-tests/cond-func-make.exp
|
||||
unit-tests/cond-func-make.mk
|
||||
unit-tests/cond-func-target.exp
|
||||
unit-tests/cond-func-target.mk
|
||||
unit-tests/cond-late.exp
|
||||
unit-tests/cond-late.mk
|
||||
unit-tests/cond-op-and.exp
|
||||
unit-tests/cond-op-and.mk
|
||||
unit-tests/cond-op-not.exp
|
||||
unit-tests/cond-op-not.mk
|
||||
unit-tests/cond-op-or.exp
|
||||
unit-tests/cond-op-or.mk
|
||||
unit-tests/cond-op-parentheses.exp
|
||||
unit-tests/cond-op-parentheses.mk
|
||||
unit-tests/cond-op.exp
|
||||
unit-tests/cond-op.mk
|
||||
unit-tests/cond-short.exp
|
||||
unit-tests/cond-short.mk
|
||||
unit-tests/cond-token-number.exp
|
||||
unit-tests/cond-token-number.mk
|
||||
unit-tests/cond-token-plain.exp
|
||||
unit-tests/cond-token-plain.mk
|
||||
unit-tests/cond-token-string.exp
|
||||
unit-tests/cond-token-string.mk
|
||||
unit-tests/cond-token-var.exp
|
||||
unit-tests/cond-token-var.mk
|
||||
unit-tests/cond1.exp
|
||||
unit-tests/cond1.mk
|
||||
unit-tests/cond2.exp
|
||||
unit-tests/cond2.mk
|
||||
unit-tests/cond-late.mk
|
||||
unit-tests/cond-late.exp
|
||||
unit-tests/cond-short.mk
|
||||
unit-tests/cond-short.exp
|
||||
unit-tests/counter.exp
|
||||
unit-tests/counter.mk
|
||||
unit-tests/dep-colon.exp
|
||||
unit-tests/dep-colon.mk
|
||||
unit-tests/dep-double-colon.exp
|
||||
unit-tests/dep-double-colon.mk
|
||||
unit-tests/dep-exclam.exp
|
||||
unit-tests/dep-exclam.mk
|
||||
unit-tests/dep-none.exp
|
||||
unit-tests/dep-none.mk
|
||||
unit-tests/dep-var.exp
|
||||
unit-tests/dep-var.mk
|
||||
unit-tests/dep-wildcards.exp
|
||||
unit-tests/dep-wildcards.mk
|
||||
unit-tests/dep.exp
|
||||
unit-tests/dep.mk
|
||||
unit-tests/depsrc-exec.exp
|
||||
unit-tests/depsrc-exec.mk
|
||||
unit-tests/depsrc-ignore.exp
|
||||
unit-tests/depsrc-ignore.mk
|
||||
unit-tests/depsrc-made.exp
|
||||
unit-tests/depsrc-made.mk
|
||||
unit-tests/depsrc-make.exp
|
||||
unit-tests/depsrc-make.mk
|
||||
unit-tests/depsrc-meta.exp
|
||||
unit-tests/depsrc-meta.mk
|
||||
unit-tests/depsrc-nometa.exp
|
||||
unit-tests/depsrc-nometa.mk
|
||||
unit-tests/depsrc-nometa_cmp.exp
|
||||
unit-tests/depsrc-nometa_cmp.mk
|
||||
unit-tests/depsrc-nopath.exp
|
||||
unit-tests/depsrc-nopath.mk
|
||||
unit-tests/depsrc-notmain.exp
|
||||
unit-tests/depsrc-notmain.mk
|
||||
unit-tests/depsrc-optional.exp
|
||||
unit-tests/depsrc-optional.mk
|
||||
unit-tests/depsrc-phony.exp
|
||||
unit-tests/depsrc-phony.mk
|
||||
unit-tests/depsrc-precious.exp
|
||||
unit-tests/depsrc-precious.mk
|
||||
unit-tests/depsrc-recursive.exp
|
||||
unit-tests/depsrc-recursive.mk
|
||||
unit-tests/depsrc-silent.exp
|
||||
unit-tests/depsrc-silent.mk
|
||||
unit-tests/depsrc-use.exp
|
||||
unit-tests/depsrc-use.mk
|
||||
unit-tests/depsrc-usebefore.exp
|
||||
unit-tests/depsrc-usebefore.mk
|
||||
unit-tests/depsrc-usebefore-double-colon.exp
|
||||
unit-tests/depsrc-usebefore-double-colon.mk
|
||||
unit-tests/depsrc-wait.exp
|
||||
unit-tests/depsrc-wait.mk
|
||||
unit-tests/depsrc.exp
|
||||
unit-tests/depsrc.mk
|
||||
unit-tests/deptgt-begin.exp
|
||||
unit-tests/deptgt-begin.mk
|
||||
unit-tests/deptgt-default.exp
|
||||
unit-tests/deptgt-default.mk
|
||||
unit-tests/deptgt-delete_on_error.exp
|
||||
unit-tests/deptgt-delete_on_error.mk
|
||||
unit-tests/deptgt-end.exp
|
||||
unit-tests/deptgt-end.mk
|
||||
unit-tests/deptgt-error.exp
|
||||
unit-tests/deptgt-error.mk
|
||||
unit-tests/deptgt-ignore.exp
|
||||
unit-tests/deptgt-ignore.mk
|
||||
unit-tests/deptgt-interrupt.exp
|
||||
unit-tests/deptgt-interrupt.mk
|
||||
unit-tests/deptgt-main.exp
|
||||
unit-tests/deptgt-main.mk
|
||||
unit-tests/deptgt-makeflags.exp
|
||||
unit-tests/deptgt-makeflags.mk
|
||||
unit-tests/deptgt-no_parallel.exp
|
||||
unit-tests/deptgt-no_parallel.mk
|
||||
unit-tests/deptgt-nopath.exp
|
||||
unit-tests/deptgt-nopath.mk
|
||||
unit-tests/deptgt-notparallel.exp
|
||||
unit-tests/deptgt-notparallel.mk
|
||||
unit-tests/deptgt-objdir.exp
|
||||
unit-tests/deptgt-objdir.mk
|
||||
unit-tests/deptgt-order.exp
|
||||
unit-tests/deptgt-order.mk
|
||||
unit-tests/deptgt-path-suffix.exp
|
||||
unit-tests/deptgt-path-suffix.mk
|
||||
unit-tests/deptgt-path.exp
|
||||
unit-tests/deptgt-path.mk
|
||||
unit-tests/deptgt-phony.exp
|
||||
unit-tests/deptgt-phony.mk
|
||||
unit-tests/deptgt-precious.exp
|
||||
unit-tests/deptgt-precious.mk
|
||||
unit-tests/deptgt-shell.exp
|
||||
unit-tests/deptgt-shell.mk
|
||||
unit-tests/deptgt-silent.exp
|
||||
unit-tests/deptgt-silent.mk
|
||||
unit-tests/deptgt-stale.exp
|
||||
unit-tests/deptgt-stale.mk
|
||||
unit-tests/deptgt-suffixes.exp
|
||||
unit-tests/deptgt-suffixes.mk
|
||||
unit-tests/deptgt.exp
|
||||
unit-tests/deptgt.mk
|
||||
unit-tests/dir.exp
|
||||
unit-tests/dir.mk
|
||||
unit-tests/dir-expand-path.exp
|
||||
unit-tests/dir-expand-path.mk
|
||||
unit-tests/directive-elif.exp
|
||||
unit-tests/directive-elif.mk
|
||||
unit-tests/directive-elifdef.exp
|
||||
unit-tests/directive-elifdef.mk
|
||||
unit-tests/directive-elifmake.exp
|
||||
unit-tests/directive-elifmake.mk
|
||||
unit-tests/directive-elifndef.exp
|
||||
unit-tests/directive-elifndef.mk
|
||||
unit-tests/directive-elifnmake.exp
|
||||
unit-tests/directive-elifnmake.mk
|
||||
unit-tests/directive-else.exp
|
||||
unit-tests/directive-else.mk
|
||||
unit-tests/directive-endif.exp
|
||||
unit-tests/directive-endif.mk
|
||||
unit-tests/directive-error.exp
|
||||
unit-tests/directive-error.mk
|
||||
unit-tests/directive-export-env.exp
|
||||
unit-tests/directive-export-env.mk
|
||||
unit-tests/directive-export-literal.exp
|
||||
unit-tests/directive-export-literal.mk
|
||||
unit-tests/directive-export.exp
|
||||
unit-tests/directive-export.mk
|
||||
unit-tests/directive-for.exp
|
||||
unit-tests/directive-for.mk
|
||||
unit-tests/directive-for-generating-endif.exp
|
||||
unit-tests/directive-for-generating-endif.mk
|
||||
unit-tests/directive-if.exp
|
||||
unit-tests/directive-if.mk
|
||||
unit-tests/directive-ifdef.exp
|
||||
unit-tests/directive-ifdef.mk
|
||||
unit-tests/directive-ifmake.exp
|
||||
unit-tests/directive-ifmake.mk
|
||||
unit-tests/directive-ifndef.exp
|
||||
unit-tests/directive-ifndef.mk
|
||||
unit-tests/directive-ifnmake.exp
|
||||
unit-tests/directive-ifnmake.mk
|
||||
unit-tests/directive-info.exp
|
||||
unit-tests/directive-info.mk
|
||||
unit-tests/directive-undef.exp
|
||||
unit-tests/directive-undef.mk
|
||||
unit-tests/directive-unexport-env.exp
|
||||
unit-tests/directive-unexport-env.mk
|
||||
unit-tests/directive-unexport.exp
|
||||
unit-tests/directive-unexport.mk
|
||||
unit-tests/directive-warning.exp
|
||||
unit-tests/directive-warning.mk
|
||||
unit-tests/directive.exp
|
||||
unit-tests/directive.mk
|
||||
unit-tests/directives.exp
|
||||
unit-tests/directives.mk
|
||||
unit-tests/dollar.exp
|
||||
unit-tests/dollar.mk
|
||||
unit-tests/doterror.exp
|
||||
unit-tests/doterror.mk
|
||||
unit-tests/dotwait.exp
|
||||
unit-tests/dotwait.mk
|
||||
unit-tests/envfirst.exp
|
||||
unit-tests/envfirst.mk
|
||||
unit-tests/error.exp
|
||||
unit-tests/error.mk
|
||||
unit-tests/escape.exp
|
||||
@ -124,6 +309,8 @@ unit-tests/export-all.exp
|
||||
unit-tests/export-all.mk
|
||||
unit-tests/export-env.exp
|
||||
unit-tests/export-env.mk
|
||||
unit-tests/export-variants.exp
|
||||
unit-tests/export-variants.mk
|
||||
unit-tests/export.exp
|
||||
unit-tests/export.mk
|
||||
unit-tests/forloop.exp
|
||||
@ -138,6 +325,10 @@ unit-tests/include-main.exp
|
||||
unit-tests/include-main.mk
|
||||
unit-tests/include-sub.mk
|
||||
unit-tests/include-subsub.mk
|
||||
unit-tests/lint.exp
|
||||
unit-tests/lint.mk
|
||||
unit-tests/make-exported.exp
|
||||
unit-tests/make-exported.mk
|
||||
unit-tests/misc.exp
|
||||
unit-tests/misc.mk
|
||||
unit-tests/moderrs.exp
|
||||
@ -146,12 +337,62 @@ unit-tests/modmatch.exp
|
||||
unit-tests/modmatch.mk
|
||||
unit-tests/modmisc.exp
|
||||
unit-tests/modmisc.mk
|
||||
unit-tests/modorder.exp
|
||||
unit-tests/modorder.mk
|
||||
unit-tests/modts.exp
|
||||
unit-tests/modts.mk
|
||||
unit-tests/modword.exp
|
||||
unit-tests/modword.mk
|
||||
unit-tests/opt-backwards.exp
|
||||
unit-tests/opt-backwards.mk
|
||||
unit-tests/opt-chdir.exp
|
||||
unit-tests/opt-chdir.mk
|
||||
unit-tests/opt-debug.exp
|
||||
unit-tests/opt-debug.mk
|
||||
unit-tests/opt-debug-g1.exp
|
||||
unit-tests/opt-debug-g1.mk
|
||||
unit-tests/opt-define.exp
|
||||
unit-tests/opt-define.mk
|
||||
unit-tests/opt-env.exp
|
||||
unit-tests/opt-env.mk
|
||||
unit-tests/opt-file.exp
|
||||
unit-tests/opt-file.mk
|
||||
unit-tests/opt-ignore.exp
|
||||
unit-tests/opt-ignore.mk
|
||||
unit-tests/opt-include-dir.exp
|
||||
unit-tests/opt-include-dir.mk
|
||||
unit-tests/opt-jobs-internal.exp
|
||||
unit-tests/opt-jobs-internal.mk
|
||||
unit-tests/opt-jobs.exp
|
||||
unit-tests/opt-jobs.mk
|
||||
unit-tests/opt-keep-going.exp
|
||||
unit-tests/opt-keep-going.mk
|
||||
unit-tests/opt-m-include-dir.exp
|
||||
unit-tests/opt-m-include-dir.mk
|
||||
unit-tests/opt-no-action-at-all.exp
|
||||
unit-tests/opt-no-action-at-all.mk
|
||||
unit-tests/opt-no-action.exp
|
||||
unit-tests/opt-no-action.mk
|
||||
unit-tests/opt-query.exp
|
||||
unit-tests/opt-query.mk
|
||||
unit-tests/opt-raw.exp
|
||||
unit-tests/opt-raw.mk
|
||||
unit-tests/opt-silent.exp
|
||||
unit-tests/opt-silent.mk
|
||||
unit-tests/opt-touch.exp
|
||||
unit-tests/opt-touch.mk
|
||||
unit-tests/opt-tracefile.exp
|
||||
unit-tests/opt-tracefile.mk
|
||||
unit-tests/opt-var-expanded.exp
|
||||
unit-tests/opt-var-expanded.mk
|
||||
unit-tests/opt-var-literal.exp
|
||||
unit-tests/opt-var-literal.mk
|
||||
unit-tests/opt-warnings-as-errors.exp
|
||||
unit-tests/opt-warnings-as-errors.mk
|
||||
unit-tests/opt-where-am-i.exp
|
||||
unit-tests/opt-where-am-i.mk
|
||||
unit-tests/opt-x-reduce-exported.exp
|
||||
unit-tests/opt-x-reduce-exported.mk
|
||||
unit-tests/opt.exp
|
||||
unit-tests/opt.mk
|
||||
unit-tests/order.exp
|
||||
unit-tests/order.mk
|
||||
unit-tests/phony-end.exp
|
||||
@ -162,6 +403,28 @@ unit-tests/posix1.exp
|
||||
unit-tests/posix1.mk
|
||||
unit-tests/qequals.exp
|
||||
unit-tests/qequals.mk
|
||||
unit-tests/recursive.exp
|
||||
unit-tests/recursive.mk
|
||||
unit-tests/sh-dots.exp
|
||||
unit-tests/sh-dots.mk
|
||||
unit-tests/sh-jobs-error.exp
|
||||
unit-tests/sh-jobs-error.mk
|
||||
unit-tests/sh-jobs.exp
|
||||
unit-tests/sh-jobs.mk
|
||||
unit-tests/sh-leading-at.exp
|
||||
unit-tests/sh-leading-at.mk
|
||||
unit-tests/sh-leading-hyphen.exp
|
||||
unit-tests/sh-leading-hyphen.mk
|
||||
unit-tests/sh-leading-plus.exp
|
||||
unit-tests/sh-leading-plus.mk
|
||||
unit-tests/sh-meta-chars.exp
|
||||
unit-tests/sh-meta-chars.mk
|
||||
unit-tests/sh-multi-line.exp
|
||||
unit-tests/sh-multi-line.mk
|
||||
unit-tests/sh-single-line.exp
|
||||
unit-tests/sh-single-line.mk
|
||||
unit-tests/sh.exp
|
||||
unit-tests/sh.mk
|
||||
unit-tests/suffixes.exp
|
||||
unit-tests/suffixes.mk
|
||||
unit-tests/sunshcmd.exp
|
||||
@ -174,12 +437,204 @@ unit-tests/unexport-env.exp
|
||||
unit-tests/unexport-env.mk
|
||||
unit-tests/unexport.exp
|
||||
unit-tests/unexport.mk
|
||||
unit-tests/use-inference.exp
|
||||
unit-tests/use-inference.mk
|
||||
unit-tests/var-class-cmdline.exp
|
||||
unit-tests/var-class-cmdline.mk
|
||||
unit-tests/var-class-env.exp
|
||||
unit-tests/var-class-env.mk
|
||||
unit-tests/var-class-global.exp
|
||||
unit-tests/var-class-global.mk
|
||||
unit-tests/var-class-local-legacy.exp
|
||||
unit-tests/var-class-local-legacy.mk
|
||||
unit-tests/var-class-local.exp
|
||||
unit-tests/var-class-local.mk
|
||||
unit-tests/var-class.exp
|
||||
unit-tests/var-class.mk
|
||||
unit-tests/var-op-append.exp
|
||||
unit-tests/var-op-append.mk
|
||||
unit-tests/var-op-assign.exp
|
||||
unit-tests/var-op-assign.mk
|
||||
unit-tests/var-op-default.exp
|
||||
unit-tests/var-op-default.mk
|
||||
unit-tests/var-op-expand.exp
|
||||
unit-tests/var-op-expand.mk
|
||||
unit-tests/var-op-shell.exp
|
||||
unit-tests/var-op-shell.mk
|
||||
unit-tests/var-op.exp
|
||||
unit-tests/var-op.mk
|
||||
unit-tests/varcmd.exp
|
||||
unit-tests/varcmd.mk
|
||||
unit-tests/vardebug.exp
|
||||
unit-tests/vardebug.mk
|
||||
unit-tests/varfind.exp
|
||||
unit-tests/varfind.mk
|
||||
unit-tests/varmisc.exp
|
||||
unit-tests/varmisc.mk
|
||||
unit-tests/varmod-assign.exp
|
||||
unit-tests/varmod-assign.mk
|
||||
unit-tests/varmod-defined.exp
|
||||
unit-tests/varmod-defined.mk
|
||||
unit-tests/varmod-edge.exp
|
||||
unit-tests/varmod-edge.mk
|
||||
unit-tests/varmod-exclam-shell.exp
|
||||
unit-tests/varmod-exclam-shell.mk
|
||||
unit-tests/varmod-extension.exp
|
||||
unit-tests/varmod-extension.mk
|
||||
unit-tests/varmod-gmtime.exp
|
||||
unit-tests/varmod-gmtime.mk
|
||||
unit-tests/varmod-hash.exp
|
||||
unit-tests/varmod-hash.mk
|
||||
unit-tests/varmod-head.exp
|
||||
unit-tests/varmod-head.mk
|
||||
unit-tests/varmod-ifelse.exp
|
||||
unit-tests/varmod-ifelse.mk
|
||||
unit-tests/varmod-l-name-to-value.exp
|
||||
unit-tests/varmod-l-name-to-value.mk
|
||||
unit-tests/varmod-localtime.exp
|
||||
unit-tests/varmod-localtime.mk
|
||||
unit-tests/varmod-loop.exp
|
||||
unit-tests/varmod-loop.mk
|
||||
unit-tests/varmod-match-escape.exp
|
||||
unit-tests/varmod-match-escape.mk
|
||||
unit-tests/varmod-match.exp
|
||||
unit-tests/varmod-match.mk
|
||||
unit-tests/varmod-no-match.exp
|
||||
unit-tests/varmod-no-match.mk
|
||||
unit-tests/varmod-order-reverse.exp
|
||||
unit-tests/varmod-order-reverse.mk
|
||||
unit-tests/varmod-order-shuffle.exp
|
||||
unit-tests/varmod-order-shuffle.mk
|
||||
unit-tests/varmod-order.exp
|
||||
unit-tests/varmod-order.mk
|
||||
unit-tests/varmod-path.exp
|
||||
unit-tests/varmod-path.mk
|
||||
unit-tests/varmod-quote-dollar.exp
|
||||
unit-tests/varmod-quote-dollar.mk
|
||||
unit-tests/varmod-quote.exp
|
||||
unit-tests/varmod-quote.mk
|
||||
unit-tests/varmod-range.exp
|
||||
unit-tests/varmod-range.mk
|
||||
unit-tests/varmod-remember.exp
|
||||
unit-tests/varmod-remember.mk
|
||||
unit-tests/varmod-root.exp
|
||||
unit-tests/varmod-root.mk
|
||||
unit-tests/varmod-select-words.exp
|
||||
unit-tests/varmod-select-words.mk
|
||||
unit-tests/varmod-shell.exp
|
||||
unit-tests/varmod-shell.mk
|
||||
unit-tests/varmod-subst-regex.exp
|
||||
unit-tests/varmod-subst-regex.mk
|
||||
unit-tests/varmod-subst.exp
|
||||
unit-tests/varmod-subst.mk
|
||||
unit-tests/varmod-sysv.exp
|
||||
unit-tests/varmod-sysv.mk
|
||||
unit-tests/varmod-tail.exp
|
||||
unit-tests/varmod-tail.mk
|
||||
unit-tests/varmod-to-abs.exp
|
||||
unit-tests/varmod-to-abs.mk
|
||||
unit-tests/varmod-to-lower.exp
|
||||
unit-tests/varmod-to-lower.mk
|
||||
unit-tests/varmod-to-many-words.exp
|
||||
unit-tests/varmod-to-many-words.mk
|
||||
unit-tests/varmod-to-one-word.exp
|
||||
unit-tests/varmod-to-one-word.mk
|
||||
unit-tests/varmod-to-separator.exp
|
||||
unit-tests/varmod-to-separator.mk
|
||||
unit-tests/varmod-to-upper.exp
|
||||
unit-tests/varmod-to-upper.mk
|
||||
unit-tests/varmod-undefined.exp
|
||||
unit-tests/varmod-undefined.mk
|
||||
unit-tests/varmod-unique.exp
|
||||
unit-tests/varmod-unique.mk
|
||||
unit-tests/varmod.exp
|
||||
unit-tests/varmod.mk
|
||||
unit-tests/varname-dollar.exp
|
||||
unit-tests/varname-dollar.mk
|
||||
unit-tests/varname-dot-alltargets.exp
|
||||
unit-tests/varname-dot-alltargets.mk
|
||||
unit-tests/varname-dot-curdir.exp
|
||||
unit-tests/varname-dot-curdir.mk
|
||||
unit-tests/varname-dot-includes.exp
|
||||
unit-tests/varname-dot-includes.mk
|
||||
unit-tests/varname-dot-includedfromdir.exp
|
||||
unit-tests/varname-dot-includedfromdir.mk
|
||||
unit-tests/varname-dot-includedfromfile.exp
|
||||
unit-tests/varname-dot-includedfromfile.mk
|
||||
unit-tests/varname-dot-libs.exp
|
||||
unit-tests/varname-dot-libs.mk
|
||||
unit-tests/varname-dot-make-dependfile.exp
|
||||
unit-tests/varname-dot-make-dependfile.mk
|
||||
unit-tests/varname-dot-make-expand_variables.exp
|
||||
unit-tests/varname-dot-make-expand_variables.mk
|
||||
unit-tests/varname-dot-make-exported.exp
|
||||
unit-tests/varname-dot-make-exported.mk
|
||||
unit-tests/varname-dot-make-jobs-prefix.exp
|
||||
unit-tests/varname-dot-make-jobs-prefix.mk
|
||||
unit-tests/varname-dot-make-jobs.exp
|
||||
unit-tests/varname-dot-make-jobs.mk
|
||||
unit-tests/varname-dot-make-level.exp
|
||||
unit-tests/varname-dot-make-level.mk
|
||||
unit-tests/varname-dot-make-makefile_preference.exp
|
||||
unit-tests/varname-dot-make-makefile_preference.mk
|
||||
unit-tests/varname-dot-make-makefiles.exp
|
||||
unit-tests/varname-dot-make-makefiles.mk
|
||||
unit-tests/varname-dot-make-meta-bailiwick.exp
|
||||
unit-tests/varname-dot-make-meta-bailiwick.mk
|
||||
unit-tests/varname-dot-make-meta-created.exp
|
||||
unit-tests/varname-dot-make-meta-created.mk
|
||||
unit-tests/varname-dot-make-meta-files.exp
|
||||
unit-tests/varname-dot-make-meta-files.mk
|
||||
unit-tests/varname-dot-make-meta-ignore_filter.exp
|
||||
unit-tests/varname-dot-make-meta-ignore_filter.mk
|
||||
unit-tests/varname-dot-make-meta-ignore_paths.exp
|
||||
unit-tests/varname-dot-make-meta-ignore_paths.mk
|
||||
unit-tests/varname-dot-make-meta-ignore_patterns.exp
|
||||
unit-tests/varname-dot-make-meta-ignore_patterns.mk
|
||||
unit-tests/varname-dot-make-meta-prefix.exp
|
||||
unit-tests/varname-dot-make-meta-prefix.mk
|
||||
unit-tests/varname-dot-make-mode.exp
|
||||
unit-tests/varname-dot-make-mode.mk
|
||||
unit-tests/varname-dot-make-path_filemon.exp
|
||||
unit-tests/varname-dot-make-path_filemon.mk
|
||||
unit-tests/varname-dot-make-pid.exp
|
||||
unit-tests/varname-dot-make-pid.mk
|
||||
unit-tests/varname-dot-make-ppid.exp
|
||||
unit-tests/varname-dot-make-ppid.mk
|
||||
unit-tests/varname-dot-make-save_dollars.exp
|
||||
unit-tests/varname-dot-make-save_dollars.mk
|
||||
unit-tests/varname-dot-makeoverrides.exp
|
||||
unit-tests/varname-dot-makeoverrides.mk
|
||||
unit-tests/varname-dot-newline.exp
|
||||
unit-tests/varname-dot-newline.mk
|
||||
unit-tests/varname-dot-objdir.exp
|
||||
unit-tests/varname-dot-objdir.mk
|
||||
unit-tests/varname-dot-parsedir.exp
|
||||
unit-tests/varname-dot-parsedir.mk
|
||||
unit-tests/varname-dot-parsefile.exp
|
||||
unit-tests/varname-dot-parsefile.mk
|
||||
unit-tests/varname-dot-path.exp
|
||||
unit-tests/varname-dot-path.mk
|
||||
unit-tests/varname-dot-shell.exp
|
||||
unit-tests/varname-dot-shell.mk
|
||||
unit-tests/varname-dot-targets.exp
|
||||
unit-tests/varname-dot-targets.mk
|
||||
unit-tests/varname-empty.exp
|
||||
unit-tests/varname-empty.mk
|
||||
unit-tests/varname-make.exp
|
||||
unit-tests/varname-make.mk
|
||||
unit-tests/varname-make_print_var_on_error.exp
|
||||
unit-tests/varname-make_print_var_on_error.mk
|
||||
unit-tests/varname-makeflags.exp
|
||||
unit-tests/varname-makeflags.mk
|
||||
unit-tests/varname-pwd.exp
|
||||
unit-tests/varname-pwd.mk
|
||||
unit-tests/varname-vpath.exp
|
||||
unit-tests/varname-vpath.mk
|
||||
unit-tests/varname.exp
|
||||
unit-tests/varname.mk
|
||||
unit-tests/varparse-dynamic.exp
|
||||
unit-tests/varparse-dynamic.mk
|
||||
unit-tests/varquote.exp
|
||||
unit-tests/varquote.mk
|
||||
unit-tests/varshell.exp
|
||||
|
1
LICENSE
1
LICENSE
@ -3,6 +3,7 @@ original contributors or assignees.
|
||||
Including:
|
||||
|
||||
Copyright (c) 1993-2020, Simon J Gerraty
|
||||
Copyright (c) 2020, Roland Illig <rillig@NetBSD.org>
|
||||
Copyright (c) 2009-2016, Juniper Networks, Inc.
|
||||
Copyright (c) 2009, John Birrell.
|
||||
Copyright (c) 1997-2020 The NetBSD Foundation, Inc.
|
||||
|
42
Makefile
42
Makefile
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile,v 1.107 2020/06/07 21:18:46 sjg Exp $
|
||||
# $Id: Makefile,v 1.112 2020/08/28 16:26:17 sjg Exp $
|
||||
|
||||
PROG= bmake
|
||||
|
||||
@ -8,9 +8,11 @@ SRCS= \
|
||||
compat.c \
|
||||
cond.c \
|
||||
dir.c \
|
||||
enum.c \
|
||||
for.c \
|
||||
hash.c \
|
||||
job.c \
|
||||
lst.c \
|
||||
main.c \
|
||||
make.c \
|
||||
make_malloc.c \
|
||||
@ -25,36 +27,6 @@ SRCS= \
|
||||
util.c \
|
||||
var.c
|
||||
|
||||
# from lst.lib/
|
||||
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 \
|
||||
lstPrev.c \
|
||||
lstRemove.c \
|
||||
lstReplace.c \
|
||||
lstSucc.c
|
||||
|
||||
.-include "VERSION"
|
||||
.-include "Makefile.inc"
|
||||
|
||||
@ -97,7 +69,6 @@ COPTS.filemon_dev.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
|
||||
.endif # USE_FILEMON
|
||||
|
||||
.PATH: ${srcdir}
|
||||
.PATH: ${srcdir}/lst.lib
|
||||
|
||||
.if make(obj) || make(clean)
|
||||
SUBDIR+= unit-tests
|
||||
@ -109,7 +80,7 @@ SUBDIR+= unit-tests
|
||||
# list of OS's which are derrived from BSD4.4
|
||||
BSD44_LIST= NetBSD FreeBSD OpenBSD DragonFly MirBSD Bitrig
|
||||
# we are...
|
||||
OS!= uname -s
|
||||
OS := ${.MAKE.OS:U${uname -s:L:sh}}
|
||||
# are we 4.4BSD ?
|
||||
isBSD44:=${BSD44_LIST:M${OS}}
|
||||
|
||||
@ -237,5 +208,8 @@ install-mk:
|
||||
# end-delete2
|
||||
|
||||
# A simple unit-test driver to help catch regressions
|
||||
TEST_MAKE ?= ${.OBJDIR}/${PROG:T}
|
||||
accept test:
|
||||
cd ${.CURDIR}/unit-tests && MAKEFLAGS= ${.MAKE} -r -m / TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}
|
||||
cd ${.CURDIR}/unit-tests && \
|
||||
MAKEFLAGS= ${TEST_MAKE} -r -m / ${.TARGET} ${TESTS:DTESTS=${TESTS:Q}}
|
||||
|
||||
|
2
VERSION
2
VERSION
@ -1,2 +1,2 @@
|
||||
# keep this compatible with sh and make
|
||||
_MAKE_VERSION=20200710
|
||||
_MAKE_VERSION=20200902
|
||||
|
499
arch.c
499
arch.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: arch.c,v 1.73 2020/07/03 08:02:55 rillig Exp $ */
|
||||
/* $NetBSD: arch.c,v 1.107 2020/08/30 11:15:05 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -69,14 +69,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: arch.c,v 1.73 2020/07/03 08:02:55 rillig Exp $";
|
||||
static char rcsid[] = "$NetBSD: arch.c,v 1.107 2020/08/30 11:15:05 rillig 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.73 2020/07/03 08:02:55 rillig Exp $");
|
||||
__RCSID("$NetBSD: arch.c,v 1.107 2020/08/30 11:15:05 rillig Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -94,7 +94,7 @@ __RCSID("$NetBSD: arch.c,v 1.73 2020/07/03 08:02:55 rillig Exp $");
|
||||
* 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
|
||||
* FALSE is returned if the specification is
|
||||
* invalid for some reason.
|
||||
*
|
||||
* Arch_Touch Alter the modification time of the archive
|
||||
@ -184,12 +184,9 @@ typedef struct Arch {
|
||||
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 *);
|
||||
static struct ar_hdr *ArchStatMember(const char *, const char *, Boolean);
|
||||
static FILE *ArchFindMember(const char *, const char *,
|
||||
struct ar_hdr *, const char *);
|
||||
#if defined(__svr4__) || defined(__SVR4) || defined(__ELF__)
|
||||
#define SVR4ARCHIVES
|
||||
static int ArchSVR4Entry(Arch *, char *, size_t, FILE *);
|
||||
@ -225,19 +222,6 @@ static int ArchSVR4Entry(Arch *, char *, size_t, FILE *);
|
||||
#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)
|
||||
{
|
||||
@ -272,23 +256,18 @@ ArchFree(void *ap)
|
||||
* ctxt Context in which to expand variables
|
||||
*
|
||||
* Results:
|
||||
* SUCCESS if it was a valid specification. The linePtr is updated
|
||||
* TRUE 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
|
||||
Boolean
|
||||
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 */
|
||||
@ -304,26 +283,25 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
|
||||
* so we can safely advance beyond it...
|
||||
*/
|
||||
int length;
|
||||
void *freeIt;
|
||||
char *result;
|
||||
void *result_freeIt;
|
||||
const char *result;
|
||||
Boolean isError;
|
||||
|
||||
result = Var_Parse(cp, ctxt, VARF_UNDEFERR|VARF_WANTRES,
|
||||
&length, &freeIt);
|
||||
free(freeIt);
|
||||
result = Var_Parse(cp, ctxt, VARE_UNDEFERR|VARE_WANTRES,
|
||||
&length, &result_freeIt);
|
||||
isError = result == var_Error;
|
||||
free(result_freeIt);
|
||||
if (isError)
|
||||
return FALSE;
|
||||
|
||||
if (result == var_Error) {
|
||||
return FAILURE;
|
||||
} else {
|
||||
subLibName = TRUE;
|
||||
}
|
||||
|
||||
cp += length-1;
|
||||
subLibName = TRUE;
|
||||
cp += length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
*cp++ = '\0';
|
||||
if (subLibName) {
|
||||
libName = Var_Subst(NULL, libName, ctxt, VARF_UNDEFERR|VARF_WANTRES);
|
||||
libName = Var_Subst(libName, ctxt, VARE_UNDEFERR|VARE_WANTRES);
|
||||
}
|
||||
|
||||
|
||||
@ -347,18 +325,18 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
|
||||
*/
|
||||
int length;
|
||||
void *freeIt;
|
||||
char *result;
|
||||
const char *result;
|
||||
Boolean isError;
|
||||
|
||||
result = Var_Parse(cp, ctxt, VARF_UNDEFERR|VARF_WANTRES,
|
||||
result = Var_Parse(cp, ctxt, VARE_UNDEFERR|VARE_WANTRES,
|
||||
&length, &freeIt);
|
||||
isError = result == var_Error;
|
||||
free(freeIt);
|
||||
|
||||
if (result == var_Error) {
|
||||
return FAILURE;
|
||||
} else {
|
||||
doSubst = TRUE;
|
||||
}
|
||||
if (isError)
|
||||
return FALSE;
|
||||
|
||||
doSubst = TRUE;
|
||||
cp += length;
|
||||
} else {
|
||||
cp++;
|
||||
@ -372,7 +350,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
|
||||
*/
|
||||
if (*cp == '\0') {
|
||||
printf("No closing parenthesis in archive specification\n");
|
||||
return FAILURE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -401,20 +379,15 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
|
||||
char *buf;
|
||||
char *sacrifice;
|
||||
char *oldMemName = memName;
|
||||
size_t sz;
|
||||
|
||||
memName = Var_Subst(NULL, memName, ctxt,
|
||||
VARF_UNDEFERR|VARF_WANTRES);
|
||||
memName = Var_Subst(memName, ctxt, VARE_UNDEFERR | VARE_WANTRES);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
buf = sacrifice = str_concat4(libName, "(", memName, ")");
|
||||
|
||||
if (strchr(memName, '$') && strcmp(memName, oldMemName) == 0) {
|
||||
/*
|
||||
@ -426,42 +399,43 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
|
||||
|
||||
if (gn == NULL) {
|
||||
free(buf);
|
||||
return FAILURE;
|
||||
return FALSE;
|
||||
} else {
|
||||
gn->type |= OP_ARCHV;
|
||||
(void)Lst_AtEnd(nodeLst, gn);
|
||||
Lst_Append(nodeLst, gn);
|
||||
}
|
||||
} else if (Arch_ParseArchive(&sacrifice, nodeLst, ctxt)!=SUCCESS) {
|
||||
} else if (!Arch_ParseArchive(&sacrifice, nodeLst, ctxt)) {
|
||||
/*
|
||||
* Error in nested call -- free buffer and return FAILURE
|
||||
* Error in nested call -- free buffer and return FALSE
|
||||
* ourselves.
|
||||
*/
|
||||
free(buf);
|
||||
return FAILURE;
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* 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);
|
||||
Lst members = Lst_Init();
|
||||
Buffer nameBuf;
|
||||
|
||||
Buf_Init(&nameBuf, 0);
|
||||
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);
|
||||
char *member = Lst_Dequeue(members);
|
||||
|
||||
snprintf(nameBuf, sz, "%s(%s)", libName, member);
|
||||
Buf_Empty(&nameBuf);
|
||||
Buf_AddStr(&nameBuf, libName);
|
||||
Buf_AddStr(&nameBuf, "(");
|
||||
Buf_AddStr(&nameBuf, member);
|
||||
Buf_AddStr(&nameBuf, ")");
|
||||
free(member);
|
||||
gn = Targ_FindNode(nameBuf, TARG_CREATE);
|
||||
|
||||
gn = Targ_FindNode(Buf_GetAll(&nameBuf, NULL), TARG_CREATE);
|
||||
if (gn == NULL) {
|
||||
free(nameBuf);
|
||||
return FAILURE;
|
||||
Buf_Destroy(&nameBuf, TRUE);
|
||||
return FALSE;
|
||||
} else {
|
||||
/*
|
||||
* We've found the node, but have to make sure the rest of
|
||||
@ -471,19 +445,24 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
|
||||
* end of the provided list.
|
||||
*/
|
||||
gn->type |= OP_ARCHV;
|
||||
(void)Lst_AtEnd(nodeLst, gn);
|
||||
Lst_Append(nodeLst, gn);
|
||||
}
|
||||
}
|
||||
Lst_Destroy(members, NULL);
|
||||
free(nameBuf);
|
||||
Lst_Free(members);
|
||||
Buf_Destroy(&nameBuf, TRUE);
|
||||
} 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);
|
||||
Buffer nameBuf;
|
||||
|
||||
Buf_Init(&nameBuf, 0);
|
||||
Buf_AddStr(&nameBuf, libName);
|
||||
Buf_AddStr(&nameBuf, "(");
|
||||
Buf_AddStr(&nameBuf, memName);
|
||||
Buf_AddStr(&nameBuf, ")");
|
||||
|
||||
gn = Targ_FindNode(Buf_GetAll(&nameBuf, NULL), TARG_CREATE);
|
||||
Buf_Destroy(&nameBuf, TRUE);
|
||||
if (gn == NULL) {
|
||||
return FAILURE;
|
||||
return FALSE;
|
||||
} else {
|
||||
/*
|
||||
* We've found the node, but have to make sure the rest of the
|
||||
@ -493,7 +472,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
|
||||
* provided list.
|
||||
*/
|
||||
gn->type |= OP_ARCHV;
|
||||
(void)Lst_AtEnd(nodeLst, gn);
|
||||
Lst_Append(nodeLst, gn);
|
||||
}
|
||||
}
|
||||
if (doSubst) {
|
||||
@ -520,31 +499,15 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
|
||||
} while (*cp != '\0' && isspace ((unsigned char)*cp));
|
||||
|
||||
*linePtr = cp;
|
||||
return SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* 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)
|
||||
/* See if the given archive is the one we are looking for.
|
||||
* Called via Lst_Find. */
|
||||
static Boolean
|
||||
ArchFindArchive(const void *ar, const void *desiredName)
|
||||
{
|
||||
return strcmp(archName, ((const Arch *)ar)->name);
|
||||
return strcmp(((const Arch *)ar)->name, desiredName) == 0;
|
||||
}
|
||||
|
||||
/*-
|
||||
@ -565,24 +528,20 @@ ArchFindArchive(const void *ar, const void *archName)
|
||||
* 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)
|
||||
ArchStatMember(const char *archive, const char *member, Boolean hash)
|
||||
{
|
||||
FILE * arch; /* Stream to archive */
|
||||
int size; /* Size of archive member */
|
||||
char *cp; /* Useful character pointer */
|
||||
size_t size; /* Size of archive member */
|
||||
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. */
|
||||
/* Current member name while hashing. */
|
||||
|
||||
/*
|
||||
* Because of space constraints and similar things, files are archived
|
||||
@ -590,14 +549,14 @@ ArchStatMember(char *archive, char *member, Boolean hash)
|
||||
* 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;
|
||||
const char *base = strrchr(member, '/');
|
||||
if (base != NULL) {
|
||||
member = base + 1;
|
||||
}
|
||||
|
||||
ln = Lst_Find(archives, archive, ArchFindArchive);
|
||||
ln = Lst_Find(archives, ArchFindArchive, archive);
|
||||
if (ln != NULL) {
|
||||
ar = (Arch *)Lst_Datum(ln);
|
||||
ar = LstNode_Datum(ln);
|
||||
|
||||
he = Hash_FindEntry(&ar->members, member);
|
||||
|
||||
@ -610,8 +569,7 @@ ArchStatMember(char *archive, char *member, Boolean hash)
|
||||
|
||||
if (len > AR_MAX_NAME_LEN) {
|
||||
len = AR_MAX_NAME_LEN;
|
||||
strncpy(copy, member, AR_MAX_NAME_LEN);
|
||||
copy[AR_MAX_NAME_LEN] = '\0';
|
||||
snprintf(copy, sizeof copy, "%s", member);
|
||||
}
|
||||
if ((he = Hash_FindEntry(&ar->members, copy)) != NULL)
|
||||
return (struct ar_hdr *)Hash_GetValue(he);
|
||||
@ -653,7 +611,7 @@ ArchStatMember(char *archive, char *member, Boolean hash)
|
||||
* can handle...
|
||||
*/
|
||||
if ((fread(magic, SARMAG, 1, arch) != 1) ||
|
||||
(strncmp(magic, ARMAG, SARMAG) != 0)) {
|
||||
(strncmp(magic, ARMAG, SARMAG) != 0)) {
|
||||
fclose(arch);
|
||||
return NULL;
|
||||
}
|
||||
@ -673,6 +631,8 @@ ArchStatMember(char *archive, char *member, Boolean hash)
|
||||
*/
|
||||
goto badarch;
|
||||
} else {
|
||||
char *nameend;
|
||||
|
||||
/*
|
||||
* We need to advance the stream's pointer to the start of the
|
||||
* next header. Files are padded with newlines to an even-byte
|
||||
@ -680,13 +640,14 @@ ArchStatMember(char *archive, char *member, Boolean hash)
|
||||
* '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);
|
||||
size = (size_t)strtol(arh.ar_size, NULL, 10);
|
||||
|
||||
memcpy(memName, arh.AR_NAME, sizeof(arh.AR_NAME));
|
||||
for (cp = &memName[AR_MAX_NAME_LEN]; *cp == ' '; cp--) {
|
||||
continue;
|
||||
nameend = memName + AR_MAX_NAME_LEN;
|
||||
while (*nameend == ' ') {
|
||||
nameend--;
|
||||
}
|
||||
cp[1] = '\0';
|
||||
nameend[1] = '\0';
|
||||
|
||||
#ifdef SVR4ARCHIVES
|
||||
/*
|
||||
@ -706,8 +667,8 @@ ArchStatMember(char *archive, char *member, Boolean hash)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (cp[0] == '/')
|
||||
cp[0] = '\0';
|
||||
if (nameend[0] == '/')
|
||||
nameend[0] = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -719,11 +680,11 @@ ArchStatMember(char *archive, char *member, Boolean hash)
|
||||
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]);
|
||||
int elen = atoi(&memName[sizeof(AR_EFMT1)-1]);
|
||||
|
||||
if (elen > MAXPATHLEN)
|
||||
if ((unsigned int)elen > MAXPATHLEN)
|
||||
goto badarch;
|
||||
if (fread(memName, elen, 1, arch) != 1)
|
||||
if (fread(memName, (size_t)elen, 1, arch) != 1)
|
||||
goto badarch;
|
||||
memName[elen] = '\0';
|
||||
if (fseek(arch, -elen, SEEK_CUR) != 0)
|
||||
@ -738,13 +699,13 @@ ArchStatMember(char *archive, char *member, Boolean hash)
|
||||
Hash_SetValue(he, bmake_malloc(sizeof(struct ar_hdr)));
|
||||
memcpy(Hash_GetValue(he), &arh, sizeof(struct ar_hdr));
|
||||
}
|
||||
if (fseek(arch, (size + 1) & ~1, SEEK_CUR) != 0)
|
||||
if (fseek(arch, ((long)size + 1) & ~1, SEEK_CUR) != 0)
|
||||
goto badarch;
|
||||
}
|
||||
|
||||
fclose(arch);
|
||||
|
||||
(void)Lst_AtEnd(archives, ar);
|
||||
Lst_Append(archives, ar);
|
||||
|
||||
/*
|
||||
* Now that the archive has been read and cached, we can look into
|
||||
@ -774,17 +735,14 @@ ArchStatMember(char *archive, char *member, Boolean hash)
|
||||
* 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.
|
||||
* If a table is read, the file pointer is moved to the next archive
|
||||
* member.
|
||||
*
|
||||
* 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
|
||||
@ -834,7 +792,7 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
|
||||
}
|
||||
if (DEBUG(ARCH)) {
|
||||
fprintf(debug_file, "Found svr4 archive name table with %lu entries\n",
|
||||
(unsigned long)entry);
|
||||
(unsigned long)entry);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -861,8 +819,7 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
|
||||
fprintf(debug_file, "Replaced %s with %s\n", name, &ar->fnametab[entry]);
|
||||
}
|
||||
|
||||
(void)strncpy(name, &ar->fnametab[entry], MAXPATHLEN);
|
||||
name[MAXPATHLEN] = '\0';
|
||||
snprintf(name, MAXPATHLEN + 1, "%s", &ar->fnametab[entry]);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@ -874,6 +831,7 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
|
||||
* 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".
|
||||
* The passed struct ar_hdr structure is filled in.
|
||||
*
|
||||
* Input:
|
||||
* archive Path to the archive
|
||||
@ -886,21 +844,17 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
|
||||
* 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,
|
||||
ArchFindMember(const char *archive, const 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;
|
||||
const char * base;
|
||||
|
||||
arch = fopen(archive, mode);
|
||||
if (arch == NULL) {
|
||||
@ -912,7 +866,7 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr,
|
||||
* can handle...
|
||||
*/
|
||||
if ((fread(magic, SARMAG, 1, arch) != 1) ||
|
||||
(strncmp(magic, ARMAG, SARMAG) != 0)) {
|
||||
(strncmp(magic, ARMAG, SARMAG) != 0)) {
|
||||
fclose(arch);
|
||||
return NULL;
|
||||
}
|
||||
@ -923,9 +877,9 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr,
|
||||
* 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;
|
||||
base = strrchr(member, '/');
|
||||
if (base != NULL) {
|
||||
member = base + 1;
|
||||
}
|
||||
len = tlen = strlen(member);
|
||||
if (len > sizeof(arhPtr->AR_NAME)) {
|
||||
@ -958,7 +912,7 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr,
|
||||
* the file at the actual member, rather than its header, but
|
||||
* not here...
|
||||
*/
|
||||
if (fseek(arch, -sizeof(struct ar_hdr), SEEK_CUR) != 0) {
|
||||
if (fseek(arch, -(long)sizeof(struct ar_hdr), SEEK_CUR) != 0) {
|
||||
fclose(arch);
|
||||
return NULL;
|
||||
}
|
||||
@ -974,14 +928,14 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr,
|
||||
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]);
|
||||
int elen = atoi(&arhPtr->AR_NAME[sizeof(AR_EFMT1)-1]);
|
||||
char ename[MAXPATHLEN + 1];
|
||||
|
||||
if (elen > MAXPATHLEN) {
|
||||
if ((unsigned int)elen > MAXPATHLEN) {
|
||||
fclose(arch);
|
||||
return NULL;
|
||||
}
|
||||
if (fread(ename, elen, 1, arch) != 1) {
|
||||
if (fread(ename, (size_t)elen, 1, arch) != 1) {
|
||||
fclose(arch);
|
||||
return NULL;
|
||||
}
|
||||
@ -991,7 +945,7 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr,
|
||||
}
|
||||
if (strncmp(ename, member, len) == 0) {
|
||||
/* Found as extended name */
|
||||
if (fseek(arch, -sizeof(struct ar_hdr) - elen,
|
||||
if (fseek(arch, -(long)sizeof(struct ar_hdr) - elen,
|
||||
SEEK_CUR) != 0) {
|
||||
fclose(arch);
|
||||
return NULL;
|
||||
@ -1035,18 +989,15 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr,
|
||||
*-----------------------------------------------------------------------
|
||||
* Arch_Touch --
|
||||
* Touch a member of an archive.
|
||||
* The modification time of the entire archive is also changed.
|
||||
* For a library, this could necessitate the re-ranlib'ing of the
|
||||
* whole thing.
|
||||
*
|
||||
* 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
|
||||
@ -1060,8 +1011,8 @@ Arch_Touch(GNode *gn)
|
||||
Var_Value(MEMBER, gn, &p2),
|
||||
&arh, "r+");
|
||||
|
||||
free(p1);
|
||||
free(p2);
|
||||
bmake_free(p1);
|
||||
bmake_free(p2);
|
||||
|
||||
snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now);
|
||||
|
||||
@ -1071,37 +1022,24 @@ Arch_Touch(GNode *gn)
|
||||
}
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Arch_TouchLib --
|
||||
* Given a node which represents a library, touch the thing, making
|
||||
* sure that the table of contents also is touched.
|
||||
/* Given a node which represents a library, touch the thing, making sure that
|
||||
* the table of contents also is touched.
|
||||
*
|
||||
* Both the modification time of the library and of the RANLIBMAG member are
|
||||
* set to 'now'.
|
||||
*
|
||||
* 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+");
|
||||
arch = ArchFindMember(gn->path, RANLIBMAG, &arh, "r+");
|
||||
snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now);
|
||||
|
||||
if (arch != NULL) {
|
||||
@ -1111,25 +1049,16 @@ Arch_TouchLib(GNode *gn)
|
||||
times.actime = times.modtime = now;
|
||||
utime(gn->path, ×);
|
||||
}
|
||||
#else
|
||||
(void)gn;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Arch_MTime --
|
||||
* Return the modification time of a member of an archive.
|
||||
/* Return the modification time of a member of an archive. The mtime field
|
||||
* of the given node is filled in with the value returned by the function.
|
||||
*
|
||||
* 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)
|
||||
@ -1142,8 +1071,8 @@ Arch_MTime(GNode *gn)
|
||||
Var_Value(MEMBER, gn, &p2),
|
||||
TRUE);
|
||||
|
||||
free(p1);
|
||||
free(p2);
|
||||
bmake_free(p1);
|
||||
bmake_free(p2);
|
||||
|
||||
if (arhPtr != NULL) {
|
||||
modTime = (time_t)strtol(arhPtr->AR_DATE, NULL, 10);
|
||||
@ -1155,34 +1084,17 @@ Arch_MTime(GNode *gn)
|
||||
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.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
/* Given a non-existent archive member's node, get its modification time from
|
||||
* its archived form, if it exists. gn->mtime is filled in as well. */
|
||||
time_t
|
||||
Arch_MemMTime(GNode *gn)
|
||||
{
|
||||
LstNode ln;
|
||||
GNode *pgn;
|
||||
char *nameStart,
|
||||
*nameEnd;
|
||||
|
||||
if (Lst_Open(gn->parents) != SUCCESS) {
|
||||
gn->mtime = 0;
|
||||
return 0;
|
||||
}
|
||||
Lst_Open(gn->parents);
|
||||
while ((ln = Lst_Next(gn->parents)) != NULL) {
|
||||
pgn = (GNode *)Lst_Datum(ln);
|
||||
pgn = LstNode_Datum(ln);
|
||||
|
||||
if (pgn->type & OP_ARCHV) {
|
||||
/*
|
||||
@ -1192,12 +1104,13 @@ Arch_MemMTime(GNode *gn)
|
||||
* child. We keep searching its parents in case some other
|
||||
* parent requires this child to exist...
|
||||
*/
|
||||
nameStart = strchr(pgn->name, '(') + 1;
|
||||
nameEnd = strchr(nameStart, ')');
|
||||
const char *nameStart = strchr(pgn->name, '(') + 1;
|
||||
const char *nameEnd = strchr(nameStart, ')');
|
||||
size_t nameLen = (size_t)(nameEnd - nameStart);
|
||||
|
||||
if ((pgn->flags & REMAKE) &&
|
||||
strncmp(nameStart, gn->name, nameEnd - nameStart) == 0) {
|
||||
gn->mtime = Arch_MTime(pgn);
|
||||
strncmp(nameStart, gn->name, nameLen) == 0) {
|
||||
gn->mtime = Arch_MTime(pgn);
|
||||
}
|
||||
} else if (pgn->flags & REMAKE) {
|
||||
/*
|
||||
@ -1214,29 +1127,20 @@ Arch_MemMTime(GNode *gn)
|
||||
return gn->mtime;
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Arch_FindLib --
|
||||
* Search for a library along the given search path.
|
||||
/* Search for a library along the given search path.
|
||||
*
|
||||
* 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 .LIBS 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.
|
||||
*
|
||||
* 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)
|
||||
@ -1258,44 +1162,38 @@ Arch_FindLib(GNode *gn, Lst path)
|
||||
#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.
|
||||
/* Decide if a node with the OP_LIB attribute is out-of-date. Called from
|
||||
* Make_OODate to make its life easier.
|
||||
* The library will be hashed if it hasn't been already.
|
||||
*
|
||||
* 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.
|
||||
* 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)
|
||||
@ -1315,7 +1213,7 @@ Arch_LibOODate(GNode *gn)
|
||||
struct ar_hdr *arhPtr; /* Header for __.SYMDEF */
|
||||
int modTimeTOC; /* The table-of-contents's mod time */
|
||||
|
||||
arhPtr = ArchStatMember(gn->path, UNCONST(RANLIBMAG), FALSE);
|
||||
arhPtr = ArchStatMember(gn->path, RANLIBMAG, FALSE);
|
||||
|
||||
if (arhPtr != NULL) {
|
||||
modTimeTOC = (int)strtol(arhPtr->AR_DATE, NULL, 10);
|
||||
@ -1340,40 +1238,14 @@ Arch_LibOODate(GNode *gn)
|
||||
return oodate;
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Arch_Init --
|
||||
* Initialize things for this module.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side Effects:
|
||||
* The 'archives' list is initialized.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
/* Initialize things for this module. */
|
||||
void
|
||||
Arch_Init(void)
|
||||
{
|
||||
archives = Lst_Init(FALSE);
|
||||
archives = Lst_Init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Arch_End --
|
||||
* Cleanup things for this module.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side Effects:
|
||||
* The 'archives' list is freed
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
/* Clean up things for this module. */
|
||||
void
|
||||
Arch_End(void)
|
||||
{
|
||||
@ -1382,35 +1254,22 @@ Arch_End(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Arch_IsLib --
|
||||
* Check if the node is a library
|
||||
*
|
||||
* Results:
|
||||
* True or False.
|
||||
*
|
||||
* Side Effects:
|
||||
* None.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
Boolean
|
||||
Arch_IsLib(GNode *gn)
|
||||
{
|
||||
static const char armag[] = "!<arch>\n";
|
||||
char buf[sizeof(armag)-1];
|
||||
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)) {
|
||||
if (read(fd, buf, sizeof buf) != sizeof buf) {
|
||||
(void)close(fd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
(void)close(fd);
|
||||
|
||||
return memcmp(buf, armag, sizeof(buf)) == 0;
|
||||
return memcmp(buf, armag, sizeof buf) == 0;
|
||||
}
|
||||
|
134
bmake.1
134
bmake.1
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: make.1,v 1.282 2020/06/06 20:28:42 wiz Exp $
|
||||
.\" $NetBSD: make.1,v 1.289 2020/08/28 17:15:04 rillig Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -29,7 +29,7 @@
|
||||
.\"
|
||||
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
|
||||
.\"
|
||||
.Dd June 5, 2020
|
||||
.Dd August 28, 2020
|
||||
.Dt BMAKE 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -166,8 +166,15 @@ 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 h
|
||||
Print debugging information about hash table operations.
|
||||
.It Ar j
|
||||
Print debugging information about running multiple shells.
|
||||
.It Ar L
|
||||
Turn on lint checks.
|
||||
This will throw errors for variable assignments that do not parse
|
||||
correctly, at the time of assignment so the file and line number
|
||||
are available.
|
||||
.It Ar l
|
||||
Print commands in Makefiles regardless of whether or not they are prefixed by
|
||||
.Ql @
|
||||
@ -311,7 +318,8 @@ 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).
|
||||
source (see below) or the command is prefixed with
|
||||
.Ql Ic + .
|
||||
.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
|
||||
@ -412,37 +420,44 @@ 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:
|
||||
and are customarily created from them.
|
||||
A target is considered out-of-date if it does not exist, or if its
|
||||
modification time is less than that of any of its sources.
|
||||
An out-of-date target will be re-created, but not until all sources
|
||||
have been examined and themselves re-created as needed.
|
||||
Three operators may be used:
|
||||
.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
|
||||
Many dependency lines may name this target but only one may have
|
||||
attached shell commands.
|
||||
All sources named in all dependency lines are considered together,
|
||||
and if needed the attached shell commands are run to create or
|
||||
re-create the target.
|
||||
If
|
||||
.Nm
|
||||
is interrupted.
|
||||
is interrupted, the target is removed.
|
||||
.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.
|
||||
The same, but the target is always re-created whether or not it is out
|
||||
of date.
|
||||
.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
|
||||
Any dependency line may have attached shell commands, but each one
|
||||
is handled independently: its sources are considered and the attached
|
||||
shell commands are run if the target is out of date with respect to
|
||||
(only) those sources.
|
||||
Thus, different groups of the attached shell commands may be run
|
||||
depending on the circumstances.
|
||||
Furthermore, unlike
|
||||
.Ic \&:,
|
||||
for dependency lines with no sources, the attached shell
|
||||
commands are always run.
|
||||
Also unlike
|
||||
.Ic \&:,
|
||||
the target will not be removed if
|
||||
.Nm
|
||||
is interrupted.
|
||||
.El
|
||||
All dependency lines mentioning a particular target must use the same
|
||||
operator.
|
||||
.Pp
|
||||
Targets and sources may contain the shell wildcard values
|
||||
.Ql \&? ,
|
||||
@ -608,7 +623,7 @@ 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!
|
||||
braces, parentheses, or whitespace are really best avoided!
|
||||
.Pp
|
||||
If the result of expanding a variable contains a dollar sign
|
||||
.Pq Ql \&$
|
||||
@ -1126,6 +1141,9 @@ is set to the value of
|
||||
for all programs which
|
||||
.Nm
|
||||
executes.
|
||||
.It Ev .SHELL
|
||||
The pathname of the shell used to run target scripts.
|
||||
It is read-only.
|
||||
.It Ev .TARGETS
|
||||
The list of targets explicitly specified on the command line, if any.
|
||||
.It Ev VPATH
|
||||
@ -1171,7 +1189,7 @@ 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
|
||||
Selects only those words that match
|
||||
.Ar pattern .
|
||||
The standard shell wildcard characters
|
||||
.Pf ( Ql * ,
|
||||
@ -1195,11 +1213,11 @@ This is identical to
|
||||
but selects all words which do not match
|
||||
.Ar pattern .
|
||||
.It Cm \&:O
|
||||
Order every word in variable alphabetically.
|
||||
Orders every word in variable alphabetically.
|
||||
.It Cm \&:Or
|
||||
Order every word in variable in reverse alphabetical order.
|
||||
Orders every word in variable in reverse alphabetical order.
|
||||
.It Cm \&:Ox
|
||||
Randomize words in variable.
|
||||
Shuffles the 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 \&:=
|
||||
@ -1249,7 +1267,7 @@ If a
|
||||
.Va utc
|
||||
value is not provided or is 0, the current time is used.
|
||||
.It Cm \&:hash
|
||||
Compute a 32-bit hash of the value and encode it as hex digits.
|
||||
Computes a 32-bit hash of the value and encode it as hex digits.
|
||||
.It Cm \&:localtime[=utc]
|
||||
The value is a format string for
|
||||
.Xr strftime 3 ,
|
||||
@ -1259,7 +1277,7 @@ If a
|
||||
.Va utc
|
||||
value is not provided or is 0, the current time is used.
|
||||
.It Cm \&:tA
|
||||
Attempt to convert variable to an absolute path using
|
||||
Attempts to convert variable to an absolute path using
|
||||
.Xr realpath 3 ,
|
||||
if that fails, the value is unchanged.
|
||||
.It Cm \&:tl
|
||||
@ -1271,7 +1289,7 @@ This modifier sets the separator to the character
|
||||
If
|
||||
.Ar c
|
||||
is omitted, then no separator is used.
|
||||
The common escapes (including octal numeric codes), work as expected.
|
||||
The common escapes (including octal numeric codes) work as expected.
|
||||
.It Cm \&:tu
|
||||
Converts variable to upper-case letters.
|
||||
.It Cm \&:tW
|
||||
@ -1287,21 +1305,21 @@ See also
|
||||
.Sm off
|
||||
.It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW
|
||||
.Sm on
|
||||
Modify the first occurrence of
|
||||
Modifies the first occurrence of
|
||||
.Ar old_string
|
||||
in the variable's value, replacing it with
|
||||
in each word of 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
|
||||
is appended to the last delimiter 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 appended to the last delimiter of the pattern, only the first occurrence
|
||||
is affected.
|
||||
If a
|
||||
.Ql W
|
||||
is appended to the last slash of the pattern,
|
||||
is appended to the last delimiter of the pattern,
|
||||
then the value is treated as a single word
|
||||
(possibly containing embedded white space).
|
||||
If
|
||||
@ -1370,13 +1388,6 @@ 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.
|
||||
.Pp
|
||||
As for the
|
||||
.Cm \&:S
|
||||
@ -1387,9 +1398,9 @@ and
|
||||
are subjected to variable expansion before being parsed as
|
||||
regular expressions.
|
||||
.It Cm \&:T
|
||||
Replaces each word in the variable with its last component.
|
||||
Replaces each word in the variable with its last path component.
|
||||
.It Cm \&:u
|
||||
Remove adjacent duplicate words (like
|
||||
Removes adjacent duplicate words (like
|
||||
.Xr uniq 1 ) .
|
||||
.Sm off
|
||||
.It Cm \&:\&? Ar true_string Cm \&: Ar false_string
|
||||
@ -1405,7 +1416,7 @@ 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:
|
||||
to determine if any words match "42" you need to use something like:
|
||||
.Dl ${"${NUMBERS:M42}" != \&"\&":?match:no} .
|
||||
.It Ar :old_string=new_string
|
||||
This is the
|
||||
@ -1449,7 +1460,7 @@ in either the
|
||||
or
|
||||
.Ar old_string ,
|
||||
only the first instance is treated specially (as the pattern character);
|
||||
all subsequent instances are treated as regular characters
|
||||
all subsequent instances are treated as regular characters.
|
||||
.Pp
|
||||
Variable expansion occurs in the normal fashion inside both
|
||||
.Ar old_string
|
||||
@ -1466,11 +1477,10 @@ 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
|
||||
loops, expansion occurs at the time of reference.
|
||||
Assigns
|
||||
.Ar temp
|
||||
to each word in the variable and evaluate
|
||||
to each word in the variable and evaluates
|
||||
.Ar string .
|
||||
The ODE convention is that
|
||||
.Ar temp
|
||||
@ -1481,7 +1491,7 @@ For example.
|
||||
However a single character variable is often more readable:
|
||||
.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
|
||||
.It Cm \&:_[=var]
|
||||
Save the current variable value in
|
||||
Saves the current variable value in
|
||||
.Ql $_
|
||||
or the named
|
||||
.Va var
|
||||
@ -1502,7 +1512,7 @@ is used to save the result of the
|
||||
modifier which is later referenced using the index values from
|
||||
.Ql :range .
|
||||
.It Cm \&:U Ns Ar newval
|
||||
If the variable is undefined
|
||||
If the variable is undefined,
|
||||
.Ar newval
|
||||
is the value.
|
||||
If the variable is defined, the existing value is returned.
|
||||
@ -1512,7 +1522,7 @@ It is handy for setting per-target CFLAGS for instance:
|
||||
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
|
||||
If the variable is defined,
|
||||
.Ar newval
|
||||
is the value.
|
||||
.It Cm \&:L
|
||||
@ -1641,7 +1651,7 @@ 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
|
||||
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
|
||||
@ -1687,7 +1697,7 @@ The possible conditionals are as follows:
|
||||
The message is printed along with the name of the makefile and line number,
|
||||
then
|
||||
.Nm
|
||||
will exit.
|
||||
will exit immediately.
|
||||
.It Ic .export Ar variable ...
|
||||
Export the specified global variable.
|
||||
If no variable list is provided, all globals are exported
|
||||
@ -1876,7 +1886,7 @@ 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
|
||||
variable is being compared against 0, or an empty string in the case
|
||||
of a string comparison.
|
||||
.Pp
|
||||
When
|
||||
@ -1917,7 +1927,7 @@ 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 Aq make-lines
|
||||
.It Ic \&.endfor
|
||||
.El
|
||||
.Pp
|
||||
@ -1929,7 +1939,7 @@ On each iteration of the loop, one word is taken and assigned to each
|
||||
in order, and these
|
||||
.Ic variables
|
||||
are substituted into the
|
||||
.Ic make-rules
|
||||
.Ic make-lines
|
||||
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
|
||||
|
130
bmake.cat1
130
bmake.cat1
@ -89,9 +89,15 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
|
||||
[4mg3[24m Print the input graph before exiting on error.
|
||||
|
||||
[4mh[24m Print debugging information about hash table operations.
|
||||
|
||||
[4mj[24m Print debugging information about running multiple
|
||||
shells.
|
||||
|
||||
[4mL[24m Turn on lint checks. This will throw errors for variable
|
||||
assignments that do not parse correctly, at the time of
|
||||
assignment so the file and line number are available.
|
||||
|
||||
[4ml[24m Print commands in Makefiles regardless of whether or not
|
||||
they are prefixed by `@' or other "quiet" flags. Also
|
||||
known as "loud" behavior.
|
||||
@ -188,7 +194,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
|
||||
[1m-n [22mDisplay 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).
|
||||
cial source (see below) or the command is prefixed with `[1m+[22m'.
|
||||
|
||||
[1m-N [22mDisplay the commands which would have been executed, but do not
|
||||
actually execute any of them; useful for debugging top-level
|
||||
@ -260,25 +266,31 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
[1mFILE DEPENDENCY SPECIFICATIONS[0m
|
||||
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:
|
||||
on the sources and are customarily created from them. A target is con-
|
||||
sidered out-of-date if it does not exist, or if its modification time is
|
||||
less than that of any of its sources. An out-of-date target will be re-
|
||||
created, but not until all sources have been examined and themselves re-
|
||||
created as needed. Three operators may be used:
|
||||
|
||||
[1m: [22mA 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 [1mbmake [22mis interrupted.
|
||||
[1m: [22mMany dependency lines may name this target but only one may have
|
||||
attached shell commands. All sources named in all dependency lines
|
||||
are considered together, and if needed the attached shell commands
|
||||
are run to create or re-create the target. If [1mbmake [22mis inter-
|
||||
rupted, the target is removed.
|
||||
|
||||
[1m! [22mTargets 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 [1mbmake [22mis interrupted.
|
||||
[1m! [22mThe same, but the target is always re-created whether or not it is
|
||||
out of date.
|
||||
|
||||
[1m:: [22mIf 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 [1mbmake [22mis interrupted.
|
||||
[1m:: [22mAny dependency line may have attached shell commands, but each one
|
||||
is handled independently: its sources are considered and the
|
||||
attached shell commands are run if the target is out of date with
|
||||
respect to (only) those sources. Thus, different groups of the
|
||||
attached shell commands may be run depending on the circumstances.
|
||||
Furthermore, unlike [1m:, [22mfor dependency lines with no sources, the
|
||||
attached shell commands are always run. Also unlike [1m:, [22mthe target
|
||||
will not be removed if [1mbmake [22mis interrupted.
|
||||
All dependency lines mentioning a particular target must use the same
|
||||
operator.
|
||||
|
||||
Targets and sources may contain the shell wildcard values `?', `*', `[]',
|
||||
and `{}'. The values `?', `*', and `[]' may only be used as part of the
|
||||
@ -374,7 +386,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
|
||||
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
|
||||
taining dollar, braces, parentheses, or whitespace are really best
|
||||
avoided!
|
||||
|
||||
If the result of expanding a variable contains a dollar sign (`$') the
|
||||
@ -729,6 +741,9 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
contains a variable transform. `PWD' is set to the value
|
||||
of `[4m.OBJDIR[24m' for all programs which [1mbmake [22mexecutes.
|
||||
|
||||
.SHELL The pathname of the shell used to run target scripts. It
|
||||
is read-only.
|
||||
|
||||
.TARGETS The list of targets explicitly specified on the command
|
||||
line, if any.
|
||||
|
||||
@ -765,7 +780,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
ponent.
|
||||
|
||||
[1m:M[4m[22mpattern[0m
|
||||
Select only those words that match [4mpattern[24m. The standard shell
|
||||
Selects only those words that match [4mpattern[24m. The standard shell
|
||||
wildcard characters (`*', `?', and `[]') may be used. The wildcard
|
||||
characters may be escaped with a backslash (`\'). As a consequence
|
||||
of the way values are split into words, matched, and then joined, a
|
||||
@ -779,11 +794,11 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
This is identical to `[1m:M[22m', but selects all words which do not match
|
||||
[4mpattern[24m.
|
||||
|
||||
[1m:O [22mOrder every word in variable alphabetically.
|
||||
[1m:O [22mOrders every word in variable alphabetically.
|
||||
|
||||
[1m:Or [22mOrder every word in variable in reverse alphabetical order.
|
||||
[1m:Or [22mOrders every word in variable in reverse alphabetical order.
|
||||
|
||||
[1m:Ox [22mRandomize words in variable. The results will be different each
|
||||
[1m:Ox [22mShuffles the words in variable. The results will be different each
|
||||
time you are referring to the modified variable; use the assignment
|
||||
with expansion (`[1m:=[22m') to prevent such behavior. For example,
|
||||
|
||||
@ -821,13 +836,13 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
[4mutc[24m value is not provided or is 0, the current time is used.
|
||||
|
||||
[1m:hash[0m
|
||||
Compute a 32-bit hash of the value and encode it as hex digits.
|
||||
Computes a 32-bit hash of the value and encode it as hex digits.
|
||||
|
||||
[1m:localtime[=utc][0m
|
||||
The value is a format string for strftime(3), using localtime(3).
|
||||
If a [4mutc[24m value is not provided or is 0, the current time is used.
|
||||
|
||||
[1m:tA [22mAttempt to convert variable to an absolute path using realpath(3),
|
||||
[1m:tA [22mAttempts to convert variable to an absolute path using realpath(3),
|
||||
if that fails, the value is unchanged.
|
||||
|
||||
[1m:tl [22mConverts variable to lower-case letters.
|
||||
@ -836,7 +851,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
Words in the variable are normally separated by a space on expan-
|
||||
sion. This modifier sets the separator to the character [4mc[24m. If [4mc[24m is
|
||||
omitted, then no separator is used. The common escapes (including
|
||||
octal numeric codes), work as expected.
|
||||
octal numeric codes) work as expected.
|
||||
|
||||
[1m:tu [22mConverts variable to upper-case letters.
|
||||
|
||||
@ -847,20 +862,20 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
white space. See also `[1m:[@][22m'.
|
||||
|
||||
[1m:S[22m/[4mold_string[24m/[4mnew_string[24m/[[1m1gW[22m]
|
||||
Modify the first occurrence of [4mold_string[24m in the variable's value,
|
||||
replacing it with [4mnew_string[24m. 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 [4mold_string[24m begins with a caret
|
||||
(`^'), [4mold_string[24m is anchored at the beginning of each word. If
|
||||
[4mold_string[24m ends with a dollar sign (`$'), it is anchored at the end
|
||||
of each word. Inside [4mnew_string[24m, an ampersand (`&') is replaced by
|
||||
[4mold_string[24m (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
|
||||
(`\').
|
||||
Modifies the first occurrence of [4mold_string[24m in each word of the
|
||||
variable's value, replacing it with [4mnew_string[24m. If a `g' is
|
||||
appended to the last delimiter of the pattern, all occurrences in
|
||||
each word are replaced. If a `1' is appended to the last delimiter
|
||||
of the pattern, only the first occurrence is affected. If a `W' is
|
||||
appended to the last delimiter of the pattern, then the value is
|
||||
treated as a single word (possibly containing embedded white space).
|
||||
If [4mold_string[24m begins with a caret (`^'), [4mold_string[24m is anchored at
|
||||
the beginning of each word. If [4mold_string[24m ends with a dollar sign
|
||||
(`$'), it is anchored at the end of each word. Inside [4mnew_string[24m,
|
||||
an ampersand (`&') is replaced by [4mold_string[24m (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
|
||||
[4mold_string[24m and [4mnew_string[24m with the single exception that a backslash
|
||||
@ -878,16 +893,13 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
instances of the search pattern [4mpattern[24m as occur in the word or
|
||||
words it is found in; the `W' modifier causes the value to be
|
||||
treated as a single 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.
|
||||
|
||||
As for the [1m:S [22mmodifier, the [4mpattern[24m and [4mreplacement[24m are subjected to
|
||||
variable expansion before being parsed as regular expressions.
|
||||
|
||||
[1m:T [22mReplaces each word in the variable with its last component.
|
||||
[1m:T [22mReplaces each word in the variable with its last path component.
|
||||
|
||||
[1m:u [22mRemove adjacent duplicate words (like uniq(1)).
|
||||
[1m:u [22mRemoves adjacent duplicate words (like uniq(1)).
|
||||
|
||||
[1m:?[4m[22mtrue_string[24m[1m:[4m[22mfalse_string[0m
|
||||
If the variable name (not its value), when parsed as a .if condi-
|
||||
@ -898,7 +910,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
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
|
||||
which actually tests defined(NUMBERS), to determine if any words
|
||||
match "42" you need to use something like:
|
||||
${"${NUMBERS:M42}" != "":?match:no}.
|
||||
|
||||
@ -916,7 +928,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
pattern matching character ([4m%[24m) in either the [4mnew_string[24m or
|
||||
[4mold_string[24m, only the first instance is treated specially (as the
|
||||
pattern character); all subsequent instances are treated as regular
|
||||
characters
|
||||
characters.
|
||||
|
||||
Variable expansion occurs in the normal fashion inside both
|
||||
[4mold_string[24m and [4mnew_string[24m with the single exception that a backslash
|
||||
@ -925,17 +937,17 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
|
||||
[1m:@[4m[22mtemp[24m[1m@[4m[22mstring[24m[1m@[0m
|
||||
This is the loop expansion mechanism from the OSF Development Envi-
|
||||
ronment (ODE) make. Unlike [1m.for [22mloops expansion occurs at the time
|
||||
of reference. Assign [4mtemp[24m to each word in the variable and evaluate
|
||||
[4mstring[24m. The ODE convention is that [4mtemp[24m should start and end with a
|
||||
period. For example.
|
||||
ronment (ODE) make. Unlike [1m.for [22mloops, expansion occurs at the time
|
||||
of reference. Assigns [4mtemp[24m to each word in the variable and evalu-
|
||||
ates [4mstring[24m. The ODE convention is that [4mtemp[24m should start and end
|
||||
with a period. For example.
|
||||
${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@}
|
||||
|
||||
However a single character variable is often more readable:
|
||||
${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
|
||||
|
||||
[1m:_[=var][0m
|
||||
Save the current variable value in `$_' or the named [4mvar[24m for later
|
||||
Saves the current variable value in `$_' or the named [4mvar[24m for later
|
||||
reference. Example usage:
|
||||
|
||||
M_cmpv.units = 1 1000 1000000
|
||||
@ -948,7 +960,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
later referenced using the index values from `:range'.
|
||||
|
||||
[1m:U[4m[22mnewval[0m
|
||||
If the variable is undefined [4mnewval[24m is the value. If the variable
|
||||
If the variable is undefined, [4mnewval[24m 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:
|
||||
@ -957,7 +969,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
${VAR:D:Unewval}
|
||||
|
||||
[1m:D[4m[22mnewval[0m
|
||||
If the variable is defined [4mnewval[24m is the value.
|
||||
If the variable is defined, [4mnewval[24m is the value.
|
||||
|
||||
[1m:L [22mThe name of the variable is the value.
|
||||
|
||||
@ -1033,7 +1045,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
[1m# [22mReturns the number of words in the value.
|
||||
|
||||
[1mINCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS[0m
|
||||
Makefile inclusion, conditional structures and for loops reminiscent of
|
||||
Makefile inclusion, conditional structures and for loops reminiscent of
|
||||
the C programming language are provided in [1mbmake[22m. All such structures
|
||||
are identified by a line beginning with a single dot (`.') character.
|
||||
Files are included with either [1m.include <[4m[22mfile[24m[1m> [22mor [1m.include "[4m[22mfile[24m[1m"[22m. Vari-
|
||||
@ -1057,7 +1069,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
|
||||
[1m.error [4m[22mmessage[0m
|
||||
The message is printed along with the name of the makefile and
|
||||
line number, then [1mbmake [22mwill exit.
|
||||
line number, then [1mbmake [22mwill exit immediately.
|
||||
|
||||
[1m.export [4m[22mvariable[24m [4m...[0m
|
||||
Export the specified global variable. If no variable list is
|
||||
@ -1191,7 +1203,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
variable expansion, either the left or right hand side of a `[1m==[22m' or `[1m!=[22m'
|
||||
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
|
||||
is assumed that the expanded variable is being compared against 0, or an
|
||||
empty string in the case of a string comparison.
|
||||
|
||||
When [1mbmake [22mis evaluating one of these conditional expressions, and it
|
||||
@ -1210,12 +1222,12 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
The syntax of a for loop is:
|
||||
|
||||
[1m.for [4m[22mvariable[24m [[4mvariable[24m [4m...[24m] [1min [4m[22mexpression[0m
|
||||
<make-rules>
|
||||
<make-lines>
|
||||
[1m.endfor[0m
|
||||
|
||||
After the for [1mexpression [22mis evaluated, it is split into words. On each
|
||||
iteration of the loop, one word is taken and assigned to each [1mvariable[22m,
|
||||
in order, and these [1mvariables [22mare substituted into the [1mmake-rules [22minside
|
||||
in order, and these [1mvariables [22mare substituted into the [1mmake-lines [22minside
|
||||
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.
|
||||
@ -1556,4 +1568,4 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
|
||||
|
||||
There is no way of escaping a space character in a filename.
|
||||
|
||||
FreeBSD 11.3 June 5, 2020 FreeBSD 11.3
|
||||
FreeBSD 11.3 August 28, 2020 FreeBSD 11.3
|
||||
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 80 KiB |
@ -1,4 +1,4 @@
|
||||
# $Id: bsd.after-import.mk,v 1.15 2018/12/30 17:14:24 sjg Exp $
|
||||
# $Id: bsd.after-import.mk,v 1.16 2020/07/12 03:39:01 sjg Exp $
|
||||
|
||||
# This makefile is for use when integrating bmake into a BSD build
|
||||
# system. Use this makefile after importing bmake.
|
||||
@ -9,7 +9,7 @@
|
||||
# The goal is to allow the benefits of autoconf without
|
||||
# the overhead of running configure.
|
||||
|
||||
all: _makefile
|
||||
all: _makefile _utmakefile
|
||||
all: after-import
|
||||
|
||||
# we rely on bmake
|
||||
@ -37,7 +37,9 @@ SRCTOP := ${srctop}
|
||||
.endif
|
||||
|
||||
# This lets us match what boot-strap does
|
||||
.if !defined(HOST_OS)
|
||||
.if defined(.MAKE.OS)
|
||||
HOST_OS:= ${.MAKE.OS}
|
||||
.elif !defined(HOST_OS)
|
||||
HOST_OS!= uname
|
||||
.endif
|
||||
|
||||
@ -107,5 +109,18 @@ _makefile: bootstrap ${MAKEFILE}
|
||||
@cmp -s ${.TARGET} ${.CURDIR}/Makefile || \
|
||||
mv ${.TARGET} ${.CURDIR}/Makefile
|
||||
|
||||
_utmakefile: bootstrap ${MAKEFILE}
|
||||
@echo Generating ${.CURDIR}/unit-tests/Makefile
|
||||
@mkdir -p ${.CURDIR}/unit-tests
|
||||
@(echo '# This is a generated file, do NOT edit!'; \
|
||||
echo '# See ${_this:S,${SRCTOP}/,,}'; \
|
||||
echo '#'; echo '# $$${HOST_OS}$$'; \
|
||||
${MAKEFILE_SED} \
|
||||
-e '/^UNIT_TESTS/s,=.*,= $${srcdir},' \
|
||||
${BMAKE_SRC}/unit-tests/Makefile ) > ${.TARGET}
|
||||
@cmp -s ${.TARGET} ${.CURDIR}/unit-tests/Makefile || \
|
||||
mv ${.TARGET} ${.CURDIR}/unit-tests/Makefile
|
||||
|
||||
|
||||
.include <bsd.obj.mk>
|
||||
|
||||
|
216
buf.c
216
buf.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: buf.c,v 1.26 2020/07/03 08:02:55 rillig Exp $ */
|
||||
/* $NetBSD: buf.c,v 1.37 2020/08/23 08:21:50 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -70,173 +70,123 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: buf.c,v 1.26 2020/07/03 08:02:55 rillig Exp $";
|
||||
static char rcsid[] = "$NetBSD: buf.c,v 1.37 2020/08/23 08:21:50 rillig 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.26 2020/07/03 08:02:55 rillig Exp $");
|
||||
__RCSID("$NetBSD: buf.c,v 1.37 2020/08/23 08:21:50 rillig Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
/*-
|
||||
* buf.c --
|
||||
* Functions for automatically-expanded buffers.
|
||||
*/
|
||||
/* Functions for automatically-expanded null-terminated buffers. */
|
||||
|
||||
#include "make.h"
|
||||
#include "buf.h"
|
||||
#include <limits.h>
|
||||
#include "make.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.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
/* Extend the buffer for adding a single byte. */
|
||||
void
|
||||
Buf_Expand_1(Buffer *bp)
|
||||
{
|
||||
bp->size += max(bp->size, 16);
|
||||
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?
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
/* Add the given bytes to the buffer. */
|
||||
void
|
||||
Buf_AddBytes(Buffer *bp, int numBytes, const Byte *bytesPtr)
|
||||
Buf_AddBytes(Buffer *bp, const char *bytesPtr, size_t numBytes)
|
||||
{
|
||||
int count = bp->count;
|
||||
Byte *ptr;
|
||||
size_t count = bp->count;
|
||||
char *ptr;
|
||||
|
||||
if (__predict_false(count + numBytes >= bp->size)) {
|
||||
bp->size += max(bp->size, numBytes + 16);
|
||||
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);
|
||||
ptr[numBytes] = '\0';
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* 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)
|
||||
/* Add the bytes between start and end to the buffer. */
|
||||
void
|
||||
Buf_AddBytesBetween(Buffer *bp, const char *start, const char *end)
|
||||
{
|
||||
Buf_AddBytes(bp, start, (size_t)(end - start));
|
||||
}
|
||||
|
||||
/* Add the given string to the buffer. */
|
||||
void
|
||||
Buf_AddStr(Buffer *bp, const char *str)
|
||||
{
|
||||
Buf_AddBytes(bp, str, strlen(str));
|
||||
}
|
||||
|
||||
/* Add the given number to the buffer. */
|
||||
void
|
||||
Buf_AddInt(Buffer *bp, int n)
|
||||
{
|
||||
enum {
|
||||
bits = sizeof(int) * CHAR_BIT,
|
||||
max_octal_digits = (bits + 2) / 3,
|
||||
max_decimal_digits = /* at most */ max_octal_digits,
|
||||
max_sign_chars = 1,
|
||||
buf_size = max_sign_chars + max_decimal_digits + 1
|
||||
};
|
||||
char buf[buf_size];
|
||||
|
||||
size_t len = (size_t)snprintf(buf, sizeof buf, "%d", n);
|
||||
Buf_AddBytes(bp, buf, len);
|
||||
}
|
||||
|
||||
/* Get the data (usually a string) from the buffer.
|
||||
* The returned data is valid until the next modifying operation
|
||||
* on the buffer.
|
||||
*
|
||||
* Returns the pointer to the data and optionally the length of the
|
||||
* data in the buffer. */
|
||||
char *
|
||||
Buf_GetAll(Buffer *bp, size_t *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.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
/* Mark the buffer as empty, so it can be filled with data again. */
|
||||
void
|
||||
Buf_Empty(Buffer *bp)
|
||||
{
|
||||
|
||||
bp->count = 0;
|
||||
*bp->buffer = 0;
|
||||
bp->buffer[0] = '\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.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
/* Initialize a buffer.
|
||||
* If the given initial size is 0, a reasonable default is used. */
|
||||
void
|
||||
Buf_Init(Buffer *bp, int size)
|
||||
Buf_Init(Buffer *bp, size_t size)
|
||||
{
|
||||
if (size <= 0) {
|
||||
size = BUF_DEF_SIZE;
|
||||
size = 256;
|
||||
}
|
||||
bp->size = size;
|
||||
bp->count = 0;
|
||||
bp->buffer = bmake_malloc(size);
|
||||
*bp->buffer = 0;
|
||||
bp->buffer[0] = '\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 *
|
||||
/* Reset the buffer.
|
||||
* If freeData is TRUE, the data from the buffer is freed as well.
|
||||
* Otherwise it is kept and returned. */
|
||||
char *
|
||||
Buf_Destroy(Buffer *buf, Boolean freeData)
|
||||
{
|
||||
Byte *data;
|
||||
|
||||
data = buf->buffer;
|
||||
char *data = buf->buffer;
|
||||
if (freeData) {
|
||||
free(data);
|
||||
data = NULL;
|
||||
@ -249,42 +199,24 @@ Buf_Destroy(Buffer *buf, Boolean freeData)
|
||||
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 */
|
||||
# define BUF_COMPACT_LIMIT 128 /* worthwhile saving */
|
||||
#endif
|
||||
|
||||
Byte *
|
||||
/* Reset the buffer and return its data.
|
||||
*
|
||||
* If the buffer size is much greater than its content,
|
||||
* a new buffer will be allocated and the old one freed. */
|
||||
char *
|
||||
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;
|
||||
}
|
||||
char *data = bmake_realloc(buf->buffer, buf->count + 1);
|
||||
data[buf->count] = '\0';
|
||||
Buf_Destroy(buf, FALSE);
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
return Buf_Destroy(buf, FALSE);
|
||||
|
66
buf.h
66
buf.h
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: buf.h,v 1.19 2017/05/31 22:02:06 maya Exp $ */
|
||||
/* $NetBSD: buf.h,v 1.28 2020/09/01 17:38:26 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -72,48 +72,54 @@
|
||||
* from: @(#)buf.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*-
|
||||
* buf.h --
|
||||
* Header for users of the buf library.
|
||||
*/
|
||||
/* Automatically growing null-terminated buffers of characters. */
|
||||
|
||||
#ifndef MAKE_BUF_H
|
||||
#define MAKE_BUF_H
|
||||
|
||||
typedef char Byte;
|
||||
#include <stddef.h>
|
||||
|
||||
/* An automatically growing null-terminated buffer of characters. */
|
||||
typedef struct Buffer {
|
||||
int size; /* Current size of the buffer */
|
||||
int count; /* Number of bytes in buffer */
|
||||
Byte *buffer; /* The buffer itself (zero terminated) */
|
||||
size_t size; /* Allocated size of the buffer, including the null */
|
||||
size_t count; /* Number of bytes in buffer, excluding the null */
|
||||
char *buffer; /* The buffer itself (always null-terminated) */
|
||||
} Buffer;
|
||||
|
||||
/* If we aren't on netbsd, __predict_false() might not be defined. */
|
||||
/* 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 *);
|
||||
|
||||
/* Buf_AddByte adds a single byte to a buffer. */
|
||||
static inline void MAKE_ATTR_UNUSED
|
||||
Buf_AddByte(Buffer *bp, char byte)
|
||||
{
|
||||
size_t 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;
|
||||
}
|
||||
|
||||
static inline size_t MAKE_ATTR_UNUSED
|
||||
Buf_Size(const Buffer *bp)
|
||||
{
|
||||
return bp->count;
|
||||
}
|
||||
|
||||
void Buf_AddBytes(Buffer *, const char *, size_t);
|
||||
void Buf_AddBytesBetween(Buffer *, const char *, const char *);
|
||||
void Buf_AddStr(Buffer *, const char *);
|
||||
void Buf_AddInt(Buffer *, int);
|
||||
char *Buf_GetAll(Buffer *, size_t *);
|
||||
void Buf_Empty(Buffer *);
|
||||
void Buf_Init(Buffer *, int);
|
||||
Byte *Buf_Destroy(Buffer *, Boolean);
|
||||
Byte *Buf_DestroyCompact(Buffer *);
|
||||
void Buf_Init(Buffer *, size_t);
|
||||
char *Buf_Destroy(Buffer *, Boolean);
|
||||
char *Buf_DestroyCompact(Buffer *);
|
||||
|
||||
#endif /* MAKE_BUF_H */
|
||||
|
136
compat.c
136
compat.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: compat.c,v 1.113 2020/07/03 08:13:23 rillig Exp $ */
|
||||
/* $NetBSD: compat.c,v 1.139 2020/08/30 20:08:47 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -70,14 +70,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: compat.c,v 1.113 2020/07/03 08:13:23 rillig Exp $";
|
||||
static char rcsid[] = "$NetBSD: compat.c,v 1.139 2020/08/30 20:08:47 rillig 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.113 2020/07/03 08:13:23 rillig Exp $");
|
||||
__RCSID("$NetBSD: compat.c,v 1.139 2020/08/30 20:08:47 rillig Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -129,34 +129,24 @@ static void
|
||||
CompatDeleteTarget(GNode *gn)
|
||||
{
|
||||
if ((gn != NULL) && !Targ_Precious (gn)) {
|
||||
char *p1;
|
||||
char *file = Var_Value(TARGET, gn, &p1);
|
||||
char *p1;
|
||||
const char *file = Var_Value(TARGET, gn, &p1);
|
||||
|
||||
if (!noExecute && eunlink(file) != -1) {
|
||||
Error("*** %s removed", file);
|
||||
}
|
||||
|
||||
free(p1);
|
||||
bmake_free(p1);
|
||||
}
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* CompatInterrupt --
|
||||
* Interrupt the creation of the current target and remove it if
|
||||
* it ain't precious.
|
||||
/* Interrupt the creation of the current target and remove it if it ain't
|
||||
* precious. Then exit.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side Effects:
|
||||
* The target is removed and the process exits. If .INTERRUPT exists,
|
||||
* its commands are run first WITH INTERRUPTS IGNORED..
|
||||
* If .INTERRUPT exists, its commands are run first WITH INTERRUPTS IGNORED.
|
||||
*
|
||||
* XXX: is .PRECIOUS supposed to inhibit .INTERRUPT? I doubt it, but I've
|
||||
* left the logic alone for now. - dholland 20160826
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
CompatInterrupt(int signo)
|
||||
@ -190,7 +180,7 @@ CompatInterrupt(int signo)
|
||||
kill(myPid, signo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* CompatRunCommand --
|
||||
@ -215,7 +205,7 @@ 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 */
|
||||
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 */
|
||||
@ -224,21 +214,17 @@ CompatRunCommand(void *cmdp, void *gnp)
|
||||
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;
|
||||
silent = (gn->type & OP_SILENT) != 0;
|
||||
errCheck = !(gn->type & OP_IGNORE);
|
||||
doIt = FALSE;
|
||||
|
||||
cmdNode = Lst_Member(gn->commands, cmd);
|
||||
cmdStart = Var_Subst(NULL, cmd, gn, VARF_WANTRES);
|
||||
cmdNode = Lst_FindDatum(gn->commands, cmd);
|
||||
cmdStart = Var_Subst(cmd, gn, VARE_WANTRES);
|
||||
|
||||
/*
|
||||
* brk_string will return an argv with a NULL in av[0], thus causing
|
||||
@ -252,10 +238,11 @@ CompatRunCommand(void *cmdp, void *gnp)
|
||||
return 0;
|
||||
}
|
||||
cmd = cmdStart;
|
||||
Lst_Replace(cmdNode, cmdStart);
|
||||
LstNode_Set(cmdNode, cmdStart);
|
||||
|
||||
if ((gn->type & OP_SAVE_CMDS) && (gn != ENDNode)) {
|
||||
(void)Lst_AtEnd(ENDNode->commands, cmdStart);
|
||||
assert(ENDNode != NULL);
|
||||
Lst_Append(ENDNode->commands, cmdStart);
|
||||
return 0;
|
||||
}
|
||||
if (strcmp(cmdStart, "...") == 0) {
|
||||
@ -266,7 +253,7 @@ CompatRunCommand(void *cmdp, void *gnp)
|
||||
while ((*cmd == '@') || (*cmd == '-') || (*cmd == '+')) {
|
||||
switch (*cmd) {
|
||||
case '@':
|
||||
silent = DEBUG(LOUD) ? FALSE : TRUE;
|
||||
silent = !DEBUG(LOUD);
|
||||
break;
|
||||
case '-':
|
||||
errCheck = FALSE;
|
||||
@ -330,7 +317,6 @@ CompatRunCommand(void *cmdp, void *gnp)
|
||||
if (DEBUG(JOB))
|
||||
fprintf(debug_file, "Execute: '%s'\n", cmd);
|
||||
|
||||
again:
|
||||
if (useShell) {
|
||||
/*
|
||||
* We need to pass the command off to the shell, typically
|
||||
@ -352,9 +338,8 @@ CompatRunCommand(void *cmdp, void *gnp)
|
||||
else
|
||||
shargv[shargc++] = "-c";
|
||||
shargv[shargc++] = cmd;
|
||||
shargv[shargc++] = NULL;
|
||||
shargv[shargc] = NULL;
|
||||
av = shargv;
|
||||
argc = 0;
|
||||
bp = NULL;
|
||||
mav = NULL;
|
||||
} else {
|
||||
@ -362,16 +347,12 @@ CompatRunCommand(void *cmdp, void *gnp)
|
||||
* 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;
|
||||
}
|
||||
Words words = Str_Words(cmd, FALSE);
|
||||
mav = words.words;
|
||||
bp = words.freeIt;
|
||||
av = (void *)mav;
|
||||
}
|
||||
|
||||
local = TRUE;
|
||||
|
||||
#ifdef USE_META
|
||||
if (useMeta) {
|
||||
meta_compat_start();
|
||||
@ -392,10 +373,7 @@ CompatRunCommand(void *cmdp, void *gnp)
|
||||
meta_compat_child();
|
||||
}
|
||||
#endif
|
||||
if (local)
|
||||
(void)execvp(av[0], (char *const *)UNCONST(av));
|
||||
else
|
||||
(void)execv(av[0], (char *const *)UNCONST(av));
|
||||
(void)execvp(av[0], (char *const *)UNCONST(av));
|
||||
execError("exec", av[0]);
|
||||
_exit(1);
|
||||
}
|
||||
@ -403,7 +381,9 @@ CompatRunCommand(void *cmdp, void *gnp)
|
||||
free(mav);
|
||||
free(bp);
|
||||
|
||||
Lst_Replace(cmdNode, NULL);
|
||||
/* XXX: Memory management looks suspicious here. */
|
||||
/* XXX: Setting a list item to NULL is unexpected. */
|
||||
LstNode_SetNull(cmdNode);
|
||||
|
||||
#ifdef USE_META
|
||||
if (useMeta) {
|
||||
@ -436,18 +416,18 @@ CompatRunCommand(void *cmdp, void *gnp)
|
||||
#endif
|
||||
if (status != 0) {
|
||||
if (DEBUG(ERROR)) {
|
||||
fprintf(debug_file, "\n*** Failed target: %s\n*** Failed command: ",
|
||||
fprintf(debug_file, "\n*** Failed target: %s\n*** Failed command: ",
|
||||
gn->name);
|
||||
for (cp = cmd; *cp; ) {
|
||||
if (isspace((unsigned char)*cp)) {
|
||||
for (cp = cmd; *cp; ) {
|
||||
if (isspace((unsigned char)*cp)) {
|
||||
fprintf(debug_file, " ");
|
||||
while (isspace((unsigned char)*cp))
|
||||
while (isspace((unsigned char)*cp))
|
||||
cp++;
|
||||
} else {
|
||||
fprintf(debug_file, "%c", *cp);
|
||||
cp++;
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(debug_file, "\n");
|
||||
}
|
||||
printf("*** Error code %d", status);
|
||||
@ -502,7 +482,7 @@ CompatRunCommand(void *cmdp, void *gnp)
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Compat_Make --
|
||||
@ -544,14 +524,14 @@ Compat_Make(void *gnp, void *pgnp)
|
||||
Lst_ForEach(gn->children, Compat_Make, gn);
|
||||
if ((gn->flags & REMAKE) == 0) {
|
||||
gn->made = ABORTED;
|
||||
pgn->flags &= ~REMAKE;
|
||||
pgn->flags &= ~(unsigned)REMAKE;
|
||||
goto cohorts;
|
||||
}
|
||||
|
||||
if (Lst_Member(gn->iParents, pgn) != NULL) {
|
||||
if (Lst_FindDatum(gn->implicitParents, pgn) != NULL) {
|
||||
char *p1;
|
||||
Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn);
|
||||
free(p1);
|
||||
bmake_free(p1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -614,7 +594,7 @@ Compat_Make(void *gnp, void *pgnp)
|
||||
Lst_ForEach(gn->commands, CompatRunCommand, gn);
|
||||
curTarg = NULL;
|
||||
} else {
|
||||
Job_Touch(gn, gn->type & OP_SILENT);
|
||||
Job_Touch(gn, (gn->type & OP_SILENT) != 0);
|
||||
}
|
||||
} else {
|
||||
gn->made = ERROR;
|
||||
@ -640,7 +620,7 @@ Compat_Make(void *gnp, void *pgnp)
|
||||
Make_TimeStamp(pgn, gn);
|
||||
}
|
||||
} else if (keepgoing) {
|
||||
pgn->flags &= ~REMAKE;
|
||||
pgn->flags &= ~(unsigned)REMAKE;
|
||||
} else {
|
||||
PrintOnError(gn, "\nStop.");
|
||||
exit(1);
|
||||
@ -650,18 +630,19 @@ Compat_Make(void *gnp, void *pgnp)
|
||||
* Already had an error when making this beastie. Tell the parent
|
||||
* to abort.
|
||||
*/
|
||||
pgn->flags &= ~REMAKE;
|
||||
pgn->flags &= ~(unsigned)REMAKE;
|
||||
} else {
|
||||
if (Lst_Member(gn->iParents, pgn) != NULL) {
|
||||
if (Lst_FindDatum(gn->implicitParents, pgn) != NULL) {
|
||||
char *p1;
|
||||
Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn);
|
||||
free(p1);
|
||||
const char *target = Var_Value(TARGET, gn, &p1);
|
||||
Var_Set(IMPSRC, target != NULL ? target : "", pgn);
|
||||
bmake_free(p1);
|
||||
}
|
||||
switch(gn->made) {
|
||||
case BEINGMADE:
|
||||
Error("Graph cycles through %s", gn->name);
|
||||
gn->made = ERROR;
|
||||
pgn->flags &= ~REMAKE;
|
||||
pgn->flags &= ~(unsigned)REMAKE;
|
||||
break;
|
||||
case MADE:
|
||||
if ((gn->type & OP_EXEC) == 0) {
|
||||
@ -683,22 +664,11 @@ Compat_Make(void *gnp, void *pgnp)
|
||||
Lst_ForEach(gn->cohorts, Compat_Make, pgnp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Compat_Run --
|
||||
* Initialize this mode and start making.
|
||||
|
||||
/* Initialize this module and start making.
|
||||
*
|
||||
* Input:
|
||||
* targs List of target nodes to re-create
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side Effects:
|
||||
* Guess what?
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
* targs The target nodes to re-create
|
||||
*/
|
||||
void
|
||||
Compat_Run(Lst targs)
|
||||
@ -732,10 +702,10 @@ Compat_Run(Lst targs)
|
||||
gn = Targ_FindNode(".BEGIN", TARG_NOCREATE);
|
||||
if (gn != NULL) {
|
||||
Compat_Make(gn, gn);
|
||||
if (gn->made == ERROR) {
|
||||
PrintOnError(gn, "\nStop.");
|
||||
exit(1);
|
||||
}
|
||||
if (gn->made == ERROR) {
|
||||
PrintOnError(gn, "\nStop.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -756,8 +726,8 @@ Compat_Run(Lst targs)
|
||||
* could not be made due to errors.
|
||||
*/
|
||||
errors = 0;
|
||||
while (!Lst_IsEmpty (targs)) {
|
||||
gn = (GNode *)Lst_DeQueue(targs);
|
||||
while (!Lst_IsEmpty(targs)) {
|
||||
gn = Lst_Dequeue(targs);
|
||||
Compat_Make(gn, gn);
|
||||
|
||||
if (gn->made == UPTODATE) {
|
||||
|
28
dir.h
28
dir.h
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dir.h,v 1.18 2017/05/31 22:02:06 maya Exp $ */
|
||||
/* $NetBSD: dir.h,v 1.23 2020/09/02 04:08:54 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -72,29 +72,34 @@
|
||||
* from: @(#)dir.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/* dir.h --
|
||||
*/
|
||||
|
||||
#ifndef MAKE_DIR_H
|
||||
#define MAKE_DIR_H
|
||||
|
||||
typedef struct Path {
|
||||
/* A cache of a directory, remembering all the files that exist in that
|
||||
* directory. */
|
||||
typedef struct {
|
||||
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 */
|
||||
Hash_Table files; /* Hash set of files in directory */
|
||||
} Path;
|
||||
|
||||
void Dir_Init(const char *);
|
||||
struct make_stat {
|
||||
time_t mst_mtime;
|
||||
mode_t mst_mode;
|
||||
};
|
||||
|
||||
void Dir_Init(void);
|
||||
void Dir_InitDir(const char *);
|
||||
void Dir_InitCur(const char *);
|
||||
void Dir_InitDot(void);
|
||||
void Dir_End(void);
|
||||
void Dir_SetPATH(void);
|
||||
Boolean Dir_HasWildcards(char *);
|
||||
Boolean Dir_HasWildcards(const char *);
|
||||
void Dir_Expand(const char *, Lst, Lst);
|
||||
char *Dir_FindFile(const char *, Lst);
|
||||
int Dir_FindHereOrAbove(char *, char *, char *, int);
|
||||
Boolean Dir_FindHereOrAbove(const char *, const char *, char *, int);
|
||||
int Dir_MTime(GNode *, Boolean);
|
||||
Path *Dir_AddDir(Lst, const char *);
|
||||
char *Dir_MakeFlags(const char *, Lst);
|
||||
@ -103,6 +108,9 @@ void Dir_Concat(Lst, Lst);
|
||||
void Dir_PrintDirectories(void);
|
||||
void Dir_PrintPath(Lst);
|
||||
void Dir_Destroy(void *);
|
||||
void * Dir_CopyDir(void *);
|
||||
void *Dir_CopyDir(void *);
|
||||
|
||||
int cached_lstat(const char *, struct make_stat *);
|
||||
int cached_stat(const char *, struct make_stat *);
|
||||
|
||||
#endif /* MAKE_DIR_H */
|
||||
|
100
enum.c
Executable file
100
enum.c
Executable file
@ -0,0 +1,100 @@
|
||||
/* $NetBSD: enum.c,v 1.6 2020/09/01 20:34:51 rillig Exp $ */
|
||||
|
||||
/*
|
||||
Copyright (c) 2020 Roland Illig <rillig@NetBSD.org>
|
||||
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 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 HOLDER 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: enum.c,v 1.6 2020/09/01 20:34:51 rillig Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: enum.c,v 1.6 2020/09/01 20:34:51 rillig Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "enum.h"
|
||||
|
||||
/* Convert a bitset into a string representation, showing the names of the
|
||||
* individual bits.
|
||||
*
|
||||
* Optionally, shortcuts for groups of bits can be added. To have an effect,
|
||||
* they need to be listed before their individual bits. */
|
||||
const char *
|
||||
Enum_FlagsToString(char *buf, size_t buf_size,
|
||||
int value, const EnumToStringSpec *spec)
|
||||
{
|
||||
const char *buf_start = buf;
|
||||
const char *sep = "";
|
||||
size_t sep_len = 0;
|
||||
|
||||
for (; spec->es_value != 0; spec++) {
|
||||
size_t name_len;
|
||||
|
||||
if ((value & spec->es_value) != spec->es_value)
|
||||
continue;
|
||||
value &= ~spec->es_value;
|
||||
|
||||
assert(buf_size >= sep_len + 1);
|
||||
memcpy(buf, sep, sep_len);
|
||||
buf += sep_len;
|
||||
buf_size -= sep_len;
|
||||
|
||||
name_len = strlen(spec->es_name);
|
||||
assert(buf_size >= name_len + 1);
|
||||
memcpy(buf, spec->es_name, name_len);
|
||||
buf += name_len;
|
||||
buf_size -= name_len;
|
||||
|
||||
sep = ENUM__SEP;
|
||||
sep_len = sizeof ENUM__SEP - 1;
|
||||
}
|
||||
|
||||
/* If this assertion fails, the listed enum values are incomplete. */
|
||||
assert(value == 0);
|
||||
|
||||
if (buf == buf_start)
|
||||
return "none";
|
||||
|
||||
assert(buf_size >= 1);
|
||||
buf[0] = '\0';
|
||||
return buf_start;
|
||||
}
|
||||
|
||||
/* Convert a fixed-value enum into a string representation. */
|
||||
const char *
|
||||
Enum_ValueToString(int value, const EnumToStringSpec *spec)
|
||||
{
|
||||
for (; spec->es_name[0] != '\0'; spec++) {
|
||||
if (value == spec->es_value)
|
||||
return spec->es_name;
|
||||
}
|
||||
abort(/* unknown enum value */);
|
||||
}
|
193
enum.h
Executable file
193
enum.h
Executable file
@ -0,0 +1,193 @@
|
||||
/* $NetBSD: enum.h,v 1.9 2020/09/01 20:34:51 rillig Exp $ */
|
||||
|
||||
/*
|
||||
Copyright (c) 2020 Roland Illig <rillig@NetBSD.org>
|
||||
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 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 HOLDER 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_ENUM_H
|
||||
#define MAKE_ENUM_H
|
||||
|
||||
/* Generate string representations for bitmasks and simple enums. */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
int es_value;
|
||||
const char *es_name;
|
||||
} EnumToStringSpec;
|
||||
|
||||
const char *Enum_FlagsToString(char *, size_t, int, const EnumToStringSpec *);
|
||||
const char *Enum_ValueToString(int, const EnumToStringSpec *);
|
||||
|
||||
/* For Enum_FlagsToString, the separator between flags. */
|
||||
#define ENUM__SEP "|"
|
||||
|
||||
/* Generate the string that joins all possible flags, to see how large the
|
||||
* buffer must be. */
|
||||
#define ENUM__JOIN_STR_1(v1) \
|
||||
#v1
|
||||
#define ENUM__JOIN_STR_2(v1, v2) \
|
||||
ENUM__JOIN_STR_1(v1) ENUM__SEP \
|
||||
ENUM__JOIN_STR_1(v2)
|
||||
#define ENUM__JOIN_STR_4(v1, v2, v3, v4) \
|
||||
ENUM__JOIN_STR_2(v1, v2) ENUM__SEP \
|
||||
ENUM__JOIN_STR_2(v3, v4)
|
||||
#define ENUM__JOIN_STR_8(v1, v2, v3, v4, v5, v6, v7, v8) \
|
||||
ENUM__JOIN_STR_4(v1, v2, v3, v4) ENUM__SEP \
|
||||
ENUM__JOIN_STR_4(v5, v6, v7, v8)
|
||||
#define ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16) \
|
||||
ENUM__JOIN_STR_8(v01, v02, v03, v04, v05, v06, v07, v08) ENUM__SEP \
|
||||
ENUM__JOIN_STR_8(v09, v10, v11, v12, v13, v14, v15, v16)
|
||||
|
||||
#define ENUM__JOIN_2(part1, part2) \
|
||||
part1 ENUM__SEP part2
|
||||
#define ENUM__JOIN_3(part1, part2, part3) \
|
||||
part1 ENUM__SEP part2 ENUM__SEP part3
|
||||
#define ENUM__JOIN_4(part1, part2, part3, part4) \
|
||||
part1 ENUM__SEP part2 ENUM__SEP part3 ENUM__SEP part4
|
||||
#define ENUM__JOIN_5(part1, part2, part3, part4, part5) \
|
||||
part1 ENUM__SEP part2 ENUM__SEP part3 ENUM__SEP part4 ENUM__SEP part5
|
||||
|
||||
/* List the pairs of enum value and corresponding name. */
|
||||
#define ENUM__SPEC_1(v1) \
|
||||
{ v1, #v1 }
|
||||
#define ENUM__SPEC_2(v1, v2) \
|
||||
ENUM__SPEC_1(v1), \
|
||||
ENUM__SPEC_1(v2)
|
||||
#define ENUM__SPEC_4(v1, v2, v3, v4) \
|
||||
ENUM__SPEC_2(v1, v2), \
|
||||
ENUM__SPEC_2(v3, v4)
|
||||
#define ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8) \
|
||||
ENUM__SPEC_4(v1, v2, v3, v4), \
|
||||
ENUM__SPEC_4(v5, v6, v7, v8)
|
||||
#define ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16) \
|
||||
ENUM__SPEC_8(v01, v02, v03, v04, v05, v06, v07, v08), \
|
||||
ENUM__SPEC_8(v09, v10, v11, v12, v13, v14, v15, v16)
|
||||
|
||||
#define ENUM__SPECS_2(part1, part2) \
|
||||
{ part1, part2, { 0, "" } }
|
||||
#define ENUM__SPECS_3(part1, part2, part3) \
|
||||
{ part1, part2, part3, { 0, "" } }
|
||||
#define ENUM__SPECS_4(part1, part2, part3, part4) \
|
||||
{ part1, part2, part3, part4, { 0, "" } }
|
||||
#define ENUM__SPECS_5(part1, part2, part3, part4, part5) \
|
||||
{ part1, part2, part3, part4, part5, { 0, "" } }
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_ValueToString. */
|
||||
#define ENUM__VALUE_RTTI(typnam, specs) \
|
||||
static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_FlagsToString. */
|
||||
#define ENUM__FLAGS_RTTI(typnam, specs, joined) \
|
||||
static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs; \
|
||||
enum { typnam ## _ ## ToStringSize = sizeof joined }
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 3 flags. */
|
||||
#define ENUM_FLAGS_RTTI_3(typnam, v1, v2, v3) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_2(v1, v2), \
|
||||
ENUM__SPEC_1(v3)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_2(v1, v2), \
|
||||
ENUM__JOIN_STR_1(v3)))
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 8 flags. */
|
||||
#define ENUM_FLAGS_RTTI_8(typnam, v1, v2, v3, v4, v5, v6, v7, v8) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_4(v1, v2, v3, v4), \
|
||||
ENUM__SPEC_4(v5, v6, v7, v8)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_4(v1, v2, v3, v4), \
|
||||
ENUM__JOIN_STR_4(v5, v6, v7, v8)))
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_ValueToString
|
||||
* for an enum with 8 constants. */
|
||||
#define ENUM_VALUE_RTTI_8(typnam, v1, v2, v3, v4, v5, v6, v7, v8) \
|
||||
ENUM__VALUE_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_4(v1, v2, v3, v4), \
|
||||
ENUM__SPEC_4(v5, v6, v7, v8)))
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 10 flags. */
|
||||
#define ENUM_FLAGS_RTTI_10(typnam, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8), \
|
||||
ENUM__SPEC_2(v9, v10)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_8(v1, v2, v3, v4, v5, v6, v7, v8), \
|
||||
ENUM__JOIN_STR_2(v9, v10)))
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 31 flags. */
|
||||
#define ENUM_FLAGS_RTTI_31(typnam, \
|
||||
v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16, \
|
||||
v17, v18, v19, v20, v21, v22, v23, v24, \
|
||||
v25, v26, v27, v28, v29, v30, v31) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_5( \
|
||||
ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16), \
|
||||
ENUM__SPEC_8(v17, v18, v19, v20, v21, v22, v23, v24), \
|
||||
ENUM__SPEC_4(v25, v26, v27, v28), \
|
||||
ENUM__SPEC_2(v29, v30), \
|
||||
ENUM__SPEC_1(v31)), \
|
||||
ENUM__JOIN_5( \
|
||||
ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16), \
|
||||
ENUM__JOIN_STR_8(v17, v18, v19, v20, v21, v22, v23, v24), \
|
||||
ENUM__JOIN_STR_4(v25, v26, v27, v28), \
|
||||
ENUM__JOIN_STR_2(v29, v30), \
|
||||
ENUM__JOIN_STR_1(v31)))
|
||||
|
||||
/* Declare the necessary data structures for calling Enum_FlagsToString
|
||||
* for an enum with 32 flags. */
|
||||
#define ENUM_FLAGS_RTTI_32(typnam, \
|
||||
v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16, \
|
||||
v17, v18, v19, v20, v21, v22, v23, v24, \
|
||||
v25, v26, v27, v28, v29, v30, v31, v32) \
|
||||
ENUM__FLAGS_RTTI(typnam, \
|
||||
ENUM__SPECS_2( \
|
||||
ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16), \
|
||||
ENUM__SPEC_16(v17, v18, v19, v20, v21, v22, v23, v24, \
|
||||
v25, v26, v27, v28, v29, v30, v31, v32)), \
|
||||
ENUM__JOIN_2( \
|
||||
ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
|
||||
v09, v10, v11, v12, v13, v14, v15, v16), \
|
||||
ENUM__JOIN_STR_16(v17, v18, v19, v20, v21, v22, v23, v24, \
|
||||
v25, v26, v27, v28, v29, v30, v31, v32)))
|
||||
|
||||
#endif
|
157
for.c
157
for.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: for.c,v 1.54 2020/07/03 08:13:23 rillig Exp $ */
|
||||
/* $NetBSD: for.c,v 1.67 2020/08/30 19:56:02 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, The Regents of the University of California.
|
||||
@ -30,14 +30,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: for.c,v 1.54 2020/07/03 08:13:23 rillig Exp $";
|
||||
static char rcsid[] = "$NetBSD: for.c,v 1.67 2020/08/30 19:56:02 rillig 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.54 2020/07/03 08:13:23 rillig Exp $");
|
||||
__RCSID("$NetBSD: for.c,v 1.67 2020/08/30 19:56:02 rillig Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -52,13 +52,7 @@ __RCSID("$NetBSD: for.c,v 1.54 2020/07/03 08:13:23 rillig Exp $");
|
||||
*
|
||||
*/
|
||||
|
||||
#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
|
||||
@ -83,34 +77,22 @@ __RCSID("$NetBSD: for.c,v 1.54 2020/07/03 08:13:23 rillig Exp $");
|
||||
* For_Run.
|
||||
*/
|
||||
|
||||
static int forLevel = 0; /* Nesting level */
|
||||
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;
|
||||
typedef struct {
|
||||
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 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)
|
||||
@ -148,14 +130,13 @@ For_Eval(char *line)
|
||||
{
|
||||
For *new_for;
|
||||
char *ptr = line, *sub;
|
||||
int len;
|
||||
size_t len;
|
||||
int escapes;
|
||||
unsigned char ch;
|
||||
char **words, *word_buf;
|
||||
int n, nwords;
|
||||
Words words;
|
||||
|
||||
/* Skip the '.' and any following whitespace */
|
||||
for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
|
||||
for (ptr++; *ptr && isspace((unsigned char)*ptr); ptr++)
|
||||
continue;
|
||||
|
||||
/*
|
||||
@ -163,8 +144,8 @@ For_Eval(char *line)
|
||||
* 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) {
|
||||
!isspace((unsigned char)ptr[3])) {
|
||||
if (ptr[0] == 'e' && strncmp(ptr + 1, "ndfor", 5) == 0) {
|
||||
Parse_Error(PARSE_FATAL, "for-less endfor");
|
||||
return -1;
|
||||
}
|
||||
@ -181,7 +162,7 @@ For_Eval(char *line)
|
||||
|
||||
/* Grab the variables. Terminate on "in". */
|
||||
for (;; ptr += len) {
|
||||
while (*ptr && isspace((unsigned char) *ptr))
|
||||
while (*ptr && isspace((unsigned char)*ptr))
|
||||
ptr++;
|
||||
if (*ptr == '\0') {
|
||||
Parse_Error(PARSE_FATAL, "missing `in' in for");
|
||||
@ -196,7 +177,7 @@ For_Eval(char *line)
|
||||
}
|
||||
if (len == 1)
|
||||
new_for->short_var = 1;
|
||||
strlist_add_str(&new_for->vars, make_str(ptr, len), len);
|
||||
strlist_add_str(&new_for->vars, bmake_strldup(ptr, len), len);
|
||||
}
|
||||
|
||||
if (strlist_num(&new_for->vars) == 0) {
|
||||
@ -205,7 +186,7 @@ For_Eval(char *line)
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (*ptr && isspace((unsigned char) *ptr))
|
||||
while (*ptr && isspace((unsigned char)*ptr))
|
||||
ptr++;
|
||||
|
||||
/*
|
||||
@ -216,23 +197,25 @@ For_Eval(char *line)
|
||||
* 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, VARF_WANTRES);
|
||||
sub = Var_Subst(ptr, VAR_GLOBAL, VARE_WANTRES);
|
||||
|
||||
/*
|
||||
* Split into words allowing for quoted strings.
|
||||
*/
|
||||
words = brk_string(sub, &nwords, FALSE, &word_buf);
|
||||
words = Str_Words(sub, FALSE);
|
||||
|
||||
free(sub);
|
||||
|
||||
if (words != NULL) {
|
||||
for (n = 0; n < nwords; n++) {
|
||||
ptr = words[n];
|
||||
{
|
||||
size_t n;
|
||||
|
||||
for (n = 0; n < words.len; n++) {
|
||||
ptr = words.words[n];
|
||||
if (!*ptr)
|
||||
continue;
|
||||
escapes = 0;
|
||||
while ((ch = *ptr++)) {
|
||||
switch(ch) {
|
||||
switch (ch) {
|
||||
case ':':
|
||||
case '$':
|
||||
case '\\':
|
||||
@ -250,17 +233,17 @@ For_Eval(char *line)
|
||||
* We have to dup words[n] to maintain the semantics of
|
||||
* strlist.
|
||||
*/
|
||||
strlist_add_str(&new_for->items, bmake_strdup(words[n]), escapes);
|
||||
strlist_add_str(&new_for->items, bmake_strdup(words.words[n]),
|
||||
escapes);
|
||||
}
|
||||
|
||||
free(words);
|
||||
free(word_buf);
|
||||
Words_Free(words);
|
||||
|
||||
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);
|
||||
"Wrong number of words (%zu) in .for substitution list"
|
||||
" with %zu vars", len, n);
|
||||
/*
|
||||
* Return 'success' so that the body of the .for loop is
|
||||
* accumulated.
|
||||
@ -288,49 +271,35 @@ For_Accum(char *line)
|
||||
|
||||
if (*ptr == '.') {
|
||||
|
||||
for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
|
||||
for (ptr++; *ptr && isspace((unsigned char)*ptr); ptr++)
|
||||
continue;
|
||||
|
||||
if (strncmp(ptr, "endfor", 6) == 0 &&
|
||||
(isspace((unsigned char) ptr[6]) || !ptr[6])) {
|
||||
(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])) {
|
||||
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_AddStr(&accumFor->buf, 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
|
||||
static size_t
|
||||
for_var_len(const char *var)
|
||||
{
|
||||
char ch, var_start, var_end;
|
||||
int depth;
|
||||
int len;
|
||||
size_t len;
|
||||
|
||||
var_start = *var;
|
||||
if (var_start == 0)
|
||||
@ -360,24 +329,24 @@ for_var_len(const char *var)
|
||||
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;
|
||||
|
||||
const char *item = strlist_str(items, item_no);
|
||||
|
||||
/* 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);
|
||||
(ech == ')' ? ~FOR_SUB_ESCAPE_BRACE : ~FOR_SUB_ESCAPE_PAREN))) {
|
||||
Buf_AddStr(cmds, item);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Escape ':', '$', '\\' and 'ech' - removed by :U processing */
|
||||
while ((ch = *item++) != 0) {
|
||||
if (ch == '$') {
|
||||
len = for_var_len(item);
|
||||
size_t len = for_var_len(item);
|
||||
if (len != 0) {
|
||||
Buf_AddBytes(cmds, len + 1, item - 1);
|
||||
Buf_AddBytes(cmds, item - 1, len + 1);
|
||||
item += len;
|
||||
continue;
|
||||
}
|
||||
@ -392,13 +361,14 @@ static char *
|
||||
For_Iterate(void *v_arg, size_t *ret_len)
|
||||
{
|
||||
For *arg = v_arg;
|
||||
int i, len;
|
||||
int i;
|
||||
char *var;
|
||||
char *cp;
|
||||
char *cmd_cp;
|
||||
char *body_end;
|
||||
char ch;
|
||||
Buffer cmds;
|
||||
size_t cmd_len;
|
||||
|
||||
if (arg->sub_next + strlist_num(&arg->vars) > strlist_num(&arg->items)) {
|
||||
/* No more iterations */
|
||||
@ -421,9 +391,9 @@ For_Iterate(void *v_arg, size_t *ret_len)
|
||||
* 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);
|
||||
cmd_cp = Buf_GetAll(&arg->buf, &cmd_len);
|
||||
body_end = cmd_cp + cmd_len;
|
||||
Buf_Init(&cmds, cmd_len + 256);
|
||||
for (cp = cmd_cp; (cp = strchr(cp, '$')) != NULL;) {
|
||||
char ech;
|
||||
ch = *++cp;
|
||||
@ -431,15 +401,15 @@ For_Iterate(void *v_arg, size_t *ret_len)
|
||||
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)
|
||||
size_t vlen = strlist_info(&arg->vars, i);
|
||||
if (memcmp(cp, var, vlen) != 0)
|
||||
continue;
|
||||
if (cp[len] != ':' && cp[len] != ech && cp[len] != '\\')
|
||||
if (cp[vlen] != ':' && cp[vlen] != ech && cp[vlen] != '\\')
|
||||
continue;
|
||||
/* Found a variable match. Replace with :U<value> */
|
||||
Buf_AddBytes(&cmds, cp - cmd_cp, cmd_cp);
|
||||
Buf_AddBytes(&cmds, 2, ":U");
|
||||
cp += len;
|
||||
Buf_AddBytesBetween(&cmds, cmd_cp, cp);
|
||||
Buf_AddStr(&cmds, ":U");
|
||||
cp += vlen;
|
||||
cmd_cp = cp;
|
||||
for_substitute(&cmds, &arg->items, arg->sub_next + i, ech);
|
||||
break;
|
||||
@ -457,15 +427,15 @@ For_Iterate(void *v_arg, size_t *ret_len)
|
||||
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");
|
||||
Buf_AddBytesBetween(&cmds, cmd_cp, cp);
|
||||
Buf_AddStr(&cmds, "{:U");
|
||||
cmd_cp = ++cp;
|
||||
for_substitute(&cmds, &arg->items, arg->sub_next + i, /*{*/ '}');
|
||||
Buf_AddBytes(&cmds, 1, "}");
|
||||
Buf_AddByte(&cmds, '}');
|
||||
break;
|
||||
}
|
||||
}
|
||||
Buf_AddBytes(&cmds, body_end - cmd_cp, cmd_cp);
|
||||
Buf_AddBytesBetween(&cmds, cmd_cp, body_end);
|
||||
|
||||
cp = Buf_Destroy(&cmds, FALSE);
|
||||
if (DEBUG(FOR))
|
||||
@ -478,6 +448,7 @@ For_Iterate(void *v_arg, size_t *ret_len)
|
||||
return cp;
|
||||
}
|
||||
|
||||
/* Run the for loop, imitating the actions of an include file. */
|
||||
void
|
||||
For_Run(int lineno)
|
||||
{
|
||||
@ -487,9 +458,9 @@ For_Run(int lineno)
|
||||
accumFor = NULL;
|
||||
|
||||
if (strlist_num(&arg->items) == 0) {
|
||||
/* Nothing to expand - possibly due to an earlier syntax error. */
|
||||
For_Free(arg);
|
||||
return;
|
||||
/* Nothing to expand - possibly due to an earlier syntax error. */
|
||||
For_Free(arg);
|
||||
return;
|
||||
}
|
||||
|
||||
Parse_SetInput(NULL, lineno, -1, For_Iterate, arg);
|
||||
|
277
hash.c
277
hash.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hash.c,v 1.22 2020/07/03 17:03:09 rillig Exp $ */
|
||||
/* $NetBSD: hash.c,v 1.29 2020/09/01 21:11:31 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -70,14 +70,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: hash.c,v 1.22 2020/07/03 17:03:09 rillig Exp $";
|
||||
static char rcsid[] = "$NetBSD: hash.c,v 1.29 2020/09/01 21:11:31 rillig 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.22 2020/07/03 17:03:09 rillig Exp $");
|
||||
__RCSID("$NetBSD: hash.c,v 1.29 2020/09/01 21:11:31 rillig Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -89,9 +89,7 @@ __RCSID("$NetBSD: hash.c,v 1.22 2020/07/03 17:03:09 rillig Exp $");
|
||||
* 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
|
||||
@ -107,29 +105,26 @@ static void RebuildTable(Hash_Table *);
|
||||
|
||||
#define rebuildLimit 3
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------
|
||||
*
|
||||
* Hash_InitTable --
|
||||
*
|
||||
* This routine just sets up the hash table.
|
||||
/* The hash function(s) */
|
||||
|
||||
#ifndef HASH
|
||||
/* The default: this one matches Gosling's emacs */
|
||||
#define HASH(h, key, p) do { \
|
||||
for (h = 0, p = key; *p;) \
|
||||
h = (h << 5) - h + *p++; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
/* Sets up the hash table.
|
||||
*
|
||||
* Input:
|
||||
* t Structure to to hold table.
|
||||
* t Structure to to hold the 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)
|
||||
{
|
||||
@ -146,118 +141,85 @@ Hash_InitTable(Hash_Table *t, int numBuckets)
|
||||
continue;
|
||||
}
|
||||
t->numEntries = 0;
|
||||
t->size = i;
|
||||
t->mask = i - 1;
|
||||
t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i);
|
||||
t->maxchain = 0;
|
||||
t->bucketsSize = i;
|
||||
t->bucketsMask = i - 1;
|
||||
t->buckets = 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.
|
||||
*
|
||||
*---------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Removes everything from the hash table and frees up the memory space it
|
||||
* occupied (except for the space in the Hash_Table structure). */
|
||||
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 (hp = t->buckets, i = t->bucketsSize; --i >= 0;) {
|
||||
for (h = *hp++; h != NULL; h = nexth) {
|
||||
nexth = h->next;
|
||||
free(h);
|
||||
}
|
||||
}
|
||||
free(t->bucketPtr);
|
||||
free(t->buckets);
|
||||
|
||||
/*
|
||||
* Set up the hash table to cause memory faults on any future access
|
||||
* attempts until re-initialization.
|
||||
*/
|
||||
t->bucketPtr = NULL;
|
||||
t->buckets = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------
|
||||
*
|
||||
* Hash_FindEntry --
|
||||
*
|
||||
* Searches a hash table for an entry corresponding to key.
|
||||
/* Searches the hash table for an entry corresponding to the 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.
|
||||
*
|
||||
*---------------------------------------------------------
|
||||
* Returns a pointer to the entry for key, or NULL if the table contains
|
||||
* no entry for the key.
|
||||
*/
|
||||
|
||||
Hash_Entry *
|
||||
Hash_FindEntry(Hash_Table *t, const char *key)
|
||||
{
|
||||
Hash_Entry *e;
|
||||
unsigned h;
|
||||
const char *p;
|
||||
int chainlen;
|
||||
|
||||
if (t == NULL || t->bucketPtr == NULL) {
|
||||
if (t == NULL || t->buckets == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (h = 0, p = key; *p;)
|
||||
h = (h << 5) - h + *p++;
|
||||
HASH(h, key, p);
|
||||
p = key;
|
||||
for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next)
|
||||
chainlen = 0;
|
||||
#ifdef DEBUG_HASH_LOOKUP
|
||||
if (DEBUG(HASH))
|
||||
fprintf(debug_file, "%s: %p h=%x key=%s\n", __func__,
|
||||
t, h, key);
|
||||
#endif
|
||||
for (e = t->buckets[h & t->bucketsMask]; e != NULL; e = e->next) {
|
||||
chainlen++;
|
||||
if (e->namehash == h && strcmp(e->name, p) == 0)
|
||||
return e;
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
if (chainlen > t->maxchain)
|
||||
t->maxchain = chainlen;
|
||||
return e;
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------
|
||||
*
|
||||
* Hash_CreateEntry --
|
||||
*
|
||||
* Searches a hash table for an entry corresponding to
|
||||
* key. If no entry is found, then one is created.
|
||||
/* Searches the hash table for an entry corresponding to the 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,
|
||||
* newPtr Filled 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)
|
||||
{
|
||||
@ -265,33 +227,44 @@ Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr)
|
||||
unsigned h;
|
||||
const char *p;
|
||||
int keylen;
|
||||
int chainlen;
|
||||
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++;
|
||||
HASH(h, key, p);
|
||||
keylen = p - key;
|
||||
p = key;
|
||||
for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) {
|
||||
chainlen = 0;
|
||||
#ifdef DEBUG_HASH_LOOKUP
|
||||
if (DEBUG(HASH))
|
||||
fprintf(debug_file, "%s: %p h=%x key=%s\n", __func__,
|
||||
t, h, key);
|
||||
#endif
|
||||
for (e = t->buckets[h & t->bucketsMask]; e != NULL; e = e->next) {
|
||||
chainlen++;
|
||||
if (e->namehash == h && strcmp(e->name, p) == 0) {
|
||||
if (newPtr != NULL)
|
||||
*newPtr = FALSE;
|
||||
return e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (chainlen > t->maxchain)
|
||||
t->maxchain = chainlen;
|
||||
if (e)
|
||||
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)
|
||||
if (t->numEntries >= rebuildLimit * t->bucketsSize)
|
||||
RebuildTable(t);
|
||||
e = bmake_malloc(sizeof(*e) + keylen);
|
||||
hp = &t->bucketPtr[h & t->mask];
|
||||
hp = &t->buckets[h & t->bucketsMask];
|
||||
e->next = *hp;
|
||||
*hp = e;
|
||||
Hash_SetValue(e, NULL);
|
||||
@ -304,23 +277,7 @@ Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr)
|
||||
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.
|
||||
*
|
||||
*---------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Delete the given hash table entry and free memory associated with it. */
|
||||
void
|
||||
Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e)
|
||||
{
|
||||
@ -328,7 +285,7 @@ Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e)
|
||||
|
||||
if (e == NULL)
|
||||
return;
|
||||
for (hp = &t->bucketPtr[e->namehash & t->mask];
|
||||
for (hp = &t->buckets[e->namehash & t->bucketsMask];
|
||||
(p = *hp) != NULL; hp = &p->next) {
|
||||
if (p == e) {
|
||||
*hp = p->next;
|
||||
@ -341,12 +298,7 @@ Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e)
|
||||
abort();
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------
|
||||
*
|
||||
* Hash_EnumFirst --
|
||||
* This procedure sets things up for a complete search
|
||||
* of all entries recorded in the hash table.
|
||||
/* Sets things up for enumerating all entries in the hash table.
|
||||
*
|
||||
* Input:
|
||||
* t Table to be searched.
|
||||
@ -355,57 +307,34 @@ Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e)
|
||||
* 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;
|
||||
searchPtr->table = t;
|
||||
searchPtr->nextBucket = 0;
|
||||
searchPtr->entry = NULL;
|
||||
return Hash_EnumNext(searchPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------
|
||||
*
|
||||
* Hash_EnumNext --
|
||||
* This procedure returns successive entries in the hash table.
|
||||
/* Returns the next entry in the hash table, or NULL if the end of the table
|
||||
* is reached.
|
||||
*
|
||||
* 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;
|
||||
Hash_Table *t = searchPtr->table;
|
||||
|
||||
/*
|
||||
* The hashEntryPtr field points to the most recently returned
|
||||
* entry, or is nil if we are starting up. If not nil, we have
|
||||
* The entry field points to the most recently returned
|
||||
* entry, or is NULL if we are starting up. If not NULL, we have
|
||||
* to start at the next one in the chain.
|
||||
*/
|
||||
e = searchPtr->hashEntryPtr;
|
||||
e = searchPtr->entry;
|
||||
if (e != NULL)
|
||||
e = e->next;
|
||||
/*
|
||||
@ -413,59 +342,49 @@ Hash_EnumNext(Hash_Search *searchPtr)
|
||||
* find the next nonempty chain.
|
||||
*/
|
||||
while (e == NULL) {
|
||||
if (searchPtr->nextIndex >= t->size)
|
||||
if (searchPtr->nextBucket >= t->bucketsSize)
|
||||
return NULL;
|
||||
e = t->bucketPtr[searchPtr->nextIndex++];
|
||||
e = t->buckets[searchPtr->nextBucket++];
|
||||
}
|
||||
searchPtr->hashEntryPtr = e;
|
||||
searchPtr->entry = 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.
|
||||
*
|
||||
*---------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Makes a new hash table that is larger than the old one. The entire hash
|
||||
* table is moved, so any bucket numbers from the old table become invalid. */
|
||||
static void
|
||||
RebuildTable(Hash_Table *t)
|
||||
{
|
||||
Hash_Entry *e, *next = NULL, **hp, **xp;
|
||||
int i, mask;
|
||||
Hash_Entry **oldhp;
|
||||
Hash_Entry **oldhp;
|
||||
int oldsize;
|
||||
|
||||
oldhp = t->bucketPtr;
|
||||
oldsize = i = t->size;
|
||||
oldhp = t->buckets;
|
||||
oldsize = i = t->bucketsSize;
|
||||
i <<= 1;
|
||||
t->size = i;
|
||||
t->mask = mask = i - 1;
|
||||
t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i);
|
||||
t->bucketsSize = i;
|
||||
t->bucketsMask = mask = i - 1;
|
||||
t->buckets = 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];
|
||||
xp = &t->buckets[e->namehash & mask];
|
||||
e->next = *xp;
|
||||
*xp = e;
|
||||
}
|
||||
}
|
||||
free(oldhp);
|
||||
if (DEBUG(HASH))
|
||||
fprintf(debug_file, "%s: %p size=%d entries=%d maxchain=%d\n",
|
||||
__func__, t, t->bucketsSize, t->numEntries, t->maxchain);
|
||||
t->maxchain = 0;
|
||||
}
|
||||
|
||||
void Hash_ForEach(Hash_Table *t, void (*action)(void *, void *), void *data)
|
||||
void
|
||||
Hash_ForEach(Hash_Table *t, void (*action)(void *, void *), void *data)
|
||||
{
|
||||
Hash_Search search;
|
||||
Hash_Entry *e;
|
||||
@ -475,3 +394,11 @@ void Hash_ForEach(Hash_Table *t, void (*action)(void *, void *), void *data)
|
||||
e = Hash_EnumNext(&search))
|
||||
action(Hash_GetValue(e), data);
|
||||
}
|
||||
|
||||
void
|
||||
Hash_DebugStats(Hash_Table *t, const char *name)
|
||||
{
|
||||
if (DEBUG(HASH))
|
||||
fprintf(debug_file, "Hash_Table %s: size=%d numEntries=%d maxchain=%d\n",
|
||||
name, t->bucketsSize, t->numEntries, t->maxchain);
|
||||
}
|
||||
|
81
hash.h
81
hash.h
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hash.h,v 1.13 2020/07/03 17:03:09 rillig Exp $ */
|
||||
/* $NetBSD: hash.h,v 1.21 2020/09/01 21:11:31 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -72,71 +72,51 @@
|
||||
* from: @(#)hash.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/* hash.h --
|
||||
*
|
||||
* This file contains definitions used by the hash module,
|
||||
* which maintains hash tables.
|
||||
*/
|
||||
/* Hash tables with strings as keys and arbitrary pointers as values. */
|
||||
|
||||
#ifndef _HASH_H
|
||||
#define _HASH_H
|
||||
|
||||
/*
|
||||
* The following defines one entry in the hash table.
|
||||
*/
|
||||
#ifndef MAKE_HASH_H
|
||||
#define MAKE_HASH_H
|
||||
|
||||
/* A single key-value 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. */
|
||||
void *clientPtr; /* Arbitrary pointer */
|
||||
unsigned namehash; /* hash value of key */
|
||||
char name[1]; /* key string */
|
||||
struct Hash_Entry *next; /* Used to link together all the entries
|
||||
* associated with the same bucket. */
|
||||
void *value;
|
||||
unsigned namehash; /* hash value of key */
|
||||
char name[1]; /* key string, variable length */
|
||||
} Hash_Entry;
|
||||
|
||||
/* The hash table containing the entries. */
|
||||
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. */
|
||||
Hash_Entry **buckets; /* Pointers to Hash_Entry, one
|
||||
* for each bucket in the table. */
|
||||
int bucketsSize;
|
||||
int numEntries; /* Number of entries in the table. */
|
||||
int mask; /* Used to select bits for hashing. */
|
||||
int bucketsMask; /* Used to select the bucket for a hash. */
|
||||
int maxchain; /* max length of chain detected */
|
||||
} 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_Table *table; /* Table being searched. */
|
||||
int nextBucket; /* Next bucket to check (after current). */
|
||||
Hash_Entry *entry; /* Next entry to check in current bucket. */
|
||||
} Hash_Search;
|
||||
|
||||
/*
|
||||
* Macros.
|
||||
*/
|
||||
static inline void * MAKE_ATTR_UNUSED
|
||||
Hash_GetValue(Hash_Entry *h)
|
||||
{
|
||||
return h->value;
|
||||
}
|
||||
|
||||
/*
|
||||
* void * Hash_GetValue(h)
|
||||
* Hash_Entry *h;
|
||||
*/
|
||||
|
||||
#define Hash_GetValue(h) ((h)->clientPtr)
|
||||
|
||||
/*
|
||||
* Hash_SetValue(h, val);
|
||||
* Hash_Entry *h;
|
||||
* char *val;
|
||||
*/
|
||||
|
||||
#define Hash_SetValue(h, val) ((h)->clientPtr = (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))
|
||||
static inline void MAKE_ATTR_UNUSED
|
||||
Hash_SetValue(Hash_Entry *h, void *datum)
|
||||
{
|
||||
h->value = datum;
|
||||
}
|
||||
|
||||
void Hash_InitTable(Hash_Table *, int);
|
||||
void Hash_DeleteTable(Hash_Table *);
|
||||
@ -146,5 +126,6 @@ void Hash_DeleteEntry(Hash_Table *, Hash_Entry *);
|
||||
Hash_Entry *Hash_EnumFirst(Hash_Table *, Hash_Search *);
|
||||
Hash_Entry *Hash_EnumNext(Hash_Search *);
|
||||
void Hash_ForEach(Hash_Table *, void (*)(void *, void *), void *);
|
||||
void Hash_DebugStats(Hash_Table *, const char *);
|
||||
|
||||
#endif /* _HASH_H */
|
||||
#endif /* MAKE_HASH_H */
|
||||
|
134
job.c
134
job.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: job.c,v 1.201 2020/07/03 08:13:23 rillig Exp $ */
|
||||
/* $NetBSD: job.c,v 1.227 2020/08/30 19:56:02 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -70,14 +70,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: job.c,v 1.201 2020/07/03 08:13:23 rillig Exp $";
|
||||
static char rcsid[] = "$NetBSD: job.c,v 1.227 2020/08/30 19:56:02 rillig 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.201 2020/07/03 08:13:23 rillig Exp $");
|
||||
__RCSID("$NetBSD: job.c,v 1.227 2020/08/30 19:56:02 rillig Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -112,7 +112,7 @@ __RCSID("$NetBSD: job.c,v 1.201 2020/07/03 08:13:23 rillig Exp $");
|
||||
*
|
||||
* Job_ParseShell Given the line following a .SHELL target, parse
|
||||
* the line as a shell specification. Returns
|
||||
* FAILURE if the spec was incorrect.
|
||||
* FALSE if the spec was incorrect.
|
||||
*
|
||||
* Job_Finish Perform any final processing which needs doing.
|
||||
* This includes the execution of any commands
|
||||
@ -142,7 +142,6 @@ __RCSID("$NetBSD: job.c,v 1.201 2020/07/03 08:13:23 rillig Exp $");
|
||||
#include <sys/time.h>
|
||||
#include "wait.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#if !defined(USE_SELECT) && defined(HAVE_POLL_H)
|
||||
#include <poll.h>
|
||||
@ -155,15 +154,12 @@ __RCSID("$NetBSD: job.c,v 1.201 2020/07/03 08:13:23 rillig Exp $");
|
||||
#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"
|
||||
@ -184,7 +180,6 @@ static int aborting = 0; /* why is the make aborting? */
|
||||
* 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
|
||||
@ -311,9 +306,9 @@ static Shell *commandShell = &shells[DEFSHELL_INDEX]; /* this is the shell to
|
||||
* Job_ParseShell function */
|
||||
const char *shellPath = NULL, /* full pathname of
|
||||
* executable image */
|
||||
*shellName = NULL; /* last component of shell */
|
||||
*shellName = NULL; /* last component of shell */
|
||||
char *shellErrFlag = NULL;
|
||||
static const char *shellArgv = NULL; /* Custom shell args */
|
||||
static char *shellArgv = NULL; /* Custom shell args */
|
||||
|
||||
|
||||
STATIC Job *job_table; /* The structures that describe them */
|
||||
@ -370,11 +365,6 @@ static void JobSigLock(sigset_t *);
|
||||
static void JobSigUnlock(sigset_t *);
|
||||
static void JobSigReset(void);
|
||||
|
||||
#if !defined(MALLOC_OPTIONS)
|
||||
# define MALLOC_OPTIONS "A"
|
||||
#endif
|
||||
const char *malloc_options= MALLOC_OPTIONS;
|
||||
|
||||
static unsigned
|
||||
nfds_per_job(void)
|
||||
{
|
||||
@ -723,15 +713,14 @@ JobPrintCommand(void *cmdp, void *jobp)
|
||||
char *escCmd = NULL; /* Command with quotes/backticks escaped */
|
||||
char *cmd = (char *)cmdp;
|
||||
Job *job = (Job *)jobp;
|
||||
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));
|
||||
LstNode dotsNode = Lst_FindDatum(job->node->commands, cmd);
|
||||
job->tailCmds = dotsNode != NULL ? LstNode_Next(dotsNode) : NULL;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -745,7 +734,7 @@ JobPrintCommand(void *cmdp, void *jobp)
|
||||
|
||||
numCommands += 1;
|
||||
|
||||
cmdStart = cmd = Var_Subst(NULL, cmd, job->node, VARF_WANTRES);
|
||||
cmdStart = cmd = Var_Subst(cmd, job->node, VARE_WANTRES);
|
||||
|
||||
cmdTemplate = "%s\n";
|
||||
|
||||
@ -785,15 +774,17 @@ JobPrintCommand(void *cmdp, void *jobp)
|
||||
*/
|
||||
|
||||
if (!commandShell->hasErrCtl) {
|
||||
int i, j;
|
||||
|
||||
/* 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];
|
||||
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;
|
||||
escCmd[j] = '\0';
|
||||
}
|
||||
|
||||
if (shutUp) {
|
||||
@ -926,15 +917,15 @@ JobPrintCommand(void *cmdp, void *jobp)
|
||||
* Always returns 0
|
||||
*
|
||||
* Side Effects:
|
||||
* The command is tacked onto the end of postCommands's commands list.
|
||||
* The command is tacked onto the end of postCommands' commands list.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
JobSaveCommand(void *cmd, void *gn)
|
||||
{
|
||||
cmd = Var_Subst(NULL, (char *)cmd, (GNode *)gn, VARF_WANTRES);
|
||||
(void)Lst_AtEnd(postCommands->commands, cmd);
|
||||
cmd = Var_Subst((char *)cmd, (GNode *)gn, VARE_WANTRES);
|
||||
Lst_Append(postCommands->commands, cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1124,7 +1115,7 @@ JobFinish (Job *job, WAIT_T status)
|
||||
if (job->tailCmds != NULL) {
|
||||
Lst_ForEachFrom(job->node->commands, job->tailCmds,
|
||||
JobSaveCommand,
|
||||
job->node);
|
||||
job->node);
|
||||
}
|
||||
job->node->made = MADE;
|
||||
if (!(job->flags & JOB_SPECIAL))
|
||||
@ -1275,7 +1266,7 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
|
||||
*/
|
||||
Make_HandleUse(DEFAULT, gn);
|
||||
Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn);
|
||||
free(p1);
|
||||
bmake_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
|
||||
@ -1302,7 +1293,7 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
|
||||
(void)fprintf(stdout, "%s%s %s (continuing)\n", progname,
|
||||
msg, gn->name);
|
||||
(void)fflush(stdout);
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
} else {
|
||||
(*abortProc)("%s%s %s. Stop", progname, msg, gn->name);
|
||||
return FALSE;
|
||||
@ -1345,7 +1336,7 @@ JobExec(Job *job, char **argv)
|
||||
for (i = 0; argv[i] != NULL; i++) {
|
||||
(void)fprintf(debug_file, "%s ", argv[i]);
|
||||
}
|
||||
(void)fprintf(debug_file, "\n");
|
||||
(void)fprintf(debug_file, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1719,7 +1710,7 @@ JobStart(GNode *gn, int flags)
|
||||
* up the graph.
|
||||
*/
|
||||
job->cmdFILE = stdout;
|
||||
Job_Touch(gn, job->flags&JOB_SILENT);
|
||||
Job_Touch(gn, job->flags&JOB_SILENT);
|
||||
noExec = TRUE;
|
||||
}
|
||||
/* Just in case it isn't already... */
|
||||
@ -1748,8 +1739,8 @@ JobStart(GNode *gn, int flags)
|
||||
if (cmdsOK && aborting == 0) {
|
||||
if (job->tailCmds != NULL) {
|
||||
Lst_ForEachFrom(job->node->commands, job->tailCmds,
|
||||
JobSaveCommand,
|
||||
job->node);
|
||||
JobSaveCommand,
|
||||
job->node);
|
||||
}
|
||||
job->node->made = MADE;
|
||||
Make_Update(job->node);
|
||||
@ -1990,8 +1981,8 @@ JobRun(GNode *targ)
|
||||
* 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);
|
||||
Lst lst = Lst_Init();
|
||||
Lst_Append(lst, targ);
|
||||
(void)Make_Run(lst);
|
||||
Lst_Destroy(lst, NULL);
|
||||
JobStart(targ, JOB_SPECIAL);
|
||||
@ -2218,8 +2209,9 @@ Shell_Init(void)
|
||||
shellName++;
|
||||
} else
|
||||
#endif
|
||||
shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
|
||||
shellPath = str_concat3(_PATH_DEFSHELLDIR, "/", shellName);
|
||||
}
|
||||
Var_Set_with_flags(".SHELL", shellPath, VAR_CMD, VAR_SET_READONLY);
|
||||
if (commandShell->exit == NULL) {
|
||||
commandShell->exit = "";
|
||||
}
|
||||
@ -2253,38 +2245,23 @@ Shell_Init(void)
|
||||
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);
|
||||
}
|
||||
|
||||
targPrefix = Var_Subst(NULL, "${" MAKE_JOB_PREFIX "}",
|
||||
VAR_GLOBAL, VARF_WANTRES);
|
||||
targPrefix = Var_Subst("${" MAKE_JOB_PREFIX "}",
|
||||
VAR_GLOBAL, VARE_WANTRES);
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Job_Init --
|
||||
* Initialize the process module
|
||||
*
|
||||
* Input:
|
||||
*
|
||||
* Results:
|
||||
* none
|
||||
*
|
||||
* Side Effects:
|
||||
* lists and counters are initialized
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
/* Initialize the process module. */
|
||||
void
|
||||
Job_Init(void)
|
||||
{
|
||||
@ -2390,19 +2367,7 @@ static void JobSigReset(void)
|
||||
(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.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
/* Find a shell in 'shells' given its name, or return NULL. */
|
||||
static Shell *
|
||||
JobMatchShell(const char *name)
|
||||
{
|
||||
@ -2425,7 +2390,7 @@ JobMatchShell(const char *name)
|
||||
* line The shell spec
|
||||
*
|
||||
* Results:
|
||||
* FAILURE if the specification was incorrect.
|
||||
* FALSE if the specification was incorrect.
|
||||
*
|
||||
* Side Effects:
|
||||
* commandShell points to a Shell structure (either predefined or
|
||||
@ -2462,12 +2427,13 @@ JobMatchShell(const char *name)
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
ReturnStatus
|
||||
Boolean
|
||||
Job_ParseShell(char *line)
|
||||
{
|
||||
Words wordsList;
|
||||
char **words;
|
||||
char **argv;
|
||||
int argc;
|
||||
size_t argc;
|
||||
char *path;
|
||||
Shell newShell;
|
||||
Boolean fullSpec = FALSE;
|
||||
@ -2477,17 +2443,20 @@ Job_ParseShell(char *line)
|
||||
line++;
|
||||
}
|
||||
|
||||
free(UNCONST(shellArgv));
|
||||
free(shellArgv);
|
||||
|
||||
memset(&newShell, 0, sizeof(newShell));
|
||||
|
||||
/*
|
||||
* Parse the specification by keyword
|
||||
*/
|
||||
words = brk_string(line, &argc, TRUE, &path);
|
||||
wordsList = Str_Words(line, TRUE);
|
||||
words = wordsList.words;
|
||||
argc = wordsList.len;
|
||||
path = wordsList.freeIt;
|
||||
if (words == NULL) {
|
||||
Error("Unterminated quoted string [%s]", line);
|
||||
return FAILURE;
|
||||
return FALSE;
|
||||
}
|
||||
shellArgv = path;
|
||||
|
||||
@ -2526,7 +2495,7 @@ Job_ParseShell(char *line)
|
||||
Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"",
|
||||
*argv);
|
||||
free(words);
|
||||
return FAILURE;
|
||||
return FALSE;
|
||||
}
|
||||
fullSpec = TRUE;
|
||||
}
|
||||
@ -2542,13 +2511,13 @@ Job_ParseShell(char *line)
|
||||
if (newShell.name == NULL) {
|
||||
Parse_Error(PARSE_FATAL, "Neither path nor name specified");
|
||||
free(words);
|
||||
return FAILURE;
|
||||
return FALSE;
|
||||
} else {
|
||||
if ((sh = JobMatchShell(newShell.name)) == NULL) {
|
||||
Parse_Error(PARSE_WARNING, "%s: No matching shell",
|
||||
newShell.name);
|
||||
free(words);
|
||||
return FAILURE;
|
||||
return FALSE;
|
||||
}
|
||||
commandShell = sh;
|
||||
shellName = newShell.name;
|
||||
@ -2584,7 +2553,7 @@ Job_ParseShell(char *line)
|
||||
Parse_Error(PARSE_WARNING, "%s: No matching shell",
|
||||
shellName);
|
||||
free(words);
|
||||
return FAILURE;
|
||||
return FALSE;
|
||||
}
|
||||
commandShell = sh;
|
||||
} else {
|
||||
@ -2613,7 +2582,7 @@ Job_ParseShell(char *line)
|
||||
* shell specification.
|
||||
*/
|
||||
free(words);
|
||||
return SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*-
|
||||
@ -2790,7 +2759,6 @@ Job_AbortAll(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* JobRestartJobs --
|
||||
@ -3125,7 +3093,7 @@ emul_poll(struct pollfd *fd, int nfd, int timeout)
|
||||
usecs = timeout * 1000;
|
||||
tv.tv_sec = usecs / 1000000;
|
||||
tv.tv_usec = usecs % 1000000;
|
||||
tvp = &tv;
|
||||
tvp = &tv;
|
||||
}
|
||||
|
||||
nselect = select(maxfd + 1, &rfds, &wfds, 0, tvp);
|
||||
|
17
job.h
17
job.h
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: job.h,v 1.43 2020/07/03 08:13:23 rillig Exp $ */
|
||||
/* $NetBSD: job.h,v 1.47 2020/08/29 12:20:17 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -77,8 +77,8 @@
|
||||
* job.h --
|
||||
* Definitions pertaining to the running of jobs in parallel mode.
|
||||
*/
|
||||
#ifndef _JOB_H_
|
||||
#define _JOB_H_
|
||||
#ifndef MAKE_JOB_H
|
||||
#define MAKE_JOB_H
|
||||
|
||||
#define TMPPAT "makeXXXXXX" /* relative to tmpdir */
|
||||
|
||||
@ -110,7 +110,6 @@ emul_poll(struct pollfd *fd, int nfd, int timeout);
|
||||
*/
|
||||
#define POLL_MSEC 5000
|
||||
|
||||
|
||||
/*-
|
||||
* Job Table definitions.
|
||||
*
|
||||
@ -164,7 +163,7 @@ typedef struct Job {
|
||||
* commands */
|
||||
#define JOB_TRACED 0x400 /* we've sent 'set -x' */
|
||||
|
||||
int jobPipe[2]; /* Pipe for readind output from job */
|
||||
int jobPipe[2]; /* Pipe for reading output from job */
|
||||
struct pollfd *inPollfd; /* pollfd associated with inPipe */
|
||||
char outBuf[JOB_BUFSIZE + 1];
|
||||
/* Buffer for storing the output of the
|
||||
@ -179,7 +178,6 @@ typedef struct Job {
|
||||
#define inPipe jobPipe[0]
|
||||
#define outPipe jobPipe[1]
|
||||
|
||||
|
||||
/*-
|
||||
* Shell Specifications:
|
||||
* Each shell type has associated with it the following information:
|
||||
@ -252,23 +250,20 @@ 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 *);
|
||||
Boolean 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);
|
||||
Boolean Job_RunTarget(const char *, const char *);
|
||||
|
||||
#endif /* _JOB_H_ */
|
||||
#endif /* MAKE_JOB_H */
|
||||
|
641
lst.c
Normal file
641
lst.c
Normal file
@ -0,0 +1,641 @@
|
||||
/* $NetBSD: lst.c,v 1.60 2020/08/31 05:56:02 rillig 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#elif defined(HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "make.h"
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: lst.c,v 1.60 2020/08/31 05:56:02 rillig Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: lst.c,v 1.60 2020/08/31 05:56:02 rillig Exp $");
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
|
||||
struct ListNode {
|
||||
struct ListNode *prev; /* previous element in list */
|
||||
struct ListNode *next; /* next in list */
|
||||
uint8_t useCount; /* Count of functions using the node.
|
||||
* node may not be deleted until count
|
||||
* goes to 0 */
|
||||
Boolean deleted; /* List node should be removed when done */
|
||||
union {
|
||||
void *datum; /* datum associated with this element */
|
||||
const GNode *gnode; /* alias, just for debugging */
|
||||
const char *str; /* alias, just for debugging */
|
||||
};
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
Head, Middle, Tail, Unknown
|
||||
} Where;
|
||||
|
||||
struct List {
|
||||
LstNode first; /* first node in list */
|
||||
LstNode last; /* last node in list */
|
||||
|
||||
/* fields for sequential access */
|
||||
Boolean isOpen; /* true if list has been Lst_Open'ed */
|
||||
Where lastAccess; /* Where in the list the last access was */
|
||||
LstNode curr; /* current node, if open. NULL if
|
||||
* *just* opened */
|
||||
LstNode prev; /* Previous node, if open. Used by Lst_Remove */
|
||||
};
|
||||
|
||||
/* Allocate and initialize a list node.
|
||||
*
|
||||
* The fields 'prev' and 'next' must be initialized by the caller.
|
||||
*/
|
||||
static LstNode
|
||||
LstNodeNew(void *datum)
|
||||
{
|
||||
LstNode node = bmake_malloc(sizeof *node);
|
||||
node->useCount = 0;
|
||||
node->deleted = FALSE;
|
||||
node->datum = datum;
|
||||
return node;
|
||||
}
|
||||
|
||||
static Boolean
|
||||
LstIsEmpty(Lst list)
|
||||
{
|
||||
return list->first == NULL;
|
||||
}
|
||||
|
||||
/* Create and initialize a new, empty list. */
|
||||
Lst
|
||||
Lst_Init(void)
|
||||
{
|
||||
Lst list = bmake_malloc(sizeof *list);
|
||||
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
list->isOpen = FALSE;
|
||||
list->lastAccess = Unknown;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/* Duplicate an entire list, usually by copying the datum pointers.
|
||||
* If copyProc is given, that function is used to create the new datum from the
|
||||
* old datum, usually by creating a copy of it. */
|
||||
Lst
|
||||
Lst_Copy(Lst list, LstCopyProc copyProc)
|
||||
{
|
||||
Lst newList;
|
||||
LstNode node;
|
||||
|
||||
assert(list != NULL);
|
||||
|
||||
newList = Lst_Init();
|
||||
|
||||
for (node = list->first; node != NULL; node = node->next) {
|
||||
void *datum = copyProc != NULL ? copyProc(node->datum) : node->datum;
|
||||
Lst_Append(newList, datum);
|
||||
}
|
||||
|
||||
return newList;
|
||||
}
|
||||
|
||||
/* Free a list and all its nodes. The list data itself are not freed though. */
|
||||
void
|
||||
Lst_Free(Lst list)
|
||||
{
|
||||
LstNode node;
|
||||
LstNode next;
|
||||
|
||||
assert(list != NULL);
|
||||
|
||||
for (node = list->first; node != NULL; node = next) {
|
||||
next = node->next;
|
||||
free(node);
|
||||
}
|
||||
|
||||
free(list);
|
||||
}
|
||||
|
||||
/* Destroy a list and free all its resources. The freeProc is called with the
|
||||
* datum from each node in turn before the node is freed. */
|
||||
void
|
||||
Lst_Destroy(Lst list, LstFreeProc freeProc)
|
||||
{
|
||||
LstNode node;
|
||||
LstNode next;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(freeProc != NULL);
|
||||
|
||||
for (node = list->first; node != NULL; node = next) {
|
||||
next = node->next;
|
||||
freeProc(node->datum);
|
||||
free(node);
|
||||
}
|
||||
|
||||
free(list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions to modify a list
|
||||
*/
|
||||
|
||||
/* Insert a new node with the given piece of data before the given node in the
|
||||
* given list. */
|
||||
void
|
||||
Lst_InsertBefore(Lst list, LstNode node, void *datum)
|
||||
{
|
||||
LstNode newNode;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(!LstIsEmpty(list));
|
||||
assert(node != NULL);
|
||||
assert(datum != NULL);
|
||||
|
||||
newNode = LstNodeNew(datum);
|
||||
newNode->prev = node->prev;
|
||||
newNode->next = node;
|
||||
|
||||
if (node->prev != NULL) {
|
||||
node->prev->next = newNode;
|
||||
}
|
||||
node->prev = newNode;
|
||||
|
||||
if (node == list->first) {
|
||||
list->first = newNode;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a piece of data at the start of the given list. */
|
||||
void
|
||||
Lst_Prepend(Lst list, void *datum)
|
||||
{
|
||||
LstNode node;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(datum != NULL);
|
||||
|
||||
node = LstNodeNew(datum);
|
||||
node->prev = NULL;
|
||||
node->next = list->first;
|
||||
|
||||
if (list->first == NULL) {
|
||||
list->first = node;
|
||||
list->last = node;
|
||||
} else {
|
||||
list->first->prev = node;
|
||||
list->first = node;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a piece of data at the end of the given list. */
|
||||
void
|
||||
Lst_Append(Lst list, void *datum)
|
||||
{
|
||||
LstNode node;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(datum != NULL);
|
||||
|
||||
node = LstNodeNew(datum);
|
||||
node->prev = list->last;
|
||||
node->next = NULL;
|
||||
|
||||
if (list->last == NULL) {
|
||||
list->first = node;
|
||||
list->last = node;
|
||||
} else {
|
||||
list->last->next = node;
|
||||
list->last = node;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove the given node from the given list.
|
||||
* The datum stored in the node must be freed by the caller, if necessary. */
|
||||
void
|
||||
Lst_Remove(Lst list, LstNode node)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(node != NULL);
|
||||
|
||||
/*
|
||||
* unlink it from the list
|
||||
*/
|
||||
if (node->next != NULL) {
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
if (node->prev != NULL) {
|
||||
node->prev->next = node->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* if either the first or last of the list point to this node,
|
||||
* adjust them accordingly
|
||||
*/
|
||||
if (list->first == node) {
|
||||
list->first = node->next;
|
||||
}
|
||||
if (list->last == node) {
|
||||
list->last = node->prev;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 (prev == NULL), we set the
|
||||
* end to be Unknown, since it is.
|
||||
*/
|
||||
if (list->isOpen && list->curr == node) {
|
||||
list->curr = list->prev;
|
||||
if (list->curr == NULL) {
|
||||
list->lastAccess = Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* note that the datum is unmolested. The caller must free it as
|
||||
* necessary and as expected.
|
||||
*/
|
||||
if (node->useCount == 0) {
|
||||
free(node);
|
||||
} else {
|
||||
node->deleted = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Replace the datum in the given node with the new datum. */
|
||||
void
|
||||
LstNode_Set(LstNode node, void *datum)
|
||||
{
|
||||
assert(node != NULL);
|
||||
assert(datum != NULL);
|
||||
|
||||
node->datum = datum;
|
||||
}
|
||||
|
||||
/* Replace the datum in the given node to NULL. */
|
||||
void
|
||||
LstNode_SetNull(LstNode node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
|
||||
node->datum = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Node-specific functions
|
||||
*/
|
||||
|
||||
/* Return the first node from the given list, or NULL if the list is empty. */
|
||||
LstNode
|
||||
Lst_First(Lst list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
|
||||
return list->first;
|
||||
}
|
||||
|
||||
/* Return the last node from the given list, or NULL if the list is empty. */
|
||||
LstNode
|
||||
Lst_Last(Lst list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
|
||||
return list->last;
|
||||
}
|
||||
|
||||
/* Return the successor to the given node on its list, or NULL. */
|
||||
LstNode
|
||||
LstNode_Next(LstNode node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
|
||||
return node->next;
|
||||
}
|
||||
|
||||
/* Return the predecessor to the given node on its list, or NULL. */
|
||||
LstNode
|
||||
LstNode_Prev(LstNode node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
return node->prev;
|
||||
}
|
||||
|
||||
/* Return the datum stored in the given node. */
|
||||
void *
|
||||
LstNode_Datum(LstNode node)
|
||||
{
|
||||
assert(node != NULL);
|
||||
return node->datum;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Functions for entire lists
|
||||
*/
|
||||
|
||||
/* Return TRUE if the given list is empty. */
|
||||
Boolean
|
||||
Lst_IsEmpty(Lst list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
|
||||
return LstIsEmpty(list);
|
||||
}
|
||||
|
||||
/* Return the first node from the list for which the match function returns
|
||||
* TRUE, or NULL if none of the nodes matched. */
|
||||
LstNode
|
||||
Lst_Find(Lst list, LstFindProc match, const void *matchArgs)
|
||||
{
|
||||
return Lst_FindFrom(list, Lst_First(list), match, matchArgs);
|
||||
}
|
||||
|
||||
/* Return the first node from the list, starting at the given node, for which
|
||||
* the match function returns TRUE, or NULL if none of the nodes matches.
|
||||
*
|
||||
* The start node may be NULL, in which case nothing is found. This allows
|
||||
* for passing Lst_First or LstNode_Next as the start node. */
|
||||
LstNode
|
||||
Lst_FindFrom(Lst list, LstNode node, LstFindProc match, const void *matchArgs)
|
||||
{
|
||||
LstNode tln;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(match != NULL);
|
||||
|
||||
for (tln = node; tln != NULL; tln = tln->next) {
|
||||
if (match(tln->datum, matchArgs))
|
||||
return tln;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the first node that contains the given datum, or NULL. */
|
||||
LstNode
|
||||
Lst_FindDatum(Lst list, const void *datum)
|
||||
{
|
||||
LstNode node;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(datum != NULL);
|
||||
|
||||
for (node = list->first; node != NULL; node = node->next) {
|
||||
if (node->datum == datum) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
int
|
||||
Lst_ForEach(Lst list, LstActionProc proc, void *procData)
|
||||
{
|
||||
if (LstIsEmpty(list))
|
||||
return 0; /* XXX: Document what this value means. */
|
||||
return Lst_ForEachFrom(list, Lst_First(list), proc, procData);
|
||||
}
|
||||
|
||||
/* Apply the given function to each element of the given list, starting from
|
||||
* the given node. The function should return 0 if traversal should continue,
|
||||
* and non-zero if it should abort. */
|
||||
int
|
||||
Lst_ForEachFrom(Lst list, LstNode node,
|
||||
LstActionProc proc, void *procData)
|
||||
{
|
||||
LstNode tln = node;
|
||||
LstNode next;
|
||||
Boolean done;
|
||||
int result;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(node != NULL);
|
||||
assert(proc != NULL);
|
||||
|
||||
do {
|
||||
/*
|
||||
* Take care of having the current element deleted out from under
|
||||
* us.
|
||||
*/
|
||||
|
||||
next = tln->next;
|
||||
|
||||
/*
|
||||
* We're done with the traversal if
|
||||
* - the next node to examine doesn't exist and
|
||||
* - nothing's been added after the current node (check this
|
||||
* after proc() has been called).
|
||||
*/
|
||||
done = next == NULL;
|
||||
|
||||
tln->useCount++;
|
||||
result = (*proc)(tln->datum, procData);
|
||||
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->next) {
|
||||
next = tln->next;
|
||||
done = 0;
|
||||
}
|
||||
|
||||
if (tln->deleted) {
|
||||
free((char *)tln);
|
||||
}
|
||||
tln = next;
|
||||
} while (!result && !LstIsEmpty(list) && !done);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Move all nodes from list2 to the end of list1.
|
||||
* List2 is destroyed and freed. */
|
||||
void
|
||||
Lst_MoveAll(Lst list1, Lst list2)
|
||||
{
|
||||
assert(list1 != NULL);
|
||||
assert(list2 != NULL);
|
||||
|
||||
if (list2->first != NULL) {
|
||||
list2->first->prev = list1->last;
|
||||
if (list1->last != NULL) {
|
||||
list1->last->next = list2->first;
|
||||
} else {
|
||||
list1->first = list2->first;
|
||||
}
|
||||
list1->last = list2->last;
|
||||
}
|
||||
free(list2);
|
||||
}
|
||||
|
||||
/* Copy the element data from src to the start of dst. */
|
||||
void
|
||||
Lst_PrependAll(Lst dst, Lst src)
|
||||
{
|
||||
LstNode node;
|
||||
for (node = src->last; node != NULL; node = node->prev)
|
||||
Lst_Prepend(dst, node->datum);
|
||||
}
|
||||
|
||||
/* Copy the element data from src to the end of dst. */
|
||||
void
|
||||
Lst_AppendAll(Lst dst, Lst src)
|
||||
{
|
||||
LstNode node;
|
||||
for (node = src->first; node != NULL; node = node->next)
|
||||
Lst_Append(dst, node->datum);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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().
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Open a list for sequential access. A list can still be searched, etc.,
|
||||
* without confusing these functions. */
|
||||
void
|
||||
Lst_Open(Lst list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(!list->isOpen);
|
||||
|
||||
list->isOpen = TRUE;
|
||||
list->lastAccess = LstIsEmpty(list) ? Head : Unknown;
|
||||
list->curr = NULL;
|
||||
}
|
||||
|
||||
/* Return the next node for the given list, or NULL if the end has been
|
||||
* reached. */
|
||||
LstNode
|
||||
Lst_Next(Lst list)
|
||||
{
|
||||
LstNode node;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(list->isOpen);
|
||||
|
||||
list->prev = list->curr;
|
||||
|
||||
if (list->curr == NULL) {
|
||||
if (list->lastAccess == Unknown) {
|
||||
/*
|
||||
* If we're just starting out, lastAccess will be Unknown.
|
||||
* Then we want to start this thing off in the right
|
||||
* direction -- at the start with lastAccess being Middle.
|
||||
*/
|
||||
list->curr = node = list->first;
|
||||
list->lastAccess = Middle;
|
||||
} else {
|
||||
node = NULL;
|
||||
list->lastAccess = Tail;
|
||||
}
|
||||
} else {
|
||||
node = list->curr->next;
|
||||
list->curr = node;
|
||||
|
||||
if (node == list->first || node == NULL) {
|
||||
/*
|
||||
* If back at the front, then we've hit the end...
|
||||
*/
|
||||
list->lastAccess = Tail;
|
||||
} else {
|
||||
/*
|
||||
* Reset to Middle if gone past first.
|
||||
*/
|
||||
list->lastAccess = Middle;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Close a list which was opened for sequential access. */
|
||||
void
|
||||
Lst_Close(Lst list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
assert(list->isOpen);
|
||||
|
||||
list->isOpen = FALSE;
|
||||
list->lastAccess = Unknown;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* for using the list as a queue
|
||||
*/
|
||||
|
||||
/* Add the datum to the tail of the given list. */
|
||||
void
|
||||
Lst_Enqueue(Lst list, void *datum)
|
||||
{
|
||||
Lst_Append(list, datum);
|
||||
}
|
||||
|
||||
/* Remove and return the datum at the head of the given list. */
|
||||
void *
|
||||
Lst_Dequeue(Lst list)
|
||||
{
|
||||
void *datum;
|
||||
|
||||
assert(list != NULL);
|
||||
assert(!LstIsEmpty(list));
|
||||
|
||||
datum = list->first->datum;
|
||||
Lst_Remove(list, list->first);
|
||||
assert(datum != NULL);
|
||||
return datum;
|
||||
}
|
194
lst.h
194
lst.h
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lst.h,v 1.20 2014/09/07 20:55:34 joerg Exp $ */
|
||||
/* $NetBSD: lst.h,v 1.60 2020/09/02 23:33:13 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -73,117 +73,107 @@
|
||||
* from: @(#)lst.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
/*-
|
||||
* lst.h --
|
||||
* Header for using the list library
|
||||
*/
|
||||
#ifndef _LST_H_
|
||||
#define _LST_H_
|
||||
/* Doubly-linked lists of arbitrary pointers. */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef MAKE_LST_H
|
||||
#define MAKE_LST_H
|
||||
|
||||
#include "sprite.h"
|
||||
|
||||
/*
|
||||
* basic typedef. This is what the Lst_ functions handle
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* A doubly-linked list of pointers. */
|
||||
typedef struct List *Lst;
|
||||
/* A single node in the doubly-linked list. */
|
||||
typedef struct ListNode *LstNode;
|
||||
|
||||
typedef void *DuplicateProc(void *);
|
||||
typedef void FreeProc(void *);
|
||||
/* Copy a node, usually by allocating a copy of the given object.
|
||||
* For reference-counted objects, the original object may need to be
|
||||
* modified, therefore the parameter is not const. */
|
||||
typedef void *LstCopyProc(void *);
|
||||
/* Free the datum of a node, called before freeing the node itself. */
|
||||
typedef void LstFreeProc(void *);
|
||||
/* Return TRUE if the datum matches the args, for Lst_Find. */
|
||||
typedef Boolean LstFindProc(const void *datum, const void *args);
|
||||
/* An action for Lst_ForEach. */
|
||||
typedef int LstActionProc(void *datum, void *args);
|
||||
|
||||
#define LST_CONCNEW 0 /* create new LstNode's when using Lst_Concat */
|
||||
#define LST_CONCLINK 1 /* relink LstNode's when using Lst_Concat */
|
||||
/* Create or destroy a list */
|
||||
|
||||
/*
|
||||
* 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);
|
||||
/* Create a new list. */
|
||||
Lst Lst_Init(void);
|
||||
/* Duplicate an existing list. */
|
||||
Lst Lst_Copy(Lst, LstCopyProc);
|
||||
/* Free the list, leaving the node data unmodified. */
|
||||
void Lst_Free(Lst);
|
||||
/* Free the list, freeing the node data using the given function. */
|
||||
void Lst_Destroy(Lst, LstFreeProc);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
/* Get information about a list */
|
||||
|
||||
/*
|
||||
* 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);
|
||||
Boolean Lst_IsEmpty(Lst);
|
||||
/* Return the first node of the list, or NULL. */
|
||||
LstNode Lst_First(Lst);
|
||||
/* Return the last node of the list, or NULL. */
|
||||
LstNode Lst_Last(Lst);
|
||||
/* Find the first node for which the function returns TRUE, or NULL. */
|
||||
LstNode Lst_Find(Lst, LstFindProc, const void *);
|
||||
/* Find the first node for which the function returns TRUE, or NULL.
|
||||
* The search starts at the given node, towards the end of the list. */
|
||||
LstNode Lst_FindFrom(Lst, LstNode, LstFindProc, const void *);
|
||||
/* Find the first node that contains the given datum, or NULL. */
|
||||
LstNode Lst_FindDatum(Lst, const void *);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
/* Modify a list */
|
||||
|
||||
/*
|
||||
* 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);
|
||||
/* Insert a datum before the given node. */
|
||||
void Lst_InsertBefore(Lst, LstNode, void *);
|
||||
/* Place a datum at the front of the list. */
|
||||
void Lst_Prepend(Lst, void *);
|
||||
/* Place a datum at the end of the list. */
|
||||
void Lst_Append(Lst, void *);
|
||||
/* Remove the node from the list. */
|
||||
void Lst_Remove(Lst, LstNode);
|
||||
void Lst_PrependAll(Lst, Lst);
|
||||
void Lst_AppendAll(Lst, Lst);
|
||||
void Lst_MoveAll(Lst, Lst);
|
||||
|
||||
#endif /* _LST_H_ */
|
||||
/* Node-specific functions */
|
||||
|
||||
/* Return the successor of the node, or NULL. */
|
||||
LstNode LstNode_Next(LstNode);
|
||||
/* Return the predecessor of the node, or NULL. */
|
||||
LstNode LstNode_Prev(LstNode);
|
||||
/* Return the datum of the node. Usually not NULL. */
|
||||
void *LstNode_Datum(LstNode);
|
||||
/* Replace the value of the node. */
|
||||
void LstNode_Set(LstNode, void *);
|
||||
/* Set the value of the node to NULL. Having NULL in a list is unusual. */
|
||||
void LstNode_SetNull(LstNode);
|
||||
|
||||
/* Iterating over a list, using a callback function */
|
||||
|
||||
/* Apply a function to each datum of the list, until the callback function
|
||||
* returns non-zero. */
|
||||
int Lst_ForEach(Lst, LstActionProc, void *);
|
||||
/* Apply a function to each datum of the list, starting at the node,
|
||||
* until the callback function returns non-zero. */
|
||||
int Lst_ForEachFrom(Lst, LstNode, LstActionProc, void *);
|
||||
|
||||
/* Iterating over a list while keeping track of the current node and possible
|
||||
* concurrent modifications */
|
||||
|
||||
/* Start iterating the list. */
|
||||
void Lst_Open(Lst);
|
||||
/* Return the next node, or NULL. */
|
||||
LstNode Lst_Next(Lst);
|
||||
/* Finish iterating the list. */
|
||||
void Lst_Close(Lst);
|
||||
|
||||
/* Using the list as a queue */
|
||||
|
||||
/* Add a datum at the tail of the queue. */
|
||||
void Lst_Enqueue(Lst, void *);
|
||||
/* Remove the head node of the queue and return its datum. */
|
||||
void *Lst_Dequeue(Lst);
|
||||
|
||||
#endif /* MAKE_LST_H */
|
||||
|
@ -1,121 +0,0 @@
|
||||
/* $NetBSD: lstAppend.c,v 1.15 2020/07/03 08:37:56 rillig 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.15 2020/07/03 08:37:56 rillig 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.15 2020/07/03 08:37:56 rillig 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;
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
/* $NetBSD: lstAtEnd.c,v 1.14 2020/07/03 08:37:56 rillig 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.14 2020/07/03 08:37:56 rillig 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.14 2020/07/03 08:37:56 rillig 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);
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/* $NetBSD: lstAtFront.c,v 1.14 2020/07/03 08:37:56 rillig 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.14 2020/07/03 08:37:56 rillig 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.14 2020/07/03 08:37:56 rillig 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);
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/* $NetBSD: lstClose.c,v 1.12 2020/07/03 08:37:56 rillig 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.12 2020/07/03 08:37:56 rillig 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.12 2020/07/03 08:37:56 rillig 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;
|
||||
}
|
||||
}
|
@ -1,184 +0,0 @@
|
||||
/* $NetBSD: lstConcat.c,v 1.17 2020/07/03 08:37:56 rillig 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.17 2020/07/03 08:37:56 rillig 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.17 2020/07/03 08:37:56 rillig 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;
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/* $NetBSD: lstDatum.c,v 1.14 2020/07/03 08:37:56 rillig 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.14 2020/07/03 08:37:56 rillig 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.14 2020/07/03 08:37:56 rillig 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;
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
/* $NetBSD: lstDeQueue.c,v 1.15 2020/07/03 08:37:56 rillig 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.15 2020/07/03 08:37:56 rillig 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.15 2020/07/03 08:37:56 rillig 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
/* $NetBSD: lstDupl.c,v 1.17 2020/07/03 08:37:56 rillig 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.17 2020/07/03 08:37:56 rillig 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.17 2020/07/03 08:37:56 rillig 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;
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/* $NetBSD: lstEnQueue.c,v 1.14 2020/07/03 08:37:56 rillig 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.14 2020/07/03 08:37:56 rillig 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.14 2020/07/03 08:37:56 rillig 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);
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
/* $NetBSD: lstFind.c,v 1.16 2020/07/03 08:37:56 rillig 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.16 2020/07/03 08:37:56 rillig 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.16 2020/07/03 08:37:56 rillig 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);
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/* $NetBSD: lstFindFrom.c,v 1.16 2020/07/03 08:37:56 rillig 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.16 2020/07/03 08:37:56 rillig 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.16 2020/07/03 08:37:56 rillig 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;
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/* $NetBSD: lstFirst.c,v 1.13 2020/07/03 08:37:56 rillig 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.13 2020/07/03 08:37:56 rillig 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.13 2020/07/03 08:37:56 rillig 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;
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/* $NetBSD: lstForEach.c,v 1.14 2020/07/03 08:37:57 rillig 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.14 2020/07/03 08:37:57 rillig 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.14 2020/07/03 08:37:57 rillig 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);
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
/* $NetBSD: lstForEachFrom.c,v 1.18 2020/07/03 08:37:57 rillig 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.18 2020/07/03 08:37:57 rillig 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.18 2020/07/03 08:37:57 rillig 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;
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/* $NetBSD: lstInit.c,v 1.13 2020/07/03 08:37:57 rillig 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.13 2020/07/03 08:37:57 rillig 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.13 2020/07/03 08:37:57 rillig 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;
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
/* $NetBSD: lstInsert.c,v 1.15 2020/07/03 08:37:57 rillig 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.15 2020/07/03 08:37:57 rillig 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.15 2020/07/03 08:37:57 rillig 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;
|
||||
}
|
105
lst.lib/lstInt.h
105
lst.lib/lstInt.h
@ -1,105 +0,0 @@
|
||||
/* $NetBSD: lstInt.h,v 1.22 2014/09/07 20:55:34 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: @(#)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_ */
|
@ -1,86 +0,0 @@
|
||||
/* $NetBSD: lstIsAtEnd.c,v 1.14 2020/07/03 08:37:57 rillig 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.14 2020/07/03 08:37:57 rillig 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.14 2020/07/03 08:37:57 rillig 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;
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
/* $NetBSD: lstIsEmpty.c,v 1.12 2020/07/03 08:37:57 rillig 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.12 2020/07/03 08:37:57 rillig 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.12 2020/07/03 08:37:57 rillig 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);
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/* $NetBSD: lstLast.c,v 1.13 2020/07/03 08:37:57 rillig 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.13 2020/07/03 08:37:57 rillig 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.13 2020/07/03 08:37:57 rillig 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;
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/* $NetBSD: lstMember.c,v 1.14 2013/11/14 00:01:28 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.
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: lstMember.c,v 1.14 2013/11/14 00:01:28 sjg 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.14 2013/11/14 00:01:28 sjg 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;
|
||||
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
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;
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
/* $NetBSD: lstNext.c,v 1.13 2020/07/03 08:37:57 rillig 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.13 2020/07/03 08:37:57 rillig 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.13 2020/07/03 08:37:57 rillig 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;
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
/* $NetBSD: lstOpen.c,v 1.13 2020/07/03 08:37:57 rillig 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.13 2020/07/03 08:37:57 rillig 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.13 2020/07/03 08:37:57 rillig 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;
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
/* $NetBSD: lstPrev.c,v 1.4 2020/07/03 08:37:57 rillig 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.4 2020/07/03 08:37:57 rillig 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.4 2020/07/03 08:37:57 rillig 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;
|
||||
}
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
/* $NetBSD: lstRemove.c,v 1.17 2020/07/03 08:37:57 rillig 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.17 2020/07/03 08:37:57 rillig 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.17 2020/07/03 08:37:57 rillig 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;
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/* $NetBSD: lstReplace.c,v 1.14 2020/07/03 08:37:57 rillig 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.14 2020/07/03 08:37:57 rillig 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.14 2020/07/03 08:37:57 rillig 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;
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
/* $NetBSD: lstSucc.c,v 1.14 2020/07/03 08:37:57 rillig 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.14 2020/07/03 08:37:57 rillig 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.14 2020/07/03 08:37:57 rillig 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;
|
||||
}
|
||||
}
|
376
main.c
376
main.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $ */
|
||||
/* $NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -69,7 +69,7 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $";
|
||||
static char rcsid[] = "$NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $");
|
||||
__RCSID("$NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -124,13 +124,13 @@ __RCSID("$NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $");
|
||||
#include <sys/utsname.h>
|
||||
#include "wait.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "make.h"
|
||||
#include "hash.h"
|
||||
@ -162,7 +162,8 @@ static Lst makefiles; /* ordered list of makefiles to read */
|
||||
static int printVars; /* -[vV] argument */
|
||||
#define COMPAT_VARS 1
|
||||
#define EXPAND_VARS 2
|
||||
static Lst variables; /* list of variables to print */
|
||||
static Lst variables; /* list of variables to print
|
||||
* (for -v and -V) */
|
||||
int maxJobs; /* -j argument */
|
||||
static int maxJobTokens; /* -j argument */
|
||||
Boolean compatMake; /* -B argument */
|
||||
@ -180,14 +181,13 @@ 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;
|
||||
static void MainParseArgs(int, char **);
|
||||
static int ReadMakefile(const void *, const void *);
|
||||
static int ReadMakefile(const char *);
|
||||
static void usage(void) MAKE_ATTR_DEAD;
|
||||
static void purge_cached_realpaths(void);
|
||||
|
||||
@ -257,7 +257,7 @@ parse_debug_options(const char *argvalue)
|
||||
for (modules = argvalue; *modules; ++modules) {
|
||||
switch (*modules) {
|
||||
case 'A':
|
||||
debug = ~0;
|
||||
debug = ~(0|DEBUG_LINT);
|
||||
break;
|
||||
case 'a':
|
||||
debug |= DEBUG_ARCH;
|
||||
@ -291,9 +291,15 @@ parse_debug_options(const char *argvalue)
|
||||
++modules;
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
debug |= DEBUG_HASH;
|
||||
break;
|
||||
case 'j':
|
||||
debug |= DEBUG_JOB;
|
||||
break;
|
||||
case 'L':
|
||||
debug |= DEBUG_LINT;
|
||||
break;
|
||||
case 'l':
|
||||
debug |= DEBUG_LOUD;
|
||||
break;
|
||||
@ -375,7 +381,7 @@ parse_debug_options(const char *argvalue)
|
||||
/*
|
||||
* does path contain any relative components
|
||||
*/
|
||||
static int
|
||||
static Boolean
|
||||
is_relpath(const char *path)
|
||||
{
|
||||
const char *cp;
|
||||
@ -383,10 +389,7 @@ is_relpath(const char *path)
|
||||
if (path[0] != '/')
|
||||
return TRUE;
|
||||
cp = path;
|
||||
do {
|
||||
cp = strstr(cp, "/.");
|
||||
if (!cp)
|
||||
break;
|
||||
while ((cp = strstr(cp, "/.")) != NULL) {
|
||||
cp += 2;
|
||||
if (cp[0] == '/' || cp[0] == '\0')
|
||||
return TRUE;
|
||||
@ -394,7 +397,7 @@ is_relpath(const char *path)
|
||||
if (cp[1] == '/' || cp[1] == '\0')
|
||||
return TRUE;
|
||||
}
|
||||
} while (cp);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -416,7 +419,7 @@ static void
|
||||
MainParseArgs(int argc, char **argv)
|
||||
{
|
||||
char *p;
|
||||
int c = '?';
|
||||
char c = '?';
|
||||
int arginc;
|
||||
char *argvalue;
|
||||
const char *getopt_def;
|
||||
@ -531,7 +534,6 @@ MainParseArgs(int argc, char **argv)
|
||||
} else {
|
||||
Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
|
||||
Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
|
||||
jobServer = TRUE;
|
||||
}
|
||||
break;
|
||||
case 'N':
|
||||
@ -553,7 +555,7 @@ MainParseArgs(int argc, char **argv)
|
||||
case 'v':
|
||||
if (argvalue == NULL) goto noarg;
|
||||
printVars = c == 'v' ? EXPAND_VARS : COMPAT_VARS;
|
||||
(void)Lst_AtEnd(variables, argvalue);
|
||||
Lst_Append(variables, argvalue);
|
||||
Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
|
||||
Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
|
||||
break;
|
||||
@ -581,7 +583,7 @@ MainParseArgs(int argc, char **argv)
|
||||
break;
|
||||
case 'f':
|
||||
if (argvalue == NULL) goto noarg;
|
||||
(void)Lst_AtEnd(makefiles, argvalue);
|
||||
Lst_Append(makefiles, argvalue);
|
||||
break;
|
||||
case 'i':
|
||||
ignoreErrors = TRUE;
|
||||
@ -674,7 +676,7 @@ MainParseArgs(int argc, char **argv)
|
||||
Punt("illegal (null) argument.");
|
||||
if (*argv[1] == '-' && !dashDash)
|
||||
goto rearg;
|
||||
(void)Lst_AtEnd(create, bmake_strdup(argv[1]));
|
||||
Lst_Append(create, bmake_strdup(argv[1]));
|
||||
}
|
||||
|
||||
return;
|
||||
@ -705,12 +707,10 @@ MainParseArgs(int argc, char **argv)
|
||||
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;
|
||||
Words words;
|
||||
char *p1;
|
||||
const char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
|
||||
char *buf;
|
||||
|
||||
if (line == NULL)
|
||||
return;
|
||||
@ -733,21 +733,19 @@ Main_ParseArgLine(const char *line)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
buf = bmake_malloc(len = strlen(line) + strlen(argv0) + 2);
|
||||
(void)snprintf(buf, len, "%s %s", argv0, line);
|
||||
buf = str_concat3(argv0, " ", line);
|
||||
free(p1);
|
||||
|
||||
argv = brk_string(buf, &argc, TRUE, &args);
|
||||
if (argv == NULL) {
|
||||
words = Str_Words(buf, TRUE);
|
||||
if (words.words == NULL) {
|
||||
Error("Unterminated quoted string [%s]", buf);
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
free(buf);
|
||||
MainParseArgs(argc, argv);
|
||||
MainParseArgs((int)words.len, words.words);
|
||||
|
||||
free(args);
|
||||
free(argv);
|
||||
Words_Free(words);
|
||||
}
|
||||
|
||||
Boolean
|
||||
@ -775,7 +773,7 @@ Main_SetObjdir(const char *fmt, ...)
|
||||
(void)fprintf(stderr, "make warning: %s: %s.\n",
|
||||
path, strerror(errno));
|
||||
} else {
|
||||
strncpy(objdir, path, MAXPATHLEN);
|
||||
snprintf(objdir, sizeof objdir, "%s", path);
|
||||
Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
|
||||
setenv("PWD", objdir, 1);
|
||||
Dir_InitDot();
|
||||
@ -792,37 +790,44 @@ Main_SetObjdir(const char *fmt, ...)
|
||||
static Boolean
|
||||
Main_SetVarObjdir(const char *var, const char *suffix)
|
||||
{
|
||||
char *p, *path, *xpath;
|
||||
char *path_freeIt;
|
||||
const char *path = Var_Value(var, VAR_CMD, &path_freeIt);
|
||||
const char *xpath;
|
||||
char *xpath_freeIt;
|
||||
|
||||
if ((path = Var_Value(var, VAR_CMD, &p)) == NULL ||
|
||||
*path == '\0')
|
||||
if (path == NULL || path[0] == '\0') {
|
||||
bmake_free(path_freeIt);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* expand variable substitutions */
|
||||
xpath = path;
|
||||
xpath_freeIt = NULL;
|
||||
if (strchr(path, '$') != 0)
|
||||
xpath = Var_Subst(NULL, path, VAR_GLOBAL, VARF_WANTRES);
|
||||
else
|
||||
xpath = path;
|
||||
xpath = xpath_freeIt = Var_Subst(path, VAR_GLOBAL,
|
||||
VARE_WANTRES);
|
||||
|
||||
(void)Main_SetObjdir("%s%s", xpath, suffix);
|
||||
|
||||
if (xpath != path)
|
||||
free(xpath);
|
||||
free(p);
|
||||
bmake_free(xpath_freeIt);
|
||||
bmake_free(path_freeIt);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*-
|
||||
* ReadAllMakefiles --
|
||||
* wrapper around ReadMakefile() to read all.
|
||||
*
|
||||
* Results:
|
||||
* TRUE if ok, FALSE on error
|
||||
*/
|
||||
static int
|
||||
ReadAllMakefiles(const void *p, const void *q)
|
||||
/* Read and parse the makefile.
|
||||
* Return TRUE if reading the makefile succeeded, for Lst_Find. */
|
||||
static Boolean
|
||||
ReadMakefileSucceeded(const void *fname, const void *unused)
|
||||
{
|
||||
return ReadMakefile(p, q) == 0;
|
||||
return ReadMakefile(fname) == 0;
|
||||
}
|
||||
|
||||
/* Read and parse the makefile.
|
||||
* Return TRUE if reading the makefile failed, for Lst_Find. */
|
||||
static Boolean
|
||||
ReadMakefileFailed(const void *fname, const void *unused)
|
||||
{
|
||||
return ReadMakefile(fname) != 0;
|
||||
}
|
||||
|
||||
int
|
||||
@ -835,7 +840,7 @@ str2Lst_Append(Lst lp, char *str, const char *sep)
|
||||
sep = " \t";
|
||||
|
||||
for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) {
|
||||
(void)Lst_AtEnd(lp, cp);
|
||||
Lst_Append(lp, cp);
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
@ -863,13 +868,13 @@ siginfo(int signo MAKE_ATTR_UNUSED)
|
||||
void
|
||||
MakeMode(const char *mode)
|
||||
{
|
||||
char *mp = NULL;
|
||||
char *mode_freeIt = NULL;
|
||||
|
||||
if (!mode)
|
||||
mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}",
|
||||
VAR_GLOBAL, VARF_WANTRES);
|
||||
if (mode == NULL)
|
||||
mode = mode_freeIt = Var_Subst("${" MAKE_MODE ":tl}",
|
||||
VAR_GLOBAL, VARE_WANTRES);
|
||||
|
||||
if (mode && *mode) {
|
||||
if (mode[0] != '\0') {
|
||||
if (strstr(mode, "compat")) {
|
||||
compatMake = TRUE;
|
||||
forceJobs = FALSE;
|
||||
@ -880,7 +885,7 @@ MakeMode(const char *mode)
|
||||
#endif
|
||||
}
|
||||
|
||||
free(mp);
|
||||
free(mode_freeIt);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -896,15 +901,13 @@ doPrintVars(void)
|
||||
else
|
||||
expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE);
|
||||
|
||||
for (ln = Lst_First(variables); ln != NULL;
|
||||
ln = Lst_Succ(ln)) {
|
||||
char *var = (char *)Lst_Datum(ln);
|
||||
char *value;
|
||||
for (ln = Lst_First(variables); ln != NULL; ln = LstNode_Next(ln)) {
|
||||
char *var = LstNode_Datum(ln);
|
||||
const char *value;
|
||||
char *p1;
|
||||
|
||||
if (strchr(var, '$')) {
|
||||
value = p1 = Var_Subst(NULL, var, VAR_GLOBAL,
|
||||
VARF_WANTRES);
|
||||
value = p1 = Var_Subst(var, VAR_GLOBAL, VARE_WANTRES);
|
||||
} else if (expandVars) {
|
||||
char tmp[128];
|
||||
int len = snprintf(tmp, sizeof(tmp), "${%s}", var);
|
||||
@ -912,13 +915,12 @@ doPrintVars(void)
|
||||
if (len >= (int)sizeof(tmp))
|
||||
Fatal("%s: variable name too big: %s",
|
||||
progname, var);
|
||||
value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL,
|
||||
VARF_WANTRES);
|
||||
value = p1 = Var_Subst(tmp, VAR_GLOBAL, VARE_WANTRES);
|
||||
} else {
|
||||
value = Var_Value(var, VAR_GLOBAL, &p1);
|
||||
}
|
||||
printf("%s\n", value ? value : "");
|
||||
free(p1);
|
||||
bmake_free(p1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -962,7 +964,7 @@ runTargets(void)
|
||||
Compat_Run(targs);
|
||||
outOfDate = FALSE;
|
||||
}
|
||||
Lst_Destroy(targs, NULL);
|
||||
Lst_Free(targs);
|
||||
return outOfDate;
|
||||
}
|
||||
|
||||
@ -1079,7 +1081,7 @@ main(int argc, char **argv)
|
||||
#else
|
||||
#ifndef MACHINE_ARCH
|
||||
#ifdef MAKE_MACHINE_ARCH
|
||||
machine_arch = MAKE_MACHINE_ARCH;
|
||||
machine_arch = MAKE_MACHINE_ARCH;
|
||||
#else
|
||||
machine_arch = "unknown";
|
||||
#endif
|
||||
@ -1113,11 +1115,11 @@ main(int argc, char **argv)
|
||||
VAR_GLOBAL);
|
||||
Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL);
|
||||
|
||||
create = Lst_Init(FALSE);
|
||||
makefiles = Lst_Init(FALSE);
|
||||
create = Lst_Init();
|
||||
makefiles = Lst_Init();
|
||||
printVars = 0;
|
||||
debugVflag = FALSE;
|
||||
variables = Lst_Init(FALSE);
|
||||
variables = Lst_Init();
|
||||
beSilent = FALSE; /* Print commands as executed */
|
||||
ignoreErrors = FALSE; /* Pay attention to non-zero returns */
|
||||
noExecute = FALSE; /* Execute all commands */
|
||||
@ -1199,7 +1201,7 @@ main(int argc, char **argv)
|
||||
#ifdef USE_META
|
||||
meta_init();
|
||||
#endif
|
||||
Dir_Init(NULL); /* Dir_* safe to call from MainParseArgs */
|
||||
Dir_Init();
|
||||
|
||||
/*
|
||||
* First snag any flags out of the MAKE environment variable.
|
||||
@ -1265,8 +1267,8 @@ main(int argc, char **argv)
|
||||
(void)strncpy(curdir, pwd, MAXPATHLEN);
|
||||
}
|
||||
}
|
||||
free(ptmp1);
|
||||
free(ptmp2);
|
||||
bmake_free(ptmp1);
|
||||
bmake_free(ptmp2);
|
||||
}
|
||||
#endif
|
||||
Var_Set(".CURDIR", curdir, VAR_GLOBAL);
|
||||
@ -1280,7 +1282,7 @@ main(int argc, char **argv)
|
||||
* and * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none
|
||||
* of these paths exist, just use .CURDIR.
|
||||
*/
|
||||
Dir_Init(curdir);
|
||||
Dir_InitDir(curdir);
|
||||
(void)Main_SetObjdir("%s", curdir);
|
||||
|
||||
if (!Main_SetVarObjdir("MAKEOBJDIRPREFIX", curdir) &&
|
||||
@ -1312,10 +1314,8 @@ main(int argc, char **argv)
|
||||
if (!Lst_IsEmpty(create)) {
|
||||
LstNode ln;
|
||||
|
||||
for (ln = Lst_First(create); ln != NULL;
|
||||
ln = Lst_Succ(ln)) {
|
||||
char *name = (char *)Lst_Datum(ln);
|
||||
|
||||
for (ln = Lst_First(create); ln != NULL; ln = LstNode_Next(ln)) {
|
||||
char *name = LstNode_Datum(ln);
|
||||
Var_Append(".TARGETS", name, VAR_GLOBAL);
|
||||
}
|
||||
} else
|
||||
@ -1327,7 +1327,8 @@ main(int argc, char **argv)
|
||||
* 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')
|
||||
/* XXX: mismatch: the -m option sets sysIncPath, not syspath */
|
||||
if (syspath == NULL || syspath[0] == '\0')
|
||||
syspath = defsyspath;
|
||||
else
|
||||
syspath = bmake_strdup(syspath);
|
||||
@ -1353,48 +1354,46 @@ main(int argc, char **argv)
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* makefiles, or the default makefile and Makefile, in that order,
|
||||
* if no makefiles were given on the command line.
|
||||
*/
|
||||
if (!noBuiltins) {
|
||||
LstNode ln;
|
||||
|
||||
sysMkPath = Lst_Init(FALSE);
|
||||
sysMkPath = Lst_Init();
|
||||
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);
|
||||
ln = Lst_Find(sysMkPath, ReadMakefileSucceeded, NULL);
|
||||
if (ln == NULL)
|
||||
Fatal("%s: cannot open %s.", progname,
|
||||
(char *)Lst_Datum(ln));
|
||||
(char *)LstNode_Datum(Lst_First(sysMkPath)));
|
||||
}
|
||||
|
||||
if (!Lst_IsEmpty(makefiles)) {
|
||||
LstNode ln;
|
||||
|
||||
ln = Lst_Find(makefiles, NULL, ReadAllMakefiles);
|
||||
ln = Lst_Find(makefiles, ReadMakefileFailed, NULL);
|
||||
if (ln != NULL)
|
||||
Fatal("%s: cannot open %s.", progname,
|
||||
(char *)Lst_Datum(ln));
|
||||
(char *)LstNode_Datum(ln));
|
||||
} else {
|
||||
p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}",
|
||||
VAR_CMD, VARF_WANTRES);
|
||||
if (p1) {
|
||||
p1 = Var_Subst("${" MAKEFILE_PREFERENCE "}",
|
||||
VAR_CMD, VARE_WANTRES);
|
||||
(void)str2Lst_Append(makefiles, p1, NULL);
|
||||
(void)Lst_Find(makefiles, NULL, ReadMakefile);
|
||||
(void)Lst_Find(makefiles, ReadMakefileSucceeded, NULL);
|
||||
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, VARF_WANTRES);
|
||||
makeDependfile = Var_Subst("${.MAKE.DEPENDFILE:T}",
|
||||
VAR_CMD, VARE_WANTRES);
|
||||
doing_depend = TRUE;
|
||||
(void)ReadMakefile(makeDependfile, NULL);
|
||||
(void)ReadMakefile(makeDependfile);
|
||||
doing_depend = FALSE;
|
||||
}
|
||||
|
||||
@ -1404,14 +1403,14 @@ main(int argc, char **argv)
|
||||
MakeMode(NULL);
|
||||
|
||||
Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
|
||||
free(p1);
|
||||
bmake_free(p1);
|
||||
|
||||
if (!forceJobs && !compatMake &&
|
||||
Var_Exists(".MAKE.JOBS", VAR_GLOBAL)) {
|
||||
char *value;
|
||||
int n;
|
||||
|
||||
value = Var_Subst(NULL, "${.MAKE.JOBS}", VAR_GLOBAL, VARF_WANTRES);
|
||||
value = Var_Subst("${.MAKE.JOBS}", VAR_GLOBAL, VARE_WANTRES);
|
||||
n = strtol(value, NULL, 0);
|
||||
if (n < 1) {
|
||||
(void)fprintf(stderr, "%s: illegal value for .MAKE.JOBS -- must be positive integer!\n",
|
||||
@ -1439,8 +1438,9 @@ main(int argc, char **argv)
|
||||
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);
|
||||
fprintf(debug_file,
|
||||
"job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
|
||||
jp_0, jp_1, maxJobs, maxJobTokens, compatMake ? 1 : 0);
|
||||
|
||||
if (!printVars)
|
||||
Main_ExportMAKEFLAGS(TRUE); /* initial export */
|
||||
@ -1461,7 +1461,7 @@ main(int argc, char **argv)
|
||||
*/
|
||||
static char VPATH[] = "${VPATH}";
|
||||
|
||||
vpath = Var_Subst(NULL, VPATH, VAR_CMD, VARF_WANTRES);
|
||||
vpath = Var_Subst(VPATH, VAR_CMD, VARE_WANTRES);
|
||||
path = vpath;
|
||||
do {
|
||||
/* skip to end of directory */
|
||||
@ -1502,9 +1502,9 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
#ifdef CLEANUP
|
||||
Lst_Destroy(variables, NULL);
|
||||
Lst_Destroy(makefiles, NULL);
|
||||
Lst_Destroy(create, (FreeProc *)free);
|
||||
Lst_Free(variables);
|
||||
Lst_Free(makefiles);
|
||||
Lst_Destroy(create, free);
|
||||
#endif
|
||||
|
||||
/* print the graph now it's been processed if the user requested it */
|
||||
@ -1522,7 +1522,7 @@ main(int argc, char **argv)
|
||||
meta_finish();
|
||||
#endif
|
||||
Suff_End();
|
||||
Targ_End();
|
||||
Targ_End();
|
||||
Arch_End();
|
||||
Var_End();
|
||||
Parse_End();
|
||||
@ -1533,23 +1533,16 @@ main(int argc, char **argv)
|
||||
return outOfDate ? 1 : 0;
|
||||
}
|
||||
|
||||
/*-
|
||||
* ReadMakefile --
|
||||
* Open and parse the given makefile.
|
||||
/* Open and parse the given makefile, with all its side effects.
|
||||
*
|
||||
* 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)
|
||||
ReadMakefile(const char *fname)
|
||||
{
|
||||
const char *fname = p; /* makefile to read */
|
||||
int fd;
|
||||
size_t len = MAXPATHLEN;
|
||||
char *name, *path = bmake_malloc(len);
|
||||
char *name, *path = NULL;
|
||||
|
||||
if (!strcmp(fname, "-")) {
|
||||
Parse_File(NULL /*stdin*/, -1);
|
||||
@ -1557,22 +1550,16 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
|
||||
} 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);
|
||||
path = str_concat3(curdir, "/", fname);
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd != -1) {
|
||||
fname = path;
|
||||
goto found;
|
||||
}
|
||||
free(path);
|
||||
|
||||
/* 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);
|
||||
path = str_concat3(objdir, "/", fname);
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd != -1) {
|
||||
fname = path;
|
||||
@ -1613,31 +1600,32 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
|
||||
/*-
|
||||
* Cmd_Exec --
|
||||
* Execute the command in cmd, and return the output of that command
|
||||
* in a string.
|
||||
* in a string. In the output, newlines are replaced with spaces.
|
||||
*
|
||||
* 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
|
||||
* A string containing the output of the command, or the empty string.
|
||||
* *errfmt returns a format string describing the command failure,
|
||||
* if any, using a single %s conversion specification.
|
||||
*
|
||||
* Side Effects:
|
||||
* The string must be freed by the caller.
|
||||
*/
|
||||
char *
|
||||
Cmd_Exec(const char *cmd, const char **errnum)
|
||||
Cmd_Exec(const char *cmd, const char **errfmt)
|
||||
{
|
||||
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 */
|
||||
ssize_t bytes_read;
|
||||
char *res; /* result */
|
||||
size_t res_len;
|
||||
char *cp;
|
||||
int cc; /* bytes read, or -1 */
|
||||
int savederr; /* saved errno */
|
||||
|
||||
|
||||
*errnum = NULL;
|
||||
*errfmt = NULL;
|
||||
|
||||
if (!shellName)
|
||||
Shell_Init();
|
||||
@ -1653,7 +1641,7 @@ Cmd_Exec(const char *cmd, const char **errnum)
|
||||
* Open a pipe for fetching its output
|
||||
*/
|
||||
if (pipe(fds) == -1) {
|
||||
*errnum = "Couldn't create pipe for \"%s\"";
|
||||
*errfmt = "Couldn't create pipe for \"%s\"";
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@ -1682,7 +1670,7 @@ Cmd_Exec(const char *cmd, const char **errnum)
|
||||
/*NOTREACHED*/
|
||||
|
||||
case -1:
|
||||
*errnum = "Couldn't exec \"%s\"";
|
||||
*errfmt = "Couldn't exec \"%s\"";
|
||||
goto bad;
|
||||
|
||||
default:
|
||||
@ -1696,12 +1684,12 @@ Cmd_Exec(const char *cmd, const char **errnum)
|
||||
|
||||
do {
|
||||
char result[BUFSIZ];
|
||||
cc = read(fds[0], result, sizeof(result));
|
||||
if (cc > 0)
|
||||
Buf_AddBytes(&buf, cc, result);
|
||||
bytes_read = read(fds[0], result, sizeof(result));
|
||||
if (bytes_read > 0)
|
||||
Buf_AddBytes(&buf, result, (size_t)bytes_read);
|
||||
}
|
||||
while (cc > 0 || (cc == -1 && errno == EINTR));
|
||||
if (cc == -1)
|
||||
while (bytes_read > 0 || (bytes_read == -1 && errno == EINTR));
|
||||
if (bytes_read == -1)
|
||||
savederr = errno;
|
||||
|
||||
/*
|
||||
@ -1716,43 +1704,28 @@ Cmd_Exec(const char *cmd, const char **errnum)
|
||||
JobReapChild(pid, status, FALSE);
|
||||
continue;
|
||||
}
|
||||
cc = Buf_Size(&buf);
|
||||
res_len = Buf_Size(&buf);
|
||||
res = Buf_Destroy(&buf, FALSE);
|
||||
|
||||
if (savederr != 0)
|
||||
*errnum = "Couldn't read shell's output for \"%s\"";
|
||||
*errfmt = "Couldn't read shell's output for \"%s\"";
|
||||
|
||||
if (WIFSIGNALED(status))
|
||||
*errnum = "\"%s\" exited on a signal";
|
||||
*errfmt = "\"%s\" exited on a signal";
|
||||
else if (WEXITSTATUS(status) != 0)
|
||||
*errnum = "\"%s\" returned non-zero status";
|
||||
*errfmt = "\"%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') {
|
||||
/* Convert newlines to spaces. A final newline is just stripped */
|
||||
if (res_len > 0 && res[res_len - 1] == '\n')
|
||||
res[res_len - 1] = '\0';
|
||||
for (cp = res; *cp != '\0'; cp++)
|
||||
if (*cp == '\n')
|
||||
*cp = ' ';
|
||||
}
|
||||
cp--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
bad:
|
||||
res = bmake_malloc(1);
|
||||
*res = '\0';
|
||||
return res;
|
||||
return bmake_strdup("");
|
||||
}
|
||||
|
||||
/*-
|
||||
@ -1888,7 +1861,7 @@ DieHorribly(void)
|
||||
*/
|
||||
void
|
||||
Finish(int errors)
|
||||
/* number of errors encountered in Make_Make */
|
||||
/* number of errors encountered in Make_Make */
|
||||
{
|
||||
if (dieQuietly(NULL, -1))
|
||||
exit(2);
|
||||
@ -1956,13 +1929,13 @@ usage(void)
|
||||
{
|
||||
char *p;
|
||||
if ((p = strchr(progname, '[')) != NULL)
|
||||
*p = '\0';
|
||||
*p = '\0';
|
||||
|
||||
(void)fprintf(stderr,
|
||||
"usage: %s [-BeikNnqrstWwX] \n\
|
||||
[-C directory] [-D variable] [-d flags] [-f makefile]\n\
|
||||
[-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\
|
||||
[-V variable] [-v variable] [variable=value] [target ...]\n",
|
||||
"usage: %s [-BeikNnqrstWwX] \n"
|
||||
" [-C directory] [-D variable] [-d flags] [-f makefile]\n"
|
||||
" [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n"
|
||||
" [-V variable] [-v variable] [variable=value] [target ...]\n",
|
||||
progname);
|
||||
exit(2);
|
||||
}
|
||||
@ -2010,7 +1983,8 @@ char *
|
||||
cached_realpath(const char *pathname, char *resolved)
|
||||
{
|
||||
GNode *cache;
|
||||
char *rp, *cp;
|
||||
const char *rp;
|
||||
char *cp;
|
||||
|
||||
if (!pathname || !pathname[0])
|
||||
return NULL;
|
||||
@ -2024,7 +1998,7 @@ cached_realpath(const char *pathname, char *resolved)
|
||||
Var_Set(pathname, rp, cache);
|
||||
} /* else should we negative-cache? */
|
||||
|
||||
free(cp);
|
||||
bmake_free(cp);
|
||||
return rp ? resolved : NULL;
|
||||
}
|
||||
|
||||
@ -2070,9 +2044,14 @@ void
|
||||
PrintOnError(GNode *gn, const char *s)
|
||||
{
|
||||
static GNode *en = NULL;
|
||||
char tmp[64];
|
||||
const char *expr;
|
||||
char *cp;
|
||||
|
||||
if (DEBUG(HASH)) {
|
||||
Targ_Stats();
|
||||
Var_Stats();
|
||||
}
|
||||
|
||||
/* we generally want to keep quiet if a sub-make died */
|
||||
if (dieQuietly(gn, -1))
|
||||
return;
|
||||
@ -2092,14 +2071,10 @@ PrintOnError(GNode *gn, const char *s)
|
||||
Var_Delete(".ERROR_CMD", VAR_GLOBAL);
|
||||
Lst_ForEach(gn->commands, addErrorCMD, gn);
|
||||
}
|
||||
strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
|
||||
sizeof(tmp) - 1);
|
||||
cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
|
||||
if (cp) {
|
||||
if (*cp)
|
||||
printf("%s", cp);
|
||||
free(cp);
|
||||
}
|
||||
expr = "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}";
|
||||
cp = Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES);
|
||||
printf("%s", cp);
|
||||
free(cp);
|
||||
fflush(stdout);
|
||||
|
||||
/*
|
||||
@ -2115,18 +2090,17 @@ PrintOnError(GNode *gn, const char *s)
|
||||
void
|
||||
Main_ExportMAKEFLAGS(Boolean first)
|
||||
{
|
||||
static int once = 1;
|
||||
char tmp[64];
|
||||
static Boolean once = TRUE;
|
||||
const char *expr;
|
||||
char *s;
|
||||
|
||||
if (once != first)
|
||||
return;
|
||||
once = 0;
|
||||
once = FALSE;
|
||||
|
||||
strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}",
|
||||
sizeof(tmp));
|
||||
s = Var_Subst(NULL, tmp, VAR_CMD, VARF_WANTRES);
|
||||
if (s && *s) {
|
||||
expr = "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}";
|
||||
s = Var_Subst(expr, VAR_CMD, VARE_WANTRES);
|
||||
if (s[0] != '\0') {
|
||||
#ifdef POSIX
|
||||
setenv("MAKEFLAGS", s, 1);
|
||||
#else
|
||||
@ -2147,8 +2121,8 @@ getTmpdir(void)
|
||||
* Honor $TMPDIR but only if it is valid.
|
||||
* Ensure it ends with /.
|
||||
*/
|
||||
tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL,
|
||||
VARF_WANTRES);
|
||||
tmpdir = Var_Subst("${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL,
|
||||
VARE_WANTRES);
|
||||
if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
|
||||
free(tmpdir);
|
||||
tmpdir = bmake_strdup(_PATH_TMP);
|
||||
@ -2235,18 +2209,12 @@ s2Boolean(const char *s, Boolean bf)
|
||||
* is FALSE, otherwise TRUE.
|
||||
*/
|
||||
Boolean
|
||||
getBoolean(const char *name, Boolean bf)
|
||||
getBoolean(const char *name, Boolean fallback)
|
||||
{
|
||||
char tmp[64];
|
||||
char *cp;
|
||||
|
||||
if (snprintf(tmp, sizeof(tmp), "${%s:U:tl}", name) < (int)(sizeof(tmp))) {
|
||||
cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
|
||||
|
||||
if (cp) {
|
||||
bf = s2Boolean(cp, bf);
|
||||
free(cp);
|
||||
}
|
||||
}
|
||||
return bf;
|
||||
char *expr = str_concat3("${", name, ":U:tl}");
|
||||
char *value = Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES);
|
||||
Boolean res = s2Boolean(value, fallback);
|
||||
free(value);
|
||||
free(expr);
|
||||
return res;
|
||||
}
|
||||
|
10
make-conf.h
10
make-conf.h
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: config.h,v 1.21 2012/03/31 00:12:24 christos Exp $ */
|
||||
/* $NetBSD: config.h,v 1.22 2020/09/01 17:40:34 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -100,7 +100,10 @@
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#define LIBSUFF ".a"
|
||||
|
||||
/*
|
||||
* RECHECK
|
||||
* If defined, Make_Update will check a target for its current
|
||||
* modification time after it has been re-made, setting it to the
|
||||
@ -108,10 +111,9 @@
|
||||
* 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
|
||||
* that don't have this problem, you should define this. Under
|
||||
* NFS you probably should not, unless you aren't exporting jobs.
|
||||
*/
|
||||
#define LIBSUFF ".a"
|
||||
#define RECHECK
|
||||
|
||||
/*
|
||||
|
134
make.1
134
make.1
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: make.1,v 1.282 2020/06/06 20:28:42 wiz Exp $
|
||||
.\" $NetBSD: make.1,v 1.289 2020/08/28 17:15:04 rillig Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -29,7 +29,7 @@
|
||||
.\"
|
||||
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
|
||||
.\"
|
||||
.Dd June 5, 2020
|
||||
.Dd August 28, 2020
|
||||
.Dt MAKE 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -166,8 +166,15 @@ 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 h
|
||||
Print debugging information about hash table operations.
|
||||
.It Ar j
|
||||
Print debugging information about running multiple shells.
|
||||
.It Ar L
|
||||
Turn on lint checks.
|
||||
This will throw errors for variable assignments that do not parse
|
||||
correctly, at the time of assignment so the file and line number
|
||||
are available.
|
||||
.It Ar l
|
||||
Print commands in Makefiles regardless of whether or not they are prefixed by
|
||||
.Ql @
|
||||
@ -311,7 +318,8 @@ 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).
|
||||
source (see below) or the command is prefixed with
|
||||
.Ql Ic + .
|
||||
.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
|
||||
@ -412,37 +420,44 @@ 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:
|
||||
and are customarily created from them.
|
||||
A target is considered out-of-date if it does not exist, or if its
|
||||
modification time is less than that of any of its sources.
|
||||
An out-of-date target will be re-created, but not until all sources
|
||||
have been examined and themselves re-created as needed.
|
||||
Three operators may be used:
|
||||
.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
|
||||
Many dependency lines may name this target but only one may have
|
||||
attached shell commands.
|
||||
All sources named in all dependency lines are considered together,
|
||||
and if needed the attached shell commands are run to create or
|
||||
re-create the target.
|
||||
If
|
||||
.Nm
|
||||
is interrupted.
|
||||
is interrupted, the target is removed.
|
||||
.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.
|
||||
The same, but the target is always re-created whether or not it is out
|
||||
of date.
|
||||
.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
|
||||
Any dependency line may have attached shell commands, but each one
|
||||
is handled independently: its sources are considered and the attached
|
||||
shell commands are run if the target is out of date with respect to
|
||||
(only) those sources.
|
||||
Thus, different groups of the attached shell commands may be run
|
||||
depending on the circumstances.
|
||||
Furthermore, unlike
|
||||
.Ic \&:,
|
||||
for dependency lines with no sources, the attached shell
|
||||
commands are always run.
|
||||
Also unlike
|
||||
.Ic \&:,
|
||||
the target will not be removed if
|
||||
.Nm
|
||||
is interrupted.
|
||||
.El
|
||||
All dependency lines mentioning a particular target must use the same
|
||||
operator.
|
||||
.Pp
|
||||
Targets and sources may contain the shell wildcard values
|
||||
.Ql \&? ,
|
||||
@ -608,7 +623,7 @@ 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!
|
||||
braces, parentheses, or whitespace are really best avoided!
|
||||
.Pp
|
||||
If the result of expanding a variable contains a dollar sign
|
||||
.Pq Ql \&$
|
||||
@ -1126,6 +1141,9 @@ is set to the value of
|
||||
for all programs which
|
||||
.Nm
|
||||
executes.
|
||||
.It Ev .SHELL
|
||||
The pathname of the shell used to run target scripts.
|
||||
It is read-only.
|
||||
.It Ev .TARGETS
|
||||
The list of targets explicitly specified on the command line, if any.
|
||||
.It Ev VPATH
|
||||
@ -1171,7 +1189,7 @@ 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
|
||||
Selects only those words that match
|
||||
.Ar pattern .
|
||||
The standard shell wildcard characters
|
||||
.Pf ( Ql * ,
|
||||
@ -1195,11 +1213,11 @@ This is identical to
|
||||
but selects all words which do not match
|
||||
.Ar pattern .
|
||||
.It Cm \&:O
|
||||
Order every word in variable alphabetically.
|
||||
Orders every word in variable alphabetically.
|
||||
.It Cm \&:Or
|
||||
Order every word in variable in reverse alphabetical order.
|
||||
Orders every word in variable in reverse alphabetical order.
|
||||
.It Cm \&:Ox
|
||||
Randomize words in variable.
|
||||
Shuffles the 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 \&:=
|
||||
@ -1249,7 +1267,7 @@ If a
|
||||
.Va utc
|
||||
value is not provided or is 0, the current time is used.
|
||||
.It Cm \&:hash
|
||||
Compute a 32-bit hash of the value and encode it as hex digits.
|
||||
Computes a 32-bit hash of the value and encode it as hex digits.
|
||||
.It Cm \&:localtime[=utc]
|
||||
The value is a format string for
|
||||
.Xr strftime 3 ,
|
||||
@ -1259,7 +1277,7 @@ If a
|
||||
.Va utc
|
||||
value is not provided or is 0, the current time is used.
|
||||
.It Cm \&:tA
|
||||
Attempt to convert variable to an absolute path using
|
||||
Attempts to convert variable to an absolute path using
|
||||
.Xr realpath 3 ,
|
||||
if that fails, the value is unchanged.
|
||||
.It Cm \&:tl
|
||||
@ -1271,7 +1289,7 @@ This modifier sets the separator to the character
|
||||
If
|
||||
.Ar c
|
||||
is omitted, then no separator is used.
|
||||
The common escapes (including octal numeric codes), work as expected.
|
||||
The common escapes (including octal numeric codes) work as expected.
|
||||
.It Cm \&:tu
|
||||
Converts variable to upper-case letters.
|
||||
.It Cm \&:tW
|
||||
@ -1287,21 +1305,21 @@ See also
|
||||
.Sm off
|
||||
.It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW
|
||||
.Sm on
|
||||
Modify the first occurrence of
|
||||
Modifies the first occurrence of
|
||||
.Ar old_string
|
||||
in the variable's value, replacing it with
|
||||
in each word of 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
|
||||
is appended to the last delimiter 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 appended to the last delimiter of the pattern, only the first occurrence
|
||||
is affected.
|
||||
If a
|
||||
.Ql W
|
||||
is appended to the last slash of the pattern,
|
||||
is appended to the last delimiter of the pattern,
|
||||
then the value is treated as a single word
|
||||
(possibly containing embedded white space).
|
||||
If
|
||||
@ -1370,13 +1388,6 @@ 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.
|
||||
.Pp
|
||||
As for the
|
||||
.Cm \&:S
|
||||
@ -1387,9 +1398,9 @@ and
|
||||
are subjected to variable expansion before being parsed as
|
||||
regular expressions.
|
||||
.It Cm \&:T
|
||||
Replaces each word in the variable with its last component.
|
||||
Replaces each word in the variable with its last path component.
|
||||
.It Cm \&:u
|
||||
Remove adjacent duplicate words (like
|
||||
Removes adjacent duplicate words (like
|
||||
.Xr uniq 1 ) .
|
||||
.Sm off
|
||||
.It Cm \&:\&? Ar true_string Cm \&: Ar false_string
|
||||
@ -1405,7 +1416,7 @@ 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:
|
||||
to determine if any words match "42" you need to use something like:
|
||||
.Dl ${"${NUMBERS:M42}" != \&"\&":?match:no} .
|
||||
.It Ar :old_string=new_string
|
||||
This is the
|
||||
@ -1449,7 +1460,7 @@ in either the
|
||||
or
|
||||
.Ar old_string ,
|
||||
only the first instance is treated specially (as the pattern character);
|
||||
all subsequent instances are treated as regular characters
|
||||
all subsequent instances are treated as regular characters.
|
||||
.Pp
|
||||
Variable expansion occurs in the normal fashion inside both
|
||||
.Ar old_string
|
||||
@ -1466,11 +1477,10 @@ 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
|
||||
loops, expansion occurs at the time of reference.
|
||||
Assigns
|
||||
.Ar temp
|
||||
to each word in the variable and evaluate
|
||||
to each word in the variable and evaluates
|
||||
.Ar string .
|
||||
The ODE convention is that
|
||||
.Ar temp
|
||||
@ -1481,7 +1491,7 @@ For example.
|
||||
However a single character variable is often more readable:
|
||||
.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
|
||||
.It Cm \&:_[=var]
|
||||
Save the current variable value in
|
||||
Saves the current variable value in
|
||||
.Ql $_
|
||||
or the named
|
||||
.Va var
|
||||
@ -1502,7 +1512,7 @@ is used to save the result of the
|
||||
modifier which is later referenced using the index values from
|
||||
.Ql :range .
|
||||
.It Cm \&:U Ns Ar newval
|
||||
If the variable is undefined
|
||||
If the variable is undefined,
|
||||
.Ar newval
|
||||
is the value.
|
||||
If the variable is defined, the existing value is returned.
|
||||
@ -1512,7 +1522,7 @@ It is handy for setting per-target CFLAGS for instance:
|
||||
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
|
||||
If the variable is defined,
|
||||
.Ar newval
|
||||
is the value.
|
||||
.It Cm \&:L
|
||||
@ -1641,7 +1651,7 @@ 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
|
||||
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
|
||||
@ -1687,7 +1697,7 @@ The possible conditionals are as follows:
|
||||
The message is printed along with the name of the makefile and line number,
|
||||
then
|
||||
.Nm
|
||||
will exit.
|
||||
will exit immediately.
|
||||
.It Ic .export Ar variable ...
|
||||
Export the specified global variable.
|
||||
If no variable list is provided, all globals are exported
|
||||
@ -1876,7 +1886,7 @@ 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
|
||||
variable is being compared against 0, or an empty string in the case
|
||||
of a string comparison.
|
||||
.Pp
|
||||
When
|
||||
@ -1917,7 +1927,7 @@ 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 Aq make-lines
|
||||
.It Ic \&.endfor
|
||||
.El
|
||||
.Pp
|
||||
@ -1929,7 +1939,7 @@ On each iteration of the loop, one word is taken and assigned to each
|
||||
in order, and these
|
||||
.Ic variables
|
||||
are substituted into the
|
||||
.Ic make-rules
|
||||
.Ic make-lines
|
||||
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
|
||||
|
464
make.c
464
make.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: make.c,v 1.99 2020/07/03 08:13:23 rillig Exp $ */
|
||||
/* $NetBSD: make.c,v 1.133 2020/08/30 14:11:42 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -69,14 +69,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: make.c,v 1.99 2020/07/03 08:13:23 rillig Exp $";
|
||||
static char rcsid[] = "$NetBSD: make.c,v 1.133 2020/08/30 14:11:42 rillig 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.99 2020/07/03 08:13:23 rillig Exp $");
|
||||
__RCSID("$NetBSD: make.c,v 1.133 2020/08/30 14:11:42 rillig Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@ -116,7 +116,7 @@ __RCSID("$NetBSD: make.c,v 1.99 2020/07/03 08:13:23 rillig Exp $");
|
||||
*/
|
||||
|
||||
#include "make.h"
|
||||
#include "hash.h"
|
||||
#include "enum.h"
|
||||
#include "dir.h"
|
||||
#include "job.h"
|
||||
|
||||
@ -151,6 +151,43 @@ make_abort(GNode *gn, int line)
|
||||
abort();
|
||||
}
|
||||
|
||||
ENUM_VALUE_RTTI_8(GNodeMade,
|
||||
UNMADE, DEFERRED, REQUESTED, BEINGMADE,
|
||||
MADE, UPTODATE, ERROR, ABORTED);
|
||||
|
||||
ENUM_FLAGS_RTTI_31(GNodeType,
|
||||
OP_DEPENDS, OP_FORCE, OP_DOUBLEDEP,
|
||||
/* OP_OPMASK is omitted since it combines other flags */
|
||||
OP_OPTIONAL, OP_USE, OP_EXEC, OP_IGNORE,
|
||||
OP_PRECIOUS, OP_SILENT, OP_MAKE, OP_JOIN,
|
||||
OP_MADE, OP_SPECIAL, OP_USEBEFORE, OP_INVISIBLE,
|
||||
OP_NOTMAIN, OP_PHONY, OP_NOPATH, OP_WAIT,
|
||||
OP_NOMETA, OP_META, OP_NOMETA_CMP, OP_SUBMAKE,
|
||||
OP_TRANSFORM, OP_MEMBER, OP_LIB, OP_ARCHV,
|
||||
OP_HAS_COMMANDS, OP_SAVE_CMDS, OP_DEPS_FOUND, OP_MARK);
|
||||
|
||||
ENUM_FLAGS_RTTI_10(GNodeFlags,
|
||||
REMAKE, CHILDMADE, FORCE, DONE_WAIT,
|
||||
DONE_ORDER, FROM_DEPEND, DONE_ALLSRC, CYCLE,
|
||||
DONECYCLE, INTERNAL);
|
||||
|
||||
void
|
||||
GNode_FprintDetails(FILE *f, const char *prefix, const GNode *gn,
|
||||
const char *suffix)
|
||||
{
|
||||
char type_buf[GNodeType_ToStringSize];
|
||||
char flags_buf[GNodeFlags_ToStringSize];
|
||||
|
||||
fprintf(f, "%smade %s, type %s, flags %s%s",
|
||||
prefix,
|
||||
Enum_ValueToString(gn->made, GNodeMade_ToStringSpecs),
|
||||
Enum_FlagsToString(type_buf, sizeof type_buf,
|
||||
gn->type, GNodeType_ToStringSpecs),
|
||||
Enum_FlagsToString(flags_buf, sizeof flags_buf,
|
||||
gn->flags, GNodeFlags_ToStringSpecs),
|
||||
suffix);
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Make_TimeStamp --
|
||||
@ -189,7 +226,7 @@ MakeTimeStamp(void *pgn, void *cgn)
|
||||
{
|
||||
return Make_TimeStamp((GNode *)pgn, (GNode *)cgn);
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Make_OODate --
|
||||
@ -350,7 +387,7 @@ Make_OODate(GNode *gn)
|
||||
|
||||
return oodate;
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* MakeAddChild --
|
||||
@ -378,11 +415,11 @@ MakeAddChild(void *gnp, void *lp)
|
||||
if (DEBUG(MAKE))
|
||||
fprintf(debug_file, "MakeAddChild: need to examine %s%s\n",
|
||||
gn->name, gn->cohort_num);
|
||||
(void)Lst_EnQueue(l, gn);
|
||||
Lst_Enqueue(l, gn);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* MakeFindChild --
|
||||
@ -412,31 +449,18 @@ MakeFindChild(void *gnp, void *pgnp)
|
||||
|
||||
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.
|
||||
|
||||
/* Called by Make_Run and SuffApplyTransform on the downward pass to handle
|
||||
* .USE and transformation nodes, by copying the child 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.
|
||||
* 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)
|
||||
@ -452,52 +476,42 @@ Make_HandleUse(GNode *cgn, GNode *pgn)
|
||||
|
||||
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);
|
||||
/* .USEBEFORE */
|
||||
Lst_PrependAll(pgn->commands, cgn->commands);
|
||||
} else {
|
||||
/*
|
||||
* .USE or target has no commands --
|
||||
* append the child's commands to the parent.
|
||||
*/
|
||||
(void)Lst_Concat(pgn->commands, cgn->commands, LST_CONCNEW);
|
||||
/* .USE, or target has no commands */
|
||||
Lst_AppendAll(pgn->commands, cgn->commands);
|
||||
}
|
||||
}
|
||||
|
||||
if (Lst_Open(cgn->children) == SUCCESS) {
|
||||
while ((ln = Lst_Next(cgn->children)) != NULL) {
|
||||
GNode *tgn, *gn = (GNode *)Lst_Datum(ln);
|
||||
Lst_Open(cgn->children);
|
||||
while ((ln = Lst_Next(cgn->children)) != NULL) {
|
||||
GNode *gn = LstNode_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 {
|
||||
free(gn->name);
|
||||
}
|
||||
gn->name = Var_Subst(NULL, gn->uname, pgn, VARF_WANTRES);
|
||||
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;
|
||||
/*
|
||||
* 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 {
|
||||
free(gn->name);
|
||||
}
|
||||
Lst_Close(cgn->children);
|
||||
gn->name = Var_Subst(gn->uname, pgn, VARE_WANTRES);
|
||||
if (gn->uname && strcmp(gn->name, gn->uname) != 0) {
|
||||
/* See if we have a target for this node. */
|
||||
GNode *tgn = Targ_FindNode(gn->name, TARG_NOCREATE);
|
||||
if (tgn != NULL)
|
||||
gn = tgn;
|
||||
}
|
||||
|
||||
Lst_Append(pgn->children, gn);
|
||||
Lst_Append(gn->parents, pgn);
|
||||
pgn->unmade += 1;
|
||||
}
|
||||
Lst_Close(cgn->children);
|
||||
|
||||
pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_USEBEFORE|OP_TRANSFORM);
|
||||
}
|
||||
@ -547,7 +561,7 @@ MakeHandleUse(void *cgnp, void *pgnp)
|
||||
* 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) {
|
||||
if ((ln = Lst_FindDatum(pgn->children, cgn)) != NULL) {
|
||||
Lst_Remove(pgn->children, ln);
|
||||
pgn->unmade--;
|
||||
}
|
||||
@ -680,8 +694,8 @@ void
|
||||
Make_Update(GNode *cgn)
|
||||
{
|
||||
GNode *pgn; /* the parent node */
|
||||
char *cname; /* the child's name */
|
||||
LstNode ln; /* Element in parents and iParents lists */
|
||||
const char *cname; /* the child's name */
|
||||
LstNode ln; /* Element in parents and implicitParents lists */
|
||||
time_t mtime = -1;
|
||||
char *p1;
|
||||
Lst parents;
|
||||
@ -691,7 +705,7 @@ Make_Update(GNode *cgn)
|
||||
checked++;
|
||||
|
||||
cname = Var_Value(TARGET, cgn, &p1);
|
||||
free(p1);
|
||||
bmake_free(p1);
|
||||
|
||||
if (DEBUG(MAKE))
|
||||
fprintf(debug_file, "Make_Update: %s%s\n", cgn->name, cgn->cohort_num);
|
||||
@ -724,123 +738,123 @@ Make_Update(GNode *cgn)
|
||||
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);
|
||||
Lst_Open(parents);
|
||||
while ((ln = Lst_Next(parents)) != NULL) {
|
||||
pgn = LstNode_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, "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);
|
||||
fprintf(debug_file, "- not needed\n");
|
||||
continue;
|
||||
}
|
||||
Lst_Close(parents);
|
||||
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;
|
||||
}
|
||||
assert(pgn->order_pred != NULL);
|
||||
if (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;
|
||||
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);
|
||||
Lst_Open(cgn->implicitParents);
|
||||
{
|
||||
const char *cpref = Var_Value(PREFIX, cgn, &p1);
|
||||
|
||||
while ((ln = Lst_Next(cgn->iParents)) != NULL) {
|
||||
pgn = (GNode *)Lst_Datum(ln);
|
||||
while ((ln = Lst_Next(cgn->implicitParents)) != NULL) {
|
||||
pgn = LstNode_Datum(ln);
|
||||
if (pgn->flags & REMAKE) {
|
||||
Var_Set(IMPSRC, cname, pgn);
|
||||
if (cpref != NULL)
|
||||
Var_Set(PREFIX, cpref, pgn);
|
||||
}
|
||||
}
|
||||
free(p1);
|
||||
Lst_Close(cgn->iParents);
|
||||
bmake_free(p1);
|
||||
Lst_Close(cgn->implicitParents);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* MakeAddAllSrc --
|
||||
@ -890,7 +904,7 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
|
||||
cgn->type |= OP_MARK;
|
||||
|
||||
if ((cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE|OP_INVISIBLE)) == 0) {
|
||||
char *child, *allsrc;
|
||||
const char *child, *allsrc;
|
||||
char *p1 = NULL, *p2 = NULL;
|
||||
|
||||
if (cgn->type & OP_ARCHV)
|
||||
@ -904,7 +918,7 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
|
||||
}
|
||||
if (allsrc != NULL)
|
||||
Var_Append(ALLSRC, allsrc, pgn);
|
||||
free(p2);
|
||||
bmake_free(p2);
|
||||
if (pgn->type & OP_JOIN) {
|
||||
if (cgn->made == MADE) {
|
||||
Var_Append(OODATE, child, pgn);
|
||||
@ -930,11 +944,11 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
|
||||
*/
|
||||
Var_Append(OODATE, child, pgn);
|
||||
}
|
||||
free(p1);
|
||||
bmake_free(p1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Make_DoAllVar --
|
||||
@ -976,11 +990,11 @@ Make_DoAllVar(GNode *gn)
|
||||
if (gn->type & OP_JOIN) {
|
||||
char *p1;
|
||||
Var_Set(TARGET, Var_Value(ALLSRC, gn, &p1), gn);
|
||||
free(p1);
|
||||
bmake_free(p1);
|
||||
}
|
||||
gn->flags |= DONE_ALLSRC;
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* MakeStartJobs --
|
||||
@ -1023,7 +1037,8 @@ MakeBuildChild(void *v_cn, void *toBeMade_next)
|
||||
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)) {
|
||||
assert(cn->order_pred);
|
||||
if (Lst_ForEach(cn->order_pred, MakeCheckOrder, 0)) {
|
||||
/* Can't build this (or anything else in this child list) yet */
|
||||
cn->made = DEFERRED;
|
||||
return 0; /* but keep looking */
|
||||
@ -1035,7 +1050,7 @@ MakeBuildChild(void *v_cn, void *toBeMade_next)
|
||||
|
||||
cn->made = REQUESTED;
|
||||
if (toBeMade_next == NULL)
|
||||
Lst_AtEnd(toBeMade, cn);
|
||||
Lst_Append(toBeMade, cn);
|
||||
else
|
||||
Lst_InsertBefore(toBeMade, toBeMade_next, cn);
|
||||
|
||||
@ -1072,13 +1087,13 @@ MakeStartJobs(void)
|
||||
GNode *gn;
|
||||
int have_token = 0;
|
||||
|
||||
while (!Lst_IsEmpty (toBeMade)) {
|
||||
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);
|
||||
gn = Lst_Dequeue(toBeMade);
|
||||
if (DEBUG(MAKE))
|
||||
fprintf(debug_file, "Examining %s%s...\n",
|
||||
gn->name, gn->cohort_num);
|
||||
@ -1147,7 +1162,7 @@ MakeStartJobs(void)
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* MakePrintStatus --
|
||||
@ -1179,15 +1194,15 @@ MakePrintStatusOrder(void *ognp, void *gnp)
|
||||
/* 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);
|
||||
printf(" `%s%s' has .ORDER dependency against %s%s ",
|
||||
gn->name, gn->cohort_num, ogn->name, ogn->cohort_num);
|
||||
GNode_FprintDetails(stdout, "(", ogn, ")\n");
|
||||
|
||||
if (DEBUG(MAKE) && debug_file != stdout) {
|
||||
fprintf(debug_file, " `%s%s' has .ORDER dependency against %s%s ",
|
||||
gn->name, gn->cohort_num, ogn->name, ogn->cohort_num);
|
||||
GNode_FprintDetails(debug_file, "(", ogn, ")\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1214,12 +1229,13 @@ MakePrintStatus(void *gnp, void *v_errors)
|
||||
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);
|
||||
printf("`%s%s' was not built", gn->name, gn->cohort_num);
|
||||
GNode_FprintDetails(stdout, " (", gn, ")!\n");
|
||||
if (DEBUG(MAKE) && debug_file != stdout) {
|
||||
fprintf(debug_file, "`%s%s' was not built",
|
||||
gn->name, gn->cohort_num);
|
||||
GNode_FprintDetails(debug_file, " (", gn, ")!\n");
|
||||
}
|
||||
/* Most likely problem is actually caused by .ORDER */
|
||||
Lst_ForEach(gn->order_pred, MakePrintStatusOrder, gn);
|
||||
break;
|
||||
@ -1262,7 +1278,7 @@ MakePrintStatus(void *gnp, void *v_errors)
|
||||
Lst_ForEach(gn->children, MakePrintStatus, errors);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
@ -1281,7 +1297,7 @@ Make_ExpandUse(Lst targs)
|
||||
GNode *gn; /* a temporary pointer */
|
||||
Lst examine; /* List of targets to examine */
|
||||
|
||||
examine = Lst_Duplicate(targs, NULL);
|
||||
examine = Lst_Copy(targs, NULL);
|
||||
|
||||
/*
|
||||
* Make an initial downward pass over the graph, marking nodes to be made
|
||||
@ -1291,8 +1307,8 @@ Make_ExpandUse(Lst targs)
|
||||
* 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);
|
||||
while (!Lst_IsEmpty(examine)) {
|
||||
gn = Lst_Dequeue(examine);
|
||||
|
||||
if (gn->flags & REMAKE)
|
||||
/* We've looked at this one already */
|
||||
@ -1302,13 +1318,8 @@ Make_ExpandUse(Lst targs)
|
||||
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;
|
||||
}
|
||||
if (gn->type & OP_DOUBLEDEP)
|
||||
Lst_PrependAll(examine, gn->cohorts);
|
||||
|
||||
/*
|
||||
* Apply any .USE rules before looking for implicit dependencies
|
||||
@ -1349,7 +1360,7 @@ Make_ExpandUse(Lst targs)
|
||||
Lst_ForEach(gn->children, MakeAddChild, examine);
|
||||
}
|
||||
|
||||
Lst_Destroy(examine, NULL);
|
||||
Lst_Free(examine);
|
||||
}
|
||||
|
||||
/*-
|
||||
@ -1369,8 +1380,8 @@ link_parent(void *cnp, void *pnp)
|
||||
GNode *cn = cnp;
|
||||
GNode *pn = pnp;
|
||||
|
||||
Lst_AtEnd(pn->children, cn);
|
||||
Lst_AtEnd(cn->parents, pn);
|
||||
Lst_Append(pn->children, cn);
|
||||
Lst_Append(cn->parents, pn);
|
||||
pn->unmade++;
|
||||
return 0;
|
||||
}
|
||||
@ -1392,9 +1403,9 @@ add_wait_dep(void *v_cn, void *v_wn)
|
||||
fprintf(debug_file, ".WAIT: add dependency %s%s -> %s\n",
|
||||
cn->name, cn->cohort_num, wn->name);
|
||||
|
||||
Lst_AtEnd(wn->children, cn);
|
||||
Lst_Append(wn->children, cn);
|
||||
wn->unmade++;
|
||||
Lst_AtEnd(cn->parents, wn);
|
||||
Lst_Append(cn->parents, wn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1417,18 +1428,18 @@ Make_ProcessWait(Lst targs)
|
||||
pgn->flags = REMAKE;
|
||||
pgn->type = OP_PHONY | OP_DEPENDS;
|
||||
/* Get it displayed in the diag dumps */
|
||||
Lst_AtFront(Targ_List(), pgn);
|
||||
Lst_Prepend(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);
|
||||
examine = Lst_Init();
|
||||
Lst_Append(examine, pgn);
|
||||
|
||||
while (!Lst_IsEmpty (examine)) {
|
||||
pgn = Lst_DeQueue(examine);
|
||||
while (!Lst_IsEmpty(examine)) {
|
||||
pgn = Lst_Dequeue(examine);
|
||||
|
||||
/* We only want to process each child-list once */
|
||||
if (pgn->flags & DONE_WAIT)
|
||||
@ -1437,30 +1448,25 @@ Make_ProcessWait(Lst targs)
|
||||
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;
|
||||
}
|
||||
if (pgn->type & OP_DOUBLEDEP)
|
||||
Lst_PrependAll(examine, pgn->cohorts);
|
||||
|
||||
owln = Lst_First(pgn->children);
|
||||
Lst_Open(pgn->children);
|
||||
for (; (ln = Lst_Next(pgn->children)) != NULL; ) {
|
||||
cgn = Lst_Datum(ln);
|
||||
cgn = LstNode_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_Append(examine, cgn);
|
||||
}
|
||||
}
|
||||
Lst_Close(pgn->children);
|
||||
}
|
||||
|
||||
Lst_Destroy(examine, NULL);
|
||||
Lst_Free(examine);
|
||||
}
|
||||
|
||||
/*-
|
||||
@ -1493,7 +1499,7 @@ Make_Run(Lst targs)
|
||||
int errors; /* Number of errors the Job module reports */
|
||||
|
||||
/* Start trying to make the current targets... */
|
||||
toBeMade = Lst_Init(FALSE);
|
||||
toBeMade = Lst_Init();
|
||||
|
||||
Make_ExpandUse(targs);
|
||||
Make_ProcessWait(targs);
|
||||
|
411
make.h
411
make.h
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: make.h,v 1.109 2020/07/02 15:14:38 rillig Exp $ */
|
||||
/* $NetBSD: make.h,v 1.137 2020/09/02 23:42:58 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@ -77,8 +77,8 @@
|
||||
* The global definitions for pmake
|
||||
*/
|
||||
|
||||
#ifndef _MAKE_H_
|
||||
#define _MAKE_H_
|
||||
#ifndef MAKE_MAKE_H
|
||||
#define MAKE_MAKE_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
@ -86,7 +86,9 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
@ -132,8 +134,34 @@
|
||||
#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) /* delete */
|
||||
#endif
|
||||
|
||||
#include "sprite.h"
|
||||
/*
|
||||
* A boolean type is defined as an integer, not an enum, for historic reasons.
|
||||
* The only allowed values are the constants TRUE and FALSE (1 and 0).
|
||||
*/
|
||||
|
||||
#ifdef USE_DOUBLE_BOOLEAN
|
||||
/* During development, to find type mismatches in function declarations. */
|
||||
typedef double Boolean;
|
||||
#elif defined(USE_UCHAR_BOOLEAN)
|
||||
/* During development, to find code that depends on the exact value of TRUE or
|
||||
* that stores other values in Boolean variables. */
|
||||
typedef unsigned char Boolean;
|
||||
#define TRUE ((unsigned char)0xFF)
|
||||
#define FALSE ((unsigned char)0x00)
|
||||
#elif defined(USE_ENUM_BOOLEAN)
|
||||
typedef enum { FALSE, TRUE} Boolean;
|
||||
#else
|
||||
typedef int Boolean;
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif /* TRUE */
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif /* FALSE */
|
||||
|
||||
#include "lst.h"
|
||||
#include "enum.h"
|
||||
#include "hash.h"
|
||||
#include "make-conf.h"
|
||||
#include "buf.h"
|
||||
@ -150,163 +178,190 @@
|
||||
#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) */
|
||||
typedef enum {
|
||||
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). */
|
||||
} GNodeMade;
|
||||
|
||||
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 */
|
||||
#define INTERNAL 0x4000 /* Internal use only */
|
||||
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
|
||||
/* 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)
|
||||
* 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 left-hand side of an operator, though it
|
||||
* may have been on the right-hand side... */
|
||||
typedef enum {
|
||||
/* Execution of commands depends on children (:) */
|
||||
OP_DEPENDS = 1 << 0,
|
||||
/* Always execute commands (!) */
|
||||
OP_FORCE = 1 << 1,
|
||||
/* Execution of commands depends on children per line (::) */
|
||||
OP_DOUBLEDEP = 1 << 2,
|
||||
|
||||
#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 */
|
||||
#define OP_SUBMAKE 0x00400000 /* Possibly a submake node */
|
||||
/* 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 */
|
||||
OP_OPMASK = OP_DEPENDS|OP_FORCE|OP_DOUBLEDEP,
|
||||
|
||||
/* Don't care if the target doesn't exist and can't be created */
|
||||
OP_OPTIONAL = 1 << 3,
|
||||
/* Use associated commands for parents */
|
||||
OP_USE = 1 << 4,
|
||||
/* Target is never out of date, but always execute commands anyway.
|
||||
* Its time doesn't matter, so it has none...sort of */
|
||||
OP_EXEC = 1 << 5,
|
||||
/* Ignore errors when creating the node */
|
||||
OP_IGNORE = 1 << 6,
|
||||
/* Don't remove the target when interrupted */
|
||||
OP_PRECIOUS = 1 << 7,
|
||||
/* Don't echo commands when executed */
|
||||
OP_SILENT = 1 << 8,
|
||||
/* 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 */
|
||||
OP_MAKE = 1 << 9,
|
||||
/* Target is out-of-date only if any of its children was out-of-date */
|
||||
OP_JOIN = 1 << 10,
|
||||
/* Assume the children of the node have been already made */
|
||||
OP_MADE = 1 << 11,
|
||||
/* Special .BEGIN, .END, .INTERRUPT */
|
||||
OP_SPECIAL = 1 << 12,
|
||||
/* Like .USE, only prepend commands */
|
||||
OP_USEBEFORE = 1 << 13,
|
||||
/* The node is invisible to its parents. I.e. it doesn't show up in the
|
||||
* parents' local variables. */
|
||||
OP_INVISIBLE = 1 << 14,
|
||||
/* The node is exempt from normal 'main target' processing in parse.c */
|
||||
OP_NOTMAIN = 1 << 15,
|
||||
/* Not a file target; run always */
|
||||
OP_PHONY = 1 << 16,
|
||||
/* Don't search for file in the path */
|
||||
OP_NOPATH = 1 << 17,
|
||||
/* .WAIT phony node */
|
||||
OP_WAIT = 1 << 18,
|
||||
/* .NOMETA do not create a .meta file */
|
||||
OP_NOMETA = 1 << 19,
|
||||
/* .META we _do_ want a .meta file */
|
||||
OP_META = 1 << 20,
|
||||
/* Do not compare commands in .meta file */
|
||||
OP_NOMETA_CMP = 1 << 21,
|
||||
/* Possibly a submake node */
|
||||
OP_SUBMAKE = 1 << 22,
|
||||
|
||||
/* Attributes applied by PMake */
|
||||
|
||||
/* The node is a transformation rule */
|
||||
OP_TRANSFORM = 1 << 31,
|
||||
/* Target is a member of an archive */
|
||||
OP_MEMBER = 1 << 30,
|
||||
/* Target is a library */
|
||||
OP_LIB = 1 << 29,
|
||||
/* Target is an archive construct */
|
||||
OP_ARCHV = 1 << 28,
|
||||
/* Target has all the commands it should. Used when parsing to catch
|
||||
* multiple commands for a target. */
|
||||
OP_HAS_COMMANDS = 1 << 27,
|
||||
/* Saving commands on .END (Compat) */
|
||||
OP_SAVE_CMDS = 1 << 26,
|
||||
/* Already processed by Suff_FindDeps */
|
||||
OP_DEPS_FOUND = 1 << 25,
|
||||
/* Node found while expanding .ALLSRC */
|
||||
OP_MARK = 1 << 24
|
||||
} GNodeType;
|
||||
|
||||
typedef enum {
|
||||
REMAKE = 0x0001, /* this target needs to be (re)made */
|
||||
CHILDMADE = 0x0002, /* children of this target were made */
|
||||
FORCE = 0x0004, /* children don't exist, and we pretend made */
|
||||
DONE_WAIT = 0x0008, /* Set by Make_ProcessWait() */
|
||||
DONE_ORDER = 0x0010, /* Build requested by .ORDER processing */
|
||||
FROM_DEPEND = 0x0020, /* Node created from .depend */
|
||||
DONE_ALLSRC = 0x0040, /* We do it once only */
|
||||
CYCLE = 0x1000, /* Used by MakePrintStatus */
|
||||
DONECYCLE = 0x2000, /* Used by MakePrintStatus */
|
||||
INTERNAL = 0x4000 /* Internal use only */
|
||||
} GNodeFlags;
|
||||
|
||||
/* A graph node represents a target that can possibly be made, including its
|
||||
* relation to other targets and a lot of other details. */
|
||||
typedef struct GNode {
|
||||
/* The target's name, such as "clean" or "make.c" */
|
||||
char *name;
|
||||
/* The unexpanded name of a .USE node */
|
||||
char *uname;
|
||||
/* The full pathname of the file belonging to the target.
|
||||
* XXX: What about .PHONY targets? These don't have an associated path. */
|
||||
char *path;
|
||||
|
||||
/* The type of operator used to define the sources (see the OP flags below).
|
||||
* XXX: This looks like a wild mixture of type and flags. */
|
||||
GNodeType type;
|
||||
/* whether it is involved in this invocation of make */
|
||||
GNodeFlags flags;
|
||||
|
||||
/* The state of processing on this node */
|
||||
GNodeMade made;
|
||||
int unmade; /* The number of unmade children */
|
||||
|
||||
time_t mtime; /* Its modification time */
|
||||
struct GNode *cmgn; /* The youngest child */
|
||||
|
||||
/* The GNodes for which this node is an implied source. May be empty.
|
||||
* For example, when there is an inference rule for .c.o, the node for
|
||||
* file.c has the node for file.o in this list. */
|
||||
Lst implicitParents;
|
||||
|
||||
/* Other nodes of the same name for the :: operator. */
|
||||
Lst cohorts;
|
||||
|
||||
/* The nodes that depend on this one, or in other words, the nodes for
|
||||
* which this is a source. */
|
||||
Lst parents;
|
||||
/* The nodes on which this one depends. */
|
||||
Lst children;
|
||||
|
||||
/* .ORDER nodes we need made. The nodes that must be made (if they're
|
||||
* made) before this node can be made, but that do not enter into the
|
||||
* datedness of this node. */
|
||||
Lst order_pred;
|
||||
/* .ORDER nodes who need us. The nodes that must be made (if they're made
|
||||
* at all) after this node is made, but that do not depend on this node,
|
||||
* in the normal sense. */
|
||||
Lst order_succ;
|
||||
|
||||
/* #n for this cohort */
|
||||
char cohort_num[8];
|
||||
/* The number of unmade instances on the cohorts list */
|
||||
int unmade_cohorts;
|
||||
/* Pointer to the first instance of a '::' node; only set when on a
|
||||
* cohorts list */
|
||||
struct GNode *centurion;
|
||||
|
||||
/* Last time (sequence number) we tried to make this node */
|
||||
unsigned int checked;
|
||||
|
||||
/* The "local" variables that are specific to this target and this target
|
||||
* only, such as $@, $<, $?. */
|
||||
Hash_Table context;
|
||||
|
||||
/* The commands to be given to a shell to create this target. */
|
||||
Lst commands;
|
||||
|
||||
/* Suffix for the node (determined by Suff_FindDeps and opaque to everyone
|
||||
* but the Suff module) */
|
||||
struct Suff *suffix;
|
||||
|
||||
/* filename where the GNode got defined */
|
||||
const char *fname;
|
||||
/* line number where the GNode got defined */
|
||||
int lineno;
|
||||
} GNode;
|
||||
|
||||
#define NoExecute(gn) ((gn->type & OP_MAKE) ? noRecursiveExecute : noExecute)
|
||||
/*
|
||||
@ -329,18 +384,6 @@ typedef struct GNode {
|
||||
#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
|
||||
@ -353,9 +396,11 @@ typedef struct GNode {
|
||||
/*
|
||||
* 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 */
|
||||
typedef enum {
|
||||
COND_PARSE, /* Parse the next lines */
|
||||
COND_SKIP, /* Skip the next lines */
|
||||
COND_INVALID /* Not a conditional statement */
|
||||
} CondEvalResult;
|
||||
|
||||
/*
|
||||
* Definitions for the "local" variables. Used only for clarity.
|
||||
@ -403,7 +448,6 @@ 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 */
|
||||
@ -420,7 +464,6 @@ extern GNode *VAR_INTERNAL; /* Variables defined internally by make
|
||||
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
|
||||
@ -439,6 +482,8 @@ extern char *progname; /* The program name */
|
||||
extern char *makeDependfile; /* .depend */
|
||||
extern char **savedEnv; /* if we replaced environ this will be non-NULL */
|
||||
|
||||
extern int makelevel;
|
||||
|
||||
/*
|
||||
* We cannot vfork() in a child of vfork().
|
||||
* Most systems do not enforce this but some do.
|
||||
@ -464,7 +509,7 @@ extern pid_t myPid;
|
||||
* There is one bit per module. It is up to the module what debug
|
||||
* information to print.
|
||||
*/
|
||||
extern FILE *debug_file; /* Output written here - default stdout */
|
||||
extern FILE *debug_file; /* Output is written here - default stderr */
|
||||
extern int debug;
|
||||
#define DEBUG_ARCH 0x00001
|
||||
#define DEBUG_COND 0x00002
|
||||
@ -481,12 +526,15 @@ extern int debug;
|
||||
#define DEBUG_ERROR 0x01000
|
||||
#define DEBUG_LOUD 0x02000
|
||||
#define DEBUG_META 0x04000
|
||||
#define DEBUG_HASH 0x08000
|
||||
|
||||
#define DEBUG_GRAPH3 0x10000
|
||||
#define DEBUG_SCRIPT 0x20000
|
||||
#define DEBUG_PARSE 0x40000
|
||||
#define DEBUG_CWD 0x80000
|
||||
|
||||
#define DEBUG_LINT 0x100000
|
||||
|
||||
#define CONCAT(a,b) a##b
|
||||
|
||||
#define DEBUG(module) (debug & CONCAT(DEBUG_,module))
|
||||
@ -501,16 +549,13 @@ 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 **);
|
||||
int dieQuietly(GNode *, int);
|
||||
void PrintOnError(GNode *, const char *);
|
||||
void Main_ExportMAKEFLAGS(Boolean);
|
||||
Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
|
||||
int mkTempFile(const char *, char **);
|
||||
int str2Lst_Append(Lst, char *, const char *);
|
||||
int cached_lstat(const char *, void *);
|
||||
int cached_stat(const char *, void *);
|
||||
void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *);
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define UNCONST(ptr) ({ \
|
||||
@ -524,10 +569,10 @@ int cached_stat(const char *, void *);
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a < b) ? a : b)
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a > b) ? a : b)
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/* At least GNU/Hurd systems lack hardcoded MAXPATHLEN/PATH_MAX */
|
||||
@ -547,4 +592,4 @@ int cached_stat(const char *, void *);
|
||||
#define KILLPG(pid, sig) killpg((pid), (sig))
|
||||
#endif
|
||||
|
||||
#endif /* _MAKE_H_ */
|
||||
#endif /* MAKE_MAKE_H */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: make_malloc.c,v 1.12 2020/07/03 08:02:55 rillig Exp $ */
|
||||
/* $NetBSD: make_malloc.c,v 1.18 2020/09/02 06:10:44 rillig Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009 The NetBSD Foundation, Inc.
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef MAKE_NATIVE
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: make_malloc.c,v 1.12 2020/07/03 08:02:55 rillig Exp $");
|
||||
__RCSID("$NetBSD: make_malloc.c,v 1.18 2020/09/02 06:10:44 rillig Exp $");
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@ -41,10 +41,7 @@ __RCSID("$NetBSD: make_malloc.c,v 1.12 2020/07/03 08:02:55 rillig Exp $");
|
||||
#ifndef USE_EMALLOC
|
||||
static MAKE_ATTR_DEAD void enomem(void);
|
||||
|
||||
/*
|
||||
* enomem --
|
||||
* die when out of memory.
|
||||
*/
|
||||
/* die when out of memory. */
|
||||
static MAKE_ATTR_DEAD void
|
||||
enomem(void)
|
||||
{
|
||||
@ -52,10 +49,7 @@ enomem(void)
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/*
|
||||
* bmake_malloc --
|
||||
* malloc, but die on error.
|
||||
*/
|
||||
/* malloc, but die on error. */
|
||||
void *
|
||||
bmake_malloc(size_t len)
|
||||
{
|
||||
@ -66,10 +60,7 @@ bmake_malloc(size_t len)
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* bmake_strdup --
|
||||
* strdup, but die on error.
|
||||
*/
|
||||
/* strdup, but die on error. */
|
||||
char *
|
||||
bmake_strdup(const char *str)
|
||||
{
|
||||
@ -82,33 +73,17 @@ bmake_strdup(const char *str)
|
||||
return memcpy(p, str, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* bmake_strndup --
|
||||
* strndup, but die on error.
|
||||
*/
|
||||
/* Allocate a string starting from str with exactly len characters. */
|
||||
char *
|
||||
bmake_strndup(const char *str, size_t max_len)
|
||||
bmake_strldup(const char *str, size_t 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);
|
||||
char *p = bmake_malloc(len + 1);
|
||||
memcpy(p, str, len);
|
||||
p[len] = '\0';
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* bmake_realloc --
|
||||
* realloc, but die on error.
|
||||
*/
|
||||
/* realloc, but die on error. */
|
||||
void *
|
||||
bmake_realloc(void *ptr, size_t size)
|
||||
{
|
||||
@ -117,3 +92,10 @@ bmake_realloc(void *ptr, size_t size)
|
||||
return ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate a string from start up to but excluding end. */
|
||||
char *
|
||||
bmake_strsedup(const char *start, const char *end)
|
||||
{
|
||||
return bmake_strldup(start, (size_t)(end - start));
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: make_malloc.h,v 1.4 2009/01/24 14:43:29 dsl Exp $ */
|
||||
/* $NetBSD: make_malloc.h,v 1.10 2020/08/29 16:47:45 rillig Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009 The NetBSD Foundation, Inc.
|
||||
@ -30,12 +30,25 @@
|
||||
void *bmake_malloc(size_t);
|
||||
void *bmake_realloc(void *, size_t);
|
||||
char *bmake_strdup(const char *);
|
||||
char *bmake_strndup(const char *, size_t);
|
||||
char *bmake_strldup(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)
|
||||
#define bmake_strldup(x,y) estrndup(x,y)
|
||||
#endif
|
||||
char *bmake_strsedup(const char *, const char *);
|
||||
|
||||
/* Thin wrapper around free(3) to avoid the extra function call in case
|
||||
* p is NULL, which on x86_64 costs about 12 machine instructions.
|
||||
* Other platforms are similarly affected.
|
||||
*
|
||||
* The case of a NULL pointer happens especially often after Var_Value,
|
||||
* since only environment variables need to be freed, but not others. */
|
||||
static inline void MAKE_ATTR_UNUSED
|
||||
bmake_free(void *p)
|
||||
{
|
||||
if (p != NULL)
|
||||
free(p);
|
||||
}
|
||||
|
151
meta.c
151
meta.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: meta.c,v 1.86 2020/07/11 00:39:53 sjg Exp $ */
|
||||
/* $NetBSD: meta.c,v 1.113 2020/09/02 04:08:54 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Implement 'meta' mode.
|
||||
@ -47,6 +47,7 @@ char * dirname(char *);
|
||||
#endif
|
||||
|
||||
#include "make.h"
|
||||
#include "dir.h"
|
||||
#include "job.h"
|
||||
|
||||
#ifdef USE_FILEMON
|
||||
@ -318,7 +319,7 @@ meta_name(char *mname, size_t mnamelen,
|
||||
static int
|
||||
is_submake(void *cmdp, void *gnp)
|
||||
{
|
||||
static char *p_make = NULL;
|
||||
static const char *p_make = NULL;
|
||||
static int p_len;
|
||||
char *cmd = cmdp;
|
||||
GNode *gn = gnp;
|
||||
@ -333,7 +334,7 @@ is_submake(void *cmdp, void *gnp)
|
||||
}
|
||||
cp = strchr(cmd, '$');
|
||||
if ((cp)) {
|
||||
mp = Var_Subst(NULL, cmd, gn, VARF_WANTRES);
|
||||
mp = Var_Subst(cmd, gn, VARE_WANTRES);
|
||||
cmd = mp;
|
||||
}
|
||||
cp2 = strstr(cmd, p_make);
|
||||
@ -372,13 +373,13 @@ printCMD(void *cmdp, void *mfpp)
|
||||
{
|
||||
meta_file_t *mfp = mfpp;
|
||||
char *cmd = cmdp;
|
||||
char *cp = NULL;
|
||||
char *cmd_freeIt = NULL;
|
||||
|
||||
if (strchr(cmd, '$')) {
|
||||
cmd = cp = Var_Subst(NULL, cmd, mfp->gn, VARF_WANTRES);
|
||||
cmd = cmd_freeIt = Var_Subst(cmd, mfp->gn, VARE_WANTRES);
|
||||
}
|
||||
fprintf(mfp->fp, "CMD %s\n", cmd);
|
||||
free(cp);
|
||||
free(cmd_freeIt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -403,7 +404,7 @@ static Boolean
|
||||
meta_needed(GNode *gn, const char *dname,
|
||||
char *objdir, int verbose)
|
||||
{
|
||||
struct stat fs;
|
||||
struct make_stat mst;
|
||||
|
||||
if (verbose)
|
||||
verbose = DEBUG(META);
|
||||
@ -437,7 +438,7 @@ meta_needed(GNode *gn, const char *dname,
|
||||
}
|
||||
|
||||
/* The object directory may not exist. Check it.. */
|
||||
if (cached_stat(dname, &fs) != 0) {
|
||||
if (cached_stat(dname, &mst) != 0) {
|
||||
if (verbose)
|
||||
fprintf(debug_file, "Skipping meta for %s: no .OBJDIR\n",
|
||||
gn->name);
|
||||
@ -488,7 +489,7 @@ meta_create(BuildMon *pbm, GNode *gn)
|
||||
char *mp;
|
||||
|
||||
/* Describe the target we are building */
|
||||
mp = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", gn, VARF_WANTRES);
|
||||
mp = Var_Subst("${" MAKE_META_PREFIX "}", gn, VARE_WANTRES);
|
||||
if (*mp)
|
||||
fprintf(stdout, "%s\n", mp);
|
||||
free(mp);
|
||||
@ -546,7 +547,7 @@ meta_create(BuildMon *pbm, GNode *gn)
|
||||
}
|
||||
out:
|
||||
for (i--; i >= 0; i--) {
|
||||
free(p[i]);
|
||||
bmake_free(p[i]);
|
||||
}
|
||||
|
||||
return mf.fp;
|
||||
@ -629,24 +630,19 @@ meta_mode_init(const char *make_mode)
|
||||
/*
|
||||
* We consider ourselves master of all within ${.MAKE.META.BAILIWICK}
|
||||
*/
|
||||
metaBailiwick = Lst_Init(FALSE);
|
||||
metaBailiwickStr = Var_Subst(NULL, "${.MAKE.META.BAILIWICK:O:u:tA}",
|
||||
VAR_GLOBAL, VARF_WANTRES);
|
||||
if (metaBailiwickStr) {
|
||||
str2Lst_Append(metaBailiwick, metaBailiwickStr, NULL);
|
||||
}
|
||||
metaBailiwick = Lst_Init();
|
||||
metaBailiwickStr = Var_Subst("${.MAKE.META.BAILIWICK:O:u:tA}",
|
||||
VAR_GLOBAL, VARE_WANTRES);
|
||||
str2Lst_Append(metaBailiwick, metaBailiwickStr, NULL);
|
||||
/*
|
||||
* We ignore any paths that start with ${.MAKE.META.IGNORE_PATHS}
|
||||
*/
|
||||
metaIgnorePaths = Lst_Init(FALSE);
|
||||
metaIgnorePaths = Lst_Init();
|
||||
Var_Append(MAKE_META_IGNORE_PATHS,
|
||||
"/dev /etc /proc /tmp /var/run /var/tmp ${TMPDIR}", VAR_GLOBAL);
|
||||
metaIgnorePathsStr = Var_Subst(NULL,
|
||||
"${" MAKE_META_IGNORE_PATHS ":O:u:tA}", VAR_GLOBAL,
|
||||
VARF_WANTRES);
|
||||
if (metaIgnorePathsStr) {
|
||||
str2Lst_Append(metaIgnorePaths, metaIgnorePathsStr, NULL);
|
||||
}
|
||||
metaIgnorePathsStr = Var_Subst("${" MAKE_META_IGNORE_PATHS ":O:u:tA}",
|
||||
VAR_GLOBAL, VARE_WANTRES);
|
||||
str2Lst_Append(metaIgnorePaths, metaIgnorePathsStr, NULL);
|
||||
|
||||
/*
|
||||
* We ignore any paths that match ${.MAKE.META.IGNORE_PATTERNS}
|
||||
@ -654,12 +650,12 @@ meta_mode_init(const char *make_mode)
|
||||
cp = NULL;
|
||||
if (Var_Value(MAKE_META_IGNORE_PATTERNS, VAR_GLOBAL, &cp)) {
|
||||
metaIgnorePatterns = TRUE;
|
||||
free(cp);
|
||||
bmake_free(cp);
|
||||
}
|
||||
cp = NULL;
|
||||
if (Var_Value(MAKE_META_IGNORE_FILTER, VAR_GLOBAL, &cp)) {
|
||||
metaIgnoreFilter = TRUE;
|
||||
free(cp);
|
||||
bmake_free(cp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -822,8 +818,8 @@ meta_job_output(Job *job, char *cp, const char *nl)
|
||||
if (!meta_prefix) {
|
||||
char *cp2;
|
||||
|
||||
meta_prefix = Var_Subst(NULL, "${" MAKE_META_PREFIX "}",
|
||||
VAR_GLOBAL, VARF_WANTRES);
|
||||
meta_prefix = Var_Subst("${" MAKE_META_PREFIX "}",
|
||||
VAR_GLOBAL, VARE_WANTRES);
|
||||
if ((cp2 = strchr(meta_prefix, '$')))
|
||||
meta_prefix_len = cp2 - meta_prefix;
|
||||
else
|
||||
@ -894,9 +890,11 @@ meta_job_finish(Job *job)
|
||||
void
|
||||
meta_finish(void)
|
||||
{
|
||||
Lst_Destroy(metaBailiwick, NULL);
|
||||
if (metaBailiwick != NULL)
|
||||
Lst_Free(metaBailiwick);
|
||||
free(metaBailiwickStr);
|
||||
Lst_Destroy(metaIgnorePaths, NULL);
|
||||
if (metaIgnorePaths != NULL)
|
||||
Lst_Free(metaIgnorePaths);
|
||||
free(metaIgnorePathsStr);
|
||||
}
|
||||
|
||||
@ -958,39 +956,23 @@ prefix_match(void *p, void *q)
|
||||
return strncmp(path, prefix, n) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* looking for exact or prefix/ match to
|
||||
* Lst_Find wants 0 to stop search
|
||||
*/
|
||||
static int
|
||||
/* See if the path equals prefix or starts with "prefix/". */
|
||||
static Boolean
|
||||
path_match(const void *p, const void *q)
|
||||
{
|
||||
const char *prefix = q;
|
||||
const char *path = p;
|
||||
const char *prefix = q;
|
||||
size_t n = strlen(prefix);
|
||||
int rc;
|
||||
|
||||
if ((rc = strncmp(path, prefix, n)) == 0) {
|
||||
switch (path[n]) {
|
||||
case '\0':
|
||||
case '/':
|
||||
break;
|
||||
default:
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
if (strncmp(path, prefix, n) != 0)
|
||||
return FALSE;
|
||||
return path[n] == '\0' || path[n] == '/';
|
||||
}
|
||||
|
||||
/* Lst_Find wants 0 to stop search */
|
||||
static int
|
||||
static Boolean
|
||||
string_match(const void *p, const void *q)
|
||||
{
|
||||
const char *p1 = p;
|
||||
const char *p2 = q;
|
||||
|
||||
return strcmp(p1, p2);
|
||||
return strcmp(p, q) == 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1015,12 +997,12 @@ meta_ignore(GNode *gn, const char *p)
|
||||
}
|
||||
|
||||
if (metaIgnorePatterns) {
|
||||
const char *expr;
|
||||
char *pm;
|
||||
|
||||
Var_Set(".p.", p, gn);
|
||||
pm = Var_Subst(NULL,
|
||||
"${" MAKE_META_IGNORE_PATTERNS ":@m@${.p.:M$m}@}",
|
||||
gn, VARF_WANTRES);
|
||||
expr = "${" MAKE_META_IGNORE_PATTERNS ":@m@${.p.:M$m}@}";
|
||||
pm = Var_Subst(expr, gn, VARE_WANTRES);
|
||||
if (*pm) {
|
||||
#ifdef DEBUG_META_MODE
|
||||
if (DEBUG(META))
|
||||
@ -1040,7 +1022,7 @@ meta_ignore(GNode *gn, const char *p)
|
||||
snprintf(fname, sizeof(fname),
|
||||
"${%s:L:${%s:ts:}}",
|
||||
p, MAKE_META_IGNORE_FILTER);
|
||||
fm = Var_Subst(NULL, fname, gn, VARF_WANTRES);
|
||||
fm = Var_Subst(fname, gn, VARE_WANTRES);
|
||||
if (*fm == '\0') {
|
||||
#ifdef DEBUG_META_MODE
|
||||
if (DEBUG(META))
|
||||
@ -1122,7 +1104,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
goto oodate_out;
|
||||
dname = fname3;
|
||||
|
||||
missingFiles = Lst_Init(FALSE);
|
||||
missingFiles = Lst_Init();
|
||||
|
||||
/*
|
||||
* We need to check if the target is out-of-date. This includes
|
||||
@ -1147,7 +1129,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
int pid;
|
||||
int x;
|
||||
LstNode ln;
|
||||
struct stat fs;
|
||||
struct make_stat mst;
|
||||
|
||||
if (!buf) {
|
||||
bufsz = 8 * BUFSIZ;
|
||||
@ -1240,7 +1222,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
CHECK_VALID_META(p);
|
||||
pid = atoi(p);
|
||||
if (pid > 0 && pid != lastpid) {
|
||||
char *ldir;
|
||||
const char *ldir;
|
||||
char *tp;
|
||||
|
||||
if (lastpid > 0) {
|
||||
@ -1254,12 +1236,12 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
ldir = Var_Value(ldir_vname, VAR_GLOBAL, &tp);
|
||||
if (ldir) {
|
||||
strlcpy(latestdir, ldir, sizeof(latestdir));
|
||||
free(tp);
|
||||
bmake_free(tp);
|
||||
}
|
||||
ldir = Var_Value(lcwd_vname, VAR_GLOBAL, &tp);
|
||||
if (ldir) {
|
||||
strlcpy(lcwd, ldir, sizeof(lcwd));
|
||||
free(tp);
|
||||
bmake_free(tp);
|
||||
}
|
||||
}
|
||||
/* Skip past the pid. */
|
||||
@ -1337,15 +1319,16 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
case 'D': /* unlink */
|
||||
if (*p == '/' && !Lst_IsEmpty(missingFiles)) {
|
||||
/* remove any missingFiles entries that match p */
|
||||
if ((ln = Lst_Find(missingFiles, p,
|
||||
path_match)) != NULL) {
|
||||
ln = Lst_Find(missingFiles, path_match, p);
|
||||
if (ln != NULL) {
|
||||
LstNode nln;
|
||||
char *tp;
|
||||
|
||||
do {
|
||||
nln = Lst_FindFrom(missingFiles, Lst_Succ(ln),
|
||||
p, path_match);
|
||||
tp = Lst_Datum(ln);
|
||||
nln = Lst_FindFrom(missingFiles,
|
||||
LstNode_Next(ln),
|
||||
path_match, p);
|
||||
tp = LstNode_Datum(ln);
|
||||
Lst_Remove(missingFiles, ln);
|
||||
free(tp);
|
||||
} while ((ln = nln) != NULL);
|
||||
@ -1411,11 +1394,11 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
if ((strstr("tmp", p)))
|
||||
break;
|
||||
|
||||
if ((link_src != NULL && cached_lstat(p, &fs) < 0) ||
|
||||
(link_src == NULL && cached_stat(p, &fs) < 0)) {
|
||||
if ((link_src != NULL && cached_lstat(p, &mst) < 0) ||
|
||||
(link_src == NULL && cached_stat(p, &mst) < 0)) {
|
||||
if (!meta_ignore(gn, p)) {
|
||||
if (Lst_Find(missingFiles, p, string_match) == NULL)
|
||||
Lst_AtEnd(missingFiles, bmake_strdup(p));
|
||||
if (Lst_Find(missingFiles, string_match, p) == NULL)
|
||||
Lst_Append(missingFiles, bmake_strdup(p));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1475,7 +1458,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
if (DEBUG(META))
|
||||
fprintf(debug_file, "%s: %d: looking for: %s\n", fname, lineno, *sdp);
|
||||
#endif
|
||||
if (cached_stat(*sdp, &fs) == 0) {
|
||||
if (cached_stat(*sdp, &mst) == 0) {
|
||||
found = 1;
|
||||
p = *sdp;
|
||||
}
|
||||
@ -1485,12 +1468,12 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
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 (!S_ISDIR(mst.mst_mode) &&
|
||||
mst.mst_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)) {
|
||||
} else if (S_ISDIR(mst.mst_mode)) {
|
||||
/* Update the latest directory. */
|
||||
cached_realpath(p, latestdir);
|
||||
}
|
||||
@ -1500,8 +1483,8 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
* A referenced file outside of CWD is missing.
|
||||
* We cannot catch every eventuality here...
|
||||
*/
|
||||
if (Lst_Find(missingFiles, p, string_match) == NULL)
|
||||
Lst_AtEnd(missingFiles, bmake_strdup(p));
|
||||
if (Lst_Find(missingFiles, string_match, p) == NULL)
|
||||
Lst_Append(missingFiles, bmake_strdup(p));
|
||||
}
|
||||
}
|
||||
if (buf[0] == 'E') {
|
||||
@ -1524,7 +1507,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
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);
|
||||
char *cmd = LstNode_Datum(ln);
|
||||
Boolean hasOODATE = FALSE;
|
||||
|
||||
if (strstr(cmd, "$?"))
|
||||
@ -1539,7 +1522,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
if (DEBUG(META))
|
||||
fprintf(debug_file, "%s: %d: cannot compare command using .OODATE\n", fname, lineno);
|
||||
}
|
||||
cmd = Var_Subst(NULL, cmd, gn, VARF_WANTRES|VARF_UNDEFERR);
|
||||
cmd = Var_Subst(cmd, gn, VARE_WANTRES|VARE_UNDEFERR);
|
||||
|
||||
if ((cp = strchr(cmd, '\n'))) {
|
||||
int n;
|
||||
@ -1576,7 +1559,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
oodate = TRUE;
|
||||
}
|
||||
free(cmd);
|
||||
ln = Lst_Succ(ln);
|
||||
ln = LstNode_Next(ln);
|
||||
}
|
||||
} else if (strcmp(buf, "CWD") == 0) {
|
||||
/*
|
||||
@ -1601,7 +1584,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
if (!Lst_IsEmpty(missingFiles)) {
|
||||
if (DEBUG(META))
|
||||
fprintf(debug_file, "%s: missing files: %s...\n",
|
||||
fname, (char *)Lst_Datum(Lst_First(missingFiles)));
|
||||
fname, (char *)LstNode_Datum(Lst_First(missingFiles)));
|
||||
oodate = TRUE;
|
||||
}
|
||||
if (!oodate && !have_filemon && filemonMissing) {
|
||||
@ -1628,7 +1611,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
}
|
||||
}
|
||||
|
||||
Lst_Destroy(missingFiles, (FreeProc *)free);
|
||||
Lst_Destroy(missingFiles, free);
|
||||
|
||||
if (oodate && needOODATE) {
|
||||
/*
|
||||
@ -1638,12 +1621,12 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
*/
|
||||
Var_Delete(OODATE, gn);
|
||||
Var_Set(OODATE, Var_Value(ALLSRC, gn, &cp), gn);
|
||||
free(cp);
|
||||
bmake_free(cp);
|
||||
}
|
||||
|
||||
oodate_out:
|
||||
for (i--; i >= 0; i--) {
|
||||
free(pa[i]);
|
||||
bmake_free(pa[i]);
|
||||
}
|
||||
return oodate;
|
||||
}
|
||||
|
36
metachar.c
36
metachar.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: metachar.c,v 1.5 2015/06/19 08:03:35 mlelstv Exp $ */
|
||||
/* $NetBSD: metachar.c,v 1.6 2020/08/03 20:43:41 rillig Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@ -38,7 +38,7 @@
|
||||
#endif
|
||||
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
__RCSID("$NetBSD: metachar.c,v 1.5 2015/06/19 08:03:35 mlelstv Exp $");
|
||||
__RCSID("$NetBSD: metachar.c,v 1.6 2020/08/03 20:43:41 rillig Exp $");
|
||||
#endif
|
||||
|
||||
#include "metachar.h"
|
||||
@ -52,37 +52,37 @@ __RCSID("$NetBSD: metachar.c,v 1.5 2015/06/19 08:03:35 mlelstv Exp $");
|
||||
*/
|
||||
|
||||
unsigned char _metachar[128] = {
|
||||
// nul soh stx etx eot enq ack bel
|
||||
/* nul soh stx etx eot enq ack bel */
|
||||
1, 0, 0, 0, 0, 0, 0, 0,
|
||||
// bs ht nl vt np cr so si
|
||||
/* bs ht nl vt np cr so si */
|
||||
0, 0, 1, 0, 0, 0, 0, 0,
|
||||
// dle dc1 dc2 dc3 dc4 nak syn etb
|
||||
/* dle dc1 dc2 dc3 dc4 nak syn etb */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// can em sub esc fs gs rs us
|
||||
/* can em sub esc fs gs rs us */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// sp ! " # $ % & '
|
||||
/* sp ! " # $ % & ' */
|
||||
0, 1, 1, 1, 1, 0, 1, 1,
|
||||
// ( ) * + , - . /
|
||||
/* ( ) * + , - . / */
|
||||
1, 1, 1, 0, 0, 0, 0, 0,
|
||||
// 0 1 2 3 4 5 6 7
|
||||
/* 0 1 2 3 4 5 6 7 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// 8 9 : ; < = > ?
|
||||
/* 8 9 : ; < = > ? */
|
||||
0, 0, 0, 1, 1, 0, 1, 1,
|
||||
// @ A B C D E F G
|
||||
/* @ A B C D E F G */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// H I J K L M N O
|
||||
/* H I J K L M N O */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// P Q R S T U V W
|
||||
/* P Q R S T U V W */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// X Y Z [ \ ] ^ _
|
||||
/* X Y Z [ \ ] ^ _ */
|
||||
0, 0, 0, 1, 1, 1, 1, 0,
|
||||
// ` a b c d e f g
|
||||
/* ` a b c d e f g */
|
||||
1, 0, 0, 0, 0, 0, 0, 0,
|
||||
// h i j k l m n o
|
||||
/* h i j k l m n o */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// p q r s t u v w
|
||||
/* p q r s t u v w */
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// x y z { | } ~ del
|
||||
/* x y z { | } ~ del */
|
||||
0, 0, 0, 1, 1, 1, 1, 0,
|
||||
};
|
||||
|
||||
|
21
metachar.h
21
metachar.h
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: metachar.h,v 1.4 2015/06/21 20:26:02 christos Exp $ */
|
||||
/* $NetBSD: metachar.h,v 1.7 2020/08/25 17:37:09 rillig Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@ -28,25 +28,16 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _METACHAR_H
|
||||
#define _METACHAR_H
|
||||
#ifndef MAKE_METACHAR_H
|
||||
#define MAKE_METACHAR_H
|
||||
|
||||
#include <ctype.h>
|
||||
#include "make.h"
|
||||
|
||||
extern unsigned char _metachar[];
|
||||
|
||||
#define ismeta(c) _metachar[(c) & 0x7f]
|
||||
|
||||
static inline int
|
||||
hasmeta(const char *cmd)
|
||||
{
|
||||
while (!ismeta(*cmd))
|
||||
cmd++;
|
||||
|
||||
return *cmd != '\0';
|
||||
}
|
||||
|
||||
static inline int
|
||||
static inline int MAKE_ATTR_UNUSED
|
||||
needshell(const char *cmd, int white)
|
||||
{
|
||||
while (!ismeta(*cmd) && *cmd != ':' && *cmd != '=') {
|
||||
@ -58,4 +49,4 @@ needshell(const char *cmd, int white)
|
||||
return *cmd != '\0';
|
||||
}
|
||||
|
||||
#endif /* _METACHAR_H */
|
||||
#endif /* MAKE_METACHAR_H */
|
||||
|
301
mk/ChangeLog
301
mk/ChangeLog
@ -1,3 +1,106 @@
|
||||
2020-08-26 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps.mk: ensure we cannot confuse a static cache for dynamic
|
||||
(even more rare that use of static cache is playing clever tricks
|
||||
with it)
|
||||
|
||||
2020-08-16 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps-cache-update.mk: allow
|
||||
MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE to control when we
|
||||
actually update STATIC_DIRDEPS_CACHE.
|
||||
|
||||
* stage-install.sh: create dest directory if needed
|
||||
before running install(1)
|
||||
|
||||
2020-08-10 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps-targets.mk: include Makefile.dirdeps.options
|
||||
|
||||
* dirdeps.mk: use _TARGETS if defined for DIRDEPS_CACHE
|
||||
|
||||
2020-08-09 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps.mk: default BUILD_DIRDEPS_MAKEFILE to empty
|
||||
|
||||
* dirdeps-cache-update.mk: building parallel cache update
|
||||
under the context of dirdeps-cached would be ideal, but
|
||||
is problematic, so it runs as a sibling.
|
||||
Use cache-built target to ensure we wait for it to complete if
|
||||
necessary.
|
||||
|
||||
2020-08-06 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20200806
|
||||
|
||||
* dirdeps-options: allow TARGET_SPEC to affect option values.
|
||||
Use DIRDEPS_OPTIONS_QUALIFIER_LIST before using bare MK_*
|
||||
|
||||
* dirdeps-targets.mk: check for MK_STATIC_DIRDEPS_CACHE defined
|
||||
before looking for STATIC_DIRDEPS_CACHE
|
||||
|
||||
2020-08-05 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* host-target.mk: Darwin use MACHINE for HOST_ARCH too
|
||||
|
||||
* dirdeps-options.mk: improve debug output
|
||||
|
||||
2020-07-22 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps.mk: set and export DYNAMIC_DIRDEPS_CACHE
|
||||
for use by dirdeps-cache-update.mk
|
||||
|
||||
* dirdeps-targets.mk: set and export STATIC_DIRDEPS_CACHE
|
||||
for use by dirdeps-cache-update.mk even if we don't use it.
|
||||
|
||||
* dirdeps-cache-update.mk: we only need worry about the background
|
||||
update case, with the above, the update from DIRDEPS_CACHE is
|
||||
simple.
|
||||
|
||||
* meta2deps.py: R 1234 . is not interesting
|
||||
|
||||
2020-07-20 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* sys.mk: default MK_STATIC_DIRDEPS_CACHE from MK_DIRDEPS_CACHE
|
||||
|
||||
* dirdeps-options.mk: do not :tu DIRDEPS_OPTIONS
|
||||
allows use of lower case for pseudo options.
|
||||
|
||||
* dirdeps-cache-update.mk: magic to deal with STATIC_DIRDEPS_CACHE
|
||||
|
||||
2020-07-18 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps-targets.mk: Look for Makefile.dirdeps.cache
|
||||
which allows us to have a static cache for expensive targets.
|
||||
Use -DWITHOUT_STATIC_DIRDEPS_CACHE -DWITH_DIRDEPS_CACHE
|
||||
to regenerate the dirdeps.cache it is a copy of.
|
||||
|
||||
2020-07-17 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* Get rid of BUILD_AT_LEVEL0, MK_DIRDEPS_BUILD makes more sense.
|
||||
|
||||
2020-07-16 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps.mk (DIRDEP_LOADAVG_REPORT): make it easy to record
|
||||
load averages at intervals during build.
|
||||
|
||||
2020-07-15 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20200715
|
||||
|
||||
* dirdeps.mk: tweak Checking line to make matching Finished
|
||||
lines for post-build analysis easier.
|
||||
|
||||
* meta.autodep.mk: use !defined(WITHOUT_META_STATS)
|
||||
|
||||
* progs.mk: avoid prog.mk outputting multiple Finished lines
|
||||
|
||||
2020-07-11 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps.mk: further optimize dirdeps.cache
|
||||
generate a DIRDEPS.${.TARGET} list for other purposes
|
||||
and improve the layout.
|
||||
|
||||
2020-07-10 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
* dirdeps.mk: optimize content of dirdeps.cache
|
||||
@ -124,7 +227,7 @@
|
||||
* install-mk (MK_VERSION): 20180919
|
||||
|
||||
* dirdeps-options.mk: .undef cannot handle var that expands to
|
||||
more than one var.
|
||||
more than one var.
|
||||
|
||||
2018-07-08 Simon J Gerraty <sjg@beast.crufty.net>
|
||||
|
||||
@ -309,8 +412,8 @@
|
||||
2016-12-12 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20161212
|
||||
|
||||
* meta2deps.py: set pid_cwd[pid] when we process 'C'hdir,
|
||||
|
||||
* meta2deps.py: set pid_cwd[pid] when we process 'C'hdir,
|
||||
rather than when we detect pid change.
|
||||
|
||||
2016-12-07 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
@ -322,7 +425,7 @@
|
||||
to use foo.tgz to reference the latest staged version - so we
|
||||
make foo.tgz a symlink to it.
|
||||
Using a target to do both operations ensures we stay in sync.
|
||||
|
||||
|
||||
2016-11-26 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20161126
|
||||
@ -374,18 +477,18 @@
|
||||
|
||||
2016-08-13 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* meta.sys.mk (.MAKE.META.IGNORE_PATHS):
|
||||
* meta.sys.mk (.MAKE.META.IGNORE_PATHS):
|
||||
in meta mode we can ignore the mtime of makefiles
|
||||
|
||||
2016-08-02 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20160802
|
||||
|
||||
|
||||
* lib.mk (libinstall): depends on beforinstall
|
||||
|
||||
* prog.mk (proginstall): depends on beforinstall
|
||||
patch from Lauri Tirkkonen
|
||||
|
||||
|
||||
* dirdeps.mk (bootstrap): When bootstrapping; creat
|
||||
.MAKE.DEPENDFILE_DEFAULT and allow additional filtering via
|
||||
.MAKE.DEPENDFILE_BOOTSTRAP_SED
|
||||
@ -408,7 +511,7 @@
|
||||
* install-mk (MK_VERSION): 20160530
|
||||
* meta.stage.mk: we assume ${CLEANFILES} gets .NOPATH
|
||||
make it so.
|
||||
|
||||
|
||||
2016-05-12 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20160512
|
||||
@ -418,7 +521,7 @@
|
||||
skip INCLUDES_* for staged libs unless SRC_* defined.
|
||||
|
||||
* own.mk: add INCLUDEDIR
|
||||
|
||||
|
||||
2016-04-18 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* dirdeps.mk: when doing -f dirdeps.mk if target suppies no
|
||||
@ -428,9 +531,9 @@
|
||||
2016-04-07 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* meta.autodep.mk: issue a warning if UPDATE_DEPENDFILE=NO due to
|
||||
NO_FILEMON_COOKIE
|
||||
NO_FILEMON_COOKIE
|
||||
|
||||
* dirdeps.mk: move the logic that allows for
|
||||
* dirdeps.mk: move the logic that allows for
|
||||
make -f dirdeps.mk some/dir.${TARGET_SPEC}
|
||||
inside the check for !target(_DIRDEP_USE)
|
||||
|
||||
@ -438,15 +541,15 @@
|
||||
|
||||
* Use <> when including local*.mk and others which may exist
|
||||
elsewhere so that user can better control what they get.
|
||||
|
||||
* meta.autodep.mk (NO_FILEMON_COOKIE):
|
||||
|
||||
* meta.autodep.mk (NO_FILEMON_COOKIE):
|
||||
create a cookie if we ever build dir with nofilemon
|
||||
so that UPDATE_DEPENDFILE will be forced to NO until cleaned.
|
||||
|
||||
2016-04-01 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20160401
|
||||
|
||||
|
||||
* meta2deps.py: fix old print statement when debugging.
|
||||
|
||||
* gendirdeps.mk: META2DEPS_CMD append M2D_EXCLUDES with -X
|
||||
@ -455,12 +558,12 @@
|
||||
2016-03-22 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20160317 (St. Pats)
|
||||
|
||||
|
||||
* warnings.mk: g++ does not like -Wimplicit
|
||||
|
||||
|
||||
* sys.mk sys/*.mk lib.mk prog.mk: use CXX_SUFFIXES to handle the
|
||||
pelthora of common suffixes for C++
|
||||
|
||||
|
||||
* lib.mk: use .So for shared objects
|
||||
|
||||
2016-03-15 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
@ -469,9 +572,9 @@
|
||||
|
||||
* meta.stage.mk (LN_CP_SCRIPT): do not ln(1) if we have to chmod(1)
|
||||
normally only applies to scripts.
|
||||
|
||||
|
||||
* dirdeps.mk: NO_DIRDEPS_BELOW to supress DIRDEPS below RELDIR as
|
||||
well as outside it.
|
||||
well as outside it.
|
||||
|
||||
2016-03-10 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
@ -509,17 +612,17 @@
|
||||
we cannot use the '$$' trick, but .export-literal does the job
|
||||
we need.
|
||||
* auto.dep.mk: make use .dinclude if we can.
|
||||
|
||||
|
||||
|
||||
2016-02-05 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* dirdeps.mk:
|
||||
* dirdeps.mk:
|
||||
Add _build_all_dirs such that local.dirdeps.mk can
|
||||
add fully qualified dirs to it.
|
||||
These will be built normally but the current
|
||||
These will be built normally but the current
|
||||
DEP_RELDIR will not depend on then (to avoid cycles).
|
||||
This makes it easy to hook things like unit-tests into build.
|
||||
|
||||
|
||||
|
||||
2016-01-21 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
@ -541,7 +644,7 @@
|
||||
to set MK_AUTO_OBJ and MK_DIRDEPS_BUILD
|
||||
include local.sys.env.mk early
|
||||
include local.sys.mk later
|
||||
|
||||
|
||||
* own.mk (OPTIONS_DEFAULT_NO): AUTO_OBJ etc moved to sys.mk
|
||||
|
||||
2015-11-13 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
@ -560,8 +663,8 @@
|
||||
2015-10-20 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20151020
|
||||
|
||||
* dirdeps.mk: Add logic for
|
||||
|
||||
* dirdeps.mk: Add logic for
|
||||
make -f dirdeps.mk some/dir.${TARGET_SPEC}
|
||||
|
||||
2015-10-14 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
@ -587,16 +690,16 @@
|
||||
2015-06-15 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20150615
|
||||
|
||||
|
||||
* auto.obj.mk: allow use of MAKEOBJDIRPREFIX too.
|
||||
Follow make's normal precedence rules.
|
||||
|
||||
|
||||
* gendirdeps.mk: allow customization of the header.
|
||||
eg. for FreeBSD:
|
||||
eg. for FreeBSD:
|
||||
GENDIRDEPS_HEADER= echo '\# ${FreeBSD:L:@v@$$$v$$ @:M*F*}';
|
||||
|
||||
* meta.autodep.mk: ignore dirdeps.cache*
|
||||
|
||||
|
||||
* meta.stage.mk: when bootstrapping options it can be handy to
|
||||
throw warnings rather than errors for staging conflicts.
|
||||
|
||||
@ -605,11 +708,11 @@
|
||||
2015-06-06 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20150606
|
||||
|
||||
|
||||
* dirdeps.mk: don't rely on manually maintained Makefile.depend
|
||||
to set DEP_RELDIR and reset DIRDEPS.
|
||||
By setting DEP_RELDIR ourselves we can skip :tA
|
||||
|
||||
|
||||
* gendirdeps.mk: skip setting DEP_RELDIR.
|
||||
|
||||
2015-05-24 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
@ -626,19 +729,19 @@
|
||||
|
||||
* meta.stage.mk: for STAGE_AS_* basename of file may not be unique
|
||||
so first use absolute path as key.
|
||||
Also skip staging at level 0.
|
||||
Also skip staging at level 0.
|
||||
|
||||
2015-04-30 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20150430
|
||||
|
||||
|
||||
* dirdeps.mk: fix _count_dirdeps for non-cache case.
|
||||
|
||||
2015-04-16 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20150411
|
||||
bump version
|
||||
|
||||
|
||||
* own.mk: put AUTO_OBJ in OPTIONS_DEFAULT_NO rather than YES.
|
||||
it is here mainly for documentation purposes, since
|
||||
if using auto.obj.mk it is better done via sys.mk
|
||||
@ -646,21 +749,21 @@
|
||||
2015-04-01 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20150401
|
||||
|
||||
|
||||
* meta2deps.sh: support @list
|
||||
|
||||
|
||||
* meta2deps.py: updates from Juniper
|
||||
o add EXCLUDES
|
||||
o add EXCLUDES
|
||||
o skip bogus input files.
|
||||
o treat 'M' and 'L' as both an 'R' and a 'W'
|
||||
|
||||
2015-03-03 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20150303
|
||||
|
||||
|
||||
* dirdeps.mk: if MK_DIRDEPS_CACHE is yes, use dirdeps-cache
|
||||
which is built via sub-make so we have a .meta file to tell if
|
||||
it is out-of-date.
|
||||
it is out-of-date.
|
||||
The dirdeps-cache contains the same dependency rules that we
|
||||
normaly construct on the fly.
|
||||
This adds a few seconds overhead when the cache is out of date,
|
||||
@ -669,15 +772,15 @@
|
||||
2014-11-18 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20141118
|
||||
|
||||
|
||||
* meta.stage.mk: add stale_staged
|
||||
|
||||
|
||||
* dirdeps.mk (_DIRDEP_USE_LEVEL): allow this to be tweaked
|
||||
only useful under very rare conditions such as
|
||||
FreeBSD's make universe.
|
||||
|
||||
* auto.obj.mk: Allow MK_AUTO_OBJ to set MKOBJDIRS=auto
|
||||
|
||||
|
||||
2014-11-11 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20141111
|
||||
@ -695,24 +798,24 @@
|
||||
for GENDIRDEPS_FILTER to avoid surprises.
|
||||
|
||||
2014-10-10 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
|
||||
* dirdeps.mk (NSkipHostDir): this needs SRCTOP prepended since by
|
||||
the time it is applied to __depdirs they have.
|
||||
|
||||
|
||||
* dirdeps.mk fix filtering of _machines since M_dep_qual_fixes
|
||||
expects patterns like *.${MACHINE}
|
||||
|
||||
|
||||
* cython.mk (pyprefix?): use pyprefix to find python bits
|
||||
since prefix might be something else (where we install our
|
||||
stuff)
|
||||
|
||||
|
||||
2014-09-11 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20140911
|
||||
|
||||
|
||||
* dirdeps.mk: add bootstrap target to simplify adding support for
|
||||
new MACHINE.
|
||||
|
||||
|
||||
2014-09-01 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* gendirdeps.mk: Add handling of GENDIRDEPS_FILTER_DIR_VARS and
|
||||
@ -722,7 +825,7 @@
|
||||
2014-08-28 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20140828
|
||||
|
||||
|
||||
* cython.mk: capture logic for building python extension modules
|
||||
with Cython.
|
||||
|
||||
@ -735,8 +838,8 @@
|
||||
* install-mk (MK_VERSION): 20140801
|
||||
|
||||
* dep.mk: use explicit MKDEP_MK rather than overload MKDEP to
|
||||
identify the autodep.mk variant.
|
||||
|
||||
identify the autodep.mk variant.
|
||||
|
||||
* sys.dependfile.mk: delete .MAKE.DEPENDFILE if its
|
||||
initial value does not match .MAKE.DEPENDFILE_PREFIX
|
||||
|
||||
@ -774,7 +877,7 @@
|
||||
build).
|
||||
|
||||
* dirdeps.mk (__depdirs): ensure // don't sneak in
|
||||
|
||||
|
||||
* gendirdeps.mk (DIRDEPS): ensure // don't sneak in
|
||||
|
||||
|
||||
@ -794,7 +897,7 @@
|
||||
|
||||
2014-02-09 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* options.mk: cleanup and simplify semanitcs
|
||||
* options.mk: cleanup and simplify semanitcs
|
||||
NO_* dominates all, if both WITH_* and WITHOUT_*
|
||||
are defined then result is DOMINATE_* which defaults to "no".
|
||||
Ie. WITHOUT_ normally wins.
|
||||
@ -815,7 +918,7 @@
|
||||
as _build_dirs.
|
||||
Also fix the filtering of Makefile.depend files - for reporting
|
||||
what we are looking for (M_dep_qual_fixes can get confused by
|
||||
Makefile.depend)
|
||||
Makefile.depend)
|
||||
Add some more debug info.
|
||||
|
||||
2013-09-04 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
@ -828,7 +931,7 @@
|
||||
|
||||
* install-mk (MK_VERSION): 20130801
|
||||
* libs.mk: update to match progs.mk
|
||||
|
||||
|
||||
2013-07-26 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20130726
|
||||
@ -837,13 +940,13 @@
|
||||
errors
|
||||
also allow @file to provide huge list of .meta files.
|
||||
* meta2deps.py: add try_parse() to cleanup the above.
|
||||
|
||||
|
||||
2013-07-16 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20130716
|
||||
* own.mk: add GPROG as an option
|
||||
* prog.mk: honor MK_GPROF==yes
|
||||
|
||||
|
||||
2013-05-10 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20130505
|
||||
@ -878,7 +981,7 @@
|
||||
* meta.stage.mk (LN_CP_SCRIPT): Add LnCp to do the ln||cp dance
|
||||
consistently.
|
||||
* dirdeps.mk: better describe the dance in sys.mk for TARGET_SPEC.
|
||||
|
||||
|
||||
2013-03-18 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* gendirdeps.mk: revert the dance around .MAKE.DEPENDFILE_DEFAULT
|
||||
@ -893,7 +996,7 @@
|
||||
* gendirdeps.mk: ensure _objroot has trailing / if it needs it.
|
||||
* meta2deps.py: if machine is "host", then also trim
|
||||
self.host_target from any OBJROOTS.
|
||||
|
||||
|
||||
|
||||
2013-03-11 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
@ -909,7 +1012,7 @@
|
||||
|
||||
2013-03-07 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* sys.dependfile.mk (.MAKE.DEPENDFILE_DEFAULT):
|
||||
* sys.dependfile.mk (.MAKE.DEPENDFILE_DEFAULT):
|
||||
use a separate variable for the default .MAKE.DEPENDFILE value
|
||||
so that it can be controlled independently of
|
||||
.MAKE.DEPENDFILE_PREFERENCE
|
||||
@ -926,12 +1029,12 @@
|
||||
2013-02-10 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): bump version to 20130210
|
||||
* import latest dirdeps.mk, gendirdeps.mk and meta2deps.py
|
||||
from Juniper.
|
||||
* import latest dirdeps.mk, gendirdeps.mk and meta2deps.py
|
||||
from Juniper.
|
||||
o dirdeps.mk now fully supports TARGET_SPEC consisting of more
|
||||
than just MACHINE.
|
||||
o no longer use DEP_MACHINE from Makefile.depend* so remove it.
|
||||
|
||||
|
||||
2013-01-23 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): bump version to 20130123
|
||||
@ -976,13 +1079,13 @@
|
||||
* progs.mk: add MAN and CXXFLAGS to PROG_VARS
|
||||
also add PROGS_TARGETS and pass on PROG_CXX if it seems
|
||||
appropriate.
|
||||
|
||||
|
||||
2012-11-04 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* meta.stage.mk: update CLEANFILES
|
||||
remove redundant cp of .dirdep from STAGE_AS_SCRIPT.
|
||||
* progs.mk: Add LDADD to PROG_VARS
|
||||
|
||||
|
||||
2012-10-12 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* meta.stage.mk (STAGE_DIR_FILTER): track dirs we stage to in
|
||||
@ -1004,11 +1107,11 @@
|
||||
|
||||
* install-mk (MK_VERSION): bump version to 20120711
|
||||
* dep.mk: add explicit dependencies on SRCS after applying
|
||||
SRCS_DEP_FILTER
|
||||
SRCS_DEP_FILTER
|
||||
* meta.autodep.mk: add explicit dependencies on SRCS after
|
||||
applying SRCS_DEP_FILTER
|
||||
* meta.autodep.mk: ensure GENDIRDEPS_FILTER is exported if needed.
|
||||
|
||||
|
||||
2012-06-26 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): bump version to 20120626
|
||||
@ -1020,14 +1123,14 @@
|
||||
* gendirdeps.mk: only produce unqualified deps if no
|
||||
.MAKE.DEPENDFILE_PREFERENCE ends in .${MACHINE}
|
||||
* meta.subdir.mk: apply SUBDIRDEPS_FILTER
|
||||
|
||||
|
||||
2012-04-20 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): bump version to 20120420
|
||||
* add sys.dependfile.mk so we can experiment with
|
||||
.MAKE.DEPENDFILE_PREFERENCE
|
||||
.MAKE.DEPENDFILE_PREFERENCE
|
||||
* meta.autodep.mk: _DEPENDFILE is precious!
|
||||
|
||||
|
||||
2012-03-15 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): bump version to 20120315
|
||||
@ -1068,37 +1171,37 @@
|
||||
o meta2deps.py add a clear 'ERROR:' token if an exception is raised.
|
||||
o gendirdeps.mk if ERROR: from meta2deps.py do not update
|
||||
anything.
|
||||
|
||||
|
||||
2011-10-30 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-new.mk separate the cmp and copy logic to its own function.
|
||||
|
||||
|
||||
2011-10-28 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): bump version to 20111028
|
||||
* sys.mk: include auto.obj.mk if MKOBJDIRS is set to auto
|
||||
* subdir.mk: ensure _SUBDIRUSE is provided
|
||||
* meta.autodep.mk: remove dependency of gendirdeps.mk on auto.obj.mk
|
||||
* meta.autodep.mk: remove dependency of gendirdeps.mk on auto.obj.mk
|
||||
* meta.subdir.mk: always allow for Makefile.depend
|
||||
|
||||
|
||||
2011-10-10 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): bump version to 20111010
|
||||
o minor tweak to *dirdeps.mk from Juniper sjg@
|
||||
|
||||
|
||||
2011-10-01 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): bump version to 20111001
|
||||
o add meta2deps.py from Juniper sjg@
|
||||
o tweak gendirdeps.mk to work with meta2deps.py when not
|
||||
cross-building
|
||||
* autoconf.mk: add autoconf-input as a hook for regenerating
|
||||
cross-building
|
||||
* autoconf.mk: add autoconf-input as a hook for regenerating
|
||||
AUTOCONF_INPUTS (configure).
|
||||
|
||||
2011-08-24 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* meta.autodep.mk: if we do not have OBJS, .depend isn't a useful
|
||||
trigger for updating Makefile.depend*
|
||||
trigger for updating Makefile.depend*
|
||||
|
||||
2011-08-08 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
@ -1155,7 +1258,7 @@
|
||||
2011-04-03 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* rst2htm.mk: convert rst to s5 (slides) or plain html depending
|
||||
on target name.
|
||||
on target name.
|
||||
|
||||
2011-03-30 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
@ -1167,16 +1270,16 @@
|
||||
can be used to debug level 0 only and DEBUG_MAKE_FLAGS for the rest.
|
||||
* sys.mk: re-define M_whence in terms of M_type.
|
||||
M_type is useful for checking if something is a builtin.
|
||||
|
||||
|
||||
2011-03-16 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* meta.stage.mk: add stage_symlinks and leverage StageLinks for
|
||||
stage_libs
|
||||
stage_libs
|
||||
|
||||
2011-03-10 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* dirdeps.mk: correct value for _depdir_files depends on
|
||||
.MAKE.DEPENDFILE
|
||||
.MAKE.DEPENDFILE
|
||||
Add our copyright - just to make it clear we have frobbed this
|
||||
quite a bit.
|
||||
DEP_MACHINE needs to be set to MACHINE each time, if using only
|
||||
@ -1216,7 +1319,7 @@
|
||||
2010-09-24 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): bump version to 20100919
|
||||
include dirdeps.mk et al from Juniper Networks,
|
||||
include dirdeps.mk et al from Juniper Networks,
|
||||
for meta mode - requires filemon(9).
|
||||
* sys.mk, subdir.mk: Add hooks for meta mode.
|
||||
we do this as meta.sys.mk, meta.autodep.mk and meta.subdir.mk
|
||||
@ -1282,7 +1385,7 @@
|
||||
* install-mk (MK_VERSION): bump version to 20100420
|
||||
* sys/NetBSD.mk: add MACHINE_CPU to keep netbsd makefiles happy
|
||||
* autoconf.mk allow AUTO_AUTOCONF
|
||||
|
||||
|
||||
2010-04-19 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* obj.mk: add objwarn to keep freebsd makefiles happy
|
||||
@ -1294,7 +1397,7 @@
|
||||
* auto.dep.mk: add some explanation of how/what we do.
|
||||
* autodep.mk: skip the .OPTIONAL frobbing of .depend
|
||||
bmake's FROM_DEPEND flag makes it redundant.
|
||||
|
||||
|
||||
2010-04-13 Simon J. Gerraty <sjg@bad.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): bump version to 20100404
|
||||
@ -1335,7 +1438,7 @@
|
||||
|
||||
* sys.mk,libnames.mk add .-include <local.*>
|
||||
this allows local customization without the need to edit the
|
||||
distributed files.
|
||||
distributed files.
|
||||
|
||||
2009-12-14 Simon J. Gerraty <sjg@void.crufty.net>
|
||||
|
||||
@ -1361,7 +1464,7 @@
|
||||
2009-11-17 Simon J. Gerraty <sjg@void.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): bump version
|
||||
* host-target.mk: only export the expensive stuff
|
||||
* host-target.mk: only export the expensive stuff
|
||||
* Generic.sys.mk (sys_mk): for SunOS we need to look for
|
||||
${HOST_OS}.${HOST_OSMAJOR} too!
|
||||
|
||||
@ -1411,7 +1514,7 @@
|
||||
|
||||
* install-mk (MK_VERSION): bump version
|
||||
* general cleanup
|
||||
* dpadd.mk introduce DPMAGIC_LIBS_*
|
||||
* dpadd.mk introduce DPMAGIC_LIBS_*
|
||||
|
||||
2007-04-30 Simon J. Gerraty <sjg@void.crufty.net>
|
||||
|
||||
@ -1453,10 +1556,10 @@
|
||||
* install-mk (MK_VERSION): bump version to 20061126
|
||||
|
||||
* warnings.mk: detect invalid WARNINGS_SET
|
||||
|
||||
|
||||
* warnings.mk: use ${.TARGET:T:R}.o when looking for target
|
||||
specific warnings.
|
||||
|
||||
specific warnings.
|
||||
|
||||
* For .cc sources, turn off warnings that g++ vomits on.
|
||||
|
||||
2006-11-08 Simon J. Gerraty <sjg@void.crufty.net>
|
||||
@ -1483,11 +1586,11 @@
|
||||
2006-03-01 Simon J. Gerraty <sjg@void.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): bump version to 20060301
|
||||
* autodep.mk (.depend):
|
||||
* autodep.mk (.depend):
|
||||
if MAKE_VERSION is newer than 20050530 we can make .END depend on
|
||||
.depend and make .depend depend on __depsrcs that exist.
|
||||
* dpadd.mk: add SRC_PATHADD
|
||||
|
||||
|
||||
2005-11-04 Simon J. Gerraty <sjg@void.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): bump version to 20051104
|
||||
@ -1512,7 +1615,7 @@
|
||||
2004-02-15 Simon J. Gerraty <sjg@void.crufty.net>
|
||||
|
||||
* own.mk: don't use NetBSD's _SRC_TOP_ it can
|
||||
cause confusion. Also don't take just 'mk' as a
|
||||
cause confusion. Also don't take just 'mk' as a
|
||||
srctop indicator.
|
||||
|
||||
2004-02-14 Simon J. Gerraty <sjg@void.crufty.net>
|
||||
@ -1538,7 +1641,7 @@
|
||||
* set OS and ROOT_GROUP for those that we know the value.
|
||||
for others (eg. Generic.sys.mk) wrap the != in an .ifndef so
|
||||
we don't do it again for each sub-make.
|
||||
|
||||
|
||||
2003-09-28 Simon J. Gerraty <sjg@void.crufty.net>
|
||||
|
||||
* install-mk (MK_VERSION): 20030928
|
||||
@ -1554,8 +1657,8 @@
|
||||
|
||||
2003-07-31 Simon J. Gerraty <sjg@void.crufty.net>
|
||||
|
||||
* install-mk: add ability to use cp -f when updating
|
||||
destination .mk files. Also now possible to play games with
|
||||
* install-mk: add ability to use cp -f when updating
|
||||
destination .mk files. Also now possible to play games with
|
||||
FORCE_SYS_MK=ln etc on *BSD machines to link /usr/share/mk/sys.mk
|
||||
into dest - not recommended unless you seriously want to.
|
||||
|
||||
@ -1575,4 +1678,4 @@
|
||||
* install-mk: Allow FORCE_SYS_MK to come from env
|
||||
|
||||
|
||||
|
||||
|
||||
|
1
mk/FILES
1
mk/FILES
@ -61,6 +61,7 @@ warnings.mk
|
||||
whats.mk
|
||||
yacc.mk
|
||||
dirdeps.mk
|
||||
dirdeps-cache-update.mk
|
||||
dirdeps-options.mk
|
||||
dirdeps-targets.mk
|
||||
gendirdeps.mk
|
||||
|
@ -1,10 +1,10 @@
|
||||
# $Id: README,v 1.1 1997/03/11 07:27:15 sjg Exp $
|
||||
# $Id: README,v 1.2 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
This directory contains some macro's derrived from the NetBSD bsd.*.mk
|
||||
macros. They have the same names but without the bsd., separate macro
|
||||
files are needed to ensure we can make them do what we want for
|
||||
builing things outside of /usr/src. Nearly all the comments below
|
||||
apply.
|
||||
apply.
|
||||
|
||||
# $NetBSD: bsd.README,v 1.18 1997/01/13 00:54:23 mark Exp $
|
||||
# @(#)bsd.README 5.1 (Berkeley) 5/11/90
|
||||
@ -347,9 +347,9 @@ If foo has multiple source files, add the line:
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
The include file <bsd.subdir.mk> contains the default targets for building
|
||||
subdirectories. It has the same eight targets as <bsd.prog.mk>: all,
|
||||
subdirectories. It has the same eight targets as <bsd.prog.mk>: all,
|
||||
clean, cleandir, depend, includes, install, lint, and tags. For all of
|
||||
the directories listed in the variable SUBDIRS, the specified directory
|
||||
the directories listed in the variable SUBDIRS, the specified directory
|
||||
will be visited and the target made. There is also a default target which
|
||||
allows the command "make subdir" where subdir is any directory listed in
|
||||
the variable SUBDIRS.
|
||||
|
@ -1,16 +1,16 @@
|
||||
#
|
||||
# RCSid:
|
||||
# $Id: auto.dep.mk,v 1.5 2016/04/05 15:58:37 sjg Exp $
|
||||
# $Id: auto.dep.mk,v 1.6 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2010, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
@ -20,11 +20,11 @@
|
||||
|
||||
# set MKDEP_MK=auto.dep.mk and dep.mk will include us
|
||||
|
||||
# This version differs from autodep.mk, in that
|
||||
# This version differs from autodep.mk, in that
|
||||
# we use ${.TARGET:T}.d rather than ${.TARGET:T:R}.d
|
||||
# this makes it simpler to get the args to -MF and -MT right
|
||||
# and ensure we can simply include all the .d files.
|
||||
#
|
||||
#
|
||||
# However suffix rules do not work with something like .o.d so we
|
||||
# don't even try to handle 'make depend' gracefully.
|
||||
# dep.mk will handle that itself.
|
||||
@ -37,7 +37,7 @@ __${.PARSEFILE}__:
|
||||
|
||||
# set this to -MMD to ignore /usr/include
|
||||
# actually it ignores <> so may not be a great idea
|
||||
CFLAGS_MD ?= -MD
|
||||
CFLAGS_MD ?= -MD
|
||||
# -MF etc not available on all gcc versions.
|
||||
CFLAGS_MF ?= -MF ${.TARGET:T}.d -MT ${.TARGET:T}
|
||||
CFLAGS += ${CFLAGS_MD} ${CFLAGS_MF}
|
||||
|
@ -1,14 +1,14 @@
|
||||
# $Id: auto.obj.mk,v 1.15 2017/11/04 21:05:04 sjg Exp $
|
||||
# $Id: auto.obj.mk,v 1.16 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2004, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
@ -16,7 +16,7 @@
|
||||
ECHO_TRACE ?= echo
|
||||
|
||||
.ifndef Mkdirs
|
||||
# A race condition in some versions of mkdir, means that it can bail
|
||||
# A race condition in some versions of mkdir, means that it can bail
|
||||
# if another process made a dir that mkdir expected to.
|
||||
# We repeat the mkdir -p a number of times to try and work around this.
|
||||
# We stop looping as soon as the dir exists.
|
||||
@ -53,7 +53,7 @@ __objdir:= ${__objdir}
|
||||
# We need to chdir, make the directory if needed
|
||||
.if !exists(${__objdir}/) && \
|
||||
(${.TARGETS} == "" || ${.TARGETS:Nclean*:N*clean:Ndestroy*} != "")
|
||||
# This will actually make it...
|
||||
# This will actually make it...
|
||||
__objdir_made != echo ${__objdir}/; umask ${OBJDIR_UMASK:U002}; \
|
||||
${ECHO_TRACE} "[Creating objdir ${__objdir}...]" >&2; \
|
||||
${Mkdirs}; Mkdirs ${__objdir}
|
||||
|
@ -1,14 +1,14 @@
|
||||
# $Id: autoconf.mk,v 1.9 2017/08/13 20:03:13 sjg Exp $
|
||||
# $Id: autoconf.mk,v 1.10 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1996-2009, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
@ -49,7 +49,7 @@ CLEANFILES+= config.recheck config.gen config.status *.meta
|
||||
AUTOCONF ?= autoconf
|
||||
AUTOHEADER ?= autoheader
|
||||
|
||||
# expand it to a full path
|
||||
# expand it to a full path
|
||||
AUTOCONF := ${AUTOCONF:${M_whence}}
|
||||
|
||||
.if exists(${AUTOCONF})
|
||||
|
@ -1,16 +1,16 @@
|
||||
#
|
||||
# RCSid:
|
||||
# $Id: autodep.mk,v 1.37 2020/04/17 21:08:17 sjg Exp $
|
||||
# $Id: autodep.mk,v 1.38 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1999-2010, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
|
||||
@ -51,7 +51,7 @@ ${s:T:R}.d: $s
|
||||
.endfor
|
||||
|
||||
__depsrcs:=${__depsrcs:T:R:S/$/.d/g}
|
||||
# we also need to handle makefiles where the .d's from __depsrcs
|
||||
# we also need to handle makefiles where the .d's from __depsrcs
|
||||
# don't match those from OBJS
|
||||
# we avoid using := here, since the modifier applied to OBJS
|
||||
# can cause trouble if there are any undefined vars in OBJS.
|
||||
@ -64,7 +64,7 @@ __dependsrcs= ${__dependsrcsx:O:u}
|
||||
|
||||
# set this to -MMD to ignore /usr/include
|
||||
# actually it ignores <> so may not be a great idea
|
||||
CFLAGS_MD?=-MD
|
||||
CFLAGS_MD?=-MD
|
||||
# -MF etc not available on all gcc versions.
|
||||
# we "fix" the .o later
|
||||
CFLAGS_MF?=-MF ${.TARGET:T:R}.d -MT ${.TARGET:T:R}.o
|
||||
@ -73,8 +73,8 @@ RM?= rm
|
||||
MAKE_SHELL?= sh
|
||||
|
||||
# watch out for people who don't use CPPFLAGS
|
||||
CPPFLAGS_MD=${CFLAGS:M-[IUD]*} ${CPPFLAGS}
|
||||
CXXFLAGS_MD=${CXXFLAGS:M-[IUD]*} ${CPPFLAGS}
|
||||
CPPFLAGS_MD=${CFLAGS:M-[IUD]*} ${CPPFLAGS}
|
||||
CXXFLAGS_MD=${CXXFLAGS:M-[IUD]*} ${CPPFLAGS}
|
||||
|
||||
# just in case these need to be different
|
||||
CC_MD?=${CC}
|
||||
|
@ -1,14 +1,14 @@
|
||||
# $Id: compiler.mk,v 1.6 2019/09/28 17:12:00 sjg Exp $
|
||||
# $Id: compiler.mk,v 1.7 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2019, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
@ -1,15 +1,15 @@
|
||||
# RCSid:
|
||||
# $Id: cython.mk,v 1.7 2018/03/25 18:46:11 sjg Exp $
|
||||
# $Id: cython.mk,v 1.8 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2014, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
179
mk/dirdeps-cache-update.mk
Normal file
179
mk/dirdeps-cache-update.mk
Normal file
@ -0,0 +1,179 @@
|
||||
# $Id: dirdeps-cache-update.mk,v 1.21 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2020, 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 makefile deals with the updating of STATIC_DIRDEPS_CACHE.
|
||||
# Some targets are so huge that computing dirdeps takes a significant
|
||||
# amount of time. For such targets a STATIC_DIRDEPS_CACHE can make
|
||||
# sense.
|
||||
#
|
||||
# If the target is represented by targets/pseudo/production
|
||||
# it's normal DIRDEPS would be in
|
||||
# targets/pseudo/production/Makefile.depend
|
||||
# and STATIC_DIRDEPS_CACHE would be
|
||||
# targets/pseudo/production/Makefile.dirdeps.cache
|
||||
# which is simply initialized by copying dirdeps.cache.production
|
||||
# from $OBJTOP
|
||||
#
|
||||
# When dirdeps-targets.mk is initializing DIRDEPS it will look for
|
||||
# Makefile.dirdeps.cache and unless told not to
|
||||
# (MK_STATIC_DIRDEPS_CACHE=no) will use it as DIRDEPS_CACHE.
|
||||
#
|
||||
# If MK_STATIC_DIRDEPS_CACHE_UPDATE is "yes", then this makefile
|
||||
# comes into play.
|
||||
#
|
||||
# We usually get included from local.dirdeps.mk
|
||||
# as well as Makefile.depend of RELDIR with a static Makefile.dirdeps.cache
|
||||
#
|
||||
# If we see that STATIC_DIRDEPS_CACHE is in use, we need to hook a
|
||||
# cache-update target into the build to regenerate dirdeps.cache
|
||||
# in parallel with the rest of the build.
|
||||
# If MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE is "yes" we update
|
||||
# STATIC_DIRDEPS_CACHE as soon as the update is ready,
|
||||
# otherwise it will be done at the end of the build.
|
||||
#
|
||||
# If STATIC_DIRDEPS_CACHE is not in use, but a DIRDEPS_CACHE is,
|
||||
# then we need do nothing except export STATIC_DIRDEPS_CACHE and
|
||||
# DYNAMIC_DIRDEPS_CACHE for use when we are include during the visit
|
||||
# to the ultimate target (targets/pseudo/production).
|
||||
#
|
||||
# Regardless of which happens, when included at .MAKE.LEVEL > 0
|
||||
# for a target other than cache-update we simply copy
|
||||
# DYNAMIC_DIRDEPS_CACHE to STATIC_DIRDEPS_CACHE with some optional
|
||||
# filtering.
|
||||
#
|
||||
# If we are included for the target cache-update we take care of
|
||||
# running dirdeps.mk again to generate the DYNAMIC_DIRDEPS_CACHE.
|
||||
#
|
||||
|
||||
.if !target(_${.PARSEFILE}_)
|
||||
_${.PARSEFILE}_: .NOTMAIN
|
||||
|
||||
STATIC_CACHE_SED += \
|
||||
-e '/Autogenerated/s,-.*,- edit with care!,' \
|
||||
-e '/cache-update/d'
|
||||
|
||||
STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT ?= \
|
||||
{ echo Saving ${DYNAMIC_DIRDEPS_CACHE} as ${STATIC_DIRDEPS_CACHE}; \
|
||||
sed ${STATIC_CACHE_SED} ${DYNAMIC_DIRDEPS_CACHE} > ${STATIC_DIRDEPS_CACHE}; }
|
||||
.endif
|
||||
|
||||
.if ${MK_DIRDEPS_CACHE:Uno} == "yes"
|
||||
.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE:Uno} == "yes"
|
||||
.if ${_debug_reldir:U0} || ${DEBUG_DIRDEPS:U:Mcache*} != ""
|
||||
_debug_cache = 1
|
||||
.else
|
||||
_debug_cache = 0
|
||||
.endif
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0 && !make(cache-update)
|
||||
|
||||
.if ${_debug_cache}
|
||||
.info ${MK_STATIC_DIRDEPS_CACHE_UPDATE MK_STATIC_DIRDEPS_CACHE MK_DIRDEPS_CACHE DIRDEPS_CACHE STATIC_DIRDEPS_CACHE:L:@v@$v=${$v}@}
|
||||
.endif
|
||||
|
||||
.if ${MK_STATIC_DIRDEPS_CACHE} == "yes" && defined(STATIC_DIRDEPS_CACHE) && exists(${STATIC_DIRDEPS_CACHE})
|
||||
.if !make(dirdeps)
|
||||
# We are using static cache and this is the only look we will get.
|
||||
# We want to generate an updated cache while we build
|
||||
# so need to hook cache-update to dirdeps now.
|
||||
# Note: we are running as a sibling to dirdeps-cached,
|
||||
# attempting to do this in that context is problematic.
|
||||
|
||||
# One of these should exist - to actually kick off the cache generation
|
||||
.for d in ${STATIC_DIRDEPS_CACHE:H}/cache-update ${STATIC_DIRDEPS_CACHE:H:H}/cache-update ${STATIC_DIRDEPS_CACHE:H:H:H}/cache-update
|
||||
.if exists($d)
|
||||
cache_update_dirdep ?= $d.${TARGET_SPEC}
|
||||
.endif
|
||||
.endfor
|
||||
.if !target(${cache_update_dirdep})
|
||||
dirdeps: ${cache_update_dirdep}
|
||||
${cache_update_dirdep}: _DIRDEP_USE
|
||||
DYNAMIC_DIRDEPS_CACHE := ${OBJTOP}/dirdeps.cache.${STATIC_DIRDEPS_CACHE:H:T}-update
|
||||
.export DYNAMIC_DIRDEPS_CACHE STATIC_DIRDEPS_CACHE
|
||||
.endif
|
||||
.endif # make(dirdeps)
|
||||
.endif # MK_*
|
||||
|
||||
.endif # .MAKE.LEVEL 0
|
||||
|
||||
.if ${.MAKE.LEVEL} > 0 && ${.CURDIR:T} == "cache-update"
|
||||
# we are the background update shim
|
||||
|
||||
.if ${_debug_cache}
|
||||
.info level ${.MAKE.LEVEL}: ${MK_DIRDEPS_CACHE DYNAMIC_DIRDEPS_CACHE STATIC_DIRDEPS_CACHE:L:@v@$v=${$v}@}
|
||||
.endif
|
||||
|
||||
all: cache-build
|
||||
cache-build: .META
|
||||
@set -x; MAKELEVEL=0 \
|
||||
${.MAKE} -C ${SRCTOP} -f ${RELDIR}/Makefile cache-update \
|
||||
-DWITHOUT_STATIC_DIRDEPS_CACHE_UPDATE
|
||||
|
||||
.endif # cache-update
|
||||
|
||||
.elif ${.MAKE.LEVEL} == 0 && make(cache-update) && !target(cache-update)
|
||||
# we were invoked above
|
||||
# we just leverage dirdeps.mk
|
||||
BUILD_DIRDEPS_TARGETS := ${STATIC_DIRDEPS_CACHE:H:T}
|
||||
DIRDEPS := ${STATIC_DIRDEPS_CACHE:H:S,^${SRCTOP}/,,}.${TARGET_SPEC}
|
||||
DIRDEPS_CACHE := ${DYNAMIC_DIRDEPS_CACHE}
|
||||
|
||||
.if ${DEBUG_DIRDEPS:U:Mcache*} != ""
|
||||
.info level 0: ${MK_DIRDEPS_CACHE DIRDEPS_CACHE DIRDEPS:L:@v@$v=${$v}@}
|
||||
.endif
|
||||
|
||||
# so cache-built below can check on us
|
||||
x!= echo; echo ${.MAKE.PID} > ${DIRDEPS_CACHE}.new.pid
|
||||
|
||||
cache-update: ${DIRDEPS_CACHE}
|
||||
@rm -f ${DIRDEPS_CACHE}.new.pid
|
||||
.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE:Uno} == "yes"
|
||||
${STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT}
|
||||
.endif
|
||||
|
||||
all:
|
||||
|
||||
.include <dirdeps.mk>
|
||||
|
||||
.endif # MK_STATIC_DIRDEPS_CACHE_UPDATE
|
||||
.endif # MK_DIRDEPS_CACHE
|
||||
|
||||
.if ${.MAKE.LEVEL} > 0 && ${MK_STATIC_DIRDEPS_CACHE_UPDATE:Uno} == "yes" && \
|
||||
${STATIC_DIRDEPS_CACHE:Uno:H} == "${SRCTOP}/${RELDIR}"
|
||||
.if !defined(DYNAMIC_DIRDEPS_CACHE)
|
||||
all:
|
||||
.else
|
||||
# This is the easy bit, time to save the cache
|
||||
|
||||
all: cache-update
|
||||
|
||||
# ensure the cache update is completed
|
||||
cache-built:
|
||||
@test -s ${DYNAMIC_DIRDEPS_CACHE}.new || exit 0; \
|
||||
pid=`cat ${DYNAMIC_DIRDEPS_CACHE}.new.pid 2> /dev/null`; \
|
||||
test $${pid:-0} -gt 1 || exit 0; \
|
||||
echo "Waiting for $$pid to finish ${DYNAMIC_DIRDEPS_CACHE} ..."; \
|
||||
while 'kill' -0 $$pid; do sleep 30; done > /dev/null 2>&1
|
||||
|
||||
cache-update: cache-built
|
||||
.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE:Uno} == "no"
|
||||
@test ! -s ${DYNAMIC_DIRDEPS_CACHE} || \
|
||||
${STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT}
|
||||
.endif
|
||||
|
||||
.endif
|
||||
.endif
|
@ -1,6 +1,6 @@
|
||||
# $Id: dirdeps-options.mk,v 1.9 2018/09/20 00:07:19 sjg Exp $
|
||||
# $Id: dirdeps-options.mk,v 1.17 2020/08/07 01:57:38 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2018, Simon J. Gerraty
|
||||
# @(#) Copyright (c) 2018-2020, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
@ -37,6 +37,11 @@
|
||||
# to whatever applies for that dir, or it can rely on globals
|
||||
# set in local.dirdeps-options.mk
|
||||
# Either way, we will .undef DIRDEPS.* when done.
|
||||
#
|
||||
# In some cases the value of MK_FOO might depend on TARGET_SPEC
|
||||
# so we qualify MK_FOO with .${TARGET_SPEC} and each component
|
||||
# TARGET_SPEC_VAR (in reverse order) before using MK_FOO.
|
||||
#
|
||||
|
||||
# This should have been set by Makefile.depend.options
|
||||
# before including us
|
||||
@ -47,21 +52,43 @@ DIRDEPS_OPTIONS ?=
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0
|
||||
# :U below avoids potential errors when we :=
|
||||
.for o in ${DIRDEPS_OPTIONS:tu}
|
||||
DIRDEPS += ${DIRDEPS.$o.${MK_$o:U}:U}
|
||||
# some options can depend on TARGET_SPEC!
|
||||
DIRDEPS_OPTIONS_QUALIFIER_LIST ?= \
|
||||
${DEP_TARGET_SPEC:U${TARGET_SPEC}} \
|
||||
${TARGET_SPEC_VARSr:U${TARGET_SPEC_VARS}:@v@${DEP_$v:U${$v}}@}
|
||||
# note that we need to include $o in the variable _o$o
|
||||
# to ensure correct evaluation.
|
||||
.for o in ${DIRDEPS_OPTIONS}
|
||||
.undef _o$o _v$o
|
||||
.for x in ${DIRDEPS_OPTIONS_QUALIFIER_LIST}
|
||||
.if defined(MK_$o.$x)
|
||||
_o$o ?= MK_$o.$x
|
||||
_v$o ?= ${MK_$o.$x}
|
||||
.endif
|
||||
.endfor
|
||||
_v$o ?= ${MK_$o}
|
||||
.if ${_debug_reldir:U0}
|
||||
.info ${DEP_RELDIR:U${RELDIR}}.${DEP_TARGET_SPEC:U${TARGET_SPEC}}: o=$o ${_o$o:UMK_$o}=${_v$o:U} DIRDEPS += ${DIRDEPS.$o.${_v$o:U}:U}
|
||||
.endif
|
||||
DIRDEPS += ${DIRDEPS.$o.${_v$o:U}:U}
|
||||
.endfor
|
||||
DIRDEPS := ${DIRDEPS:O:u}
|
||||
.if ${_debug_reldir:U0}
|
||||
.info ${DEP_RELDIR:U${RELDIR}}: DIRDEPS=${DIRDEPS}
|
||||
.endif
|
||||
# avoid cross contamination
|
||||
.for o in ${DIRDEPS_OPTIONS:tu}
|
||||
.for o in ${DIRDEPS_OPTIONS}
|
||||
.undef DIRDEPS.$o.yes
|
||||
.undef DIRDEPS.$o.no
|
||||
.undef _o$o
|
||||
.undef _v$o
|
||||
.endfor
|
||||
.else
|
||||
# whether options are enabled or not,
|
||||
# we want to filter out the relevant DIRDEPS.*
|
||||
# we should only be included by meta.autodep.mk
|
||||
# if dependencies are to be updated
|
||||
.for o in ${DIRDEPS_OPTIONS:tu}
|
||||
.for o in ${DIRDEPS_OPTIONS}
|
||||
.for d in ${DIRDEPS.$o.yes} ${DIRDEPS.$o.no}
|
||||
.if exists(${SRCTOP}/$d)
|
||||
GENDIRDEPS_FILTER += N$d*
|
||||
|
@ -1,15 +1,15 @@
|
||||
# RCSid:
|
||||
# $Id: dirdeps-targets.mk,v 1.10 2020/06/06 22:41:02 sjg Exp $
|
||||
# $Id: dirdeps-targets.mk,v 1.22 2020/08/15 18:00:11 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2019-2020 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
@ -25,7 +25,16 @@
|
||||
# We then search those dirs for any Makefile.depend*
|
||||
# Finally we select any that match conditions like REQUESTED_MACHINE
|
||||
# or TARGET_SPEC and initialize DIRDEPS accordingly.
|
||||
#
|
||||
#
|
||||
# We will check each of the initial DIRDEPS for Makefile.dirdeps.options
|
||||
# and include any found.
|
||||
# This makes it feasible to tweak options like MK_DIRDEPS_CACHE
|
||||
# for a specific target.
|
||||
#
|
||||
# If MK_STATIC_DIRDEPS_CACHE is defined we will check if the
|
||||
# initial DIRDEPS has a static cache (Makefile.dirdeps.cache).
|
||||
# This only makes sense for seriously expensive targets.
|
||||
#
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0
|
||||
# pickup customizations
|
||||
@ -125,12 +134,38 @@ DIRDEPS := ${DIRDEPS:O:u}
|
||||
.endif
|
||||
# if we got DIRDEPS get to work
|
||||
.if !empty(DIRDEPS)
|
||||
DIRDEPS.dirs := ${DIRDEPS:S,^,${SRCTOP}/,:@d@${exists($d):?$d:${d:R}}@}
|
||||
# some targets what to tweak options we might want to process now
|
||||
.for m in ${DIRDEPS.dirs:S,$,/Makefile.dirdeps.options,}
|
||||
.-include <$m>
|
||||
.endfor
|
||||
.if defined(MK_STATIC_DIRDEPS_CACHE)
|
||||
# some targets are very expensive to compute dirdeps for
|
||||
# so we may have a static cache
|
||||
.for c in ${DIRDEPS.dirs:S,$,/Makefile.dirdeps.cache,}
|
||||
.if exists($c)
|
||||
STATIC_DIRDEPS_CACHE ?= $c
|
||||
.if ${MK_STATIC_DIRDEPS_CACHE} == "yes"
|
||||
DIRDEPS_CACHE ?= $c
|
||||
MK_DIRDEPS_CACHE = yes
|
||||
.endif
|
||||
.endif
|
||||
.endfor
|
||||
.if defined(STATIC_DIRDEPS_CACHE)
|
||||
.export STATIC_DIRDEPS_CACHE
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# allow a top-level makefile to do other stuff
|
||||
# before including dirdeps.mk
|
||||
.if ${MK_DIRDEPS_TARGETS_INCLUDE_DIRDEPS:Uyes} == "yes"
|
||||
.include <dirdeps.mk>
|
||||
.endif
|
||||
|
||||
DIRDEPS_TARGETS_SKIP += all clean* destroy*
|
||||
|
||||
.for t in ${.TARGETS:${DIRDEPS_TARGETS_SKIP:${M_ListToSkip}}}
|
||||
$t: dirdeps
|
||||
.endfor
|
||||
.endfor
|
||||
.endif
|
||||
.endif
|
||||
|
132
mk/dirdeps.mk
132
mk/dirdeps.mk
@ -1,4 +1,4 @@
|
||||
# $Id: dirdeps.mk,v 1.106 2020/07/11 16:25:17 sjg Exp $
|
||||
# $Id: dirdeps.mk,v 1.125 2020/08/26 21:49:45 sjg Exp $
|
||||
|
||||
# Copyright (c) 2010-2020, Simon J. Gerraty
|
||||
# Copyright (c) 2010-2018, Juniper Networks, Inc.
|
||||
@ -41,7 +41,7 @@
|
||||
# or .<target_spec> suffix (see TARGET_SPEC_VARS below),
|
||||
# for example to force building something for the pseudo
|
||||
# machines "host" or "common" regardless of current ${MACHINE}.
|
||||
#
|
||||
#
|
||||
# All unqualified entries end up being qualified with .${TARGET_SPEC}
|
||||
# and partially qualified (if TARGET_SPEC_VARS has multiple
|
||||
# entries) are also expanded to a full .<target_spec>.
|
||||
@ -50,29 +50,22 @@
|
||||
#
|
||||
# The fully qualified directory entries are used to construct a
|
||||
# dependency graph that will drive the build later.
|
||||
#
|
||||
#
|
||||
# Also, for each fully qualified directory target, we will search
|
||||
# using ${.MAKE.DEPENDFILE_PREFERENCE} to find additional
|
||||
# dependencies. We use Makefile.depend (default value for
|
||||
# .MAKE.DEPENDFILE_PREFIX) to refer to these makefiles to
|
||||
# distinguish them from others.
|
||||
#
|
||||
#
|
||||
# Before each Makefile.depend file is read, we set
|
||||
# DEP_RELDIR to be the RELDIR (path relative to SRCTOP) for
|
||||
# its directory, and DEP_MACHINE etc according to the .<target_spec>
|
||||
# represented by the suffix of the corresponding target.
|
||||
#
|
||||
#
|
||||
# Since each Makefile.depend file includes dirdeps.mk, this
|
||||
# processing is recursive and results in .MAKE.LEVEL 0 learning the
|
||||
# dependencies of the tree wrt the initial directory (_DEP_RELDIR).
|
||||
#
|
||||
# BUILD_AT_LEVEL0
|
||||
# Indicates whether .MAKE.LEVEL 0 builds anything:
|
||||
# if "no" sub-makes are used to build everything,
|
||||
# if "yes" sub-makes are only used to build for other machines.
|
||||
# It is best to use "no", but this can require fixing some
|
||||
# makefiles to not do anything at .MAKE.LEVEL 0.
|
||||
#
|
||||
# TARGET_SPEC_VARS
|
||||
# The default value is just MACHINE, and for most environments
|
||||
# this is sufficient. The _DIRDEP_USE target actually sets
|
||||
@ -113,12 +106,12 @@
|
||||
# # make sure we know what TARGET_SPEC is
|
||||
# # as we may need it to find Makefile.depend*
|
||||
# TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
|
||||
#
|
||||
#
|
||||
# The following variables can influence the initial DIRDEPS
|
||||
# computation with regard to the TARGET_SPECs that will be
|
||||
# built.
|
||||
# Most should also be considered by init.mk
|
||||
#
|
||||
#
|
||||
# ONLY_TARGET_SPEC_LIST
|
||||
# Defines a list of TARGET_SPECs for which the current
|
||||
# directory can be built.
|
||||
@ -137,6 +130,19 @@
|
||||
# A list of MACHINEs the current directory should not be
|
||||
# built for.
|
||||
#
|
||||
# _build_xtra_dirs
|
||||
# local.dirdeps.mk can add targets to this variable.
|
||||
# They will be hooked into the build, but independent of
|
||||
# any other DIRDEP.
|
||||
#
|
||||
# This allows for adding TESTS to the build, such that the build
|
||||
# if any test fails, but without the risk of introducing
|
||||
# circular dependencies.
|
||||
|
||||
now_utc ?= ${%s:L:gmtime}
|
||||
.if !defined(start_utc)
|
||||
start_utc := ${now_utc}
|
||||
.endif
|
||||
|
||||
.if !target(bootstrap) && (make(bootstrap) || \
|
||||
make(bootstrap-this) || \
|
||||
@ -157,11 +163,6 @@ _DIRDEP_USE_LEVEL?= 0
|
||||
_CURDIR ?= ${.CURDIR}
|
||||
_OBJDIR ?= ${.OBJDIR}
|
||||
|
||||
now_utc = ${%s:L:gmtime}
|
||||
.if !defined(start_utc)
|
||||
start_utc := ${now_utc}
|
||||
.endif
|
||||
|
||||
.if ${MAKEFILE:T} == ${.PARSEFILE} && empty(DIRDEPS) && ${.TARGETS:Uall:M*/*} != ""
|
||||
# This little trick let's us do
|
||||
#
|
||||
@ -223,6 +224,7 @@ _tspec_m$i := ${TARGET_SPEC_VARS:[2..$i]:@w@[^,]+@:ts,}
|
||||
_tspec_a$i := ,${TARGET_SPEC_VARS:[$i..-1]:@v@$$$${DEP_$v}@:ts,}
|
||||
M_dep_qual_fixes += C;(\.${_tspec_m$i})$$;\1${_tspec_a$i};
|
||||
.endfor
|
||||
TARGET_SPEC_VARSr := ${TARGET_SPEC_VARS:[-1..1]}
|
||||
.else
|
||||
# A harmless? default.
|
||||
M_dep_qual_fixes = U
|
||||
@ -307,6 +309,7 @@ DEP_MACHINE := ${_DEP_TARGET_SPEC}
|
||||
|
||||
# reset each time through
|
||||
_build_all_dirs =
|
||||
_build_xtra_dirs =
|
||||
|
||||
# the first time we are included the _DIRDEP_USE target will not be defined
|
||||
# we can use this as a clue to do initialization and other one time things.
|
||||
@ -337,7 +340,7 @@ BUILD_DIRDEPS ?= yes
|
||||
|
||||
.if ${MK_DIRDEPS_CACHE} == "yes"
|
||||
# this is where we will cache all our work
|
||||
DIRDEPS_CACHE ?= ${_OBJDIR:tA}/dirdeps.cache${.TARGETS:Nall:O:u:ts-:S,/,_,g:S,^,.,:N.}
|
||||
DIRDEPS_CACHE ?= ${_OBJDIR:tA}/dirdeps.cache${_TARGETS:U${.TARGETS}:Nall:O:u:ts-:S,/,_,g:S,^,.,:N.}
|
||||
.endif
|
||||
|
||||
.if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.${DEP_MACHINE}:L:M$x}@} != ""
|
||||
@ -393,6 +396,18 @@ DIRDEPS_FILTER += M${_DEP_RELDIR}
|
||||
DIRDEP_MAKE ?= ${.MAKE}
|
||||
DIRDEP_DIR ?= ${.TARGET:R}
|
||||
|
||||
# if you want us to report load averages during build
|
||||
# DIRDEP_USE_PRELUDE += ${DIRDEP_LOADAVG_REPORT};
|
||||
|
||||
DIRDEP_LOADAVG_CMD ?= ${UPTIME:Uuptime} | sed 's,.*\(load\),\1,'
|
||||
DIRDEP_LOADAVG_LAST = 0
|
||||
# yes the expression here is a bit complicated,
|
||||
# the trick is to only eval ${DIRDEP_LOADAVG_LAST::=${now_utc}}
|
||||
# when we want to report.
|
||||
DIRDEP_LOADAVG_REPORT = \
|
||||
test -z "${"${expr ${now_utc} - ${DIRDEP_LOADAVG_INTEVAL:U60} - ${DIRDEP_LOADAVG_LAST}:L:sh:N-*}":?yes${DIRDEP_LOADAVG_LAST::=${now_utc}}:}" || \
|
||||
echo "${TRACER}`${DIRDEP_LOADAVG_CMD}`"
|
||||
|
||||
# we suppress SUBDIR when visiting the leaves
|
||||
# we assume sys.mk will set MACHINE_ARCH
|
||||
# you can add extras to DIRDEP_USE_ENV
|
||||
@ -400,7 +415,7 @@ DIRDEP_DIR ?= ${.TARGET:R}
|
||||
_DIRDEP_USE: .USE .MAKE
|
||||
@for m in ${.MAKE.MAKEFILE_PREFERENCE}; do \
|
||||
test -s ${.TARGET:R}/$$m || continue; \
|
||||
echo "${TRACER}Checking ${.TARGET:R} for ${.TARGET:E} ..."; \
|
||||
echo "${TRACER}Checking ${.TARGET:S,${SRCTOP}/,,} for ${.TARGET:E} ..."; \
|
||||
${DIRDEP_USE_PRELUDE} \
|
||||
MACHINE_ARCH= NO_SUBDIR=1 ${DIRDEP_USE_ENV} \
|
||||
TARGET_SPEC=${.TARGET:E} \
|
||||
@ -480,9 +495,13 @@ dirdeps-cached: ${DIRDEPS_CACHE} .MAKE
|
||||
dirdeps MK_DIRDEPS_CACHE=no BUILD_DIRDEPS=no
|
||||
|
||||
# these should generally do
|
||||
BUILD_DIRDEPS_MAKEFILE ?= ${MAKEFILE}
|
||||
BUILD_DIRDEPS_MAKEFILE ?=
|
||||
BUILD_DIRDEPS_TARGETS ?= ${.TARGETS}
|
||||
|
||||
.if ${DIRDEPS_CACHE} != ${STATIC_DIRDEPS_CACHE:Uno} && ${DIRDEPS_CACHE:M${SRCTOP}/*} == ""
|
||||
# export this for dirdeps-cache-update.mk
|
||||
DYNAMIC_DIRDEPS_CACHE := ${DIRDEPS_CACHE}
|
||||
.export DYNAMIC_DIRDEPS_CACHE
|
||||
# we need the .meta file to ensure we update if
|
||||
# any of the Makefile.depend* changed.
|
||||
# We do not want to compare the command line though.
|
||||
@ -494,26 +513,28 @@ ${DIRDEPS_CACHE}: .META .NOMETA_CMP
|
||||
+@MAKELEVEL=${.MAKE.LEVEL} DIRDEPS_CACHE=${DIRDEPS_CACHE} \
|
||||
DIRDEPS="${DIRDEPS}" \
|
||||
TARGET_SPEC=${TARGET_SPEC} \
|
||||
MAKEFLAGS= ${.MAKE} -C ${_CURDIR} -f ${BUILD_DIRDEPS_MAKEFILE} \
|
||||
MAKEFLAGS= ${DIRDEP_CACHE_MAKE:U${.MAKE}} -C ${_CURDIR} \
|
||||
${BUILD_DIRDEPS_MAKEFILE} \
|
||||
${BUILD_DIRDEPS_TARGETS} BUILD_DIRDEPS_CACHE=yes \
|
||||
.MAKE.DEPENDFILE=.none \
|
||||
${.MAKEFLAGS:tW:S,-D ,-D,g:tw:M*WITH*} \
|
||||
${.MAKEFLAGS:tW:S,-d ,-d,g:tw:M-d*} \
|
||||
3>&1 1>&2 | sed 's,${SRCTOP},$${SRCTOP},g' >> ${.TARGET}.new && \
|
||||
3>&1 1>&2 | sed 's,${SRCTOP},$${SRCTOP},g;s,_{,$${,g' >> ${.TARGET}.new && \
|
||||
mv ${.TARGET}.new ${.TARGET}
|
||||
|
||||
.endif
|
||||
.endif
|
||||
.elif !target(_count_dirdeps)
|
||||
# we want to capture the dirdeps count in the cache
|
||||
.END: _count_dirdeps
|
||||
_count_dirdeps: .NOMETA
|
||||
@{ echo; echo '.info $${.newline}$${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]}'; } >&3
|
||||
@{ echo; echo '.info $${.newline}$${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]} ${DIRDEP_INFO_XTRAS}'; } >&3
|
||||
|
||||
.endif
|
||||
.elif !make(dirdeps) && !target(_count_dirdeps)
|
||||
beforedirdeps: _count_dirdeps
|
||||
_count_dirdeps: .NOMETA
|
||||
@echo "${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]} seconds=`expr ${now_utc} - ${start_utc}`"
|
||||
@echo "${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]} ${DIRDEP_INFO_XTRAS} seconds=`expr ${now_utc} - ${start_utc}`"
|
||||
|
||||
.endif
|
||||
.endif
|
||||
@ -570,19 +591,7 @@ _build_dirs =
|
||||
|
||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
||||
# pickup other machines for this dir if necessary
|
||||
.if ${BUILD_AT_LEVEL0:Uyes} == "no"
|
||||
_build_dirs += ${_machines:@m@${_CURDIR}.$m@}
|
||||
.else
|
||||
_build_dirs += ${_machines:N${DEP_TARGET_SPEC}:@m@${_CURDIR}.$m@}
|
||||
.if ${DEP_TARGET_SPEC} == ${TARGET_SPEC}
|
||||
# pickup local dependencies now
|
||||
.if ${MAKE_VERSION} < 20160220
|
||||
.-include <.depend>
|
||||
.else
|
||||
.dinclude <.depend>
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${_debug_reldir}
|
||||
@ -635,7 +644,7 @@ _build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u}
|
||||
|
||||
.endif # empty DIRDEPS
|
||||
|
||||
_build_all_dirs += ${_build_dirs}
|
||||
_build_all_dirs += ${_build_dirs} ${_build_xtra_dirs}
|
||||
_build_all_dirs := ${_build_all_dirs:O:u}
|
||||
|
||||
# Normally if doing make -V something,
|
||||
@ -647,12 +656,7 @@ _build_all_dirs := ${_build_all_dirs:O:u}
|
||||
x!= echo; { echo; echo '\# ${DEP_RELDIR}.${DEP_TARGET_SPEC}'; } >&3
|
||||
# guard against _new_dirdeps being too big for a single command line
|
||||
_new_dirdeps := ${_build_all_dirs:@x@${target($x):?:$x}@}
|
||||
.if !empty(_new_dirdeps)
|
||||
.export _new_dirdeps
|
||||
x!= echo; { echo; echo "dirdeps: \\"; \
|
||||
for x in $$_new_dirdeps; do echo " $$x \\"; done; echo; \
|
||||
for x in $$_new_dirdeps; do echo "$$x: _DIRDEP_USE"; done; } >&3
|
||||
.endif
|
||||
.export _build_xtra_dirs _new_dirdeps
|
||||
.if !empty(DEP_EXPORT_VARS)
|
||||
# Discouraged, but there are always exceptions.
|
||||
# Handle it here rather than explain how.
|
||||
@ -676,7 +680,8 @@ DEP_EXPORT_VARS=
|
||||
# this builds the dependency graph
|
||||
.for m in ${_machines}
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes" && !empty(_build_dirs)
|
||||
x!= echo; { echo; echo "${_this_dir}.$m: \\"; } >&3
|
||||
x!= echo; { echo; echo 'DIRDEPS.${_this_dir}.$m = \'; } >&3
|
||||
_cache_deps =
|
||||
.endif
|
||||
# it would be nice to do :N${.TARGET}
|
||||
.if !empty(__qual_depdirs)
|
||||
@ -685,11 +690,7 @@ x!= echo; { echo; echo "${_this_dir}.$m: \\"; } >&3
|
||||
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$q}
|
||||
.endif
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes"
|
||||
_cache_deps := ${_build_dirs:M*.$q}
|
||||
.if !empty(_cache_deps)
|
||||
.export _cache_deps
|
||||
x!= echo; for x in $$_cache_deps; do echo " $$x \\"; done >&3
|
||||
.endif
|
||||
_cache_deps += ${_build_dirs:M*.$q}
|
||||
.else
|
||||
${_this_dir}.$m: ${_build_dirs:M*.$q}
|
||||
.endif
|
||||
@ -699,11 +700,17 @@ ${_this_dir}.$m: ${_build_dirs:M*.$q}
|
||||
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
.endif
|
||||
.if ${BUILD_DIRDEPS_CACHE} == "yes"
|
||||
_cache_deps := ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
.if !empty(_build_dirs)
|
||||
_cache_deps += ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
.if !empty(_cache_deps)
|
||||
.export _cache_deps
|
||||
x!= echo; for x in $$_cache_deps; do echo " $$x \\"; done >&3
|
||||
.endif
|
||||
x!= echo; { echo; echo '${_this_dir}.$m: $${DIRDEPS.${_this_dir}.$m}'; \
|
||||
echo; echo 'dirdeps: ${_this_dir}.$m \'; \
|
||||
for x in $$_build_xtra_dirs; do echo " $$x \\"; done; \
|
||||
echo; for x in $$_new_dirdeps; do echo "$$x: _DIRDEP_USE"; done; } >&3
|
||||
.endif
|
||||
.else
|
||||
${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m}
|
||||
.endif
|
||||
@ -773,6 +780,27 @@ _DEP_RELDIR := ${RELDIR}
|
||||
# This is a final opportunity to add/hook global rules.
|
||||
.-include <local.dirdeps-build.mk>
|
||||
|
||||
# skip _reldir_{finish,failed} if not included from Makefile.depend*
|
||||
# or not in meta mode
|
||||
.if !defined(WITHOUT_META_STATS) && ${.INCLUDEDFROMFILE:U:M${.MAKE.DEPENDFILE_PREFIX}*} != "" && ${.MAKE.MODE:Mmeta} != ""
|
||||
|
||||
meta_stats= meta=${empty(.MAKE.META.FILES):?0:${.MAKE.META.FILES:[#]}} \
|
||||
created=${empty(.MAKE.META.CREATED):?0:${.MAKE.META.CREATED:[#]}}
|
||||
|
||||
.if !target(_reldir_finish)
|
||||
.END: _reldir_finish
|
||||
_reldir_finish: .NOMETA
|
||||
@echo "${TRACER}Finished ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}"
|
||||
.endif
|
||||
|
||||
.if !target(_reldir_failed)
|
||||
.ERROR: _reldir_failed
|
||||
_reldir_failed: .NOMETA
|
||||
@echo "${TRACER}Failed ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}"
|
||||
.endif
|
||||
|
||||
.endif
|
||||
|
||||
# pickup local dependencies
|
||||
.if ${MAKE_VERSION} < 20160220
|
||||
.-include <.depend>
|
||||
|
30
mk/dpadd.mk
30
mk/dpadd.mk
@ -1,14 +1,14 @@
|
||||
# $Id: dpadd.mk,v 1.27 2019/05/17 13:58:53 sjg Exp $
|
||||
# $Id: dpadd.mk,v 1.28 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2004, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
@ -75,7 +75,7 @@
|
||||
# and -L${STAGE_OBJTOP}/usr/lib are sufficient, and we should
|
||||
# have no need of anything else.
|
||||
#
|
||||
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
|
||||
@ -98,7 +98,7 @@ RELOBJTOP?= ${OBJTOP}
|
||||
RELSRCTOP?= ${SRCTOP}
|
||||
|
||||
# we get included just about everywhere so this is handy...
|
||||
# C*DEBUG_XTRA are for defining on cmd line etc
|
||||
# C*DEBUG_XTRA are for defining on cmd line etc
|
||||
# so do not use in makefiles.
|
||||
.ifdef CFLAGS_DEBUG_XTRA
|
||||
CFLAGS_LAST += ${CFLAGS_DEBUG_XTRA}
|
||||
@ -180,14 +180,14 @@ SRC_LIBS+= ${_OBJDIR}/lib${LIB}.a
|
||||
.endif
|
||||
.endif
|
||||
|
||||
#
|
||||
#
|
||||
# This little bit of magic, assumes that SRC_libfoo will be
|
||||
# set if it cannot be correctly derrived from ${LIBFOO}
|
||||
# Note that SRC_libfoo and INCLUDES_libfoo should be named for the
|
||||
# actual library name not the variable name that might refer to it.
|
||||
# 99% of the time the two are the same, but the DPADD logic
|
||||
# only has the library name available, so stick to that.
|
||||
#
|
||||
#
|
||||
|
||||
SRC_LIBS?=
|
||||
# magic_libs includes those we want to link with
|
||||
@ -198,7 +198,7 @@ DPMAGIC_LIBS += ${__dpadd_magic_libs} \
|
||||
|
||||
# we skip this for staged libs
|
||||
.for __lib in ${DPMAGIC_LIBS:O:u:N${STAGE_OBJTOP:Unot}*/lib/*}
|
||||
#
|
||||
#
|
||||
# if SRC_libfoo is not set, then we assume that the srcdir corresponding
|
||||
# to where we found the library is correct.
|
||||
#
|
||||
@ -215,8 +215,8 @@ INCLUDES_${__lib:T:R}?= -I${exists(${SRC_${__lib:T:R}}/h):?${SRC_${__lib:T:R}}/h
|
||||
|
||||
.endfor
|
||||
|
||||
# even for staged libs we sometimes
|
||||
# need to allow direct -I to avoid cicular dependencies
|
||||
# even for staged libs we sometimes
|
||||
# need to allow direct -I to avoid cicular dependencies
|
||||
.for __lib in ${DPMAGIC_LIBS:O:u:T:R}
|
||||
.if !empty(SRC_${__lib}) && empty(INCLUDES_${__lib})
|
||||
# must be a staged lib
|
||||
@ -267,7 +267,7 @@ __dpadd_last_incs += ${__dpadd_magic_libs:O:u:@s@${SRC_LIBS_${s:T:R}:U}@:@x@${IN
|
||||
__dpadd_last_incs := \
|
||||
${__dpadd_last_incs:N-I/usr/*} \
|
||||
${__dpadd_incs:M-I/usr/*} \
|
||||
${__dpadd_last_incs:M-I/usr/*}
|
||||
${__dpadd_last_incs:M-I/usr/*}
|
||||
__dpadd_incs := ${__dpadd_incs:N-I/usr/*}
|
||||
.endif
|
||||
|
||||
@ -310,12 +310,12 @@ dpadd: .NOTMAIN
|
||||
.endif
|
||||
|
||||
.ifdef SRC_PATHADD
|
||||
# We don't want to assume that we need to .PATH every element of
|
||||
# We don't want to assume that we need to .PATH every element of
|
||||
# SRC_LIBS, but the Makefile cannot do
|
||||
# .PATH: ${SRC_libfoo}
|
||||
# since the value of SRC_libfoo must be available at the time .PATH:
|
||||
# is read - and we only just worked it out.
|
||||
# Further, they can't wait until after include of {lib,prog}.mk as
|
||||
# is read - and we only just worked it out.
|
||||
# Further, they can't wait until after include of {lib,prog}.mk as
|
||||
# the .PATH is needed before then.
|
||||
# So we let the Makefile do
|
||||
# SRC_PATHADD+= ${SRC_libfoo}
|
||||
|
@ -1,14 +1,14 @@
|
||||
# $Id: files.mk,v 1.6 2017/05/07 02:21:02 sjg Exp $
|
||||
# $Id: files.mk,v 1.7 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2017, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
@ -1,18 +1,18 @@
|
||||
# $Id: gendirdeps.mk,v 1.44 2020/06/23 04:21:51 sjg Exp $
|
||||
# $Id: gendirdeps.mk,v 1.46 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
# Copyright (c) 2011-2020, Simon J. Gerraty
|
||||
# Copyright (c) 2010-2018, Juniper Networks, 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:
|
||||
# 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.
|
||||
# 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.
|
||||
#
|
||||
# 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
|
||||
@ -23,7 +23,7 @@
|
||||
# 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.
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#
|
||||
# This makefile [re]generates ${.MAKE.DEPENDFILE}
|
||||
@ -104,7 +104,7 @@ GENDIRDEPS_FILTER += ${GENDIRDEPS_FILTER_DIR_VARS:@v@S,${$v},_{${v}},@}
|
||||
GENDIRDEPS_FILTER += ${GENDIRDEPS_FILTER_VARS:@v@S,/${$v}/,/_{${v}}/,@:NS,//,*:u}
|
||||
.endif
|
||||
|
||||
# this (*should* be set in meta.sys.mk)
|
||||
# this (*should* be set in meta.sys.mk)
|
||||
# is the script that extracts what we want.
|
||||
META2DEPS ?= ${.PARSEDIR}/meta2deps.sh
|
||||
META2DEPS := ${META2DEPS}
|
||||
@ -122,7 +122,7 @@ _py_d =
|
||||
.if ${META2DEPS:E} == "py"
|
||||
# we can afford to do this all the time.
|
||||
DPDEPS ?= no
|
||||
META2DEPS_CMD = ${_time} ${PYTHON} ${META2DEPS} ${_py_d}
|
||||
META2DEPS_CMD = ${_time} ${PYTHON} ${META2DEPS} ${_py_d}
|
||||
.if ${DPDEPS:tl} != "no"
|
||||
META2DEPS_CMD += -D ${DPDEPS}
|
||||
.endif
|
||||
@ -155,8 +155,8 @@ M2D_OBJROOTS += ${STAGE_ROOT}
|
||||
# and tell it not to add machine qualifiers
|
||||
META2DEPS_ARGS += MACHINE=none
|
||||
.endif
|
||||
.if defined(SB_BACKING_SB)
|
||||
META2DEPS_CMD += -S ${SB_BACKING_SB}/src
|
||||
.if defined(SB_BACKING_SB)
|
||||
META2DEPS_CMD += -S ${SB_BACKING_SB}/src
|
||||
M2D_OBJROOTS += ${SB_BACKING_SB}/${SB_OBJPREFIX}
|
||||
.endif
|
||||
|
||||
@ -177,7 +177,7 @@ _meta_files := ${META_FILES:N\*.meta:O:u}
|
||||
# assume a big list
|
||||
_meta_files_arg= @meta.list
|
||||
.if empty(_meta_files) && ${META_FILES:M\*.meta} != ""
|
||||
# XXX this should be considered a bad idea,
|
||||
# XXX this should be considered a bad idea,
|
||||
# since we cannot ignore stale .meta
|
||||
x != cd ${_OBJDIR} && find . -name '*.meta' -print -o \( -type d ! -name . -prune \) | sed 's,^./,,' > meta.list; echo
|
||||
.elif ${_meta_files:[#]} > 500
|
||||
@ -234,10 +234,10 @@ dir_list += ${ddeps}
|
||||
|
||||
# DIRDEPS represent things that had to have been built first
|
||||
# so they should all be undir OBJTOP.
|
||||
# Note that ${_OBJTOP}/bsd/include/machine will get reported
|
||||
# Note that ${_OBJTOP}/bsd/include/machine will get reported
|
||||
# to us as $SRCTOP/bsd/sys/$MACHINE_ARCH/include meaning we
|
||||
# will want to visit bsd/include
|
||||
# so we add
|
||||
# so we add
|
||||
# ${"${dir_list:M*bsd/sys/${MACHINE_ARCH}/include}":?bsd/include:}
|
||||
# to GENDIRDEPS_DIR_LIST_XTRAS
|
||||
_objtops = ${OBJTOP} ${_OBJTOP} ${_objtop}
|
||||
@ -272,11 +272,11 @@ DIRDEPS = \
|
||||
|
||||
# We only consider things below $RELDIR/ if they have a makefile.
|
||||
# This is the same test that _DIRDEP_USE applies.
|
||||
# We have do a double test with dirdep_list as it _may_ contain
|
||||
# We have do a double test with dirdep_list as it _may_ contain
|
||||
# qualified dirs - if we got anything from a stage dir.
|
||||
# qualdir_list we know are all qualified.
|
||||
# It would be nice do peform this check for all of DIRDEPS,
|
||||
# but we cannot assume that all of the tree is present,
|
||||
# but we cannot assume that all of the tree is present,
|
||||
# in fact we can only assume that RELDIR is.
|
||||
DIRDEPS += \
|
||||
${dirdep_list:M${RELDIR}/*:@d@${.MAKE.MAKEFILE_PREFERENCE:@m@${exists(${SRCTOP}/$d/$m):?$d:${exists(${SRCTOP}/${d:R}/$m):?$d:}}@}@} \
|
||||
@ -309,7 +309,7 @@ SRC_DIRDEPS = \
|
||||
SRC_DIRDEPS := ${SRC_DIRDEPS:${GENDIRDEPS_SRC_FILTER:UN/*:ts:}:C,//+,/,g:O:u}
|
||||
|
||||
# if you want to capture SRC_DIRDEPS in .MAKE.DEPENDFILE put
|
||||
# SRC_DIRDEPS_FILE = ${_DEPENDFILE}
|
||||
# SRC_DIRDEPS_FILE = ${_DEPENDFILE}
|
||||
# in local.gendirdeps.mk
|
||||
.if ${SRC_DIRDEPS_FILE:Uno:tl} != "no"
|
||||
ECHO_SRC_DIRDEPS = echo 'SRC_DIRDEPS = \'; echo '${SRC_DIRDEPS:@d@ $d \\${.newline}@}'; echo;
|
||||
@ -324,7 +324,7 @@ ${SRC_DIRDEPS_FILE}: ${META_FILES} ${_this} ${META2DEPS}
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
_include_src_dirdeps ?=
|
||||
_include_src_dirdeps ?=
|
||||
|
||||
all: ${_DEPENDFILE}
|
||||
|
||||
@ -339,11 +339,7 @@ CAT_DEPEND ?= .depend
|
||||
.PHONY: ${_DEPENDFILE}
|
||||
.endif
|
||||
|
||||
.if ${BUILD_AT_LEVEL0:Uno:tl} == "no"
|
||||
LOCAL_DEPENDS_GUARD ?= _{.MAKE.LEVEL} > 0
|
||||
.else
|
||||
LOCAL_DEPENDS_GUARD ?= _{DEP_RELDIR} == _{_DEP_RELDIR}
|
||||
.endif
|
||||
|
||||
# 'cat .depend' should suffice, but if we are mixing build modes
|
||||
# .depend may contain things we don't want.
|
||||
|
@ -1,5 +1,5 @@
|
||||
# RCSid:
|
||||
# $Id: host-target.mk,v 1.12 2020/07/08 23:35:29 sjg Exp $
|
||||
# $Id: host-target.mk,v 1.13 2020/08/05 23:32:08 sjg Exp $
|
||||
|
||||
# Host platform information; may be overridden
|
||||
.if !defined(_HOST_OSNAME)
|
||||
@ -16,7 +16,7 @@ _HOST_MACHINE != uname -m
|
||||
.endif
|
||||
.if !defined(_HOST_ARCH)
|
||||
# for NetBSD prefer $MACHINE (amd64 rather than x86_64)
|
||||
.if ${_HOST_OSNAME:NNetBSD} == ""
|
||||
.if ${_HOST_OSNAME:NDarwin:NNetBSD} == ""
|
||||
_HOST_ARCH := ${_HOST_MACHINE}
|
||||
.else
|
||||
_HOST_ARCH != uname -p 2> /dev/null || uname -m
|
||||
|
@ -1,14 +1,14 @@
|
||||
# $Id: host.libnames.mk,v 1.4 2010/01/11 23:01:31 sjg Exp $
|
||||
# $Id: host.libnames.mk,v 1.5 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2007-2009, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
@ -1,14 +1,14 @@
|
||||
# $Id: inc.mk,v 1.7 2017/05/06 17:29:45 sjg Exp $
|
||||
# $Id: inc.mk,v 1.8 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2008, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
14
mk/init.mk
14
mk/init.mk
@ -1,14 +1,14 @@
|
||||
# $Id: init.mk,v 1.17 2020/05/25 20:15:07 sjg Exp $
|
||||
# $Id: init.mk,v 1.21 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
@ -65,7 +65,11 @@ CC_PIC?= -DPIC
|
||||
CXX_PIC?= ${CC_PIC}
|
||||
PROFFLAGS?= -DGPROF -DPROF
|
||||
|
||||
.if ${.MAKE.LEVEL:U1} == 0 && ${BUILD_AT_LEVEL0:Uyes:tl} == "no"
|
||||
# targets that are ok at level 0
|
||||
LEVEL0_TARGETS += clean* destory*
|
||||
M_ListToSkip= O:u:S,^,N,:ts:
|
||||
|
||||
.if ${.MAKE.LEVEL:U1} == 0 && ${MK_DIRDEPS_BUILD:Uno} == "yes" && ${.TARGETS:Uall:${LEVEL0_TARGETS:${M_ListToSkip}}} != ""
|
||||
# this tells lib.mk and prog.mk to not actually build anything
|
||||
_SKIP_BUILD = not building at level 0
|
||||
.endif
|
||||
|
@ -33,7 +33,7 @@
|
||||
#
|
||||
# All our *.mk files are copied to "dest" with appropriate
|
||||
# ownership and permissions.
|
||||
#
|
||||
#
|
||||
# By default if a sys.mk can be found in a standard location
|
||||
# (that bmake will find) then no sys.mk will be put in "dest".
|
||||
#
|
||||
@ -55,22 +55,22 @@
|
||||
# Simon J. Gerraty <sjg@crufty.net>
|
||||
|
||||
# RCSid:
|
||||
# $Id: install-mk,v 1.174 2020/07/10 21:50:14 sjg Exp $
|
||||
# $Id: install-mk,v 1.179 2020/08/26 21:49:45 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
MK_VERSION=20200710
|
||||
MK_VERSION=20200826
|
||||
OWNER=
|
||||
GROUP=
|
||||
MODE=444
|
||||
@ -137,7 +137,7 @@ if [ -s $SYS_MK -a -d $dest ]; then
|
||||
sys_mk_dir=`realpath $SYS_MK_DIR`
|
||||
if [ $dest = $sys_mk_dir ]; then
|
||||
case "$os" in
|
||||
*BSD*) SKIP_SYS_MK=:
|
||||
*BSD*) SKIP_SYS_MK=:
|
||||
SKIP_BSD_MK=:
|
||||
;;
|
||||
*) # could be fake?
|
||||
|
@ -1,14 +1,14 @@
|
||||
# $Id: install-new.mk,v 1.3 2012/03/24 18:25:49 sjg Exp $
|
||||
# $Id: install-new.mk,v 1.4 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2009, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
10
mk/java.mk
10
mk/java.mk
@ -1,16 +1,16 @@
|
||||
#
|
||||
# RCSid:
|
||||
# $Id: java.mk,v 1.14 2007/11/22 08:16:25 sjg Exp $
|
||||
# $Id: java.mk,v 1.15 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
# @(#) Copyright (c) 1998-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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
@ -53,7 +53,7 @@ JAVAC_FLAGS+= ${JAVAC_DBG}
|
||||
|
||||
.if defined(MAKE_VERSION) && !defined(NO_CLASSES_COOKIE)
|
||||
# java works best by compiling a bunch of classes at once.
|
||||
# this lot does that but needs a recent netbsd make or
|
||||
# this lot does that but needs a recent netbsd make or
|
||||
# or its portable cousin bmake.
|
||||
.for __s in ${SRCS}
|
||||
__c:= ${__classdest}${__s:.java=.class}
|
||||
|
14
mk/lib.mk
14
mk/lib.mk
@ -1,4 +1,4 @@
|
||||
# $Id: lib.mk,v 1.70 2020/05/02 02:10:20 sjg Exp $
|
||||
# $Id: lib.mk,v 1.71 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
.if !target(__${.PARSEFILE}__)
|
||||
__${.PARSEFILE}__:
|
||||
@ -67,7 +67,7 @@ META_NOECHO?= echo
|
||||
# Alpha-specific shared library flags
|
||||
FPICFLAGS ?= -fPIC
|
||||
CPICFLAGS ?= -fPIC -DPIC
|
||||
CPPPICFLAGS?= -DPIC
|
||||
CPPPICFLAGS?= -DPIC
|
||||
CAPICFLAGS?= ${CPPPICFLAGS} ${CPICFLAGS}
|
||||
APICFLAGS ?=
|
||||
.elif ${MACHINE_ARCH} == "mipsel" || ${MACHINE_ARCH} == "mipseb"
|
||||
@ -87,7 +87,7 @@ MKPICLIB= no
|
||||
|
||||
.elif (${MACHINE_ARCH} == "sparc" || ${MACHINE_ARCH} == "sparc64") && \
|
||||
${OBJECT_FMT} == "ELF"
|
||||
# If you use -fPIC you need to define BIGPIC to turn on 32-bit
|
||||
# If you use -fPIC you need to define BIGPIC to turn on 32-bit
|
||||
# relocations in asm code
|
||||
FPICFLAGS ?= -fPIC
|
||||
CPICFLAGS ?= -fPIC -DPIC
|
||||
@ -102,7 +102,7 @@ SHLIB_SOVERSION=${SHLIB_FULLVERSION}
|
||||
SHLIB_SHFLAGS=
|
||||
FPICFLAGS ?= -fPIC
|
||||
CPICFLAGS?= -fPIC -DPIC
|
||||
CPPPICFLAGS?= -DPIC
|
||||
CPPPICFLAGS?= -DPIC
|
||||
CAPICFLAGS?= ${CPPPICFLAGS} ${CPICFLAGS}
|
||||
APICFLAGS?= -k
|
||||
|
||||
@ -246,7 +246,7 @@ DLLIB ?= -ldl
|
||||
.endif
|
||||
|
||||
# some libs have lots of objects, and scanning all .o, .po and ${PICO} meta files
|
||||
# is a waste of time, this tells meta.autodep.mk to just pick one
|
||||
# is a waste of time, this tells meta.autodep.mk to just pick one
|
||||
# (typically ${PICO})
|
||||
# yes, 42 is a random number.
|
||||
.if ${MK_DIRDEPS_BUILD} == "yes" && ${SRCS:Uno:[\#]} > 42
|
||||
@ -272,7 +272,7 @@ ${CXX_SUFFIXES:%=%.o}:
|
||||
${COMPILE.cc} ${.IMPSRC}
|
||||
|
||||
.S.o .s.o:
|
||||
${COMPILE.S} ${CFLAGS:M-[ID]*} ${AINC} ${.IMPSRC}
|
||||
${COMPILE.S} ${CFLAGS:M-[ID]*} ${AINC} ${.IMPSRC}
|
||||
|
||||
.if (${LD_X} == "")
|
||||
.c.po:
|
||||
@ -382,7 +382,7 @@ _LIBS+= ${libLDORDER_INC}
|
||||
.endif
|
||||
|
||||
.if !defined(_SKIP_BUILD)
|
||||
realbuild: ${_LIBS}
|
||||
realbuild: ${_LIBS}
|
||||
.endif
|
||||
|
||||
all: _SUBDIRUSE
|
||||
|
@ -1,14 +1,14 @@
|
||||
# $Id: libnames.mk,v 1.8 2016/04/05 15:58:37 sjg Exp $
|
||||
# $Id: libnames.mk,v 1.9 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2007-2009, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
20
mk/libs.mk
20
mk/libs.mk
@ -1,14 +1,14 @@
|
||||
# $Id: libs.mk,v 1.3 2013/08/02 18:28:48 sjg Exp $
|
||||
# $Id: libs.mk,v 1.6 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2006, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
@ -82,12 +82,18 @@ UPDATE_DEPENDFILE = NO
|
||||
LIBS_TARGETS+= cleandepend cleandir cleanobj depend install
|
||||
|
||||
.for b in ${LIBS:R:T:S,^lib,,}
|
||||
lib$b.a: ${SRCS} ${DPADD} ${SRCS_lib$b} ${DPADD_lib$b}
|
||||
(cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$b)
|
||||
lib$b.a: ${SRCS} ${DPADD} ${SRCS_lib$b} ${DPADD_lib$b}
|
||||
(cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$b -DWITHOUT_META_STATS)
|
||||
|
||||
.for t in ${LIBS_TARGETS:O:u}
|
||||
$b.$t: .PHONY .MAKE
|
||||
(cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$b ${@:E})
|
||||
(cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$b ${@:E} -DWITHOUT_META_STATS)
|
||||
.endfor
|
||||
.endfor
|
||||
|
||||
.if !defined(WITHOUT_META_STATS) && ${.MAKE.LEVEL} > 0
|
||||
.END: _reldir_finish
|
||||
.ERROR: _reldir_failed
|
||||
.endif
|
||||
|
||||
.endif
|
||||
|
@ -1,14 +1,14 @@
|
||||
# $Id: links.mk,v 1.6 2014/09/29 17:14:40 sjg Exp $
|
||||
# $Id: links.mk,v 1.7 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2005, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
@ -1,14 +1,14 @@
|
||||
# $Id: manifest.mk,v 1.2 2014/10/31 18:06:17 sjg Exp $
|
||||
# $Id: manifest.mk,v 1.3 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2014, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
@ -21,12 +21,12 @@
|
||||
# ${MANIFEST}.DIRS += bin sbin usr/bin ...
|
||||
# for each dir we have a ${MANIFEST}.SRCS.$dir
|
||||
# that provides the absolute path to the contents
|
||||
# ${MANIFEST}.SRCS.bin += ${OBJTOP}/bin/sh/sh
|
||||
# ${MANIFEST}.SRCS.bin += ${OBJTOP}/bin/sh/sh
|
||||
# ${MANIFEST}.SYMLINKS is a list of src target pairs
|
||||
# for each file/dir there are a number of attributes
|
||||
# UID GID MODE FLAGS
|
||||
# which can be set per dir, per file or we use defaults
|
||||
# eg.
|
||||
# eg.
|
||||
# MODE.sbin = 550
|
||||
# MODE.usr/sbin = 550
|
||||
# MODE.dirs = 555
|
||||
@ -37,7 +37,7 @@
|
||||
# means passwd gets 4555 other files in usr/bin get 555 and
|
||||
# files in usr/sbin get 500
|
||||
# STORE defaults to basename of src and target directory
|
||||
# but we can use
|
||||
# but we can use
|
||||
# ${MANIFEST}.SRCS.sbin += ${OBJTOP}/bin/sh-static/sh-static
|
||||
# STORE.sbin/sh-static = sbin/sh
|
||||
#
|
||||
@ -47,7 +47,7 @@
|
||||
UID.dirs ?= 0
|
||||
GID.dirs ?= 0
|
||||
MODE.dirs ?= 775
|
||||
FLAGS.dirs ?=
|
||||
FLAGS.dirs ?=
|
||||
|
||||
UID.files ?= 0
|
||||
GID.files ?= 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: meta.autodep.mk,v 1.50 2018/06/08 01:25:31 sjg Exp $
|
||||
# $Id: meta.autodep.mk,v 1.52 2020/07/18 05:57:57 sjg Exp $
|
||||
|
||||
#
|
||||
# @(#) Copyright (c) 2010, Simon J. Gerraty
|
||||
@ -57,7 +57,7 @@ _OBJTOP ?= ${OBJTOP}
|
||||
_OBJROOT ?= ${OBJROOT:U${_OBJTOP}}
|
||||
_DEPENDFILE := ${_CURDIR}/${.MAKE.DEPENDFILE:T}
|
||||
|
||||
.if ${.MAKE.LEVEL} > 0 || ${BUILD_AT_LEVEL0:Uyes:tl} == "yes"
|
||||
.if ${.MAKE.LEVEL} > 0
|
||||
# do not allow auto update if we ever built this dir without filemon
|
||||
NO_FILEMON_COOKIE = .nofilemon
|
||||
CLEANFILES += ${NO_FILEMON_COOKIE}
|
||||
@ -73,10 +73,8 @@ UPDATE_DEPENDFILE = NO
|
||||
.endif
|
||||
|
||||
.if ${.MAKE.LEVEL} == 0
|
||||
.if ${BUILD_AT_LEVEL0:Uyes:tl} == "no"
|
||||
UPDATE_DEPENDFILE = NO
|
||||
.endif
|
||||
.endif
|
||||
.if !exists(${_DEPENDFILE})
|
||||
_bootstrap_dirdeps = yes
|
||||
.endif
|
||||
@ -283,9 +281,7 @@ ${_DEPENDFILE}: ${_depend} ${.PARSEDIR}/gendirdeps.mk ${META2DEPS} $${.MAKE.MET
|
||||
.endif
|
||||
|
||||
.if ${_bootstrap_dirdeps} == "yes"
|
||||
.if ${BUILD_AT_LEVEL0:Uno} == "no"
|
||||
DIRDEPS+= ${RELDIR}.${TARGET_SPEC:U${MACHINE}}
|
||||
.endif
|
||||
# make sure this is included at least once
|
||||
.include <dirdeps.mk>
|
||||
.else
|
||||
@ -312,7 +308,7 @@ _reldir_finish: .NOMETA
|
||||
_reldir_failed: .NOMETA
|
||||
@echo "${TIME_STAMP} Failed ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}"
|
||||
|
||||
.if defined(WITH_META_STATS) && ${.MAKE.LEVEL} > 0
|
||||
.if !defined(WITHOUT_META_STATS) && ${.MAKE.LEVEL} > 0
|
||||
.END: _reldir_finish
|
||||
.ERROR: _reldir_failed
|
||||
.endif
|
||||
|
@ -1,14 +1,14 @@
|
||||
# $Id: meta.stage.mk,v 1.59 2020/04/25 18:18:27 sjg Exp $
|
||||
# $Id: meta.stage.mk,v 1.60 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2011-2017, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: meta.subdir.mk,v 1.11 2015/11/24 22:26:51 sjg Exp $
|
||||
# $Id: meta.subdir.mk,v 1.12 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
#
|
||||
# @(#) Copyright (c) 2010, Simon J. Gerraty
|
||||
@ -6,10 +6,10 @@
|
||||
# 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
@ -32,7 +32,7 @@ DIRDEPS = ${SUBDIR:N.WAIT:O:u:@d@${RELDIR}/$d@}
|
||||
.include <meta.autodep.mk>
|
||||
.else
|
||||
# this is the cunning bit
|
||||
# actually it is probably a bit risky
|
||||
# actually it is probably a bit risky
|
||||
# since we may pickup subdirs which are not relevant
|
||||
# the alternative is a walk through the tree though
|
||||
# which is difficult without a sub-make.
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: meta.sys.mk,v 1.36 2020/05/16 23:21:48 sjg Exp $
|
||||
# $Id: meta.sys.mk,v 1.38 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
#
|
||||
# @(#) Copyright (c) 2010-2020, Simon J. Gerraty
|
||||
@ -6,10 +6,10 @@
|
||||
# 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
@ -155,12 +155,6 @@ dirdeps:
|
||||
# the first .MAIN: is what counts
|
||||
# by default dirdeps is all we want at level0
|
||||
.MAIN: dirdeps
|
||||
# tell dirdeps.mk what we want
|
||||
BUILD_AT_LEVEL0 = no
|
||||
.endif
|
||||
.if ${.TARGETS:Nall} == ""
|
||||
# it works best if we do everything via sub-makes
|
||||
BUILD_AT_LEVEL0 ?= no
|
||||
.endif
|
||||
|
||||
.endif
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
'W' files opened for write or read-write,
|
||||
for filemon V3 and earlier.
|
||||
|
||||
|
||||
'E' files executed.
|
||||
|
||||
'L' files linked
|
||||
@ -37,20 +37,20 @@
|
||||
|
||||
"""
|
||||
RCSid:
|
||||
$Id: meta2deps.py,v 1.30 2020/06/08 23:05:00 sjg Exp $
|
||||
$Id: meta2deps.py,v 1.33 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
Copyright (c) 2011-2019, Simon J. Gerraty
|
||||
Copyright (c) 2011-2020, Simon J. Gerraty
|
||||
Copyright (c) 2011-2017, Juniper Networks, 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:
|
||||
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.
|
||||
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.
|
||||
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
|
||||
@ -62,8 +62,8 @@
|
||||
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.
|
||||
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""
|
||||
|
||||
import os, re, sys
|
||||
@ -164,7 +164,7 @@ def sort_unique(list, cmp=None, key=None, reverse=False):
|
||||
|
||||
def add_trims(x):
|
||||
return ['/' + x + '/',
|
||||
'/' + x,
|
||||
'/' + x,
|
||||
x + '/',
|
||||
x]
|
||||
|
||||
@ -181,7 +181,7 @@ class MetaFile:
|
||||
obj_deps = []
|
||||
src_deps = []
|
||||
file_deps = []
|
||||
|
||||
|
||||
def __init__(self, name, conf={}):
|
||||
"""if name is set we will parse it now.
|
||||
conf can have the follwing keys:
|
||||
@ -198,7 +198,7 @@ def __init__(self, name, conf={}):
|
||||
|
||||
TARGET_SPEC
|
||||
Sometimes MACHINE isn't enough.
|
||||
|
||||
|
||||
HOST_TARGET
|
||||
when we build for the pseudo machine 'host'
|
||||
the object tree uses HOST_TARGET rather than MACHINE.
|
||||
@ -222,7 +222,7 @@ def __init__(self, name, conf={}):
|
||||
debug_out open file to send debug output to (sys.stderr)
|
||||
|
||||
"""
|
||||
|
||||
|
||||
self.name = name
|
||||
self.debug = getv(conf, 'debug', 0)
|
||||
self.debug_out = getv(conf, 'debug_out', sys.stderr)
|
||||
@ -310,11 +310,11 @@ def reset(self):
|
||||
self.obj_deps = []
|
||||
self.src_deps = []
|
||||
self.file_deps = []
|
||||
|
||||
|
||||
def dirdeps(self, sep='\n'):
|
||||
"""return DIRDEPS"""
|
||||
return sep.strip() + sep.join(self.obj_deps)
|
||||
|
||||
|
||||
def src_dirdeps(self, sep='\n'):
|
||||
"""return SRC_DIRDEPS"""
|
||||
return sep.strip() + sep.join(self.src_deps)
|
||||
@ -333,7 +333,7 @@ def file_depends(self, out=None):
|
||||
def seenit(self, dir):
|
||||
"""rememer that we have seen dir."""
|
||||
self.seen[dir] = 1
|
||||
|
||||
|
||||
def add(self, list, data, clue=''):
|
||||
"""add data to list if it isn't already there."""
|
||||
if data not in list:
|
||||
@ -392,10 +392,10 @@ def try_parse(self, name=None, file=None):
|
||||
# give a useful clue
|
||||
print('{}:{}: '.format(self.name, self.line), end=' ', file=sys.stderr)
|
||||
raise
|
||||
|
||||
|
||||
def parse(self, name=None, file=None):
|
||||
"""A meta file looks like:
|
||||
|
||||
|
||||
# Meta data file "path"
|
||||
CMD "command-line"
|
||||
CWD "cwd"
|
||||
@ -506,6 +506,8 @@ def parse(self, name=None, file=None):
|
||||
continue
|
||||
elif w[0] in 'ERWS':
|
||||
path = w[2]
|
||||
if path == '.':
|
||||
continue
|
||||
self.parse_path(path, cwd, w[0], w)
|
||||
|
||||
if not file:
|
||||
@ -601,13 +603,13 @@ def parse_path(self, path, cwd, op=None, w=[]):
|
||||
self.seenit(w[2])
|
||||
self.seenit(dir)
|
||||
|
||||
|
||||
|
||||
def main(argv, klass=MetaFile, xopts='', xoptf=None):
|
||||
"""Simple driver for class MetaFile.
|
||||
|
||||
Usage:
|
||||
script [options] [key=value ...] "meta" ...
|
||||
|
||||
|
||||
Options and key=value pairs contribute to the
|
||||
dictionary passed to MetaFile.
|
||||
|
||||
@ -615,7 +617,7 @@ def main(argv, klass=MetaFile, xopts='', xoptf=None):
|
||||
add "SRCTOP" to the "SRCTOPS" list.
|
||||
|
||||
-C "CURDIR"
|
||||
|
||||
|
||||
-O "OBJROOT"
|
||||
add "OBJROOT" to the "OBJROOTS" list.
|
||||
|
||||
@ -626,7 +628,7 @@ def main(argv, klass=MetaFile, xopts='', xoptf=None):
|
||||
-H "HOST_TARGET"
|
||||
|
||||
-D "DPDEPS"
|
||||
|
||||
|
||||
-d bumps debug level
|
||||
|
||||
"""
|
||||
@ -666,7 +668,7 @@ def main(argv, klass=MetaFile, xopts='', xoptf=None):
|
||||
|
||||
debug = 0
|
||||
output = True
|
||||
|
||||
|
||||
opts, args = getopt.getopt(argv[1:], 'a:dS:C:O:R:m:D:H:qT:X:' + xopts)
|
||||
for o, a in opts:
|
||||
if o == '-a':
|
||||
|
@ -5,11 +5,11 @@
|
||||
#
|
||||
# SYNOPSIS:
|
||||
# meta2deps.sh SB="SB" "meta" ...
|
||||
#
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# This script looks each "meta" file and extracts the
|
||||
# information needed to deduce build and src dependencies.
|
||||
#
|
||||
#
|
||||
# To do this, we extract the 'CWD' record as well as all the
|
||||
# syscall traces which describe 'R'ead, 'C'hdir and 'E'xec
|
||||
# syscalls.
|
||||
@ -77,20 +77,20 @@
|
||||
|
||||
|
||||
# RCSid:
|
||||
# $Id: meta2deps.sh,v 1.12 2016/12/13 20:44:16 sjg Exp $
|
||||
# $Id: meta2deps.sh,v 1.13 2020/08/19 17:51:53 sjg Exp $
|
||||
|
||||
# Copyright (c) 2010-2013, Juniper Networks, 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:
|
||||
# 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.
|
||||
# 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.
|
||||
#
|
||||
# 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
|
||||
@ -101,14 +101,14 @@
|
||||
# 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.
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
meta2src() {
|
||||
cat /dev/null "$@" |
|
||||
sed -n '/^R .*\.[chyl]$/s,^..[0-9]* ,,p' |
|
||||
sort -u
|
||||
}
|
||||
|
||||
|
||||
meta2dirs() {
|
||||
cat /dev/null "$@" |
|
||||
sed -n '/^R .*\/.*\.[a-z0-9][^\/]*$/s,^..[0-9]* \(.*\)/[^/]*$,\1,p' |
|
||||
@ -169,7 +169,7 @@ meta2deps() {
|
||||
case "$MACHINE" in
|
||||
host) _ht=$HOST_TARGET;;
|
||||
esac
|
||||
|
||||
|
||||
for o in $OBJROOTS
|
||||
do
|
||||
case "$MACHINE,/$o/" in
|
||||
@ -203,7 +203,7 @@ meta2deps() {
|
||||
obj_re=
|
||||
add_list '|' -s '/*' src_re $SRCTOPS
|
||||
add_list '|' -s '*' obj_re $OBJROOTS
|
||||
|
||||
|
||||
[ -z "$RELDIR" ] && unset DPDEPS
|
||||
tf=/tmp/m2d$$-$USER
|
||||
rm -f $tf.*
|
||||
@ -274,10 +274,10 @@ meta2deps() {
|
||||
eval cwd_$pid=$cwd
|
||||
continue
|
||||
;;
|
||||
F,*) # $path is new pid
|
||||
F,*) # $path is new pid
|
||||
eval cwd_$path=$cwd ldir_$path=$ldir
|
||||
continue
|
||||
;;
|
||||
;;
|
||||
*) dir=${path%/*}
|
||||
case "$path" in
|
||||
$src_re|$obj_re) ;;
|
||||
|
@ -14,17 +14,17 @@ Many years ago, when building large software projects, I used GNU make
|
||||
to simplify developing complex build trees.
|
||||
|
||||
Since the early 90's my main development machines, run BSD
|
||||
(NetBSD_ to be precise), and the BSD source tree is good example of a
|
||||
large software project. It quickly became clear that
|
||||
``/usr/share/mk/*.mk`` were a great model, but were quite tightly
|
||||
linked to building the BSD tree.
|
||||
(NetBSD_ to be precise, and more recently FreeBSD), and the BSD source
|
||||
tree is good example of a large software project.
|
||||
It quickly became clear that ``/usr/share/mk/*.mk`` were a great
|
||||
model, but at the time were quite tightly linked to building the BSD tree.
|
||||
|
||||
Much as I liked using NetBSD, my customers were more likely to be
|
||||
using SunOS, HP-UX etc, so I started on bmake_ and a portable collection
|
||||
of mk-files (mk.tar.gz_). NetBSD provided much of the original structure.
|
||||
|
||||
Since then I've added a lot of features to NetBSD's make and hence to
|
||||
bmake which is kept closely in sync. The mk-files however have
|
||||
bmake which is kept closely in sync. The mk-files however have
|
||||
diverged quite a bit, though ideas are still picked up from NetBSD
|
||||
and FreeBSD.
|
||||
|
||||
@ -59,7 +59,7 @@ in such cases even the ``SRCS`` line is unnecessary as ``prog.mk``
|
||||
will default it to ``${PROG}.c``.
|
||||
|
||||
It is the sensible use of defaults and the plethora of macro modifiers
|
||||
provided by bmake_ that allow simple makefiles such as the above
|
||||
provided by bmake_ that allow simple makefiles such as the above to
|
||||
*just work* on many different systems.
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ mk-files
|
||||
========
|
||||
|
||||
This section provides a brief description of some of the ``*.mk``
|
||||
files.
|
||||
files.
|
||||
|
||||
sys.mk
|
||||
------
|
||||
@ -76,7 +76,7 @@ When bmake starts, it looks for ``sys.mk`` and reads it before doing
|
||||
anything else. Thus, this is the place to setup the environment for
|
||||
everyone else.
|
||||
|
||||
In this distribution, sys.mk avoids doing anything platform dependent.
|
||||
In this distribution, ``sys.mk`` avoids doing anything platform dependent.
|
||||
It is quite short, and includes a number of other files (which may or
|
||||
may not exists)
|
||||
|
||||
@ -97,7 +97,7 @@ examples/sys.clean-env.mk
|
||||
PATH HOME USER LOGNAME \
|
||||
SRCTOP OBJTOP OBJROOT \
|
||||
${_env_vars}
|
||||
|
||||
|
||||
_env_vars != env | egrep '^(${MAKE_SAVE_ENV_PREFIX:ts|})' | sed 's,=.*,,'; echo
|
||||
_export_list =
|
||||
.for v in ${MAKE_SAVE_ENV_VARS:O:u}
|
||||
@ -169,7 +169,7 @@ lib${LIB}.a
|
||||
An archive lib of ``.o`` files, this is the default
|
||||
|
||||
lib${LIB}_p.a
|
||||
A profiled lib of ``.po`` files.
|
||||
A profiled lib of ``.po`` files.
|
||||
Still an archive lib, but all the objects are built with
|
||||
profiling in mind - hence the different extension.
|
||||
It is skipped if ``MKPROFILE`` is "no".
|
||||
@ -194,7 +194,7 @@ lib${LIB}.${LD_so}
|
||||
|
||||
There is a lot of platform specific tweaking in ``lib.mk``, largely the
|
||||
result of the original distributions trying to avoid interfering with
|
||||
the system's ``sys.mk``.
|
||||
the system's ``sys.mk``.
|
||||
|
||||
libnames.mk
|
||||
-----------
|
||||
@ -204,22 +204,19 @@ include ``*.libnames.mk`` of which:
|
||||
|
||||
local.libnames.mk
|
||||
does not exist unless you create it. It is a handy way for you
|
||||
to customize without touching the distributed files.
|
||||
to customize without touching the distributed files.
|
||||
For example, on a test machine I needed to build openssl but
|
||||
not install it, so put the following in ``local.libnames.mk``::
|
||||
not install it, so put the following in ``local.libnames.mk``::
|
||||
|
||||
.if ${host_os} == "sunos"
|
||||
LIBCRYPTO = ${OBJTOP}/openssl/lib/crypto/libcrypto${DLIBEXT}
|
||||
LIBSSL = ${OBJTOP}/openssl/lib/ssl/libssl${DLIBEXT}
|
||||
INCLUDES_libcrypto = -I${OBJ_libcrypto}
|
||||
.endif
|
||||
|
||||
|
||||
The makefile created an openssl dir in ``${OBJ_libcrypto}`` to
|
||||
gather all the headers. dpadd.mk_ did the rest.
|
||||
|
||||
sjg.libnames.mk
|
||||
not part of the mk-files distribution.
|
||||
|
||||
host.libnames.mk
|
||||
contains logic to find any libs named in ``HOST_LIBS`` in
|
||||
``HOST_LIBDIRS``.
|
||||
@ -248,7 +245,7 @@ else in various ways::
|
||||
# it also has the same effect as SRC_LIBS
|
||||
DPADD += ${LIBSSLFD}
|
||||
|
||||
# indicate that not only must libsslfd be built,
|
||||
# indicate that not only must libsslfd be built,
|
||||
# but that we need to link with it.
|
||||
# this is almost exactly equivalent to
|
||||
# DPADD += ${LIBSSLFD}
|
||||
@ -324,7 +321,7 @@ If ``SUBDIR_MUST_EXIST`` is set, missing directories cause an error,
|
||||
otherwise a warning is issued. If you don't even want the warning,
|
||||
set ``MISSING_DIR=continue``.
|
||||
|
||||
Traditionally, ``subdir.mk`` prints clue as it visits each subdir::
|
||||
Traditionally, ``subdir.mk`` prints clues as it visits each subdir::
|
||||
|
||||
===> ssl
|
||||
===> ssl/lib
|
||||
@ -342,7 +339,7 @@ links.mk
|
||||
|
||||
Provides rules for processing lists of ``LINKS`` and ``SYMLINKS``.
|
||||
Each is expected to be a list of ``link`` and ``target`` pairs
|
||||
(``link`` -> ``target``).
|
||||
(``link`` -> ``target``).
|
||||
|
||||
The logic is generally in a ``_*_SCRIPT`` which is referenced in a
|
||||
``_*_USE`` (``.USE``) target.
|
||||
@ -353,7 +350,7 @@ For example::
|
||||
|
||||
SYMLINKS += ${.CURDIR}/${MACHINE_ARCH}/include machine
|
||||
header_links: _BUILD_SYMLINKS_USE
|
||||
|
||||
|
||||
md.o: header_links
|
||||
|
||||
would create a symlink called ``machine`` in ``${.OBJDIR}`` pointing to
|
||||
@ -394,10 +391,10 @@ post process the ``.d`` files into ``.depend``.
|
||||
auto.dep.mk
|
||||
-----------
|
||||
|
||||
A much simpler implementation than autodep.mk_ it uses
|
||||
A much simpler implementation than autodep.mk_ it uses
|
||||
``-MF ${.TARGET:T}.d``
|
||||
to avoid possible conflicts during parallel builds.
|
||||
This precludes the use of suffix rules to drive ``make depend``, so
|
||||
to avoid possible conflicts during parallel builds.
|
||||
This precludes the use of suffix rules to drive ``make depend``, so
|
||||
dep.mk_ handles that if specifically requested.
|
||||
|
||||
options.mk
|
||||
@ -452,7 +449,7 @@ on sparc, ``-Wno-unused`` would replace ``-Wunused``.
|
||||
|
||||
You should never need to edit ``warnings.mk``, it will include
|
||||
``warnings-sets.mk`` if it exists and you use that to make any local
|
||||
customizations.
|
||||
customizations.
|
||||
|
||||
rst2htm.mk
|
||||
----------
|
||||
@ -470,7 +467,7 @@ Meta mode
|
||||
=========
|
||||
|
||||
The 20110505 and later versions of ``mk-files`` include a number of
|
||||
makefiles contributed by Juniper Networks, Inc.
|
||||
makefiles contributed by Juniper Networks, Inc.
|
||||
These allow the latest version of bmake_ to run in `meta mode`_
|
||||
see `dirdeps.mk`_
|
||||
|
||||
@ -499,5 +496,5 @@ where you unpacked the tar file, you can::
|
||||
.. _mk.tar.gz: http://www.crufty.net/ftp/pub/sjg/mk.tar.gz
|
||||
|
||||
:Author: sjg@crufty.net
|
||||
:Revision: $Id: mk-files.txt,v 1.18 2018/12/08 07:27:15 sjg Exp $
|
||||
:Revision: $Id: mk-files.txt,v 1.20 2020/08/19 17:51:53 sjg Exp $
|
||||
:Copyright: Crufty.NET
|
||||
|
@ -1,16 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
# $Id: mkopt.sh,v 1.12 2020/06/23 04:16:35 sjg Exp $
|
||||
# $Id: mkopt.sh,v 1.13 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2014, 2020, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
@ -1,14 +1,14 @@
|
||||
# $Id: obj.mk,v 1.15 2012/11/11 22:37:02 sjg Exp $
|
||||
# $Id: obj.mk,v 1.16 2020/08/19 17:51:53 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 1999-2010, 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
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user