tools/make: Synchronize on NetBSD-current (30/03/2021 16:09 UTC)

This commit is contained in:
Marcelo Alencar 2021-03-30 18:26:46 -03:00
parent 4db99f4012
commit 21b3ce3e7e
848 changed files with 47753 additions and 25225 deletions

View File

@ -3544,114 +3544,828 @@
./usr/tests/usr.bin/m4/d_m4wrap.m4 tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/m4/d_m4wrap.m4 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/m4/d_m4wrap.out tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/m4/d_m4wrap.out tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/m4/t_m4 tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/m4/t_m4 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/Atffile tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/Atffile tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/Kyuafile tests-usr.bin-tests compattestfile,atf,kyua ./usr/tests/usr.bin/make/Kyuafile tests-usr.bin-tests compattestfile,atf,kyua
./usr/tests/usr.bin/make/d_comment.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_comment.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_comment.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_comment.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_cond1.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_cond1.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_cond1.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_cond1.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_dotwait.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_dotwait.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_dotwait.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_dotwait.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_export.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_export.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_export.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_export.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_export_all.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_export_all.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_export_all.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_export_all.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_moderrs.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_moderrs.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_moderrs.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_moderrs.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_modmatch.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_modmatch.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_modmatch.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_modmatch.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_modmisc.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_modmisc.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_modmisc.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_modmisc.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_modorder.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_modorder.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_modorder.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_modorder.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_modts.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_modts.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_modts.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_modts.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_modword.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_modword.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_modword.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_modword.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_posix.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_posix.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_posix.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_posix.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_qequals.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_qequals.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_qequals.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_qequals.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_ternary.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_ternary.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_ternary.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_ternary.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_unmatchedvarparen.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_unmatchedvarparen.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_unmatchedvarparen.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_unmatchedvarparen.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_varcmd.mk tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_varcmd.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/d_varcmd.out tests-obsolete obsolete,atf ./usr/tests/usr.bin/make/d_varcmd.out tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/t_make tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/t_make tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/Makefile tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/Makefile tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/comment.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/archive-suffix.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/comment.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/archive-suffix.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond1.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/archive.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond1.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/archive.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond2.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmd-errors-jobs.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond2.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmd-errors-jobs.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/doterror.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmd-errors-lint.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/doterror.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmd-errors-lint.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dotwait.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmd-errors.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dotwait.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmd-errors.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/error.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmd-interrupt.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/error.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmd-interrupt.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/escape.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmdline-redirect-stdin.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/escape.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmdline-redirect-stdin.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export-all.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmdline-undefined.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export-all.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmdline-undefined.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export-env.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmdline.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export-env.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cmdline.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/comment.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/comment.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/forloop.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/compat-error.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/forloop.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/compat-error.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/forsubst.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric-eq.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/forsubst.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric-eq.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/hash.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric-ge.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/hash.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric-ge.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/impsrc.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric-gt.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/impsrc.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric-gt.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/misc.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric-le.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/misc.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric-le.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/moderrs.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric-lt.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/moderrs.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric-lt.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modmatch.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric-ne.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modmatch.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric-ne.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modmisc.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modmisc.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-numeric.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modorder.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-string.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modorder.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-string.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modts.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-unary.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modts.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-cmp-unary.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modword.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-eof.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modword.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-eof.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/order.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-commands.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/order.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-commands.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/phony-end.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-defined.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/phony-end.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-defined.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/posix.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-empty.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/posix.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-empty.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/posix1.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-exists.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/posix1.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-exists.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/qequals.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-make-main.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/qequals.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-make-main.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suffixes.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-make.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suffixes.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-make.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sunshcmd.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-target.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sunshcmd.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func-target.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sysv.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sysv.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-func.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/ternary.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-late.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/ternary.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-late.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/unexport-env.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-op-and-lint.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/unexport-env.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-op-and-lint.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/unexport.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-op-and.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/unexport.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-op-and.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varcmd.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-op-not.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varcmd.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-op-not.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmisc.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-op-or-lint.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmisc.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-op-or-lint.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varshell.exp tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-op-or.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varshell.mk tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/make/unit-tests/cond-op-or.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-op-parentheses.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-op-parentheses.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-op.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-op.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-short.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-short.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-token-number.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-token-number.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-token-plain.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-token-plain.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-token-string.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-token-string.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-token-var.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-token-var.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-undef-lint.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond-undef-lint.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond1.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond1.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/cond2.exp obsolete-tests obsolete
./usr/tests/usr.bin/make/unit-tests/cond2.mk obsolete-tests obsolete
./usr/tests/usr.bin/make/unit-tests/counter-append.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/counter-append.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/counter.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/counter.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-colon-bug-cross-file.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-colon-bug-cross-file.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-colon.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-colon.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-double-colon-indep.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-double-colon-indep.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-double-colon.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-double-colon.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-exclam.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-exclam.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-none.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-none.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-percent.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-percent.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-var.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-var.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-wildcards.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep-wildcards.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dep.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-end.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-end.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-exec.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-exec.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-ignore.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-ignore.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-made.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-made.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-make.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-make.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-meta.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-meta.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-nometa.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-nometa.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-nometa_cmp.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-nometa_cmp.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-nopath.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-nopath.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-notmain.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-notmain.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-optional.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-optional.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-phony.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-phony.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-precious.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-precious.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-recursive.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-recursive.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-silent.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-silent.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-use.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-use.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-usebefore-double-colon.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-usebefore-double-colon.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-usebefore.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-usebefore.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-wait.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc-wait.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/depsrc.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-begin-fail-indirect.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-begin-fail-indirect.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-begin-fail.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-begin-fail.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-begin.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-begin.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-default.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-default.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-delete_on_error.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-delete_on_error.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-end-fail-all.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-end-fail-all.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-end-fail-indirect.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-end-fail-indirect.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-end-fail.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-end-fail.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-end-jobs.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-end-jobs.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-end.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-end.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-error.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-error.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-ignore.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-ignore.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-interrupt.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-interrupt.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-main.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-main.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-makeflags.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-makeflags.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-no_parallel.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-no_parallel.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-nopath.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-nopath.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-notparallel.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-notparallel.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-objdir.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-objdir.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-order.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-order.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-path-suffix.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-path-suffix.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-path.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-path.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-phony.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-phony.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-precious.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-precious.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-shell.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-shell.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-silent.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-silent.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-stale.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-stale.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-suffixes.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-suffixes.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dir-expand-path.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dir-expand-path.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dir.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dir.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-dinclude.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-dinclude.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-elif.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-elif.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-elifdef.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-elifdef.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-elifmake.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-elifmake.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-elifndef.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-elifndef.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-elifnmake.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-elifnmake.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-else.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-else.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-endfor.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-endfor.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-endif.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-endif.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-error.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-error.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-export-env.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-export-env.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-export-gmake.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-export-gmake.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-export-impl.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-export-impl.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-export-literal.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-export-literal.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-export.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-export.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for-errors.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for-errors.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for-escape.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for-escape.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for-generating-endif.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for-generating-endif.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for-lines.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for-lines.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for-null.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for-null.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-hyphen-include.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-hyphen-include.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-if-nested.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-if-nested.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-if.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-if.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-ifdef.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-ifdef.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-ifmake.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-ifmake.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-ifndef.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-ifndef.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-ifnmake.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-ifnmake.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-include-fatal.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-include-fatal.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-include.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-include.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-info.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-info.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-misspellings.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-misspellings.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-sinclude.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-sinclude.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-undef.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-undef.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-unexport-env.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-unexport-env.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-unexport.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-unexport.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-warning.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-warning.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directives.exp tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/directives.mk tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/dollar.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dollar.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/doterror.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/doterror.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dotwait.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/dotwait.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/envfirst.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/envfirst.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/error.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/error.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/escape.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/escape.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export-all.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export-all.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export-env.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export-env.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export-variants.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export-variants.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/export.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/forloop.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/forloop.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/forsubst.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/forsubst.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/gnode-submake.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/gnode-submake.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/hanoi-include.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/hanoi-include.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/hash.exp tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/hash.mk tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/impsrc.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/impsrc.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/include-main.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/include-main.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/include-sub.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/include-subsub.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/job-flags.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/job-flags.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/job-output-long-lines.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/job-output-long-lines.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/jobs-empty-commands.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/jobs-empty-commands.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/jobs-error-indirect.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/jobs-error-indirect.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/jobs-error-nested-make.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/jobs-error-nested-make.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/jobs-error-nested.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/jobs-error-nested.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/lint.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/lint.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/make-exported.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/make-exported.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/meta-cmd-cmp.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/meta-cmd-cmp.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/misc.exp tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/misc.mk tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/moderrs.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/moderrs.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modmatch.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modmatch.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modmisc.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modmisc.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modorder.exp tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/modorder.mk tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/modts.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modts.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modword.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/modword.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/objdir-writable.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/objdir-writable.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-backwards.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-backwards.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-chdir.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-chdir.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-all.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-all.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-archive.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-archive.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-cond.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-cond.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-curdir.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-curdir.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-dir.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-dir.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-errors.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-errors.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-file.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-file.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-for.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-for.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-g1.exp tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/opt-debug-g1.mk tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/opt-debug-graph1.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-graph1.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-graph2.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-graph2.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-graph3.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-graph3.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-hash.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-hash.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-jobs.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-jobs.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-lint.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-lint.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-loud.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-loud.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-making.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-making.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-meta.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-meta.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-no-rm.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-no-rm.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-parse.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-parse.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-suff.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-suff.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-targets.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-targets.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-var.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-var.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-varraw.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-varraw.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-x-trace.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug-x-trace.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-debug.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-define.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-define.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-env.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-env.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-file.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-file.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-ignore.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-ignore.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-include-dir.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-include-dir.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-jobs-internal.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-jobs-internal.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-jobs-no-action.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-jobs-no-action.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-jobs.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-jobs.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-keep-going-multiple.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-keep-going-multiple.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-keep-going.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-keep-going.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-m-include-dir.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-m-include-dir.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-no-action-at-all.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-no-action-at-all.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-no-action-runflags.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-no-action-runflags.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-no-action-touch.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-no-action-touch.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-no-action.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-no-action.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-query.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-query.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-raw.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-raw.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-silent.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-silent.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-touch-jobs.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-touch-jobs.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-touch.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-touch.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-tracefile.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-tracefile.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-var-expanded.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-var-expanded.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-var-literal.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-var-literal.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-warnings-as-errors.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-warnings-as-errors.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-where-am-i.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-where-am-i.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-x-reduce-exported.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt-x-reduce-exported.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/opt.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/order.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/order.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/parse-var.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/parse-var.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/phony-end.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/phony-end.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/posix.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/posix.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/posix1.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/posix1.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/qequals.exp tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/unit-tests/qequals.mk tests-obsolete obsolete,atf
./usr/tests/usr.bin/make/unit-tests/recursive.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/recursive.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-dots.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-dots.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-errctl.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-errctl.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-flags.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-flags.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-jobs-error.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-jobs-error.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-jobs.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-jobs.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-leading-at.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-leading-at.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-leading-hyphen.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-leading-hyphen.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-leading-plus.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-leading-plus.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-meta-chars.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-meta-chars.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-multi-line.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-multi-line.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-single-line.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh-single-line.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sh.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/shell-csh.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/shell-csh.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/shell-custom.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/shell-custom.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/shell-ksh.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/shell-ksh.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/shell-sh.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/shell-sh.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-add-later.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-add-later.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-clear-regular.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-clear-regular.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-clear-single.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-clear-single.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-incomplete.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-incomplete.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-lookup.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-lookup.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-main-several.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-main-several.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-main.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-main.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-phony.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-phony.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-rebuild.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-rebuild.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-self.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-self.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-transform-debug.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-transform-debug.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-transform-endless.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-transform-endless.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-transform-expand.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-transform-expand.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-transform-select.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suff-transform-select.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/suffixes.exp tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/suffixes.mk tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/sunshcmd.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sunshcmd.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/sysv.exp tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/sysv.mk tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/ternary.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/ternary.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/unexport-env.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/unexport-env.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/unexport.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/unexport.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/use-inference.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/use-inference.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class-cmdline.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class-cmdline.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class-env.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class-env.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class-global.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class-global.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class-local-legacy.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class-local-legacy.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class-local.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class-local.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-eval-short.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-eval-short.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-append.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-append.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-assign.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-assign.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-default.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-default.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-expand.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-expand.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-shell.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-shell.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-sunsh.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-sunsh.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-recursive.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-recursive.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varcmd.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varcmd.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/vardebug.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/vardebug.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varfind.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varfind.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmisc.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmisc.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-assign.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-assign.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-defined.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-defined.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-edge.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-edge.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-exclam-shell.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-exclam-shell.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-extension.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-extension.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-gmtime.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-gmtime.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-hash.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-hash.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-head.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-head.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-ifelse.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-ifelse.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-indirect.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-indirect.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-l-name-to-value.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-l-name-to-value.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-localtime.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-localtime.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-loop.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-loop.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-match-escape.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-match-escape.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-match.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-match.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-no-match.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-no-match.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-order-reverse.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-order-reverse.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-order-shuffle.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-order-shuffle.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-order.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-order.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-path.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-path.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-quote-dollar.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-quote-dollar.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-quote.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-quote.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-range.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-range.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-remember.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-remember.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-root.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-root.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-select-words.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-select-words.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-shell.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-shell.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-subst-regex.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-subst-regex.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-subst.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-subst.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-sun-shell.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-sun-shell.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-sysv.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-sysv.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-tail.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-tail.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-to-abs.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-to-abs.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-to-lower.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-to-lower.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-to-many-words.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-to-many-words.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-to-one-word.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-to-one-word.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-to-separator.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-to-separator.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-to-upper.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-to-upper.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-undefined.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-undefined.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-unique.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod-unique.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varmod.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dollar.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dollar.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-alltargets.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-alltargets.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-curdir.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-curdir.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-includedfromdir.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-includedfromdir.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-includedfromfile.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-includedfromfile.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-includes.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-includes.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-libs.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-libs.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-dependfile.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-dependfile.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-expand_variables.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-expand_variables.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-exported.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-exported.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-jobs-prefix.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-jobs-prefix.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-jobs.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-jobs.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-level.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-level.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-makefile_preference.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-makefile_preference.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-makefiles.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-makefiles.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-bailiwick.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-bailiwick.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-created.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-created.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-files.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-files.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-ignore_filter.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-ignore_filter.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-ignore_paths.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-ignore_paths.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-ignore_patterns.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-ignore_patterns.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-prefix.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-meta-prefix.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-mode.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-mode.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-path_filemon.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-path_filemon.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-pid.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-pid.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-ppid.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-ppid.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-save_dollars.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-make-save_dollars.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-makeflags.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-makeflags.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-makeoverrides.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-makeoverrides.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-newline.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-newline.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-objdir.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-objdir.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-parsedir.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-parsedir.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-parsefile.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-parsefile.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-path.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-path.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-shell.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-shell.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-targets.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-dot-targets.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-empty.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-empty.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-make.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-make.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-make_print_var_on_error-jobs.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-make_print_var_on_error-jobs.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-make_print_var_on_error.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-make_print_var_on_error.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-makefile.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-makefile.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-makeflags.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-makeflags.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-pwd.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-pwd.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-vpath.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname-vpath.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varname.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varparse-dynamic.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varparse-dynamic.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varparse-errors.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varparse-errors.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varparse-mod.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varparse-mod.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varparse-undef-partial.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varparse-undef-partial.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varquote.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varquote.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/varshell.exp tests-obsolete obsolete
./usr/tests/usr.bin/make/unit-tests/varshell.mk tests-obsolete obsolete
./usr/tests/usr.bin/mkdep tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/mkdep tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/mkdep/Atffile tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/mkdep/Atffile tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/mkdep/Kyuafile tests-usr.bin-tests compattestfile,atf,kyua ./usr/tests/usr.bin/mkdep/Kyuafile tests-usr.bin-tests compattestfile,atf,kyua

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.2 2012/04/12 01:05:31 mrg Exp $ # $NetBSD: Makefile,v 1.3 2016/01/09 01:13:42 christos Exp $
# #
GNUHOSTDIST= ${.CURDIR}/../../external/lgpl3/gmp/dist GNUHOSTDIST= ${.CURDIR}/../../external/lgpl3/gmp/dist
@ -11,7 +11,7 @@ CONFIGURE_ARGS+=--disable-shared
# PATH needs special treating since "make" tries to expand $PATH # PATH needs special treating since "make" tries to expand $PATH
# when variable is used. # when variable is used.
CONFIGURE_ENV:= ${CONFIGURE_ENV:NPATH=*:NCFLAGS=*:NCXXFLAGS=*} \ CONFIGURE_ENV:= ${CONFIGURE_ENV:NPATH=*:NCFLAGS=*:NCXXFLAGS=*} \
PATH="${TOOLDIR:Q}/bin:$$$$PATH" PATH="${TOOLDIR:Q}/bin:$$PATH"
.if ${HOST_OSTYPE:C/\-.*//} != "Minix" .if ${HOST_OSTYPE:C/\-.*//} != "Minix"
# Force avoiding possibly non-executable install-sh. # Force avoiding possibly non-executable install-sh.

View File

@ -1,23 +1,36 @@
#! /bin/sh #! /bin/sh
# $NetBSD: buildmake.sh.in,v 1.8 2006/08/26 22:17:48 christos Exp $ # $NetBSD: buildmake.sh.in,v 1.16 2020/07/26 09:17:24 rillig Exp $
# #
# buildmake.sh.in - Autoconf-processed shell script for building make(1). # buildmake.sh.in - Autoconf-processed shell script for building make(1).
# #
: ${HOST_CC="@CC@"} : ${NETBSDSRCDIR:=@srcdir@/../..}
: ${HOST_CFLAGS="@CPPFLAGS@ @CFLAGS@"} MKSRCDIR=${NETBSDSRCDIR}/usr.bin/make
: ${HOST_LDFLAGS="@LDFLAGS@ @LIBS@"}
: ${runcmd=""} _CC="@CC@"
_CFLAGS="@CPPFLAGS@"
_CFLAGS="${_CFLAGS} -D_PATH_DEFSYSPATH=\"${NETBSDSRCDIR}/share/mk\""
_CFLAGS="${_CFLAGS} @DEFS@"
_CFLAGS="${_CFLAGS} @CFLAGS@"
_LDFLAGS="@LDFLAGS@ @LIBS@"
docmd () { docmd () {
echo "$1" case "${MAKEVERBOSE:-2}" in
$1 || exit 1 0)
;;
1)
echo " $1 ${2##*/}" ;;
*)
echo "$3" ;;
esac
$3 || exit 1
} }
MKSRCDIR=@srcdir@/../../usr.bin/make for f in $MKSRCDIR/*.c; do
docmd "compile " "$f" "${_CC} ${_CFLAGS} -c $f"
for f in $MKSRCDIR/*.c $MKSRCDIR/lst.lib/*.c; do
docmd "${HOST_CC} ${HOST_CFLAGS} @DEFS@ -c $f"
done done
docmd "${HOST_CC} ${HOST_CFLAGS} -o ${_TOOL_PREFIX:-nb}make *.o ${HOST_LDFLAGS}" docmd " link " "${_TOOL_PREFIX:-nb}make" \
"${_CC} -o ${_TOOL_PREFIX:-nb}make *.o ${_LDFLAGS}"

View File

@ -1,58 +1,222 @@
# $NetBSD: Makefile,v 1.58 2015/06/17 17:43:23 christos Exp $ # $NetBSD: Makefile,v 1.113 2021/02/22 20:45:46 rillig Exp $
# @(#)Makefile 5.2 (Berkeley) 12/28/90 # @(#)Makefile 5.2 (Berkeley) 12/28/90
PROG= make PROG= make
SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \ SRCS= arch.c
make.c metachar.c parse.c str.c suff.c targ.c trace.c var.c util.c SRCS+= buf.c
SRCS+= strlist.c SRCS+= compat.c
SRCS+= cond.c
SRCS+= dir.c
SRCS+= enum.c
SRCS+= for.c
SRCS+= hash.c
SRCS+= job.c
SRCS+= lst.c
SRCS+= main.c
SRCS+= make.c
SRCS+= make_malloc.c SRCS+= make_malloc.c
SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \ SRCS+= metachar.c
lstDatum.c lstDeQueue.c lstDestroy.c lstDupl.c lstEnQueue.c \ SRCS+= parse.c
lstFind.c lstFindFrom.c lstFirst.c lstForEach.c lstForEachFrom.c \ SRCS+= str.c
lstInit.c lstInsert.c lstIsAtEnd.c lstIsEmpty.c lstLast.c \ SRCS+= suff.c
lstMember.c lstNext.c lstOpen.c lstRemove.c lstReplace.c lstSucc.c SRCS+= targ.c
SRCS += lstPrev.c SRCS+= trace.c
SRCS+= var.c
SRCS+= util.c
HDRS= buf.h
HDRS+= config.h
HDRS+= dir.h
HDRS+= enum.h
HDRS+= hash.h
HDRS+= job.h
HDRS+= lst.h
HDRS+= make.h
HDRS+= make_malloc.h
HDRS+= meta.h
HDRS+= metachar.h
HDRS+= nonints.h
HDRS+= pathnames.h
HDRS+= trace.h
# let people experiment for a bit # Whether to generate a coverage report after running the tests.
USE_META ?= no USE_COVERAGE?= no # works only with gcc; clang9 fails to link
.if ${USE_COVERAGE} == "yes"
GCOV?= gcov
COPTS+= --coverage -O0 -ggdb
GCOV_PERL= if (/^File '(?:.*\/)?(\S+)'/) {
GCOV_PERL+= $$file = $$1; $$func = "";
GCOV_PERL+= } elsif (/^Function '(\S+)'/) {
GCOV_PERL+= $$func = $$1;
GCOV_PERL+= } elsif (/^Lines executed:(\d+\.\d+)% of (\d+)/ && defined($$file)) {
GCOV_PERL+= my ($$percent, $$lines) = ($$1, $$2);
GCOV_PERL+= my $$uncovered = `grep -c '\#\#\#\#\#:' < \$$(basename $$file.gcov)`;
GCOV_PERL+= printf("%7.2f %4d/%4d %s%s\n",
GCOV_PERL+= $$percent, $$uncovered, $$lines, $$file, $$func);
GCOV_PERL+= $$file = undef;
GCOV_PERL+= }
LDADD+= --coverage
.endif
CLEANFILES+= *.gcda *.gcno *.gcov
# Whether to compile using the Undefined Behavior Sanitizer (GCC, Clang).
USE_UBSAN?= no
.if ${USE_UBSAN} == "yes"
COPTS+= -fsanitize=undefined
LDADD+= -fsanitize=undefined
.endif
# Whether to compile with GCC 10 from pkgsrc, during development.
USE_GCC10?= no
.if ${USE_GCC10} == "yes"
# CC is set further down in this file
COPTS+= -Wno-attributes # for abs and labs
COPTS.arch.c+= -Wno-error=format-truncation
COPTS.dir.c+= -Wno-error=format-truncation
COPTS.main.c+= -Wno-error=format-truncation
COPTS.meta.c+= -Wno-error=format-truncation
.endif
# Whether to compile with GCC 9 from pkgsrc, during development.
USE_GCC9?= no
.if ${USE_GCC9} == "yes"
# CC is set further down in this file
COPTS+= -Wno-attributes # for abs and labs
COPTS.arch.c+= -Wno-error=format-truncation
COPTS.dir.c+= -Wno-error=format-truncation
COPTS.main.c+= -Wno-error=format-truncation
COPTS.meta.c+= -Wno-error=format-truncation
.endif
# Whether to compile with GCC 8 from pkgsrc, during development.
USE_GCC8?= no
.if ${USE_GCC8} == "yes"
# CC is set further down in this file
COPTS+= -Wno-attributes # for abs and labs
COPTS.arch.c+= -Wno-error=format-truncation
COPTS.dir.c+= -Wno-error=format-truncation
COPTS.main.c+= -Wno-error=format-truncation
COPTS.meta.c+= -Wno-error=format-truncation
.endif
USE_META?= yes
.if ${USE_META:tl} != "no" .if ${USE_META:tl} != "no"
SRCS+= meta.c
CPPFLAGS+= -DUSE_META
FILEMON_H ?= ${.CURDIR:H:H}/sys/dev/filemon/filemon.h
.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
COPTS.meta.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
.endif
.endif
.if defined(__MINIX) SRCS+= meta.c
CPPFLAGS+= -DMAKE_MACHINE=\"${MACHINE}\" -DMAKE_MACHINE_ARCH=\"${MACHINE_ARCH}\" CPPFLAGS+= -DUSE_META
.endif #defined(__MINIX)
.PATH: ${.CURDIR}/lst.lib
.if !defined(__MINIX) .if !defined(__MINIX)
SUBDIR= PSD.doc USE_FILEMON?= ktrace
.endif #!defined(__MINIX) . if ${USE_FILEMON:tl} != "no"
.if make(obj) || make(clean)
SUBDIR+= unit-tests .PATH: ${.CURDIR}/filemon
SRCS+= filemon_${USE_FILEMON}.c
CPPFLAGS+= -DUSE_FILEMON
CPPFLAGS+= -DUSE_FILEMON_${USE_FILEMON:tu}
. if ${USE_FILEMON} == "dev"
FILEMON_H?= /usr/include/dev/filemon/filemon.h
. if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
COPTS.filemon_dev.c+= \
-DHAVE_FILEMON_H -I${FILEMON_H:H}
. endif
. endif
. endif
.endif .endif
.endif # !defined(__MINIX)
SUBDIR.roff+= PSD.doc
.if make(obj) || make(clean)
SUBDIR+= unit-tests
.endif
LINTFLAGS+= -T # strict bool mode, available since 2021-01-11
${SRCS:M*.c:.c=.o}: ${HDRS}
CLEANFILES+= *.o
COPTS.arch.c+= ${GCC_NO_FORMAT_TRUNCATION}
COPTS.dir.c+= ${GCC_NO_FORMAT_TRUNCATION}
COPTS.job.c+= -Wno-format-nonliteral
COPTS.main.c+= ${GCC_NO_FORMAT_TRUNCATION} ${GCC_NO_STRINGOP_TRUNCATION}
COPTS.meta.c+= ${GCC_NO_FORMAT_TRUNCATION}
COPTS.parse.c+= -Wno-format-nonliteral
COPTS.var.c+= -Wno-format-nonliteral
CPPFLAGS+= -DMAKE_NATIVE
.if ${USE_GCC10} == "yes"
GCC10BASE?= /usr/pkg/gcc10
LATE_CC= ${GCC10BASE}/bin/gcc
GCOV= ${GCC10BASE}/bin/gcov
.endif
.if ${USE_GCC9} == "yes"
GCC9BASE?= /usr/pkg/gcc9
LATE_CC= ${GCC9BASE}/bin/gcc
GCOV= ${GCC9BASE}/bin/gcov
.endif
.if ${USE_GCC8} == "yes"
GCC8BASE?= /usr/pkg/gcc8
LATE_CC= ${GCC8BASE}/bin/gcc
GCOV= ${GCC8BASE}/bin/gcov
.endif
.if defined(TOOLDIR)
# This is a native NetBSD build, use libutil rather than the local emalloc etc.
CPPFLAGS+= -DUSE_EMALLOC
LDADD+= -lutil
DPADD+= ${LIBUTIL}
.endif
COPTS+= -Wdeclaration-after-statement
CWARNFLAGS.gcc+= -Wno-error=clobbered
# A simple unit-test driver to help catch regressions
TEST_MAKE ?= ${.OBJDIR}/${PROG:T}
test: .MAKE
cd ${.CURDIR}/unit-tests \
&& MAKEFLAGS= ${TEST_MAKE} -r -m / TEST_MAKE=${TEST_MAKE} ${TESTS:DTESTS=${TESTS:Q}} ${.TARGET}
.if ${USE_COVERAGE} == yes
${MAKE} report-coverage
.endif
accept sync-mi: .MAKE
cd ${.CURDIR}/unit-tests && ${.MAKE} ${.TARGET}
retest:
${.MAKE} -C ${.CURDIR}/unit-tests cleandir
.if ${USE_COVERAGE} == yes
rm -f *.gcov *.gcda
.endif
${.MAKE} test
# Just out of curiosity, during development.
.SUFFIXES: .cpre .casm
.c.cpre:
${COMPILE.c:S,^-c$,-E,} ${COPTS.${.IMPSRC}} ${.IMPSRC} -o ${.TARGET}
.c.casm:
${COMPILE.c:S,^-c$,-S,} ${COPTS.${.IMPSRC}} ${.IMPSRC} -o ${.TARGET}
test-coverage: .PHONY
@make -s clean cleandir
@env USE_COVERAGE=yes COPTS="-O0 -ggdb" USER_CPPFLAGS="-DCLEANUP" \
sh -c 'make -s all -j8 && make -s test'
report-coverage: .PHONY
@echo 'covered uncovered file'
@${GCOV} ${GCOV_OPTS} *.gcda 2>&1 \
| perl -ne ${GCOV_PERL:Q} \
| sort -nr
@sed -i 's,^\([^:]*\): *[0-9]*:,\1: ,' *.gcov
.include <bsd.prog.mk> .include <bsd.prog.mk>
.include <bsd.subdir.mk> .include <bsd.subdir.mk>
CPPFLAGS+= -DMAKE_NATIVE # For -DCLEANUP and similar feature toggles.
COPTS.var.c += -Wno-cast-qual CPPFLAGS+= ${USER_CPPFLAGS}
COPTS.job.c += -Wno-format-nonliteral # For overriding -std=gnu99 or similar options.
COPTS.parse.c += -Wno-format-nonliteral CFLAGS+= ${USER_CFLAGS}
COPTS.var.c += -Wno-format-nonliteral .if defined(LATE_CC)
CC= ${LATE_CC}
.ifdef TOOLDIR
# this is a native netbsd build,
# use libutil rather than the local emalloc etc.
CPPFLAGS+= -DUSE_EMALLOC
LDADD+=-lutil
DPADD+=${LIBUTIL}
.endif .endif
# A simple unit-test driver to help catch regressions
accept test:
cd ${.CURDIR}/unit-tests && MAKEFLAGS= ${.MAKE} -r -m / TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}

View File

@ -1,45 +1,39 @@
# $NetBSD: Makefile.boot,v 1.21 2014/02/24 07:23:44 skrll Exp $ # $NetBSD: Makefile.boot,v 1.23 2020/10/25 13:25:19 rillig Exp $
# #
# a very simple makefile... # A very simple makefile...
# #
# You only want to use this if you aren't running NetBSD. # You only want to use this if you aren't running NetBSD.
# #
# modify MACHINE and MACHINE_ARCH as appropriate for your target architecture # Modify MACHINE and MACHINE_ARCH as appropriate for your target architecture.
# See config.h and the various #ifdef directives for further configuration.
# #
CC=gcc -O -g
PROG= bmake
MACHINE= i386
MACHINE_ARCH= i386
CC= gcc
CFLAGS= -O -g
EXTRA_CFLAGS=
EXTRA_LIBS=
OBJS= arch.o buf.o compat.o cond.o dir.o enum.o for.o hash.o \
job.o lst.o main.o make.o make_malloc.o metachar.o parse.o \
str.o suff.o targ.o trace.o var.o util.o
.c.o: .c.o:
${CC} ${CFLAGS} -c $< -o $@ ${CC} ${CPPFLAGS} ${CFLAGS} ${EXTRA_CFLAGS} -c $< -o $@
MACHINE=i386 CPPFLAGS= \
MACHINE_ARCH=i386 -DTARGET_MACHINE=\"${MACHINE}\" \
# tested on HP-UX 10.20
#MAKE_MACHINE=hppa
#MAKE_MACHINE_ARCH=hppa
CFLAGS= -DTARGET_MACHINE=\"${MACHINE}\" \
-DTARGET_MACHINE_ARCH=\"${MACHINE_ARCH}\" \ -DTARGET_MACHINE_ARCH=\"${MACHINE_ARCH}\" \
-DMAKE_MACHINE=\"${MACHINE}\" -DMAKE_MACHINE=\"${MACHINE}\"
LIBS=
OBJ=arch.o buf.o compat.o cond.o dir.o for.o hash.o job.o main.o make.o \ ${PROG}: ${OBJS}
make_malloc.o parse.o str.o strlist.o suff.o targ.o trace.o var.o util.o # @echo 'make of ${PROG} and make.0 started.'
${CC} ${CFLAGS} ${OBJS} -o $@ ${EXTRA_LIBS}
LIBOBJ= lst.lib/lstAppend.o lst.lib/lstAtEnd.o lst.lib/lstAtFront.o \
lst.lib/lstClose.o lst.lib/lstConcat.o lst.lib/lstDatum.o \
lst.lib/lstDeQueue.o lst.lib/lstDestroy.o lst.lib/lstDupl.o \
lst.lib/lstEnQueue.o lst.lib/lstFind.o lst.lib/lstFindFrom.o \
lst.lib/lstFirst.o lst.lib/lstForEach.o lst.lib/lstForEachFrom.o \
lst.lib/lstInit.o lst.lib/lstInsert.o lst.lib/lstIsAtEnd.o \
lst.lib/lstIsEmpty.o lst.lib/lstLast.o lst.lib/lstMember.o \
lst.lib/lstNext.o lst.lib/lstOpen.o lst.lib/lstRemove.o \
lst.lib/lstReplace.o lst.lib/lstSucc.o lst.lib/lstPrev.o
bmake: ${OBJ} ${LIBOBJ}
# @echo 'make of make and make.0 started.'
${CC} ${CFLAGS} ${OBJ} ${LIBOBJ} -o bmake ${LIBS}
@ls -l $@ @ls -l $@
# nroff -h -man make.1 > make.0 # nroff -h -man make.1 > make.0
# @echo 'make of make and make.0 completed.' # @echo 'make of ${PROG} and make.0 completed.'
clean: clean:
rm -f ${OBJ} ${LIBOBJ} ${PORTOBJ} bmake rm -f ${OBJS} ${PROG}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: tutorial.ms,v 1.12 2014/09/30 21:33:14 christos Exp $ .\" $NetBSD: tutorial.ms,v 1.14 2020/12/18 15:47:34 rillig Exp $
.\" Copyright (c) 1988, 1989, 1993 .\" Copyright (c) 1988, 1989, 1993
.\" The Regents of the University of California. All rights reserved. .\" The Regents of the University of California. All rights reserved.
.\" .\"
@ -117,6 +117,15 @@
.de No .de No
.br .br
.ne 0.5i .ne 0.5i
.ie n \{\
.nr g3 \w'NOTE '
.po -\\n(g3u
.br
NOTE
.br
.po +\\n(g3u
.\}
.el \{\
.po -0.5i .po -0.5i
.br .br
.mk .mk
@ -148,12 +157,14 @@
.rt .rt
.ft \\n(g3 .ft \\n(g3
.ps \\n(g4 .ps \\n(g4
.\}
.. ..
.de Bp .de Bp
.ie !\\n(.$ .IP \(bu 2 .ie !\\n(.$ .IP \(bu 2
.el .IP "\&" 2 .el .IP "\&" 2
.. ..
.po +.3i .ie n .po +\w'NOTE 'u
.el .po +.3i
.TL .TL
PMake \*- A Tutorial PMake \*- A Tutorial
.AU .AU
@ -1907,15 +1918,15 @@ Suff_FindDeps (jive.c)
applying .l -> .c to "jive.l" applying .l -> .c to "jive.l"
Suff_FindDeps (jive.l) Suff_FindDeps (jive.l)
Examining jive.l...modified 17:16:01 Oct 4, 1987...up-to-date Examining jive.l...modified 17:16:01 Oct 4, 1987...up-to-date
Examining jive.c...non-existent...out-of-date Examining jive.c...nonexistent...out-of-date
--- jive.c --- --- jive.c ---
lex jive.l lex jive.l
\&.\|.\|. meaningless lex output deleted .\|.\|. \&.\|.\|. meaningless lex output deleted .\|.\|.
mv lex.yy.c jive.c mv lex.yy.c jive.c
Examining jive.o...non-existent...out-of-date Examining jive.o...nonexistent...out-of-date
--- jive.o --- --- jive.o ---
cc -c jive.c cc -c jive.c
Examining jive.out...non-existent...out-of-date Examining jive.out...nonexistent...out-of-date
--- jive.out --- --- jive.out ---
cc -o jive.out jive.o cc -o jive.out jive.o
.DE .DE
@ -2860,7 +2871,7 @@ current directory. While people have suggested that PMake should read
the directories each time, my experience suggests that the caching seldom the directories each time, my experience suggests that the caching seldom
causes problems. In addition, not caching the directories slows things causes problems. In addition, not caching the directories slows things
down enormously because of PMake's attempts to apply transformation down enormously because of PMake's attempts to apply transformation
rules through non-existent files \*- the number of extra file-system rules through nonexistent files \*- the number of extra file-system
searches is truly staggering, especially if many files without searches is truly staggering, especially if many files without
suffixes are used and the null suffix isn't changed from suffixes are used and the null suffix isn't changed from
.CW .out . .CW .out .

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $ */ /* $NetBSD: buf.c,v 1.51 2021/01/30 21:18:14 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -69,223 +69,152 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#ifndef MAKE_NATIVE /* Automatically-expanding null-terminated character buffers. */
static char rcsid[] = "$NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $";
#else #include <limits.h>
#include <sys/cdefs.h> #include "make.h"
#ifndef lint
#if 0 /* "@(#)buf.c 8.1 (Berkeley) 6/6/93" */
static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93"; MAKE_RCSID("$NetBSD: buf.c,v 1.51 2021/01/30 21:18:14 rillig Exp $");
#else
__RCSID("$NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $"); /* Make space in the buffer for adding at least 16 more bytes. */
void
Buf_Expand(Buffer *buf)
{
buf->cap += buf->cap > 16 ? buf->cap : 16;
buf->data = bmake_realloc(buf->data, buf->cap);
}
/* Add the bytes to the buffer. */
void
Buf_AddBytes(Buffer *buf, const char *bytes, size_t bytes_len)
{
size_t old_len = buf->len;
char *end;
if (old_len + bytes_len >= buf->cap) {
size_t minIncr = bytes_len + 16;
buf->cap += buf->cap > minIncr ? buf->cap : minIncr;
buf->data = bmake_realloc(buf->data, buf->cap);
}
end = buf->data + old_len;
buf->len = old_len + bytes_len;
memcpy(end, bytes, bytes_len);
end[bytes_len] = '\0';
}
/* Add the bytes between start and end to the buffer. */
void
Buf_AddBytesBetween(Buffer *buf, const char *start, const char *end)
{
Buf_AddBytes(buf, start, (size_t)(end - start));
}
/* Add the string to the buffer. */
void
Buf_AddStr(Buffer *buf, const char *str)
{
Buf_AddBytes(buf, str, strlen(str));
}
/* Add the number to the buffer. */
void
Buf_AddInt(Buffer *buf, 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,
str_size = max_sign_chars + max_decimal_digits + 1
};
char str[str_size];
size_t len = (size_t)snprintf(str, sizeof str, "%d", n);
Buf_AddBytes(buf, str, len);
}
/* Mark the buffer as empty, so it can be filled with data again. */
void
Buf_Empty(Buffer *buf)
{
buf->len = 0;
buf->data[0] = '\0';
}
/* Initialize a buffer. */
void
Buf_InitSize(Buffer *buf, size_t cap)
{
buf->cap = cap;
buf->len = 0;
buf->data = bmake_malloc(cap);
buf->data[0] = '\0';
}
void
Buf_Init(Buffer *buf)
{
Buf_InitSize(buf, 256);
}
/*
* Free the data from the buffer.
* Leave the buffer itself in an indeterminate state.
*/
void
Buf_Done(Buffer *buf)
{
free(buf->data);
#ifdef CLEANUP
buf->cap = 0;
buf->len = 0;
buf->data = NULL;
#endif #endif
#endif /* not lint */ }
/*
* Return the data from the buffer.
* Leave the buffer itself in an indeterminate state.
*/
char *
Buf_DoneData(Buffer *buf)
{
char *data = buf->data;
#ifdef CLEANUP
buf->cap = 0;
buf->len = 0;
buf->data = NULL;
#endif #endif
/*- return data;
* buf.c --
* Functions for automatically-expanded buffers.
*/
#include "make.h"
#include "buf.h"
#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
#define BUF_DEF_SIZE 256 /* Default buffer size */
/*-
*-----------------------------------------------------------------------
* Buf_Expand_1 --
* Extend buffer for single byte add.
*
*-----------------------------------------------------------------------
*/
void
Buf_Expand_1(Buffer *bp)
{
bp->size += max(bp->size, 16);
bp->buffer = bmake_realloc(bp->buffer, bp->size);
} }
/*-
*-----------------------------------------------------------------------
* Buf_AddBytes --
* Add a number of bytes to the buffer.
*
* Results:
* None.
*
* Side Effects:
* Guess what?
*
*-----------------------------------------------------------------------
*/
void
Buf_AddBytes(Buffer *bp, int numBytes, const Byte *bytesPtr)
{
int count = bp->count;
Byte *ptr;
if (__predict_false(count + numBytes >= bp->size)) {
bp->size += max(bp->size, numBytes + 16);
bp->buffer = bmake_realloc(bp->buffer, bp->size);
}
ptr = bp->buffer + count;
bp->count = count + numBytes;
ptr[numBytes] = 0;
memcpy(ptr, bytesPtr, numBytes);
}
/*-
*-----------------------------------------------------------------------
* Buf_GetAll --
* Get all the available data at once.
*
* Results:
* A pointer to the data and the number of bytes available.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
Byte *
Buf_GetAll(Buffer *bp, int *numBytesPtr)
{
if (numBytesPtr != NULL)
*numBytesPtr = bp->count;
return (bp->buffer);
}
/*-
*-----------------------------------------------------------------------
* Buf_Empty --
* Throw away bytes in a buffer.
*
* Results:
* None.
*
* Side Effects:
* The bytes are discarded.
*
*-----------------------------------------------------------------------
*/
void
Buf_Empty(Buffer *bp)
{
bp->count = 0;
*bp->buffer = 0;
}
/*-
*-----------------------------------------------------------------------
* Buf_Init --
* Initialize a buffer. If no initial size is given, a reasonable
* default is used.
*
* Input:
* size Initial size for the buffer
*
* Results:
* A buffer to be given to other functions in this library.
*
* Side Effects:
* The buffer is created, the space allocated and pointers
* initialized.
*
*-----------------------------------------------------------------------
*/
void
Buf_Init(Buffer *bp, int size)
{
if (size <= 0) {
size = BUF_DEF_SIZE;
}
bp->size = size;
bp->count = 0;
bp->buffer = bmake_malloc(size);
*bp->buffer = 0;
}
/*-
*-----------------------------------------------------------------------
* Buf_Destroy --
* Nuke a buffer and all its resources.
*
* Input:
* buf Buffer to destroy
* freeData TRUE if the data should be destroyed
*
* Results:
* Data buffer, NULL if freed
*
* Side Effects:
* The buffer is freed.
*
*-----------------------------------------------------------------------
*/
Byte *
Buf_Destroy(Buffer *buf, Boolean freeData)
{
Byte *data;
data = buf->buffer;
if (freeData) {
free(data);
data = NULL;
}
buf->size = 0;
buf->count = 0;
buf->buffer = NULL;
return data;
}
/*-
*-----------------------------------------------------------------------
* Buf_DestroyCompact --
* Nuke a buffer and return its data.
*
* Input:
* buf Buffer to destroy
*
* Results:
* Data buffer
*
* Side Effects:
* If the buffer size is much greater than its content,
* a new buffer will be allocated and the old one freed.
*
*-----------------------------------------------------------------------
*/
#ifndef BUF_COMPACT_LIMIT #ifndef BUF_COMPACT_LIMIT
# define BUF_COMPACT_LIMIT 128 /* worthwhile saving */ # define BUF_COMPACT_LIMIT 128 /* worthwhile saving */
#endif #endif
Byte * /*
Buf_DestroyCompact(Buffer *buf) * Return the data from the buffer.
* Leave the buffer itself in an indeterminate state.
*
* If the buffer size is much greater than its content,
* a new buffer will be allocated and the old one freed.
*/
char *
Buf_DoneDataCompact(Buffer *buf)
{ {
#if BUF_COMPACT_LIMIT > 0 #if BUF_COMPACT_LIMIT > 0
Byte *data; if (buf->cap - buf->len >= BUF_COMPACT_LIMIT) {
/* We trust realloc to be smart */
if (buf->size - buf->count >= BUF_COMPACT_LIMIT) { char *data = bmake_realloc(buf->data, buf->len + 1);
/* We trust realloc to be smart */ data[buf->len] = '\0'; /* XXX: unnecessary */
data = bmake_realloc(buf->buffer, buf->count + 1); Buf_DoneData(buf);
if (data) { return data;
data[buf->count] = 0;
Buf_Destroy(buf, FALSE);
return data;
} }
}
#endif #endif
return Buf_Destroy(buf, FALSE); return Buf_DoneData(buf);
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: buf.h,v 1.17 2012/04/24 20:26:58 sjg Exp $ */ /* $NetBSD: buf.h,v 1.42 2021/01/30 21:25:10 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -72,48 +72,50 @@
* from: @(#)buf.h 8.1 (Berkeley) 6/6/93 * from: @(#)buf.h 8.1 (Berkeley) 6/6/93
*/ */
/*- /* Automatically growing null-terminated buffers of characters. */
* buf.h --
* Header for users of the buf library.
*/
#ifndef _BUF_H #ifndef MAKE_BUF_H
#define _BUF_H #define MAKE_BUF_H
typedef char Byte; #include <stddef.h>
/* An automatically growing null-terminated buffer of characters. */
typedef struct Buffer { typedef struct Buffer {
int size; /* Current size of the buffer */ size_t cap; /* Allocated size of the buffer, including the '\0' */
int count; /* Number of bytes in buffer */ size_t len; /* Number of bytes in buffer, excluding the '\0' */
Byte *buffer; /* The buffer itself (zero terminated) */ char *data; /* The buffer itself (always null-terminated) */
} Buffer; } Buffer;
/* If we aren't on netbsd, __predict_false() might not be defined. */ void Buf_Expand(Buffer *);
#ifndef __predict_false
#define __predict_false(x) (x)
#endif
/* Buf_AddByte adds a single byte to a buffer. */ /* Buf_AddByte adds a single byte to a buffer. */
#define Buf_AddByte(bp, byte) do { \ MAKE_INLINE void
int _count = ++(bp)->count; \ Buf_AddByte(Buffer *buf, char byte)
char *_ptr; \ {
if (__predict_false(_count >= (bp)->size)) \ size_t old_len = buf->len++;
Buf_Expand_1(bp); \ char *end;
_ptr = (bp)->buffer + _count; \ if (old_len + 1 >= buf->cap)
_ptr[-1] = (byte); \ Buf_Expand(buf);
_ptr[0] = 0; \ end = buf->data + old_len;
} while (0) end[0] = byte;
end[1] = '\0';
}
#define BUF_ERROR 256 MAKE_INLINE Boolean
Buf_EndsWith(const Buffer *buf, char ch)
{
return buf->len > 0 && buf->data[buf->len - 1] == ch;
}
#define Buf_Size(bp) ((bp)->count) void Buf_AddBytes(Buffer *, const char *, size_t);
void Buf_AddBytesBetween(Buffer *, const char *, const char *);
void Buf_Expand_1(Buffer *); void Buf_AddStr(Buffer *, const char *);
void Buf_AddBytes(Buffer *, int, const Byte *); void Buf_AddInt(Buffer *, int);
Byte *Buf_GetAll(Buffer *, int *);
void Buf_Empty(Buffer *); void Buf_Empty(Buffer *);
void Buf_Init(Buffer *, int); void Buf_Init(Buffer *);
Byte *Buf_Destroy(Buffer *, Boolean); void Buf_InitSize(Buffer *, size_t);
Byte *Buf_DestroyCompact(Buffer *); void Buf_Done(Buffer *);
char *Buf_DoneData(Buffer *);
char *Buf_DoneDataCompact(Buffer *);
#endif /* _BUF_H */ #endif /* MAKE_BUF_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: config.h,v 1.21 2012/03/31 00:12:24 christos Exp $ */ /* $NetBSD: config.h,v 1.28 2020/12/11 22:53:08 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -72,26 +72,16 @@
* from: @(#)config.h 8.1 (Berkeley) 6/6/93 * from: @(#)config.h 8.1 (Berkeley) 6/6/93
*/ */
/*
* DEFMAXJOBS
* DEFMAXLOCAL
* These control the default concurrency. On no occasion will more
* than DEFMAXJOBS targets be created at once (locally or remotely)
* DEFMAXLOCAL is the highest number of targets which will be
* created on the local machine at once. Note that if you set this
* to 0, nothing will ever happen...
*/
#define DEFMAXJOBS 4
#define DEFMAXLOCAL 1
/* /*
* INCLUDES * INCLUDES
* LIBRARIES * LIBRARIES
* These control the handling of the .INCLUDES and .LIBS variables. * These control the handling of the .INCLUDES and .LIBS variables.
*
* If INCLUDES is defined, the .INCLUDES variable will be filled * If INCLUDES is defined, the .INCLUDES variable will be filled
* from the search paths of those suffixes which are marked by * from the search paths of those suffixes which are marked by
* .INCLUDES dependency lines. Similarly for LIBRARIES and .LIBS * .INCLUDES dependency lines. Similarly for LIBRARIES and .LIBS.
* See suff.c for more details. *
* See varname-dot-include.mk and varname-dot-libs.mk for more details.
*/ */
#define INCLUDES #define INCLUDES
#define LIBRARIES #define LIBRARIES
@ -100,34 +90,39 @@
* LIBSUFF * LIBSUFF
* Is the suffix used to denote libraries and is used by the Suff module * 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. * to find the search path on which to seek any -l<xx> targets.
* */
#define LIBSUFF ".a"
/*
* RECHECK * RECHECK
* If defined, Make_Update will check a target for its current * If defined, Make_Update will check a target for its current
* modification time after it has been re-made, setting it to the * modification time after it has been re-made, setting it to the
* starting time of the make only if the target still doesn't exist. * starting time of the make only if the target still doesn't exist.
*
* Unfortunately, under NFS the modification time often doesn't * Unfortunately, under NFS the modification time often doesn't
* get updated in time, so a target will appear to not have been * 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 * re-made, causing later targets to appear up-to-date.
* that don't have this problem, you should defined this. Under *
* NFS you probably should not, unless you aren't exporting jobs. * On systems 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
#define RECHECK
/* /*
* POSIX * POSIX
* Adhere to the POSIX 1003.2 draft for the make(1) program. * Adhere to the POSIX 1003.2 draft for the make(1) program.
* - Use MAKEFLAGS instead of MAKE to pick arguments from the * - Use MAKEFLAGS instead of MAKE to pick arguments from the
* environment. * environment.
* - Allow empty command lines if starting with tab.
*/ */
#define POSIX #define POSIX
/* /*
* SYSVINCLUDE * SYSVINCLUDE
* Recognize system V like include directives [include "filename"] * Recognize system V like include directives [include "filename"]
* (required by POSIX 2018)
* SYSVVARSUB * SYSVVARSUB
* Recognize system V like ${VAR:x=y} variable substitutions * Recognize system V like ${VAR:x=y} variable substitutions
* (required by POSIX 2018)
*/ */
#define SYSVINCLUDE #define SYSVINCLUDE
#define SYSVVARSUB #define SYSVVARSUB
@ -147,12 +142,6 @@
*/ */
#define SUNSHCMD #define SUNSHCMD
/*
* USE_IOVEC
* We have writev(2)
*/
#define USE_IOVEC
#if defined(MAKE_NATIVE) && !defined(__ELF__) #if defined(MAKE_NATIVE) && !defined(__ELF__)
# ifndef RANLIBMAG # ifndef RANLIBMAG
# define RANLIBMAG "__.SYMDEF" # define RANLIBMAG "__.SYMDEF"

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: dir.h,v 1.15 2012/04/07 18:29:08 christos Exp $ */ /* $NetBSD: dir.h,v 1.43 2021/02/05 05:48:19 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -72,37 +72,36 @@
* from: @(#)dir.h 8.1 (Berkeley) 6/6/93 * from: @(#)dir.h 8.1 (Berkeley) 6/6/93
*/ */
/* dir.h -- #ifndef MAKE_DIR_H
*/ #define MAKE_DIR_H
#ifndef _DIR typedef struct CachedDir CachedDir;
#define _DIR
typedef struct Path { void Dir_Init(void);
char *name; /* Name of directory */
int refCount; /* Number of paths with this directory */
int hits; /* the number of times a file in this
* directory has been found */
Hash_Table files; /* Hash table of files in directory */
} Path;
void Dir_Init(const char *);
void Dir_InitCur(const char *); void Dir_InitCur(const char *);
void Dir_InitDot(void); void Dir_InitDot(void);
void Dir_End(void); void Dir_End(void);
void Dir_SetPATH(void); void Dir_SetPATH(void);
Boolean Dir_HasWildcards(char *); Boolean Dir_HasWildcards(const char *);
void Dir_Expand(const char *, Lst, Lst); void SearchPath_Expand(SearchPath *, const char *, StringList *);
char *Dir_FindFile(const char *, Lst); char *Dir_FindFile(const char *, SearchPath *);
int Dir_FindHereOrAbove(char *, char *, char *, int); char *Dir_FindHereOrAbove(const char *, const char *);
int Dir_MTime(GNode *, Boolean); void Dir_UpdateMTime(GNode *, Boolean);
Path *Dir_AddDir(Lst, const char *); CachedDir *SearchPath_Add(SearchPath *, const char *);
char *Dir_MakeFlags(const char *, Lst); char *SearchPath_ToFlags(SearchPath *, const char *);
void Dir_ClearPath(Lst); void SearchPath_Clear(SearchPath *);
void Dir_Concat(Lst, Lst); void SearchPath_AddAll(SearchPath *, SearchPath *);
void Dir_PrintDirectories(void); void Dir_PrintDirectories(void);
void Dir_PrintPath(Lst); void SearchPath_Print(const SearchPath *);
void Dir_Destroy(void *); SearchPath *Dir_CopyDirSearchPath(void);
void * Dir_CopyDir(void *);
#endif /* _DIR */ /* Stripped-down variant of struct stat. */
struct cached_stat {
time_t cst_mtime;
mode_t cst_mode;
};
int cached_lstat(const char *, struct cached_stat *);
int cached_stat(const char *, struct cached_stat *);
#endif /* MAKE_DIR_H */

80
usr.bin/make/enum.c Normal file
View File

@ -0,0 +1,80 @@
/* $NetBSD: enum.c,v 1.15 2021/02/02 17:56:31 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.
*/
#include "make.h"
MAKE_RCSID("$NetBSD: enum.c,v 1.15 2021/02/02 17:56:31 rillig Exp $");
/*
* 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;
}

179
usr.bin/make/enum.h Normal file
View File

@ -0,0 +1,179 @@
/* $NetBSD: enum.h,v 1.19 2021/03/15 16:00:05 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 EnumToStringSpec {
int es_value;
const char *es_name;
} EnumToStringSpec;
const char *Enum_FlagsToString(char *, size_t, 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_FlagsToString. */
#define ENUM__FLAGS_RTTI(typnam, specs, joined) \
static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs; \
enum { typnam ## _ ## ToStringSize = sizeof (joined) }; \
MAKE_INLINE const char *typnam ## _ToString(char *buf, typnam value) \
{ return Enum_FlagsToString(buf, typnam ## _ ## ToStringSize, \
value, typnam ## _ ## ToStringSpecs); \
} \
extern void enum_flags_rtti_dummy(void)
/*
* 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 6 flags.
*/
#define ENUM_FLAGS_RTTI_6(typnam, v1, v2, v3, v4, v5, v6) \
ENUM__FLAGS_RTTI(typnam, \
ENUM__SPECS_2( \
ENUM__SPEC_4(v1, v2, v3, v4), \
ENUM__SPEC_2(v5, v6)), \
ENUM__JOIN_2( \
ENUM__JOIN_STR_4(v1, v2, v3, v4), \
ENUM__JOIN_STR_2(v5, v6)))
/*
* Declare the necessary data structures for calling Enum_FlagsToString
* for an enum with 9 flags.
*/
#define ENUM_FLAGS_RTTI_9(typnam, v1, v2, v3, v4, v5, v6, v7, v8, v9) \
ENUM__FLAGS_RTTI(typnam, \
ENUM__SPECS_2( \
ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8), \
ENUM__SPEC_1(v9)), \
ENUM__JOIN_2( \
ENUM__JOIN_STR_8(v1, v2, v3, v4, v5, v6, v7, v8), \
ENUM__JOIN_STR_1(v9)))
/*
* 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)))
#endif

View File

@ -1,11 +1,11 @@
/* $NetBSD: strlist.h,v 1.3 2009/01/16 21:15:34 dsl Exp $ */ /* $NetBSD: filemon.h,v 1.5 2021/01/19 20:51:46 rillig Exp $ */
/*- /*
* Copyright (c) 2008 - 2009 The NetBSD Foundation, Inc. * Copyright (c) 2019 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
* This code is derived from software contributed to The NetBSD Foundation * This code is derived from software contributed to The NetBSD Foundation
* by David Laight. * by Taylor R. Campbell.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -15,9 +15,6 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * 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.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@ -32,31 +29,25 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _STRLIST_H #ifndef MAKE_FILEMON_H
#define _STRLIST_H #define MAKE_FILEMON_H
typedef struct { #include <sys/types.h>
char *si_str;
unsigned int si_info;
} strlist_item_t;
typedef struct { struct filemon;
unsigned int sl_num;
unsigned int sl_max;
strlist_item_t *sl_items;
} strlist_t;
void strlist_init(strlist_t *); const char *
void strlist_clean(strlist_t *); filemon_path(void);
void strlist_add_str(strlist_t *, char *, unsigned int);
#define strlist_num(sl) ((sl)->sl_num) struct filemon *
#define strlist_str(sl, n) ((sl)->sl_items[n].si_str) filemon_open(void);
#define strlist_info(sl, n) ((sl)->sl_items[n].si_info) int filemon_close(struct filemon *);
#define strlist_set_info(sl, n, v) ((void)((sl)->sl_items[n].si_info = (v)))
#define STRLIST_FOREACH(v, sl, index) \ int filemon_setfd(struct filemon *, int);
if ((sl)->sl_items != NULL) \ void filemon_setpid_parent(struct filemon *, pid_t);
for (index = 0; (v = strlist_str(sl, index)) != NULL; index++) int filemon_setpid_child(const struct filemon *, pid_t);
#endif /* _STRLIST_H */ int filemon_readfd(const struct filemon *);
int filemon_process(struct filemon *);
#endif /* MAKE_FILEMON_H */

View File

@ -0,0 +1,151 @@
/* $NetBSD: filemon_dev.c,v 1.8 2021/02/01 21:09:25 rillig Exp $ */
/*
* Copyright (c) 2020 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Taylor R. Campbell.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "filemon.h"
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_FILEMON_H
# include <filemon.h>
#endif
#ifndef _PATH_FILEMON
#define _PATH_FILEMON "/dev/filemon"
#endif
struct filemon {
int fd;
};
const char *
filemon_path(void)
{
return _PATH_FILEMON;
}
struct filemon *
filemon_open(void)
{
struct filemon *F;
unsigned i;
int error;
/* Allocate and zero a struct filemon object. */
F = calloc(1, sizeof *F);
if (F == NULL)
return NULL;
/* Try opening /dev/filemon, up to six times (cargo cult!). */
for (i = 0; (F->fd = open(_PATH_FILEMON, O_RDWR|O_CLOEXEC)) == -1; i++) {
if (i == 5) {
error = errno;
goto fail0;
}
}
/* Success! */
return F;
fail0: free(F);
errno = error;
return NULL;
}
int
filemon_setfd(struct filemon *F, int fd)
{
/* Point the kernel at this file descriptor. */
if (ioctl(F->fd, FILEMON_SET_FD, &fd) == -1)
return -1;
/* No need for it in userland any more; close it. */
(void)close(fd);
/* Success! */
return 0;
}
void
filemon_setpid_parent(struct filemon *F, pid_t pid)
{
/* Nothing to do! */
}
int
filemon_setpid_child(const struct filemon *F, pid_t pid)
{
/* Just pass it on to the kernel. */
return ioctl(F->fd, FILEMON_SET_PID, &pid);
}
int
filemon_close(struct filemon *F)
{
int error = 0;
/* Close the filemon device fd. */
if (close(F->fd) == -1 && error == 0)
error = errno;
/* Free the filemon descriptor. */
free(F);
/* Set errno and return -1 if anything went wrong. */
if (error != 0) {
errno = error;
return -1;
}
/* Success! */
return 0;
}
int
filemon_readfd(const struct filemon *F)
{
return -1;
}
int
filemon_process(struct filemon *F)
{
return 0;
}

View File

@ -0,0 +1,894 @@
/* $NetBSD: filemon_ktrace.c,v 1.14 2021/02/01 21:34:41 rillig Exp $ */
/*
* Copyright (c) 2019 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Taylor R. Campbell.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#define _KERNTYPES /* register_t */
#include "filemon.h"
#include <sys/param.h>
#include <sys/types.h>
#include <sys/rbtree.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <sys/ktrace.h>
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef AT_CWD
#define AT_CWD -1
#endif
struct filemon;
struct filemon_key;
struct filemon_state;
typedef struct filemon_state *filemon_syscall_t(struct filemon *,
const struct filemon_key *, const struct ktr_syscall *);
static filemon_syscall_t filemon_sys_chdir;
static filemon_syscall_t filemon_sys_execve;
static filemon_syscall_t filemon_sys_exit;
static filemon_syscall_t filemon_sys_fork;
static filemon_syscall_t filemon_sys_link;
static filemon_syscall_t filemon_sys_open;
static filemon_syscall_t filemon_sys_openat;
static filemon_syscall_t filemon_sys_symlink;
static filemon_syscall_t filemon_sys_unlink;
static filemon_syscall_t filemon_sys_rename;
static filemon_syscall_t *const filemon_syscalls[] = {
[SYS_chdir] = &filemon_sys_chdir,
[SYS_execve] = &filemon_sys_execve,
[SYS_exit] = &filemon_sys_exit,
[SYS_fork] = &filemon_sys_fork,
[SYS_link] = &filemon_sys_link,
[SYS_open] = &filemon_sys_open,
[SYS_openat] = &filemon_sys_openat,
[SYS_symlink] = &filemon_sys_symlink,
[SYS_unlink] = &filemon_sys_unlink,
[SYS_rename] = &filemon_sys_rename,
};
struct filemon {
int ktrfd; /* kernel writes ktrace events here */
FILE *in; /* we read ktrace events from here */
FILE *out; /* we write filemon events to here */
rb_tree_t active;
pid_t child;
/* I/O state machine. */
enum {
FILEMON_START = 0,
FILEMON_HEADER,
FILEMON_PAYLOAD,
FILEMON_ERROR,
} state;
unsigned char *p;
size_t resid;
/* I/O buffer. */
struct ktr_header hdr;
union {
struct ktr_syscall syscall;
struct ktr_sysret sysret;
char namei[PATH_MAX];
unsigned char buf[4096];
} payload;
};
struct filemon_state {
struct filemon_key {
pid_t pid;
lwpid_t lid;
} key;
struct rb_node node;
int syscode;
void (*show)(struct filemon *, const struct filemon_state *,
const struct ktr_sysret *);
unsigned i;
unsigned npath;
char *path[/*npath*/];
};
/*ARGSUSED*/
static int
compare_filemon_states(void *cookie, const void *na, const void *nb)
{
const struct filemon_state *Sa = na;
const struct filemon_state *Sb = nb;
if (Sa->key.pid < Sb->key.pid)
return -1;
if (Sa->key.pid > Sb->key.pid)
return +1;
if (Sa->key.lid < Sb->key.lid)
return -1;
if (Sa->key.lid > Sb->key.lid)
return +1;
return 0;
}
/*ARGSUSED*/
static int
compare_filemon_key(void *cookie, const void *n, const void *k)
{
const struct filemon_state *S = n;
const struct filemon_key *key = k;
if (S->key.pid < key->pid)
return -1;
if (S->key.pid > key->pid)
return +1;
if (S->key.lid < key->lid)
return -1;
if (S->key.lid > key->lid)
return +1;
return 0;
}
static const rb_tree_ops_t filemon_rb_ops = {
.rbto_compare_nodes = &compare_filemon_states,
.rbto_compare_key = &compare_filemon_key,
.rbto_node_offset = offsetof(struct filemon_state, node),
.rbto_context = NULL,
};
/*
* filemon_path()
*
* Return a pointer to a constant string denoting the `path' of
* the filemon.
*/
const char *
filemon_path(void)
{
return "ktrace";
}
/*
* filemon_open()
*
* Allocate a filemon descriptor. Returns NULL and sets errno on
* failure.
*/
struct filemon *
filemon_open(void)
{
struct filemon *F;
int ktrpipe[2];
int error;
/* Allocate and zero a struct filemon object. */
F = calloc(1, sizeof *F);
if (F == NULL)
return NULL;
/* Create a pipe for ktrace events. */
if (pipe2(ktrpipe, O_CLOEXEC|O_NONBLOCK) == -1) {
error = errno;
goto fail0;
}
/* Create a file stream for reading the ktrace events. */
if ((F->in = fdopen(ktrpipe[0], "r")) == NULL) {
error = errno;
goto fail1;
}
ktrpipe[0] = -1; /* claimed by fdopen */
/*
* Set the fd for writing ktrace events and initialize the
* rbtree. The rest can be safely initialized to zero.
*/
F->ktrfd = ktrpipe[1];
rb_tree_init(&F->active, &filemon_rb_ops);
/* Success! */
return F;
(void)fclose(F->in);
fail1: (void)close(ktrpipe[0]);
(void)close(ktrpipe[1]);
fail0: free(F);
errno = error;
return NULL;
}
/*
* filemon_closefd(F)
*
* Internal subroutine to try to flush and close the output file.
* If F is not open for output, do nothing. Never leaves F open
* for output even on failure. Returns 0 on success; sets errno
* and return -1 on failure.
*/
static int
filemon_closefd(struct filemon *F)
{
int error = 0;
/* If we're not open, nothing to do. */
if (F->out == NULL)
return 0;
/*
* Flush it, close it, and null it unconditionally, but be
* careful to return the earliest error in errno.
*/
if (fflush(F->out) == EOF && error == 0)
error = errno;
if (fclose(F->out) == EOF && error == 0)
error = errno;
F->out = NULL;
/* Set errno and return -1 if anything went wrong. */
if (error != 0) {
errno = error;
return -1;
}
/* Success! */
return 0;
}
/*
* filemon_setfd(F, fd)
*
* Cause filemon activity on F to be sent to fd. Claims ownership
* of fd; caller should not use fd afterward, and any duplicates
* of fd may see their file positions changed.
*/
int
filemon_setfd(struct filemon *F, int fd)
{
/*
* Close an existing output file if done. Fail now if there's
* an error closing.
*/
if ((filemon_closefd(F)) == -1)
return -1;
assert(F->out == NULL);
/* Open a file stream and claim ownership of the fd. */
if ((F->out = fdopen(fd, "a")) == NULL)
return -1;
/*
* Print the opening output. Any failure will be deferred
* until closing. For hysterical raisins, we show the parent
* pid, not the child pid.
*/
fprintf(F->out, "# filemon version 4\n");
fprintf(F->out, "# Target pid %jd\n", (intmax_t)getpid());
fprintf(F->out, "V 4\n");
/* Success! */
return 0;
}
/*
* filemon_setpid_parent(F, pid)
*
* Set the traced pid, from the parent. Never fails.
*/
void
filemon_setpid_parent(struct filemon *F, pid_t pid)
{
F->child = pid;
}
/*
* filemon_setpid_child(F, pid)
*
* Set the traced pid, from the child. Returns 0 on success; sets
* errno and returns -1 on failure.
*/
int
filemon_setpid_child(const struct filemon *F, pid_t pid)
{
int ops, trpoints;
ops = KTROP_SET|KTRFLAG_DESCEND;
trpoints = KTRFACv2;
trpoints |= KTRFAC_SYSCALL|KTRFAC_NAMEI|KTRFAC_SYSRET;
trpoints |= KTRFAC_INHERIT;
if (fktrace(F->ktrfd, ops, trpoints, pid) == -1)
return -1;
return 0;
}
/*
* filemon_close(F)
*
* Close F for output if necessary, and free a filemon descriptor.
* Returns 0 on success; sets errno and returns -1 on failure, but
* frees the filemon descriptor either way;
*/
int
filemon_close(struct filemon *F)
{
struct filemon_state *S;
int error = 0;
/* Close for output. */
if (filemon_closefd(F) == -1 && error == 0)
error = errno;
/* Close the ktrace pipe. */
if (fclose(F->in) == EOF && error == 0)
error = errno;
if (close(F->ktrfd) == -1 && error == 0)
error = errno;
/* Free any active records. */
while ((S = RB_TREE_MIN(&F->active)) != NULL) {
rb_tree_remove_node(&F->active, S);
free(S);
}
/* Free the filemon descriptor. */
free(F);
/* Set errno and return -1 if anything went wrong. */
if (error != 0) {
errno = error;
return -1;
}
/* Success! */
return 0;
}
/*
* filemon_readfd(F)
*
* Returns a file descriptor which will select/poll ready for read
* when there are filemon events to be processed by
* filemon_process, or -1 if anything has gone wrong.
*/
int
filemon_readfd(const struct filemon *F)
{
if (F->state == FILEMON_ERROR)
return -1;
return fileno(F->in);
}
/*
* filemon_dispatch(F)
*
* Internal subroutine to dispatch a filemon ktrace event.
* Silently ignore events that we don't recognize.
*/
static void
filemon_dispatch(struct filemon *F)
{
const struct filemon_key key = {
.pid = F->hdr.ktr_pid,
.lid = F->hdr.ktr_lid,
};
struct filemon_state *S;
switch (F->hdr.ktr_type) {
case KTR_SYSCALL: {
struct ktr_syscall *call = &F->payload.syscall;
struct filemon_state *S1;
/* Validate the syscall code. */
if (call->ktr_code < 0 ||
(size_t)call->ktr_code >= __arraycount(filemon_syscalls) ||
filemon_syscalls[call->ktr_code] == NULL)
break;
/*
* Invoke the syscall-specific logic to create a new
* active state.
*/
S = (*filemon_syscalls[call->ktr_code])(F, &key, call);
if (S == NULL)
break;
/*
* Insert the active state, or ignore it if there
* already is one.
*
* Collisions shouldn't happen because the states are
* keyed by <pid,lid>, in which syscalls should happen
* sequentially in CALL/RET pairs, but let's be
* defensive.
*/
S1 = rb_tree_insert_node(&F->active, S);
if (S1 != S) {
/* XXX Which one to drop? */
free(S);
break;
}
break;
}
case KTR_NAMEI:
/* Find an active syscall state, or drop it. */
S = rb_tree_find_node(&F->active, &key);
if (S == NULL)
break;
/* Find the position of the next path, or drop it. */
if (S->i >= S->npath)
break;
/* Record the path. */
S->path[S->i++] = strndup(F->payload.namei,
sizeof F->payload.namei);
break;
case KTR_SYSRET: {
struct ktr_sysret *ret = &F->payload.sysret;
unsigned i;
/* Find and remove an active syscall state, or drop it. */
S = rb_tree_find_node(&F->active, &key);
if (S == NULL)
break;
rb_tree_remove_node(&F->active, S);
/*
* If the active syscall state matches this return,
* invoke the syscall-specific logic to show a filemon
* event.
*/
/* XXX What to do if syscall code doesn't match? */
if (S->i == S->npath && S->syscode == ret->ktr_code)
S->show(F, S, ret);
/* Free the state now that it is no longer active. */
for (i = 0; i < S->i; i++)
free(S->path[i]);
free(S);
break;
}
default:
/* Ignore all other ktrace events. */
break;
}
}
/*
* filemon_process(F)
*
* Process all pending events after filemon_readfd(F) has
* selected/polled ready for read.
*
* Returns -1 on failure, 0 on end of events, and anything else if
* there may be more events.
*
* XXX What about fairness to other activities in the event loop?
* If we stop while there's events buffered in F->in, then select
* or poll may not return ready even though there's work queued up
* in the buffer of F->in, but if we don't stop then ktrace events
* may overwhelm all other activity in the event loop.
*/
int
filemon_process(struct filemon *F)
{
size_t nread;
top: /* If the child has exited, nothing to do. */
/* XXX What if one thread calls exit while another is running? */
if (F->child == 0)
return 0;
/* If we're waiting for input, read some. */
if (F->resid > 0) {
nread = fread(F->p, 1, F->resid, F->in);
if (nread == 0) {
if (feof(F->in) != 0)
return 0;
assert(ferror(F->in) != 0);
/*
* If interrupted or would block, there may be
* more events. Otherwise fail.
*/
if (errno == EAGAIN || errno == EINTR)
return 1;
F->state = FILEMON_ERROR;
F->p = NULL;
F->resid = 0;
return -1;
}
assert(nread <= F->resid);
F->p += nread;
F->resid -= nread;
if (F->resid > 0) /* may be more events */
return 1;
}
/* Process a state transition now that we've read a buffer. */
switch (F->state) {
case FILEMON_START: /* just started filemon; read header next */
F->state = FILEMON_HEADER;
F->p = (void *)&F->hdr;
F->resid = sizeof F->hdr;
goto top;
case FILEMON_HEADER: /* read header */
/* Sanity-check ktrace header; then read payload. */
if (F->hdr.ktr_len < 0 ||
(size_t)F->hdr.ktr_len > sizeof F->payload) {
F->state = FILEMON_ERROR;
F->p = NULL;
F->resid = 0;
errno = EIO;
return -1;
}
F->state = FILEMON_PAYLOAD;
F->p = (void *)&F->payload;
F->resid = (size_t)F->hdr.ktr_len;
goto top;
case FILEMON_PAYLOAD: /* read header and payload */
/* Dispatch ktrace event; then read next header. */
filemon_dispatch(F);
F->state = FILEMON_HEADER;
F->p = (void *)&F->hdr;
F->resid = sizeof F->hdr;
goto top;
default: /* paranoia */
F->state = FILEMON_ERROR;
/*FALLTHROUGH*/
case FILEMON_ERROR: /* persistent error indicator */
F->p = NULL;
F->resid = 0;
errno = EIO;
return -1;
}
}
static struct filemon_state *
syscall_enter(
const struct filemon_key *key, const struct ktr_syscall *call,
unsigned npath,
void (*show)(struct filemon *, const struct filemon_state *,
const struct ktr_sysret *))
{
struct filemon_state *S;
unsigned i;
S = calloc(1, offsetof(struct filemon_state, path[npath]));
if (S == NULL)
return NULL;
S->key = *key;
S->show = show;
S->syscode = call->ktr_code;
S->i = 0;
S->npath = npath;
for (i = 0; i < npath; i++)
S->path[i] = NULL; /* paranoia */
return S;
}
static void
show_paths(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret, const char *prefix)
{
unsigned i;
/* Caller must ensure all paths have been specified. */
assert(S->i == S->npath);
/*
* Ignore it if it failed or yielded EJUSTRETURN (-2), or if
* we're not producing output.
*/
if (ret->ktr_error != 0 && ret->ktr_error != -2)
return;
if (F->out == NULL)
return;
/*
* Print the prefix, pid, and paths -- with the paths quoted if
* there's more than one.
*/
fprintf(F->out, "%s %jd", prefix, (intmax_t)S->key.pid);
for (i = 0; i < S->npath; i++) {
const char *q = S->npath > 1 ? "'" : "";
fprintf(F->out, " %s%s%s", q, S->path[i], q);
}
fprintf(F->out, "\n");
}
static void
show_retval(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret, const char *prefix)
{
/*
* Ignore it if it failed or yielded EJUSTRETURN (-2), or if
* we're not producing output.
*/
if (ret->ktr_error != 0 && ret->ktr_error != -2)
return;
if (F->out == NULL)
return;
fprintf(F->out, "%s %jd %jd\n", prefix, (intmax_t)S->key.pid,
(intmax_t)ret->ktr_retval);
}
static void
show_chdir(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret)
{
show_paths(F, S, ret, "C");
}
static void
show_execve(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret)
{
show_paths(F, S, ret, "E");
}
static void
show_fork(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret)
{
show_retval(F, S, ret, "F");
}
static void
show_link(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret)
{
show_paths(F, S, ret, "L"); /* XXX same as symlink */
}
static void
show_open_read(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret)
{
show_paths(F, S, ret, "R");
}
static void
show_open_write(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret)
{
show_paths(F, S, ret, "W");
}
static void
show_open_readwrite(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret)
{
show_paths(F, S, ret, "R");
show_paths(F, S, ret, "W");
}
static void
show_openat_read(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret)
{
if (S->path[0][0] != '/')
show_paths(F, S, ret, "A");
show_paths(F, S, ret, "R");
}
static void
show_openat_write(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret)
{
if (S->path[0][0] != '/')
show_paths(F, S, ret, "A");
show_paths(F, S, ret, "W");
}
static void
show_openat_readwrite(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret)
{
if (S->path[0][0] != '/')
show_paths(F, S, ret, "A");
show_paths(F, S, ret, "R");
show_paths(F, S, ret, "W");
}
static void
show_symlink(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret)
{
show_paths(F, S, ret, "L"); /* XXX same as link */
}
static void
show_unlink(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret)
{
show_paths(F, S, ret, "D");
}
static void
show_rename(struct filemon *F, const struct filemon_state *S,
const struct ktr_sysret *ret)
{
show_paths(F, S, ret, "M");
}
/*ARGSUSED*/
static struct filemon_state *
filemon_sys_chdir(struct filemon *F, const struct filemon_key *key,
const struct ktr_syscall *call)
{
return syscall_enter(key, call, 1, &show_chdir);
}
/* TODO: monitor fchdir as well */
/*ARGSUSED*/
static struct filemon_state *
filemon_sys_execve(struct filemon *F, const struct filemon_key *key,
const struct ktr_syscall *call)
{
return syscall_enter(key, call, 1, &show_execve);
}
static struct filemon_state *
filemon_sys_exit(struct filemon *F, const struct filemon_key *key,
const struct ktr_syscall *call)
{
const register_t *args = (const void *)&call[1];
int status = (int)args[0];
if (F->out != NULL) {
fprintf(F->out, "X %jd %d\n", (intmax_t)key->pid, status);
if (key->pid == F->child) {
fprintf(F->out, "# Bye bye\n");
F->child = 0;
}
}
return NULL;
}
/*ARGSUSED*/
static struct filemon_state *
filemon_sys_fork(struct filemon *F, const struct filemon_key *key,
const struct ktr_syscall *call)
{
return syscall_enter(key, call, 0, &show_fork);
}
/*ARGSUSED*/
static struct filemon_state *
filemon_sys_link(struct filemon *F, const struct filemon_key *key,
const struct ktr_syscall *call)
{
return syscall_enter(key, call, 2, &show_link);
}
/*ARGSUSED*/
static struct filemon_state *
filemon_sys_open(struct filemon *F, const struct filemon_key *key,
const struct ktr_syscall *call)
{
const register_t *args = (const void *)&call[1];
int flags;
if (call->ktr_argsize < 2)
return NULL;
flags = (int)args[1];
if ((flags & O_RDWR) == O_RDWR)
return syscall_enter(key, call, 1, &show_open_readwrite);
else if ((flags & O_WRONLY) == O_WRONLY)
return syscall_enter(key, call, 1, &show_open_write);
else if ((flags & O_RDONLY) == O_RDONLY)
return syscall_enter(key, call, 1, &show_open_read);
else
return NULL; /* XXX Do we care if no read or write? */
}
/*ARGSUSED*/
static struct filemon_state *
filemon_sys_openat(struct filemon *F, const struct filemon_key *key,
const struct ktr_syscall *call)
{
const register_t *args = (const void *)&call[1];
int flags, fd;
/*
* XXX: In the .meta log, the base directory is missing, which makes
* all references to relative pathnames useless.
*/
if (call->ktr_argsize < 3)
return NULL;
fd = (int)args[0];
flags = (int)args[2];
if (fd == AT_CWD) {
if ((flags & O_RDWR) == O_RDWR)
return syscall_enter(key, call, 1,
&show_open_readwrite);
else if ((flags & O_WRONLY) == O_WRONLY)
return syscall_enter(key, call, 1, &show_open_write);
else if ((flags & O_RDONLY) == O_RDONLY)
return syscall_enter(key, call, 1, &show_open_read);
else
return NULL;
} else {
if ((flags & O_RDWR) == O_RDWR)
return syscall_enter(key, call, 1,
&show_openat_readwrite);
else if ((flags & O_WRONLY) == O_WRONLY)
return syscall_enter(key, call, 1, &show_openat_write);
else if ((flags & O_RDONLY) == O_RDONLY)
return syscall_enter(key, call, 1, &show_openat_read);
else
return NULL;
}
}
/* TODO: monitor the other *at syscalls as well, not only openat. */
/*ARGSUSED*/
static struct filemon_state *
filemon_sys_symlink(struct filemon *F, const struct filemon_key *key,
const struct ktr_syscall *call)
{
return syscall_enter(key, call, 2, &show_symlink);
}
/*ARGSUSED*/
static struct filemon_state *
filemon_sys_unlink(struct filemon *F, const struct filemon_key *key,
const struct ktr_syscall *call)
{
return syscall_enter(key, call, 1, &show_unlink);
}
/*ARGSUSED*/
static struct filemon_state *
filemon_sys_rename(struct filemon *F, const struct filemon_key *key,
const struct ktr_syscall *call)
{
return syscall_enter(key, call, 2, &show_rename);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $ */ /* $NetBSD: for.c,v 1.141 2021/02/04 21:33:13 rillig Exp $ */
/* /*
* Copyright (c) 1992, The Regents of the University of California. * Copyright (c) 1992, The Regents of the University of California.
@ -29,106 +29,188 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#ifndef MAKE_NATIVE /*
static char rcsid[] = "$NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $"; * Handling of .for/.endfor loops in a makefile.
#else *
#include <sys/cdefs.h> * For loops have the form:
#ifndef lint *
#if 0 * .for <varname...> in <value...>
static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93"; * # the body
#else * .endfor
__RCSID("$NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $"); *
#endif * When a .for line is parsed, the following lines are copied to the body of
#endif /* not lint */ * the .for loop, until the corresponding .endfor line is reached. In this
#endif * phase, the body is not yet evaluated. This also applies to any nested
* .for loops.
/*- *
* for.c -- * After reaching the .endfor, the values from the .for line are grouped
* Functions to handle loops in a makefile. * according to the number of variables. For each such group, the unexpanded
* body is scanned for variable expressions, and those that match the variable
* names are replaced with expressions of the form ${:U...} or $(:U...).
* After that, the body is treated like a file from an .include directive.
* *
* Interface: * Interface:
* For_Eval Evaluate the loop in the passed line. * For_Eval Evaluate the loop in the passed line.
*
* For_Run Run accumulated loop * For_Run Run accumulated loop
*
*/ */
#include <assert.h> #include "make.h"
#include <ctype.h>
#include "make.h" /* "@(#)for.c 8.1 (Berkeley) 6/6/93" */
#include "hash.h" MAKE_RCSID("$NetBSD: for.c,v 1.141 2021/02/04 21:33:13 rillig Exp $");
#include "dir.h"
#include "buf.h"
#include "strlist.h"
#define FOR_SUB_ESCAPE_CHAR 1
#define FOR_SUB_ESCAPE_BRACE 2
#define FOR_SUB_ESCAPE_PAREN 4
/* /* One of the variables to the left of the "in" in a .for loop. */
* For statements are of the form: typedef struct ForVar {
* char *name;
* .for <variable> in <varlist> size_t nameLen;
* ... } ForVar;
* .endfor
*
* The trick is to look for the matching end inside for for loop
* To do that, we count the current nesting level of the for loops.
* and the .endfor statements, accumulating all the statements between
* the initial .for loop and the matching .endfor;
* then we evaluate the for loop for each variable in the varlist.
*
* Note that any nested fors are just passed through; they get handled
* recursively in For_Eval when we're expanding the enclosing for in
* For_Run.
*/
static int forLevel = 0; /* Nesting level */ typedef struct ForLoop {
Buffer body; /* Unexpanded body of the loop */
Vector /* of ForVar */ vars; /* Iteration variables */
Words items; /* Substitution items */
Buffer curBody; /* Expanded body of the current iteration */
/* Is any of the names 1 character long? If so, when the variable values
* are substituted, the parser must handle $V expressions as well, not
* only ${V} and $(V). */
Boolean short_var;
unsigned int sub_next; /* Where to continue iterating */
} ForLoop;
/*
* State of a for loop.
*/
typedef struct _For {
Buffer buf; /* Body of loop */
strlist_t vars; /* Iteration variables */
strlist_t items; /* Substitution items */
char *parse_buf;
int short_var;
int sub_next;
} For;
static For *accumFor; /* Loop being accumulated */ static ForLoop *accumFor; /* Loop being accumulated */
static int forLevel = 0; /* Nesting level */
static char * static ForLoop *
make_str(const char *ptr, int len) ForLoop_New(void)
{ {
char *new_ptr; ForLoop *f = bmake_malloc(sizeof *f);
new_ptr = bmake_malloc(len + 1); Buf_Init(&f->body);
memcpy(new_ptr, ptr, len); Vector_Init(&f->vars, sizeof(ForVar));
new_ptr[len] = 0; f->items.words = NULL;
return new_ptr; f->items.freeIt = NULL;
Buf_Init(&f->curBody);
f->short_var = FALSE;
f->sub_next = 0;
return f;
} }
static void static void
For_Free(For *arg) ForLoop_Free(ForLoop *f)
{ {
Buf_Destroy(&arg->buf, TRUE); Buf_Done(&f->body);
strlist_clean(&arg->vars);
strlist_clean(&arg->items);
free(arg->parse_buf);
free(arg); while (f->vars.len > 0) {
ForVar *var = Vector_Pop(&f->vars);
free(var->name);
}
Vector_Done(&f->vars);
Words_Free(f->items);
Buf_Done(&f->curBody);
free(f);
} }
/*- static void
*----------------------------------------------------------------------- ForLoop_AddVar(ForLoop *f, const char *name, size_t len)
* For_Eval -- {
* Evaluate the for loop in the passed line. The line ForVar *var = Vector_Push(&f->vars);
* looks like this: var->name = bmake_strldup(name, len);
* .for <variable> in <varlist> var->nameLen = len;
}
static Boolean
ForLoop_ParseVarnames(ForLoop *f, const char **pp)
{
const char *p = *pp;
for (;;) {
size_t len;
cpp_skip_whitespace(&p);
if (*p == '\0') {
Parse_Error(PARSE_FATAL, "missing `in' in for");
return FALSE;
}
/*
* XXX: This allows arbitrary variable names;
* see directive-for.mk.
*/
for (len = 1; p[len] != '\0' && !ch_isspace(p[len]); len++)
continue;
if (len == 2 && p[0] == 'i' && p[1] == 'n') {
p += 2;
break;
}
if (len == 1)
f->short_var = TRUE;
ForLoop_AddVar(f, p, len);
p += len;
}
if (f->vars.len == 0) {
Parse_Error(PARSE_FATAL, "no iteration variables in for");
return FALSE;
}
*pp = p;
return TRUE;
}
static Boolean
ForLoop_ParseItems(ForLoop *f, const char *p)
{
char *items;
cpp_skip_whitespace(&p);
if (Var_Subst(p, SCOPE_GLOBAL, VARE_WANTRES, &items) != VPR_OK) {
Parse_Error(PARSE_FATAL, "Error in .for loop items");
return FALSE;
}
f->items = Str_Words(items, FALSE);
free(items);
if (f->items.len == 1 && f->items.words[0][0] == '\0')
f->items.len = 0; /* .for var in ${:U} */
if (f->items.len != 0 && f->items.len % f->vars.len != 0) {
Parse_Error(PARSE_FATAL,
"Wrong number of words (%u) in .for "
"substitution list with %u variables",
(unsigned)f->items.len, (unsigned)f->vars.len);
return FALSE;
}
return TRUE;
}
static Boolean
IsFor(const char *p)
{
return p[0] == 'f' && p[1] == 'o' && p[2] == 'r' && ch_isspace(p[3]);
}
static Boolean
IsEndfor(const char *p)
{
return p[0] == 'e' && strncmp(p, "endfor", 6) == 0 &&
(p[6] == '\0' || ch_isspace(p[6]));
}
/*
* Evaluate the for loop in the passed line. The line looks like this:
* .for <varname...> in <value...>
* *
* Input: * Input:
* line Line to parse * line Line to parse
@ -137,360 +219,299 @@ For_Free(For *arg)
* 0: Not a .for statement, parse the line * 0: Not a .for statement, parse the line
* 1: We found a for loop * 1: We found a for loop
* -1: A .for statement with a bad syntax error, discard. * -1: A .for statement with a bad syntax error, discard.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/ */
int int
For_Eval(char *line) For_Eval(const char *line)
{ {
For *new_for; ForLoop *f;
char *ptr = line, *sub; const char *p;
int len;
int escapes;
unsigned char ch;
char **words, *word_buf;
int n, nwords;
/* Skip the '.' and any following whitespace */ p = line + 1; /* skip the '.' */
for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++) cpp_skip_whitespace(&p);
continue;
/* if (!IsFor(p)) {
* If we are not in a for loop quickly determine if the statement is if (IsEndfor(p)) {
* a for. Parse_Error(PARSE_FATAL, "for-less endfor");
*/ return -1;
if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' ||
!isspace((unsigned char) ptr[3])) {
if (ptr[0] == 'e' && strncmp(ptr+1, "ndfor", 5) == 0) {
Parse_Error(PARSE_FATAL, "for-less endfor");
return -1;
}
return 0;
}
ptr += 3;
/*
* we found a for loop, and now we are going to parse it.
*/
new_for = bmake_malloc(sizeof *new_for);
memset(new_for, 0, sizeof *new_for);
/* Grab the variables. Terminate on "in". */
for (;; ptr += len) {
while (*ptr && isspace((unsigned char) *ptr))
ptr++;
if (*ptr == '\0') {
Parse_Error(PARSE_FATAL, "missing `in' in for");
For_Free(new_for);
return -1;
}
for (len = 1; ptr[len] && !isspace((unsigned char)ptr[len]); len++)
continue;
if (len == 2 && ptr[0] == 'i' && ptr[1] == 'n') {
ptr += 2;
break;
}
if (len == 1)
new_for->short_var = 1;
strlist_add_str(&new_for->vars, make_str(ptr, len), len);
}
if (strlist_num(&new_for->vars) == 0) {
Parse_Error(PARSE_FATAL, "no iteration variables in for");
For_Free(new_for);
return -1;
}
while (*ptr && isspace((unsigned char) *ptr))
ptr++;
/*
* Make a list with the remaining words
* The values are substituted as ${:U<value>...} so we must \ escape
* characters that break that syntax.
* Variables are fully expanded - so it is safe for escape $.
* We can't do the escapes here - because we don't know whether
* we are substuting into ${...} or $(...).
*/
sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE);
/*
* Split into words allowing for quoted strings.
*/
words = brk_string(sub, &nwords, FALSE, &word_buf);
free(sub);
if (words != NULL) {
for (n = 0; n < nwords; n++) {
ptr = words[n];
if (!*ptr)
continue;
escapes = 0;
while ((ch = *ptr++)) {
switch(ch) {
case ':':
case '$':
case '\\':
escapes |= FOR_SUB_ESCAPE_CHAR;
break;
case ')':
escapes |= FOR_SUB_ESCAPE_PAREN;
break;
case /*{*/ '}':
escapes |= FOR_SUB_ESCAPE_BRACE;
break;
} }
} return 0;
/* }
* We have to dup words[n] to maintain the semantics of p += 3;
* strlist.
*/ f = ForLoop_New();
strlist_add_str(&new_for->items, bmake_strdup(words[n]), escapes);
if (!ForLoop_ParseVarnames(f, &p)) {
ForLoop_Free(f);
return -1;
} }
free(words); if (!ForLoop_ParseItems(f, p)) {
free(word_buf); /* Continue parsing the .for loop, but don't iterate. */
f->items.len = 0;
if ((len = strlist_num(&new_for->items)) > 0 &&
len % (n = strlist_num(&new_for->vars))) {
Parse_Error(PARSE_FATAL,
"Wrong number of words (%d) in .for substitution list"
" with %d vars", len, n);
/*
* Return 'success' so that the body of the .for loop is
* accumulated.
* Remove all items so that the loop doesn't iterate.
*/
strlist_clean(&new_for->items);
} }
}
Buf_Init(&new_for->buf, 0); accumFor = f;
accumFor = new_for; forLevel = 1;
forLevel = 1; return 1;
return 1;
} }
/* /*
* Add another line to a .for loop. * Add another line to the .for loop that is being built up.
* Returns 0 when the matching .endfor is reached. * Returns FALSE when the matching .endfor is reached.
*/ */
Boolean
int For_Accum(const char *line)
For_Accum(char *line)
{ {
char *ptr = line; const char *p = line;
if (*ptr == '.') { if (*p == '.') {
p++;
cpp_skip_whitespace(&p);
for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++) if (IsEndfor(p)) {
continue; DEBUG1(FOR, "For: end for %d\n", forLevel);
if (--forLevel <= 0)
if (strncmp(ptr, "endfor", 6) == 0 && return FALSE;
(isspace((unsigned char) ptr[6]) || !ptr[6])) { } else if (IsFor(p)) {
if (DEBUG(FOR)) forLevel++;
(void)fprintf(debug_file, "For: end for %d\n", forLevel); DEBUG1(FOR, "For: new loop %d\n", forLevel);
if (--forLevel <= 0) }
return 0;
} else if (strncmp(ptr, "for", 3) == 0 &&
isspace((unsigned char) ptr[3])) {
forLevel++;
if (DEBUG(FOR))
(void)fprintf(debug_file, "For: new loop %d\n", forLevel);
} }
}
Buf_AddBytes(&accumFor->buf, strlen(line), line); Buf_AddStr(&accumFor->body, line);
Buf_AddByte(&accumFor->buf, '\n'); Buf_AddByte(&accumFor->body, '\n');
return 1; return TRUE;
} }
/*-
*-----------------------------------------------------------------------
* 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) for_var_len(const char *var)
{ {
char ch, var_start, var_end; char ch, var_start, var_end;
int depth; int depth;
int len; size_t len;
var_start = *var; var_start = *var;
if (var_start == 0) if (var_start == '\0')
/* just escape the $ */ /* just escape the $ */
return 0;
if (var_start == '(')
var_end = ')';
else if (var_start == '{')
var_end = '}';
else
return 1; /* Single char variable */
depth = 1;
for (len = 1; (ch = var[len++]) != '\0';) {
if (ch == var_start)
depth++;
else if (ch == var_end && --depth == 0)
return len;
}
/* Variable end not found, escape the $ */
return 0; return 0;
if (var_start == '(')
var_end = ')';
else if (var_start == '{')
var_end = '}';
else
/* Single char variable */
return 1;
depth = 1;
for (len = 1; (ch = var[len++]) != 0;) {
if (ch == var_start)
depth++;
else if (ch == var_end && --depth == 0)
return len;
}
/* Variable end not found, escape the $ */
return 0;
} }
/*
* The .for loop substitutes the items as ${:U<value>...}, which means
* that characters that break this syntax must be backslash-escaped.
*/
static Boolean
NeedsEscapes(const char *value, char endc)
{
const char *p;
for (p = value; *p != '\0'; p++) {
if (*p == ':' || *p == '$' || *p == '\\' || *p == endc)
return TRUE;
}
return FALSE;
}
/*
* While expanding the body of a .for loop, write the item in the ${:U...}
* expression, escaping characters as needed.
*
* The result is later unescaped by ApplyModifier_Defined.
*/
static void static void
for_substitute(Buffer *cmds, strlist_t *items, unsigned int item_no, char ech) Buf_AddEscaped(Buffer *cmds, const char *item, char endc)
{ {
const char *item = strlist_str(items, item_no); char ch;
int len;
char ch;
/* If there were no escapes, or the only escape is the other variable if (!NeedsEscapes(item, endc)) {
* terminator, then just substitute the full string */ Buf_AddStr(cmds, item);
if (!(strlist_info(items, item_no) & return;
(ech == ')' ? ~FOR_SUB_ESCAPE_BRACE : ~FOR_SUB_ESCAPE_PAREN))) { }
Buf_AddBytes(cmds, strlen(item), item);
/* Escape ':', '$', '\\' and 'endc' - these will be removed later by
* :U processing, see ApplyModifier_Defined. */
while ((ch = *item++) != '\0') {
if (ch == '$') {
size_t len = for_var_len(item);
if (len != 0) {
Buf_AddBytes(cmds, item - 1, len + 1);
item += len;
continue;
}
Buf_AddByte(cmds, '\\');
} else if (ch == ':' || ch == '\\' || ch == endc)
Buf_AddByte(cmds, '\\');
Buf_AddByte(cmds, ch);
}
}
/*
* While expanding the body of a .for loop, replace the variable name of an
* expression like ${i} or ${i:...} or $(i) or $(i:...) with ":Uvalue".
*/
static void
ForLoop_SubstVarLong(ForLoop *f, const char **pp, const char *bodyEnd,
char endc, const char **inout_mark)
{
size_t i;
const char *p = *pp;
for (i = 0; i < f->vars.len; i++) {
ForVar *forVar = Vector_Get(&f->vars, i);
char *varname = forVar->name;
size_t varnameLen = forVar->nameLen;
if (varnameLen >= (size_t)(bodyEnd - p))
continue;
if (memcmp(p, varname, varnameLen) != 0)
continue;
/* XXX: why test for backslash here? */
if (p[varnameLen] != ':' && p[varnameLen] != endc &&
p[varnameLen] != '\\')
continue;
/*
* Found a variable match. Skip over the variable name and
* instead add ':U<value>' to the current body.
*/
Buf_AddBytesBetween(&f->curBody, *inout_mark, p);
Buf_AddStr(&f->curBody, ":U");
Buf_AddEscaped(&f->curBody,
f->items.words[f->sub_next + i], endc);
p += varnameLen;
*inout_mark = p;
*pp = p;
return;
}
}
/*
* While expanding the body of a .for loop, replace single-character
* variable expressions like $i with their ${:U...} expansion.
*/
static void
ForLoop_SubstVarShort(ForLoop *f, const char *p, const char **inout_mark)
{
const char ch = *p;
ForVar *vars;
size_t i;
/* Skip $$ and stupid ones. */
if (!f->short_var || strchr("}):$", ch) != NULL)
return;
vars = Vector_Get(&f->vars, 0);
for (i = 0; i < f->vars.len; i++) {
const char *varname = vars[i].name;
if (varname[0] == ch && varname[1] == '\0')
goto found;
}
return; return;
}
/* Escape ':', '$', '\\' and 'ech' - removed by :U processing */ found:
while ((ch = *item++) != 0) { /* Replace $<ch> with ${:U<value>} */
if (ch == '$') { Buf_AddBytesBetween(&f->curBody, *inout_mark, p), *inout_mark = p + 1;
len = for_var_len(item); Buf_AddStr(&f->curBody, "{:U");
if (len != 0) { Buf_AddEscaped(&f->curBody, f->items.words[f->sub_next + i], '}');
Buf_AddBytes(cmds, len + 1, item - 1); Buf_AddByte(&f->curBody, '}');
item += len;
continue;
}
Buf_AddByte(cmds, '\\');
} else if (ch == ':' || ch == '\\' || ch == ech)
Buf_AddByte(cmds, '\\');
Buf_AddByte(cmds, ch);
}
} }
static char * /*
For_Iterate(void *v_arg, size_t *ret_len) * Compute the body for the current iteration by copying the unexpanded body,
* replacing the expressions for the iteration variables on the way.
*
* Using variable expressions ensures that the .for loop can't generate
* syntax, and that the later parsing will still see a variable.
* This code assumes that the variable with the empty name will never be
* defined, see unit-tests/varname-empty.mk for more details.
*
* The detection of substitutions of the loop control variables is naive.
* Many of the modifiers use '\' to escape '$' (not '$'), so it is possible
* to contrive a makefile where an unwanted substitution happens.
*/
static void
ForLoop_SubstBody(ForLoop *f)
{ {
For *arg = v_arg; const char *p, *bodyEnd;
int i, len; const char *mark; /* where the last replacement left off */
char *var;
char *cp;
char *cmd_cp;
char *body_end;
char ch;
Buffer cmds;
if (arg->sub_next + strlist_num(&arg->vars) > strlist_num(&arg->items)) { Buf_Empty(&f->curBody);
/* No more iterations */
For_Free(arg);
return NULL;
}
free(arg->parse_buf); mark = f->body.data;
arg->parse_buf = NULL; bodyEnd = f->body.data + f->body.len;
for (p = mark; (p = strchr(p, '$')) != NULL;) {
/* if (p[1] == '{' || p[1] == '(') {
* Scan the for loop body and replace references to the loop variables p += 2;
* with variable references that expand to the required text. ForLoop_SubstVarLong(f, &p, bodyEnd,
* Using variable expansions ensures that the .for loop can't generate p[-1] == '{' ? '}' : ')', &mark);
* syntax, and that the later parsing will still see a variable. } else if (p[1] != '\0') {
* We assume that the null variable will never be defined. ForLoop_SubstVarShort(f, p + 1, &mark);
* p += 2;
* The detection of substitions of the loop control variable is naive. } else
* Many of the modifiers use \ to escape $ (not $) so it is possible break;
* to contrive a makefile where an unwanted substitution happens.
*/
cmd_cp = Buf_GetAll(&arg->buf, &len);
body_end = cmd_cp + len;
Buf_Init(&cmds, len + 256);
for (cp = cmd_cp; (cp = strchr(cp, '$')) != NULL;) {
char ech;
ch = *++cp;
if ((ch == '(' && (ech = ')')) || (ch == '{' && (ech = '}'))) {
cp++;
/* Check variable name against the .for loop variables */
STRLIST_FOREACH(var, &arg->vars, i) {
len = strlist_info(&arg->vars, i);
if (memcmp(cp, var, len) != 0)
continue;
if (cp[len] != ':' && cp[len] != ech && cp[len] != '\\')
continue;
/* Found a variable match. Replace with :U<value> */
Buf_AddBytes(&cmds, cp - cmd_cp, cmd_cp);
Buf_AddBytes(&cmds, 2, ":U");
cp += len;
cmd_cp = cp;
for_substitute(&cmds, &arg->items, arg->sub_next + i, ech);
break;
}
continue;
} }
if (ch == 0)
break;
/* Probably a single character name, ignore $$ and stupid ones. {*/
if (!arg->short_var || strchr("}):$", ch) != NULL) {
cp++;
continue;
}
STRLIST_FOREACH(var, &arg->vars, i) {
if (var[0] != ch || var[1] != 0)
continue;
/* Found a variable match. Replace with ${:U<value>} */
Buf_AddBytes(&cmds, cp - cmd_cp, cmd_cp);
Buf_AddBytes(&cmds, 3, "{:U");
cmd_cp = ++cp;
for_substitute(&cmds, &arg->items, arg->sub_next + i, /*{*/ '}');
Buf_AddBytes(&cmds, 1, "}");
break;
}
}
Buf_AddBytes(&cmds, body_end - cmd_cp, cmd_cp);
cp = Buf_Destroy(&cmds, FALSE); Buf_AddBytesBetween(&f->curBody, mark, bodyEnd);
if (DEBUG(FOR))
(void)fprintf(debug_file, "For: loop body:\n%s", cp);
arg->sub_next += strlist_num(&arg->vars);
arg->parse_buf = cp;
*ret_len = strlen(cp);
return cp;
} }
/*
* Compute the body for the current iteration by copying the unexpanded body,
* replacing the expressions for the iteration variables on the way.
*/
static char *
ForReadMore(void *v_arg, size_t *out_len)
{
ForLoop *f = v_arg;
if (f->sub_next == f->items.len) {
/* No more iterations */
ForLoop_Free(f);
return NULL;
}
ForLoop_SubstBody(f);
DEBUG1(FOR, "For: loop body:\n%s", f->curBody.data);
f->sub_next += (unsigned int)f->vars.len;
*out_len = f->curBody.len;
return f->curBody.data;
}
/* Run the .for loop, imitating the actions of an include file. */
void void
For_Run(int lineno) For_Run(int lineno)
{ {
For *arg; ForLoop *f = accumFor;
accumFor = NULL;
arg = accumFor;
accumFor = NULL;
if (strlist_num(&arg->items) == 0) { if (f->items.len == 0) {
/* Nothing to expand - possibly due to an earlier syntax error. */ /*
For_Free(arg); * Nothing to expand - possibly due to an earlier syntax
return; * error.
} */
ForLoop_Free(f);
Parse_SetInput(NULL, lineno, -1, For_Iterate, arg); return;
}
Parse_SetInput(NULL, lineno, -1, ForReadMore, f);
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: hash.c,v 1.20 2013/11/14 00:27:05 sjg Exp $ */ /* $NetBSD: hash.c,v 1.61 2021/02/01 17:32:10 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -69,398 +69,264 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#ifndef MAKE_NATIVE /* Hash tables with string keys. */
static char rcsid[] = "$NetBSD: hash.c,v 1.20 2013/11/14 00:27:05 sjg 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.20 2013/11/14 00:27:05 sjg Exp $");
#endif
#endif /* not lint */
#endif
/* hash.c --
*
* This module contains routines to manipulate a hash table.
* See hash.h for a definition of the structure of the hash
* table. Hash tables grow automatically as the amount of
* information increases.
*/
#include "sprite.h"
#include "make.h" #include "make.h"
#include "hash.h"
/* "@(#)hash.c 8.1 (Berkeley) 6/6/93" */
MAKE_RCSID("$NetBSD: hash.c,v 1.61 2021/02/01 17:32:10 rillig Exp $");
/* /*
* Forward references to local procedures that are used before they're * The ratio of # entries to # buckets at which we rebuild the table to
* defined: * make it larger.
*/ */
static void RebuildTable(Hash_Table *);
/*
* The following defines the ratio of # entries to # buckets
* at which we rebuild the table to make it larger.
*/
#define rebuildLimit 3 #define rebuildLimit 3
/* /* This hash function matches Gosling's Emacs and java.lang.String. */
*--------------------------------------------------------- static unsigned int
* hash(const char *key, size_t *out_keylen)
* Hash_InitTable --
*
* This routine just sets up the hash table.
*
* Input:
* t Structure to to hold table.
* numBuckets How many buckets to create for starters. This
* number is rounded up to a power of two. If
* <= 0, a reasonable default is chosen. The
* table will grow in size later as needed.
*
* Results:
* None.
*
* Side Effects:
* Memory is allocated for the initial bucket area.
*
*---------------------------------------------------------
*/
void
Hash_InitTable(Hash_Table *t, int numBuckets)
{ {
int i; unsigned int h;
struct Hash_Entry **hp; const char *p;
/* h = 0;
* Round up the size to a power of two. for (p = key; *p != '\0'; p++)
*/ h = 31 * h + (unsigned char)*p;
if (numBuckets <= 0)
i = 16; if (out_keylen != NULL)
else { *out_keylen = (size_t)(p - key);
for (i = 2; i < numBuckets; i <<= 1) return h;
continue; }
unsigned int
Hash_Hash(const char *key)
{
return hash(key, NULL);
}
static HashEntry *
HashTable_Find(HashTable *t, unsigned int h, const char *key)
{
HashEntry *e;
unsigned int chainlen = 0;
#ifdef DEBUG_HASH_LOOKUP
DEBUG4(HASH, "%s: %p h=%08x key=%s\n", __func__, t, h, key);
#endif
for (e = t->buckets[h & t->bucketsMask]; e != NULL; e = e->next) {
chainlen++;
if (e->key_hash == h && strcmp(e->key, key) == 0)
break;
} }
if (chainlen > t->maxchain)
t->maxchain = chainlen;
return e;
}
/* Set up the hash table. */
void
HashTable_Init(HashTable *t)
{
unsigned int n = 16, i;
HashEntry **buckets = bmake_malloc(sizeof *buckets * n);
for (i = 0; i < n; i++)
buckets[i] = NULL;
t->buckets = buckets;
t->bucketsSize = n;
t->numEntries = 0; t->numEntries = 0;
t->size = i; t->bucketsMask = n - 1;
t->mask = i - 1; t->maxchain = 0;
t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i);
while (--i >= 0)
*hp++ = NULL;
} }
/* /*
*--------------------------------------------------------- * Remove everything from the hash table and free up the memory for the keys
* * of the hash table, but not for the values associated to these keys.
* Hash_DeleteTable --
*
* This routine removes everything from a hash table
* and frees up the memory space it occupied (except for
* the space in the Hash_Table structure).
*
* Results:
* None.
*
* Side Effects:
* Lots of memory is freed up.
*
*---------------------------------------------------------
*/ */
void void
Hash_DeleteTable(Hash_Table *t) HashTable_Done(HashTable *t)
{ {
struct Hash_Entry **hp, *h, *nexth = NULL; HashEntry **buckets = t->buckets;
int i; size_t i, n = t->bucketsSize;
for (hp = t->bucketPtr, i = t->size; --i >= 0;) { for (i = 0; i < n; i++) {
for (h = *hp++; h != NULL; h = nexth) { HashEntry *he = buckets[i];
nexth = h->next; while (he != NULL) {
free(h); HashEntry *next = he->next;
} free(he);
} he = next;
free(t->bucketPtr);
/*
* Set up the hash table to cause memory faults on any future access
* attempts until re-initialization.
*/
t->bucketPtr = NULL;
}
/*
*---------------------------------------------------------
*
* Hash_FindEntry --
*
* Searches a hash table for an entry corresponding to key.
*
* Input:
* t Hash table to search.
* key A hash key.
*
* Results:
* The return value is a pointer to the entry for key,
* if key was present in the table. If key was not
* present, NULL is returned.
*
* Side Effects:
* None.
*
*---------------------------------------------------------
*/
Hash_Entry *
Hash_FindEntry(Hash_Table *t, const char *key)
{
Hash_Entry *e;
unsigned h;
const char *p;
if (t == NULL || t->bucketPtr == NULL) {
return NULL;
}
for (h = 0, p = key; *p;)
h = (h << 5) - h + *p++;
p = key;
for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next)
if (e->namehash == h && strcmp(e->name, p) == 0)
return (e);
return NULL;
}
/*
*---------------------------------------------------------
*
* Hash_CreateEntry --
*
* Searches a hash table for an entry corresponding to
* key. If no entry is found, then one is created.
*
* Input:
* t Hash table to search.
* key A hash key.
* newPtr Filled in with TRUE if new entry created,
* FALSE otherwise.
*
* Results:
* The return value is a pointer to the entry. If *newPtr
* isn't NULL, then *newPtr is filled in with TRUE if a
* new entry was created, and FALSE if an entry already existed
* with the given key.
*
* Side Effects:
* Memory may be allocated, and the hash buckets may be modified.
*---------------------------------------------------------
*/
Hash_Entry *
Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr)
{
Hash_Entry *e;
unsigned h;
const char *p;
int keylen;
struct Hash_Entry **hp;
/*
* Hash the key. As a side effect, save the length (strlen) of the
* key in case we need to create the entry.
*/
for (h = 0, p = key; *p;)
h = (h << 5) - h + *p++;
keylen = p - key;
p = key;
for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) {
if (e->namehash == h && strcmp(e->name, p) == 0) {
if (newPtr != NULL)
*newPtr = FALSE;
return (e);
} }
} }
/* free(t->buckets);
* The desired entry isn't there. Before allocating a new entry, #ifdef CLEANUP
* expand the table if necessary (and this changes the resulting t->buckets = NULL;
* bucket chain). #endif
*/ }
if (t->numEntries >= rebuildLimit * t->size)
RebuildTable(t); /* Find the entry corresponding to the key, or return NULL. */
e = bmake_malloc(sizeof(*e) + keylen); HashEntry *
hp = &t->bucketPtr[h & t->mask]; HashTable_FindEntry(HashTable *t, const char *key)
e->next = *hp; {
*hp = e; unsigned int h = hash(key, NULL);
Hash_SetValue(e, NULL); return HashTable_Find(t, h, key);
e->namehash = h; }
(void)strcpy(e->name, p);
/* Find the value corresponding to the key, or return NULL. */
void *
HashTable_FindValue(HashTable *t, const char *key)
{
HashEntry *he = HashTable_FindEntry(t, key);
return he != NULL ? he->value : NULL;
}
/*
* Find the value corresponding to the key and the precomputed hash,
* or return NULL.
*/
void *
HashTable_FindValueHash(HashTable *t, const char *key, unsigned int h)
{
HashEntry *he = HashTable_Find(t, h, key);
return he != NULL ? he->value : NULL;
}
/*
* Make the hash table larger. Any bucket numbers from the old table become
* invalid; the hash codes stay valid though.
*/
static void
HashTable_Enlarge(HashTable *t)
{
unsigned int oldSize = t->bucketsSize;
HashEntry **oldBuckets = t->buckets;
unsigned int newSize = 2 * oldSize;
unsigned int newMask = newSize - 1;
HashEntry **newBuckets = bmake_malloc(sizeof *newBuckets * newSize);
size_t i;
for (i = 0; i < newSize; i++)
newBuckets[i] = NULL;
for (i = 0; i < oldSize; i++) {
HashEntry *he = oldBuckets[i];
while (he != NULL) {
HashEntry *next = he->next;
he->next = newBuckets[he->key_hash & newMask];
newBuckets[he->key_hash & newMask] = he;
he = next;
}
}
free(oldBuckets);
t->bucketsSize = newSize;
t->bucketsMask = newMask;
t->buckets = newBuckets;
DEBUG5(HASH, "%s: %p size=%d entries=%d maxchain=%d\n",
__func__, t, t->bucketsSize, t->numEntries, t->maxchain);
t->maxchain = 0;
}
/*
* Find or create an entry corresponding to the key.
* Return in out_isNew whether a new entry has been created.
*/
HashEntry *
HashTable_CreateEntry(HashTable *t, const char *key, Boolean *out_isNew)
{
size_t keylen;
unsigned int h = hash(key, &keylen);
HashEntry *he = HashTable_Find(t, h, key);
if (he != NULL) {
if (out_isNew != NULL)
*out_isNew = FALSE;
return he;
}
if (t->numEntries >= rebuildLimit * t->bucketsSize)
HashTable_Enlarge(t);
he = bmake_malloc(sizeof *he + keylen);
he->value = NULL;
he->key_hash = h;
memcpy(he->key, key, keylen + 1);
he->next = t->buckets[h & t->bucketsMask];
t->buckets[h & t->bucketsMask] = he;
t->numEntries++; t->numEntries++;
if (newPtr != NULL) if (out_isNew != NULL)
*newPtr = TRUE; *out_isNew = TRUE;
return (e); return he;
} }
/* HashEntry *
*--------------------------------------------------------- HashTable_Set(HashTable *t, const char *key, void *value)
*
* Hash_DeleteEntry --
*
* Delete the given hash table entry and free memory associated with
* it.
*
* Results:
* None.
*
* Side Effects:
* Hash chain that entry lives in is modified and memory is freed.
*
*---------------------------------------------------------
*/
void
Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e)
{ {
Hash_Entry **hp, *p; HashEntry *he = HashTable_CreateEntry(t, key, NULL);
HashEntry_Set(he, value);
return he;
}
if (e == NULL) /* Delete the entry from the table and free the associated memory. */
return; void
for (hp = &t->bucketPtr[e->namehash & t->mask]; HashTable_DeleteEntry(HashTable *t, HashEntry *he)
(p = *hp) != NULL; hp = &p->next) { {
if (p == e) { HashEntry **ref = &t->buckets[he->key_hash & t->bucketsMask];
*hp = p->next; HashEntry *p;
for (; (p = *ref) != NULL; ref = &p->next) {
if (p == he) {
*ref = p->next;
free(p); free(p);
t->numEntries--; t->numEntries--;
return; return;
} }
} }
(void)write(2, "bad call to Hash_DeleteEntry\n", 29);
abort(); abort();
} }
/* /* Set things up for iterating over all entries in the hash table. */
*--------------------------------------------------------- void
* HashIter_Init(HashIter *hi, HashTable *t)
* Hash_EnumFirst --
* This procedure sets things up for a complete search
* of all entries recorded in the hash table.
*
* Input:
* t Table to be searched.
* searchPtr Area in which to keep state about search.
*
* Results:
* The return value is the address of the first entry in
* the hash table, or NULL if the table is empty.
*
* Side Effects:
* The information in searchPtr is initialized so that successive
* calls to Hash_Next will return successive HashEntry's
* from the table.
*
*---------------------------------------------------------
*/
Hash_Entry *
Hash_EnumFirst(Hash_Table *t, Hash_Search *searchPtr)
{ {
searchPtr->tablePtr = t; hi->table = t;
searchPtr->nextIndex = 0; hi->nextBucket = 0;
searchPtr->hashEntryPtr = NULL; hi->entry = NULL;
return Hash_EnumNext(searchPtr);
} }
/* /*
*--------------------------------------------------------- * Return the next entry in the hash table, or NULL if the end of the table
* * is reached.
* Hash_EnumNext --
* This procedure returns successive entries in the hash table.
*
* Input:
* searchPtr Area used to keep state about search.
*
* Results:
* The return value is a pointer to the next HashEntry
* in the table, or NULL when the end of the table is
* reached.
*
* Side Effects:
* The information in searchPtr is modified to advance to the
* next entry.
*
*---------------------------------------------------------
*/ */
HashEntry *
Hash_Entry * HashIter_Next(HashIter *hi)
Hash_EnumNext(Hash_Search *searchPtr)
{ {
Hash_Entry *e; HashTable *t = hi->table;
Hash_Table *t = searchPtr->tablePtr; HashEntry *he = hi->entry;
HashEntry **buckets = t->buckets;
unsigned int bucketsSize = t->bucketsSize;
/* if (he != NULL)
* The hashEntryPtr field points to the most recently returned he = he->next; /* skip the most recently returned entry */
* entry, or is nil if we are starting up. If not nil, we have
* to start at the next one in the chain. while (he == NULL) { /* find the next nonempty chain */
*/ if (hi->nextBucket >= bucketsSize)
e = searchPtr->hashEntryPtr;
if (e != NULL)
e = e->next;
/*
* If the chain ran out, or if we are starting up, we need to
* find the next nonempty chain.
*/
while (e == NULL) {
if (searchPtr->nextIndex >= t->size)
return NULL; return NULL;
e = t->bucketPtr[searchPtr->nextIndex++]; he = buckets[hi->nextBucket++];
} }
searchPtr->hashEntryPtr = e; hi->entry = he;
return (e); return he;
} }
/* void
*--------------------------------------------------------- HashTable_DebugStats(HashTable *t, const char *name)
*
* RebuildTable --
* This local routine makes a new hash table that
* is larger than the old one.
*
* Results:
* None.
*
* Side Effects:
* The entire hash table is moved, so any bucket numbers
* from the old table are invalid.
*
*---------------------------------------------------------
*/
static void
RebuildTable(Hash_Table *t)
{ {
Hash_Entry *e, *next = NULL, **hp, **xp; DEBUG4(HASH, "HashTable %s: size=%u numEntries=%u maxchain=%u\n",
int i, mask; name, t->bucketsSize, t->numEntries, t->maxchain);
Hash_Entry **oldhp;
int oldsize;
oldhp = t->bucketPtr;
oldsize = i = t->size;
i <<= 1;
t->size = i;
t->mask = mask = i - 1;
t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i);
while (--i >= 0)
*hp++ = NULL;
for (hp = oldhp, i = oldsize; --i >= 0;) {
for (e = *hp++; e != NULL; e = next) {
next = e->next;
xp = &t->bucketPtr[e->namehash & mask];
e->next = *xp;
*xp = e;
}
}
free(oldhp);
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: hash.h,v 1.10 2009/01/24 10:59:09 dsl Exp $ */ /* $NetBSD: hash.h,v 1.38 2020/12/15 01:23:55 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -72,83 +72,99 @@
* from: @(#)hash.h 8.1 (Berkeley) 6/6/93 * from: @(#)hash.h 8.1 (Berkeley) 6/6/93
*/ */
/* hash.h -- /* Hash tables with strings as keys and arbitrary pointers as values. */
*
* This file contains definitions used by the hash module,
* which maintains hash tables.
*/
#ifndef _HASH #ifndef MAKE_HASH_H
#define _HASH #define MAKE_HASH_H
/* /* A single key-value entry in the hash table. */
* The following defines one entry in the hash table. typedef struct HashEntry {
*/ struct HashEntry *next; /* Used to link together all the entries
* associated with the same bucket. */
void *value;
unsigned int key_hash; /* hash value of the key */
char key[1]; /* key string, variable length */
} HashEntry;
typedef struct Hash_Entry { /* The hash table containing the entries. */
struct Hash_Entry *next; /* Used to link together all the typedef struct HashTable {
* entries associated with the same HashEntry **buckets; /* Pointers to HashEntry, one
* bucket. */ * for each bucket in the table. */
union { unsigned int bucketsSize;
void *clientPtr; /* Arbitrary pointer */ unsigned int numEntries; /* Number of entries in the table. */
time_t clientTime; /* Arbitrary Time */ unsigned int bucketsMask; /* Used to select the bucket for a hash. */
} clientInfo; unsigned int maxchain; /* max length of chain detected */
unsigned namehash; /* hash value of key */ } HashTable;
char name[1]; /* key string */
} Hash_Entry;
typedef struct Hash_Table { /* State of an iteration over all entries in a table. */
struct Hash_Entry **bucketPtr;/* Pointers to Hash_Entry, one typedef struct HashIter {
* for each bucket in the table. */ HashTable *table; /* Table being searched. */
int size; /* Actual size of array. */ unsigned int nextBucket; /* Next bucket to check (after current). */
int numEntries; /* Number of entries in the table. */ HashEntry *entry; /* Next entry to check in current bucket. */
int mask; /* Used to select bits for hashing. */ } HashIter;
} Hash_Table;
/* /* A set of strings. */
* The following structure is used by the searching routines typedef struct HashSet {
* to record where we are in the search. HashTable tbl;
*/ } HashSet;
typedef struct Hash_Search { MAKE_INLINE void *
Hash_Table *tablePtr; /* Table being searched. */ HashEntry_Get(HashEntry *h)
int nextIndex; /* Next bucket to check (after current). */ {
Hash_Entry *hashEntryPtr; /* Next entry to check in current bucket. */ return h->value;
} Hash_Search; }
/* MAKE_INLINE void
* Macros. HashEntry_Set(HashEntry *h, void *datum)
*/ {
h->value = datum;
}
/* void HashTable_Init(HashTable *);
* void * Hash_GetValue(h) void HashTable_Done(HashTable *);
* Hash_Entry *h; HashEntry *HashTable_FindEntry(HashTable *, const char *);
*/ void *HashTable_FindValue(HashTable *, const char *);
unsigned int Hash_Hash(const char *);
void *HashTable_FindValueHash(HashTable *, const char *, unsigned int);
HashEntry *HashTable_CreateEntry(HashTable *, const char *, Boolean *);
HashEntry *HashTable_Set(HashTable *, const char *, void *);
void HashTable_DeleteEntry(HashTable *, HashEntry *);
void HashTable_DebugStats(HashTable *, const char *);
#define Hash_GetValue(h) ((h)->clientInfo.clientPtr) void HashIter_Init(HashIter *, HashTable *);
#define Hash_GetTimeValue(h) ((h)->clientInfo.clientTime) HashEntry *HashIter_Next(HashIter *);
/* MAKE_INLINE void
* Hash_SetValue(h, val); HashSet_Init(HashSet *set)
* Hash_Entry *h; {
* char *val; HashTable_Init(&set->tbl);
*/ }
#define Hash_SetValue(h, val) ((h)->clientInfo.clientPtr = (val)) MAKE_INLINE void
#define Hash_SetTimeValue(h, val) ((h)->clientInfo.clientTime = (val)) HashSet_Done(HashSet *set)
{
HashTable_Done(&set->tbl);
}
/* MAKE_INLINE Boolean
* Hash_Size(n) returns the number of words in an object of n bytes HashSet_Add(HashSet *set, const char *key)
*/ {
Boolean isNew;
#define Hash_Size(n) (((n) + sizeof (int) - 1) / sizeof (int)) (void)HashTable_CreateEntry(&set->tbl, key, &isNew);
return isNew;
}
void Hash_InitTable(Hash_Table *, int); MAKE_INLINE Boolean
void Hash_DeleteTable(Hash_Table *); HashSet_Contains(HashSet *set, const char *key)
Hash_Entry *Hash_FindEntry(Hash_Table *, const char *); {
Hash_Entry *Hash_CreateEntry(Hash_Table *, const char *, Boolean *); return HashTable_FindEntry(&set->tbl, key) != NULL;
void Hash_DeleteEntry(Hash_Table *, Hash_Entry *); }
Hash_Entry *Hash_EnumFirst(Hash_Table *, Hash_Search *);
Hash_Entry *Hash_EnumNext(Hash_Search *);
#endif /* _HASH */ MAKE_INLINE void
HashIter_InitSet(HashIter *hi, HashSet *set)
{
HashIter_Init(hi, &set->tbl);
}
#endif /* MAKE_HASH_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: job.h,v 1.42 2013/07/05 22:14:56 sjg Exp $ */ /* $NetBSD: job.h,v 1.72 2021/02/05 19:19:17 sjg Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -73,12 +73,12 @@
* from: @(#)job.h 8.1 (Berkeley) 6/6/93 * from: @(#)job.h 8.1 (Berkeley) 6/6/93
*/ */
/*- /*
* job.h -- * Running of jobs in parallel mode.
* 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 */ #define TMPPAT "makeXXXXXX" /* relative to tmpdir */
@ -97,8 +97,8 @@ struct emul_pollfd {
short revents; short revents;
}; };
#define POLLIN 0x0001 #define POLLIN 0x0001
#define POLLOUT 0x0004 #define POLLOUT 0x0004
int int
emul_poll(struct pollfd *fd, int nfd, int timeout); emul_poll(struct pollfd *fd, int nfd, int timeout);
@ -106,33 +106,10 @@ emul_poll(struct pollfd *fd, int nfd, int timeout);
/* /*
* The POLL_MSEC constant determines the maximum number of milliseconds spent * The POLL_MSEC constant determines the maximum number of milliseconds spent
* in poll before coming out to see if a child has finished. * in poll before coming out to see if a child has finished.
*/ */
#define POLL_MSEC 5000 #define POLL_MSEC 5000
/*-
* Job Table definitions.
*
* Each job has several things associated with it:
* 1) The process id of the child shell
* 2) The graph node describing the target being made by this job
* 3) A LstNode for the first command to be saved after the job
* completes. This is NULL if there was no "..." in the job's
* commands.
* 4) An FILE* for writing out the commands. This is only
* used before the job is actually started.
* 5) The output is being caught via a pipe and
* the descriptors of our pipe, an array in which output is line
* buffered and the current position in that buffer are all
* maintained for each job.
* 6) A word of flags which determine how the module handles errors,
* echoing, etc. for the job
*
* When a job is finished, the Make_Update function is called on each of the
* parents of the node which was just remade. This takes care of the upward
* traversal of the dependency graph.
*/
struct pollfd; struct pollfd;
@ -140,135 +117,94 @@ struct pollfd;
# include "meta.h" # include "meta.h"
#endif #endif
#define JOB_BUFSIZE 1024 typedef enum JobStatus {
typedef struct Job { JOB_ST_FREE = 0, /* Job is available */
int pid; /* The child's process ID */ JOB_ST_SET_UP = 1, /* Job is allocated but otherwise invalid */
GNode *node; /* The target the child is making */ /* XXX: What about the 2? */
LstNode tailCmds; /* The node of the first command to be JOB_ST_RUNNING = 3, /* Job is running, pid valid */
* saved when the job has been run */ JOB_ST_FINISHED = 4 /* Job is done (ie after SIGCHILD) */
FILE *cmdFILE; /* When creating the shell script, this is } JobStatus;
* where the commands go */
int exit_status; /* from wait4() in signal handler */
char job_state; /* status of the job entry */
#define JOB_ST_FREE 0 /* Job is available */
#define JOB_ST_SETUP 1 /* Job is allocated but otherwise invalid */
#define JOB_ST_RUNNING 3 /* Job is running, pid valid */
#define JOB_ST_FINISHED 4 /* Job is done (ie after SIGCHILD) */
char job_suspended;
short flags; /* Flags to control treatment of job */
#define JOB_IGNERR 0x001 /* Ignore non-zero exits */
#define JOB_SILENT 0x002 /* no output */
#define JOB_SPECIAL 0x004 /* Target is a special one. i.e. run it locally
* if we can't export it and maxLocal is 0 */
#define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing
* commands */
#define JOB_TRACED 0x400 /* we've sent 'set -x' */
int jobPipe[2]; /* Pipe for readind output from job */ /*
struct pollfd *inPollfd; /* pollfd associated with inPipe */ * A Job manages the shell commands that are run to create a single target.
char outBuf[JOB_BUFSIZE + 1]; * Each job is run in a separate subprocess by a shell. Several jobs can run
/* Buffer for storing the output of the * in parallel.
* job, line by line */ *
int curPos; /* Current position in op_outBuf */ * The shell commands for the target are written to a temporary file,
* then the shell is run with the temporary file as stdin, and the output
* of that shell is captured via a pipe.
*
* When a job is finished, Make_Update updates all parents of the node
* that was just remade, marking them as ready to be made next if all
* other dependencies are finished as well.
*/
typedef struct Job {
/* The process ID of the shell running the commands */
int pid;
/* The target the child is making */
GNode *node;
/* If one of the shell commands is "...", all following commands are
* delayed until the .END node is made. This list node points to the
* first of these commands, if any. */
StringListNode *tailCmds;
/* This is where the shell commands go. */
FILE *cmdFILE;
int exit_status; /* from wait4() in signal handler */
JobStatus status;
Boolean suspended;
/* Ignore non-zero exits */
Boolean ignerr;
/* Output the command before or instead of running it. */
Boolean echo;
/* Target is a special one. */
Boolean special;
int inPipe; /* Pipe for reading output from job */
int outPipe; /* Pipe for writing control commands */
struct pollfd *inPollfd; /* pollfd associated with inPipe */
#define JOB_BUFSIZE 1024
/* Buffer for storing the output of the job, line by line. */
char outBuf[JOB_BUFSIZE + 1];
size_t curPos; /* Current position in outBuf. */
#ifdef USE_META #ifdef USE_META
struct BuildMon bm; struct BuildMon bm;
#endif #endif
} Job; } Job;
#define inPipe jobPipe[0]
#define outPipe jobPipe[1]
/*-
* Shell Specifications:
* Each shell type has associated with it the following information:
* 1) The string which must match the last character of the shell name
* for the shell to be considered of this type. The longest match
* wins.
* 2) A command to issue to turn off echoing of command lines
* 3) A command to issue to turn echoing back on again
* 4) What the shell prints, and its length, when given the echo-off
* command. This line will not be printed when received from the shell
* 5) A boolean to tell if the shell has the ability to control
* error checking for individual commands.
* 6) The string to turn this checking on.
* 7) The string to turn it off.
* 8) The command-flag to give to cause the shell to start echoing
* commands right away.
* 9) The command-flag to cause the shell to Lib_Exit when an error is
* detected in one of the commands.
*
* Some special stuff goes on if a shell doesn't have error control. In such
* a case, errCheck becomes a printf template for echoing the command,
* should echoing be on and ignErr becomes another printf template for
* executing the command while ignoring the return status. Finally errOut
* is a printf template for running the command and causing the shell to
* exit on error. If any of these strings are empty when hasErrCtl is FALSE,
* the command will be executed anyway as is and if it causes an error, so be
* it. Any templates setup to echo the command will escape any '$ ` \ "'i
* characters in the command string to avoid common problems with
* echo "%s\n" as a template.
*/
typedef struct Shell {
const char *name; /* the name of the shell. For Bourne and C
* shells, this is used only to find the
* shell description when used as the single
* source of a .SHELL target. For user-defined
* shells, this is the full path of the shell.
*/
Boolean hasEchoCtl; /* True if both echoOff and echoOn defined */
const char *echoOff; /* command to turn off echo */
const char *echoOn; /* command to turn it back on again */
const char *noPrint; /* command to skip when printing output from
* shell. This is usually the command which
* was executed to turn off echoing */
int noPLen; /* length of noPrint command */
Boolean hasErrCtl; /* set if can control error checking for
* individual commands */
const char *errCheck; /* string to turn error checking on */
const char *ignErr; /* string to turn off error checking */
const char *errOut; /* string to use for testing exit code */
const char *newline; /* string literal that results in a newline
* character when it appears outside of any
* 'quote' or "quote" characters */
char commentChar; /* character used by shell for comment lines */
/*
* command-line flags
*/
const char *echo; /* echo commands */
const char *exit; /* exit on error */
} Shell;
extern const char *shellPath; extern const char *shellPath;
extern const char *shellName; extern const char *shellName;
extern char *shellErrFlag; extern char *shellErrFlag;
extern int jobTokensRunning; /* tokens currently "out" */ extern int jobTokensRunning; /* tokens currently "out" */
extern int maxJobs; /* Max jobs we can run */
void Shell_Init(void); void Shell_Init(void);
const char *Shell_GetNewline(void); const char *Shell_GetNewline(void);
void Job_Touch(GNode *, Boolean); void Job_Touch(GNode *, Boolean);
Boolean Job_CheckCommands(GNode *, void (*abortProc )(const char *, ...)); Boolean Job_CheckCommands(GNode *, void (*abortProc)(const char *, ...));
#define CATCH_BLOCK 1
void Job_CatchChildren(void); void Job_CatchChildren(void);
void Job_CatchOutput(void); void Job_CatchOutput(void);
void Job_Make(GNode *); void Job_Make(GNode *);
void Job_Init(void); void Job_Init(void);
Boolean Job_Full(void); Boolean Job_ParseShell(char *);
Boolean Job_Empty(void);
ReturnStatus Job_ParseShell(char *);
int Job_Finish(void); int Job_Finish(void);
void Job_End(void); void Job_End(void);
void Job_Wait(void); void Job_Wait(void);
void Job_AbortAll(void); void Job_AbortAll(void);
void JobFlagForMigration(int);
void Job_TokenReturn(void); void Job_TokenReturn(void);
Boolean Job_TokenWithdraw(void); Boolean Job_TokenWithdraw(void);
void Job_ServerStart(int, int, int); void Job_ServerStart(int, int, int);
void Job_SetPrefix(void); void Job_SetPrefix(void);
Boolean Job_RunTarget(const char *, const char *); Boolean Job_RunTarget(const char *, const char *);
void Job_FlagsToString(const Job *, char *, size_t);
int Job_TempFile(const char *, char *, size_t);
#endif /* _JOB_H_ */ #endif /* MAKE_JOB_H */

292
usr.bin/make/lst.c Normal file
View File

@ -0,0 +1,292 @@
/* $NetBSD: lst.c,v 1.105 2021/03/15 16:45:30 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.
*/
#include "make.h"
MAKE_RCSID("$NetBSD: lst.c,v 1.105 2021/03/15 16:45:30 rillig Exp $");
static ListNode *
LstNodeNew(ListNode *prev, ListNode *next, void *datum)
{
ListNode *ln = bmake_malloc(sizeof *ln);
ln->prev = prev;
ln->next = next;
ln->datum = datum;
return ln;
}
/* Create and initialize a new, empty list. */
List *
Lst_New(void)
{
List *list = bmake_malloc(sizeof *list);
Lst_Init(list);
return list;
}
void
Lst_Done(List *list)
{
ListNode *ln, *next;
for (ln = list->first; ln != NULL; ln = next) {
next = ln->next;
free(ln);
}
}
void
Lst_DoneCall(List *list, LstFreeProc freeProc)
{
ListNode *ln, *next;
for (ln = list->first; ln != NULL; ln = next) {
next = ln->next;
freeProc(ln->datum);
free(ln);
}
}
/* Free a list and all its nodes. The node data are not freed though. */
void
Lst_Free(List *list)
{
Lst_Done(list);
free(list);
}
/* Insert a new node with the datum before the given node. */
void
Lst_InsertBefore(List *list, ListNode *ln, void *datum)
{
ListNode *newNode;
assert(datum != NULL);
newNode = LstNodeNew(ln->prev, ln, datum);
if (ln->prev != NULL)
ln->prev->next = newNode;
ln->prev = newNode;
if (ln == list->first)
list->first = newNode;
}
/* Add a piece of data at the start of the given list. */
void
Lst_Prepend(List *list, void *datum)
{
ListNode *ln;
assert(datum != NULL);
ln = LstNodeNew(NULL, list->first, datum);
if (list->first == NULL) {
list->first = ln;
list->last = ln;
} else {
list->first->prev = ln;
list->first = ln;
}
}
/* Add a piece of data at the end of the given list. */
void
Lst_Append(List *list, void *datum)
{
ListNode *ln;
assert(datum != NULL);
ln = LstNodeNew(list->last, NULL, datum);
if (list->last == NULL) {
list->first = ln;
list->last = ln;
} else {
list->last->next = ln;
list->last = ln;
}
}
/*
* 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(List *list, ListNode *ln)
{
/* unlink it from its neighbors */
if (ln->next != NULL)
ln->next->prev = ln->prev;
if (ln->prev != NULL)
ln->prev->next = ln->next;
/* unlink it from the list */
if (list->first == ln)
list->first = ln->next;
if (list->last == ln)
list->last = ln->prev;
}
/* Replace the datum in the given node with the new datum. */
void
LstNode_Set(ListNode *ln, void *datum)
{
assert(datum != NULL);
ln->datum = datum;
}
/*
* Replace the datum in the given node with NULL.
* Having NULL values in a list is unusual though.
*/
void
LstNode_SetNull(ListNode *ln)
{
ln->datum = NULL;
}
/*
* Return the first node that contains the given datum, or NULL.
*
* Time complexity: O(length(list))
*/
ListNode *
Lst_FindDatum(List *list, const void *datum)
{
ListNode *ln;
assert(datum != NULL);
for (ln = list->first; ln != NULL; ln = ln->next)
if (ln->datum == datum)
return ln;
return NULL;
}
/*
* Move all nodes from src to the end of dst.
* The source list becomes indeterminate.
*/
void
Lst_MoveAll(List *dst, List *src)
{
if (src->first != NULL) {
src->first->prev = dst->last;
if (dst->last != NULL)
dst->last->next = src->first;
else
dst->first = src->first;
dst->last = src->last;
}
#ifdef CLEANUP
src->first = NULL;
src->last = NULL;
#endif
}
/* Copy the element data from src to the start of dst. */
void
Lst_PrependAll(List *dst, List *src)
{
ListNode *ln;
for (ln = src->last; ln != NULL; ln = ln->prev)
Lst_Prepend(dst, ln->datum);
}
/* Copy the element data from src to the end of dst. */
void
Lst_AppendAll(List *dst, List *src)
{
ListNode *ln;
for (ln = src->first; ln != NULL; ln = ln->next)
Lst_Append(dst, ln->datum);
}
/* Remove and return the datum at the head of the given list. */
void *
Lst_Dequeue(List *list)
{
void *datum = list->first->datum;
Lst_Remove(list, list->first);
assert(datum != NULL); /* since NULL would mean end of the list */
return datum;
}
void
Vector_Init(Vector *v, size_t itemSize)
{
v->len = 0;
v->cap = 10;
v->itemSize = itemSize;
v->items = bmake_malloc(v->cap * v->itemSize);
}
/*
* Add space for a new item to the vector and return a pointer to that space.
* The returned data is valid until the next modifying operation.
*/
void *
Vector_Push(Vector *v)
{
if (v->len >= v->cap) {
v->cap *= 2;
v->items = bmake_realloc(v->items, v->cap * v->itemSize);
}
v->len++;
return Vector_Get(v, v->len - 1);
}
/*
* Remove the last item from the vector, return the pointer to it.
* The returned data is valid until the next modifying operation.
*/
void *
Vector_Pop(Vector *v)
{
assert(v->len > 0);
v->len--;
return Vector_Get(v, v->len);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: lst.h,v 1.20 2014/09/07 20:55:34 joerg Exp $ */ /* $NetBSD: lst.h,v 1.97 2021/03/15 16:06:05 rillig Exp $ */
/* /*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -73,117 +73,128 @@
* from: @(#)lst.h 8.1 (Berkeley) 6/6/93 * from: @(#)lst.h 8.1 (Berkeley) 6/6/93
*/ */
/*- /* Doubly-linked lists of arbitrary pointers. */
* lst.h --
* Header for using the list library
*/
#ifndef _LST_H_
#define _LST_H_
#include <sys/param.h> #ifndef MAKE_LST_H
#include <stdlib.h> #define MAKE_LST_H
#include "sprite.h" #include <sys/param.h>
#include <stdint.h>
#include <stdlib.h>
/* A doubly-linked list of pointers. */
typedef struct List List;
/* A single node in the doubly-linked list. */
typedef struct ListNode ListNode;
struct ListNode {
ListNode *prev; /* previous node in list, or NULL */
ListNode *next; /* next node in list, or NULL */
void *datum; /* datum associated with this element */
};
struct List {
ListNode *first;
ListNode *last;
};
/* Free the datum of a node, called before freeing the node itself. */
typedef void LstFreeProc(void *);
/* Create or destroy a list */
/* Create a new list. */
List *Lst_New(void);
/* Free the list nodes, but not the list itself. */
void Lst_Done(List *);
/* Free the list nodes, freeing the node data using the given function. */
void Lst_DoneCall(List *, LstFreeProc);
/* Free the list, leaving the node data unmodified. */
void Lst_Free(List *);
#define LST_INIT { NULL, NULL }
/* Initialize a list, without memory allocation. */
MAKE_INLINE void
Lst_Init(List *list)
{
list->first = NULL;
list->last = NULL;
}
/* Get information about a list */
MAKE_INLINE Boolean
Lst_IsEmpty(List *list)
{
return list->first == NULL;
}
/* Find the first node that contains the given datum, or NULL. */
ListNode *Lst_FindDatum(List *, const void *);
/* Modify a list */
/* Insert a datum before the given node. */
void Lst_InsertBefore(List *, ListNode *, void *);
/* Place a datum at the front of the list. */
void Lst_Prepend(List *, void *);
/* Place a datum at the end of the list. */
void Lst_Append(List *, void *);
/* Remove the node from the list. */
void Lst_Remove(List *, ListNode *);
void Lst_PrependAll(List *, List *);
void Lst_AppendAll(List *, List *);
void Lst_MoveAll(List *, List *);
/* Node-specific functions */
/* Replace the value of the node. */
void LstNode_Set(ListNode *, void *);
/* Set the value of the node to NULL. Having NULL in a list is unusual. */
void LstNode_SetNull(ListNode *);
/* Using the list as a queue */
/* Add a datum at the tail of the queue. */
MAKE_INLINE void
Lst_Enqueue(List *list, void *datum) {
Lst_Append(list, datum);
}
/* Remove the head node of the queue and return its datum. */
void *Lst_Dequeue(List *);
/* /*
* basic typedef. This is what the Lst_ functions handle * A vector is an ordered collection of items, allowing for fast indexed
* access.
*/ */
typedef struct Vector {
void *items; /* memory holding the items */
size_t itemSize; /* size of a single item */
size_t len; /* number of actually usable elements */
size_t cap; /* capacity */
} Vector;
typedef struct List *Lst; void Vector_Init(Vector *, size_t);
typedef struct ListNode *LstNode;
typedef void *DuplicateProc(void *);
typedef void FreeProc(void *);
#define LST_CONCNEW 0 /* create new LstNode's when using Lst_Concat */
#define LST_CONCLINK 1 /* relink LstNode's when using Lst_Concat */
/* /*
* Creation/destruction functions * Return the pointer to the given item in the vector.
* The returned data is valid until the next modifying operation.
*/ */
/* Create a new list */ MAKE_INLINE void *
Lst Lst_Init(Boolean); Vector_Get(Vector *v, size_t i)
/* Duplicate an existing list */ {
Lst Lst_Duplicate(Lst, DuplicateProc *); unsigned char *items = v->items;
/* Destroy an old one */ return items + i * v->itemSize;
void Lst_Destroy(Lst, FreeProc *); }
/* True if list is empty */
Boolean Lst_IsEmpty(Lst);
/* void *Vector_Push(Vector *);
* Functions to modify a list void *Vector_Pop(Vector *);
*/
/* 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);
/* MAKE_INLINE void
* Node-specific functions Vector_Done(Vector *v) {
*/ free(v->items);
/* 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);
/* #endif /* MAKE_LST_H */
* Functions for entire lists
*/
/* Find an element in a list */
LstNode Lst_Find(Lst, const void *, int (*)(const void *, const void *));
/* Find an element starting from somewhere */
LstNode Lst_FindFrom(Lst, LstNode, const void *,
int (*cProc)(const void *, const void *));
/*
* See if the given datum is on the list. Returns the LstNode containing
* the datum
*/
LstNode Lst_Member(Lst, void *);
/* Apply a function to all elements of a lst */
int Lst_ForEach(Lst, int (*)(void *, void *), void *);
/*
* Apply a function to all elements of a lst starting from a certain point.
* If the list is circular, the application will wrap around to the
* beginning of the list again.
*/
int Lst_ForEachFrom(Lst, LstNode, int (*)(void *, void *),
void *);
/*
* these functions are for dealing with a list as a table, of sorts.
* An idea of the "current element" is kept and used by all the functions
* between Lst_Open() and Lst_Close().
*/
/* Open the list */
ReturnStatus Lst_Open(Lst);
/* Next element please */
LstNode Lst_Next(Lst);
/* Done yet? */
Boolean Lst_IsAtEnd(Lst);
/* Finish table access */
void Lst_Close(Lst);
/*
* for using the list as a queue
*/
/* Place an element at tail of queue */
ReturnStatus Lst_EnQueue(Lst, void *);
/* Remove an element from head of queue */
void *Lst_DeQueue(Lst);
#endif /* _LST_H_ */

View File

@ -1,10 +0,0 @@
# $NetBSD: Makefile,v 1.6 2006/11/11 21:23:36 dsl Exp $
OBJ=lstAppend.o lstDupl.o lstInit.o lstOpen.o lstAtEnd.o lstEnQueue.o \
lstInsert.o lstAtFront.o lstIsAtEnd.o lstClose.o lstFind.o lstIsEmpty.o \
lstRemove.o lstConcat.o lstFindFrom.o lstLast.o lstReplace.o lstFirst.o \
lstDatum.o lstForEach.o lstMember.o lstSucc.o lstDeQueue.o \
lstForEachFrom.o lstDestroy.o lstNext.o lstPrev.o
CPPFLAGS=-I${.CURDIR}/..
all: ${OBJ}

View File

@ -1,122 +0,0 @@
/* $NetBSD: lstAppend.c,v 1.14 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstAppend.c,v 1.14 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstAppend.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstAppend.c,v 1.14 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstAppend.c --
* Add a new node with a new datum after an existing node
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_InsertAfter --
* Create a new node and add it to the given list after the given node.
*
* Input:
* l affected list
* ln node after which to append the datum
* d said datum
*
* Results:
* SUCCESS if all went well.
*
* Side Effects:
* A new ListNode is created and linked in to the List. The lastPtr
* field of the List will be altered if ln is the last node in the
* list. lastPtr and firstPtr will alter if the list was empty and
* ln was NULL.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_InsertAfter(Lst l, LstNode ln, void *d)
{
List list;
ListNode lNode;
ListNode nLNode;
if (LstValid (l) && (ln == NULL && LstIsEmpty (l))) {
goto ok;
}
if (!LstValid (l) || LstIsEmpty (l) || ! LstNodeValid (ln, l)) {
return (FAILURE);
}
ok:
list = l;
lNode = ln;
PAlloc (nLNode, ListNode);
nLNode->datum = d;
nLNode->useCount = nLNode->flags = 0;
if (lNode == NULL) {
if (list->isCirc) {
nLNode->nextPtr = nLNode->prevPtr = nLNode;
} else {
nLNode->nextPtr = nLNode->prevPtr = NULL;
}
list->firstPtr = list->lastPtr = nLNode;
} else {
nLNode->prevPtr = lNode;
nLNode->nextPtr = lNode->nextPtr;
lNode->nextPtr = nLNode;
if (nLNode->nextPtr != NULL) {
nLNode->nextPtr->prevPtr = nLNode;
}
if (lNode == list->lastPtr) {
list->lastPtr = nLNode;
}
}
return (SUCCESS);
}

View File

@ -1,79 +0,0 @@
/* $NetBSD: lstAtEnd.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstAtEnd.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstAtEnd.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstAtEnd.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstAtEnd.c --
* Add a node at the end of the list
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_AtEnd --
* Add a node to the end of the given list
*
* Input:
* l List to which to add the datum
* d Datum to add
*
* Results:
* SUCCESS if life is good.
*
* Side Effects:
* A new ListNode is created and added to the list.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_AtEnd(Lst l, void *d)
{
LstNode end;
end = Lst_Last(l);
return (Lst_InsertAfter(l, end, d));
}

View File

@ -1,76 +0,0 @@
/* $NetBSD: lstAtFront.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstAtFront.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstAtFront.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstAtFront.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstAtFront.c --
* Add a node at the front of the list
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_AtFront --
* Place a piece of data at the front of a list
*
* Results:
* SUCCESS or FAILURE
*
* Side Effects:
* A new ListNode is created and stuck at the front of the list.
* hence, firstPtr (and possible lastPtr) in the list are altered.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_AtFront(Lst l, void *d)
{
LstNode front;
front = Lst_First(l);
return (Lst_InsertBefore(l, front, d));
}

View File

@ -1,86 +0,0 @@
/* $NetBSD: lstClose.c,v 1.11 2006/10/27 21:37:25 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstClose.c,v 1.11 2006/10/27 21:37:25 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstClose.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstClose.c,v 1.11 2006/10/27 21:37:25 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstClose.c --
* Close a list for sequential access.
* The sequential functions access the list in a slightly different way.
* CurPtr points to their idea of the current node in the list and they
* access the list based on it. Because the list is circular, Lst_Next
* and Lst_Prev will go around the list forever. Lst_IsAtEnd must be
* used to determine when to stop.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Close --
* Close a list which was opened for sequential access.
*
* Input:
* l The list to close
*
* Results:
* None.
*
* Side Effects:
* The list is closed.
*
*-----------------------------------------------------------------------
*/
void
Lst_Close(Lst l)
{
List list = l;
if (LstValid(l) == TRUE) {
list->isOpen = FALSE;
list->atEnd = Unknown;
}
}

View File

@ -1,185 +0,0 @@
/* $NetBSD: lstConcat.c,v 1.16 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstConcat.c,v 1.16 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstConcat.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstConcat.c,v 1.16 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* listConcat.c --
* Function to concatentate two lists.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Concat --
* Concatenate two lists. New elements are created to hold the data
* elements, if specified, but the elements themselves are not copied.
* If the elements should be duplicated to avoid confusion with another
* list, the Lst_Duplicate function should be called first.
* If LST_CONCLINK is specified, the second list is destroyed since
* its pointers have been corrupted and the list is no longer useable.
*
* Input:
* l1 The list to which l2 is to be appended
* l2 The list to append to l1
* flags LST_CONCNEW if LstNode's should be duplicated
* LST_CONCLINK if should just be relinked
*
* Results:
* SUCCESS if all went well. FAILURE otherwise.
*
* Side Effects:
* New elements are created and appended the first list.
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_Concat(Lst l1, Lst l2, int flags)
{
ListNode ln; /* original LstNode */
ListNode nln; /* new LstNode */
ListNode last; /* the last element in the list. Keeps
* bookkeeping until the end */
List list1 = l1;
List list2 = l2;
if (!LstValid (l1) || !LstValid (l2)) {
return (FAILURE);
}
if (flags == LST_CONCLINK) {
if (list2->firstPtr != NULL) {
/*
* We set the nextPtr of the
* last element of list two to be NIL to make the loop easier and
* so we don't need an extra case should the first list turn
* out to be non-circular -- the final element will already point
* to NIL space and the first element will be untouched if it
* existed before and will also point to NIL space if it didn't.
*/
list2->lastPtr->nextPtr = NULL;
/*
* So long as the second list isn't empty, we just link the
* first element of the second list to the last element of the
* first list. If the first list isn't empty, we then link the
* last element of the list to the first element of the second list
* The last element of the second list, if it exists, then becomes
* the last element of the first list.
*/
list2->firstPtr->prevPtr = list1->lastPtr;
if (list1->lastPtr != NULL) {
list1->lastPtr->nextPtr = list2->firstPtr;
} else {
list1->firstPtr = list2->firstPtr;
}
list1->lastPtr = list2->lastPtr;
}
if (list1->isCirc && list1->firstPtr != NULL) {
/*
* If the first list is supposed to be circular and it is (now)
* non-empty, we must make sure it's circular by linking the
* first element to the last and vice versa
*/
list1->firstPtr->prevPtr = list1->lastPtr;
list1->lastPtr->nextPtr = list1->firstPtr;
}
free(l2);
} else if (list2->firstPtr != NULL) {
/*
* We set the nextPtr of the last element of list 2 to be nil to make
* the loop less difficult. The loop simply goes through the entire
* second list creating new LstNodes and filling in the nextPtr, and
* prevPtr to fit into l1 and its datum field from the
* datum field of the corresponding element in l2. The 'last' node
* follows the last of the new nodes along until the entire l2 has
* been appended. Only then does the bookkeeping catch up with the
* changes. During the first iteration of the loop, if 'last' is nil,
* the first list must have been empty so the newly-created node is
* made the first node of the list.
*/
list2->lastPtr->nextPtr = NULL;
for (last = list1->lastPtr, ln = list2->firstPtr;
ln != NULL;
ln = ln->nextPtr)
{
PAlloc (nln, ListNode);
nln->datum = ln->datum;
if (last != NULL) {
last->nextPtr = nln;
} else {
list1->firstPtr = nln;
}
nln->prevPtr = last;
nln->flags = nln->useCount = 0;
last = nln;
}
/*
* Finish bookkeeping. The last new element becomes the last element
* of list one.
*/
list1->lastPtr = last;
/*
* The circularity of both list one and list two must be corrected
* for -- list one because of the new nodes added to it; list two
* because of the alteration of list2->lastPtr's nextPtr to ease the
* above for loop.
*/
if (list1->isCirc) {
list1->lastPtr->nextPtr = list1->firstPtr;
list1->firstPtr->prevPtr = list1->lastPtr;
} else {
last->nextPtr = NULL;
}
if (list2->isCirc) {
list2->lastPtr->nextPtr = list2->firstPtr;
}
}
return (SUCCESS);
}

View File

@ -1,77 +0,0 @@
/* $NetBSD: lstDatum.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstDatum.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstDatum.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstDatum.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstDatum.c --
* Return the datum associated with a list node.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Datum --
* Return the datum stored in the given node.
*
* Results:
* The datum or NULL if the node is invalid.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
void *
Lst_Datum(LstNode ln)
{
if (ln != NULL) {
return ((ln)->datum);
} else {
return NULL;
}
}

View File

@ -1,87 +0,0 @@
/* $NetBSD: lstDeQueue.c,v 1.14 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstDeQueue.c,v 1.14 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstDeQueue.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstDeQueue.c,v 1.14 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstDeQueue.c --
* Remove the node and return its datum from the head of the list
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_DeQueue --
* Remove and return the datum at the head of the given list.
*
* Results:
* The datum in the node at the head or NULL if the list
* is empty.
*
* Side Effects:
* The head node is removed from the list.
*
*-----------------------------------------------------------------------
*/
void *
Lst_DeQueue(Lst l)
{
void *rd;
ListNode tln;
tln = Lst_First(l);
if (tln == NULL) {
return NULL;
}
rd = tln->datum;
if (Lst_Remove(l, tln) == FAILURE) {
return NULL;
} else {
return (rd);
}
}

View File

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

View File

@ -1,107 +0,0 @@
/* $NetBSD: lstDupl.c,v 1.16 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstDupl.c,v 1.16 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstDupl.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstDupl.c,v 1.16 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* listDupl.c --
* Duplicate a list. This includes duplicating the individual
* elements.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Duplicate --
* Duplicate an entire list. If a function to copy a void *is
* given, the individual client elements will be duplicated as well.
*
* Input:
* l the list to duplicate
* copyProc A function to duplicate each void *
*
* Results:
* The new Lst structure or NULL if failure.
*
* Side Effects:
* A new list is created.
*-----------------------------------------------------------------------
*/
Lst
Lst_Duplicate(Lst l, DuplicateProc *copyProc)
{
Lst nl;
ListNode ln;
List list = l;
if (!LstValid (l)) {
return NULL;
}
nl = Lst_Init(list->isCirc);
if (nl == NULL) {
return NULL;
}
ln = list->firstPtr;
while (ln != NULL) {
if (copyProc != NULL) {
if (Lst_AtEnd(nl, copyProc(ln->datum)) == FAILURE) {
return NULL;
}
} else if (Lst_AtEnd(nl, ln->datum) == FAILURE) {
return NULL;
}
if (list->isCirc && ln == list->lastPtr) {
ln = NULL;
} else {
ln = ln->nextPtr;
}
}
return (nl);
}

View File

@ -1,78 +0,0 @@
/* $NetBSD: lstEnQueue.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstEnQueue.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstEnQueue.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstEnQueue.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstEnQueue.c--
* Treat the list as a queue and place a datum at its end
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_EnQueue --
* Add the datum to the tail of the given list.
*
* Results:
* SUCCESS or FAILURE as returned by Lst_InsertAfter.
*
* Side Effects:
* the lastPtr field is altered all the time and the firstPtr field
* will be altered if the list used to be empty.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_EnQueue(Lst l, void *d)
{
if (LstValid (l) == FALSE) {
return (FAILURE);
}
return (Lst_InsertAfter(l, Lst_Last(l), d));
}

View File

@ -1,74 +0,0 @@
/* $NetBSD: lstFind.c,v 1.15 2009/01/23 21:58:28 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstFind.c,v 1.15 2009/01/23 21:58:28 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstFind.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstFind.c,v 1.15 2009/01/23 21:58:28 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstFind.c --
* Find a node on a list.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Find --
* Find a node on the given list using the given comparison function
* and the given datum.
*
* Results:
* The found node or NULL if none matches.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_Find(Lst l, const void *d, int (*cProc)(const void *, const void *))
{
return (Lst_FindFrom(l, Lst_First(l), d, cProc));
}

View File

@ -1,90 +0,0 @@
/* $NetBSD: lstFindFrom.c,v 1.15 2009/01/23 21:58:28 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstFindFrom.c,v 1.15 2009/01/23 21:58:28 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstFindFrom.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstFindFrom.c,v 1.15 2009/01/23 21:58:28 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstFindFrom.c --
* Find a node on a list from a given starting point. Used by Lst_Find.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_FindFrom --
* Search for a node starting and ending with the given one on the
* given list using the passed datum and comparison function to
* determine when it has been found.
*
* Results:
* The found node or NULL
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_FindFrom(Lst l, LstNode ln, const void *d,
int (*cProc)(const void *, const void *))
{
ListNode tln;
if (!LstValid (l) || LstIsEmpty (l) || !LstNodeValid (ln, l)) {
return NULL;
}
tln = ln;
do {
if ((*cProc)(tln->datum, d) == 0)
return (tln);
tln = tln->nextPtr;
} while (tln != ln && tln != NULL);
return NULL;
}

View File

@ -1,77 +0,0 @@
/* $NetBSD: lstFirst.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstFirst.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstFirst.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstFirst.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstFirst.c --
* Return the first node of a list
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_First --
* Return the first node on the given list.
*
* Results:
* The first node or NULL if the list is empty.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_First(Lst l)
{
if (!LstValid (l) || LstIsEmpty (l)) {
return NULL;
} else {
return (l->firstPtr);
}
}

View File

@ -1,76 +0,0 @@
/* $NetBSD: lstForEach.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstForEach.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstForEach.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstForEach.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstForeach.c --
* Perform a given function on all elements of a list.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_ForEach --
* Apply the given function to each element of the given list. The
* function should return 0 if Lst_ForEach should continue and non-
* zero if it should abort.
*
* Results:
* None.
*
* Side Effects:
* Only those created by the passed-in function.
*
*-----------------------------------------------------------------------
*/
/*VARARGS2*/
int
Lst_ForEach(Lst l, int (*proc)(void *, void *), void *d)
{
return Lst_ForEachFrom(l, Lst_First(l), proc, d);
}

View File

@ -1,125 +0,0 @@
/* $NetBSD: lstForEachFrom.c,v 1.17 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstForEachFrom.c,v 1.17 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstForEachFrom.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstForEachFrom.c,v 1.17 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* lstForEachFrom.c --
* Perform a given function on all elements of a list starting from
* a given point.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_ForEachFrom --
* Apply the given function to each element of the given list. The
* function should return 0 if traversal should continue and non-
* zero if it should abort.
*
* Results:
* None.
*
* Side Effects:
* Only those created by the passed-in function.
*
*-----------------------------------------------------------------------
*/
/*VARARGS2*/
int
Lst_ForEachFrom(Lst l, LstNode ln, int (*proc)(void *, void *),
void *d)
{
ListNode tln = ln;
List list = l;
ListNode next;
Boolean done;
int result;
if (!LstValid (list) || LstIsEmpty (list)) {
return 0;
}
do {
/*
* Take care of having the current element deleted out from under
* us.
*/
next = tln->nextPtr;
/*
* We're done with the traversal if
* - the next node to examine is the first in the queue or
* doesn't exist and
* - nothing's been added after the current node (check this
* after proc() has been called).
*/
done = (next == NULL || next == list->firstPtr);
(void) tln->useCount++;
result = (*proc) (tln->datum, d);
(void) tln->useCount--;
/*
* Now check whether a node has been added.
* Note: this doesn't work if this node was deleted before
* the new node was added.
*/
if (next != tln->nextPtr) {
next = tln->nextPtr;
done = 0;
}
if (tln->flags & LN_DELETED) {
free((char *)tln);
}
tln = next;
} while (!result && !LstIsEmpty(list) && !done);
return result;
}

View File

@ -1,85 +0,0 @@
/* $NetBSD: lstInit.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstInit.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstInit.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstInit.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* init.c --
* Initialize a new linked list.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Init --
* Create and initialize a new list.
*
* Input:
* circ TRUE if the list should be made circular
*
* Results:
* The created list.
*
* Side Effects:
* A list is created, what else?
*
*-----------------------------------------------------------------------
*/
Lst
Lst_Init(Boolean circ)
{
List nList;
PAlloc (nList, List);
nList->firstPtr = NULL;
nList->lastPtr = NULL;
nList->isOpen = FALSE;
nList->isCirc = circ;
nList->atEnd = Unknown;
return (nList);
}

View File

@ -1,122 +0,0 @@
/* $NetBSD: lstInsert.c,v 1.14 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstInsert.c,v 1.14 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstInsert.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstInsert.c,v 1.14 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstInsert.c --
* Insert a new datum before an old one
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_InsertBefore --
* Insert a new node with the given piece of data before the given
* node in the given list.
*
* Input:
* l list to manipulate
* ln node before which to insert d
* d datum to be inserted
*
* Results:
* SUCCESS or FAILURE.
*
* Side Effects:
* the firstPtr field will be changed if ln is the first node in the
* list.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_InsertBefore(Lst l, LstNode ln, void *d)
{
ListNode nLNode; /* new lnode for d */
ListNode lNode = ln;
List list = l;
/*
* check validity of arguments
*/
if (LstValid (l) && (LstIsEmpty (l) && ln == NULL))
goto ok;
if (!LstValid (l) || LstIsEmpty (l) || !LstNodeValid (ln, l)) {
return (FAILURE);
}
ok:
PAlloc (nLNode, ListNode);
nLNode->datum = d;
nLNode->useCount = nLNode->flags = 0;
if (ln == NULL) {
if (list->isCirc) {
nLNode->prevPtr = nLNode->nextPtr = nLNode;
} else {
nLNode->prevPtr = nLNode->nextPtr = NULL;
}
list->firstPtr = list->lastPtr = nLNode;
} else {
nLNode->prevPtr = lNode->prevPtr;
nLNode->nextPtr = lNode;
if (nLNode->prevPtr != NULL) {
nLNode->prevPtr->nextPtr = nLNode;
}
lNode->prevPtr = nLNode;
if (lNode == list->firstPtr) {
list->firstPtr = nLNode;
}
}
return (SUCCESS);
}

View File

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

View File

@ -1,87 +0,0 @@
/* $NetBSD: lstIsAtEnd.c,v 1.13 2008/02/15 21:29:50 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstIsAtEnd.c,v 1.13 2008/02/15 21:29:50 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstIsAtEnd.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstIsAtEnd.c,v 1.13 2008/02/15 21:29:50 christos Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstIsAtEnd.c --
* Tell if the current node is at the end of the list.
* The sequential functions access the list in a slightly different way.
* CurPtr points to their idea of the current node in the list and they
* access the list based on it. Because the list is circular, Lst_Next
* and Lst_Prev will go around the list forever. Lst_IsAtEnd must be
* used to determine when to stop.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_IsAtEnd --
* Return true if have reached the end of the given list.
*
* Results:
* TRUE if at the end of the list (this includes the list not being
* open or being invalid) or FALSE if not. We return TRUE if the list
* is invalid or unopend so as to cause the caller to exit its loop
* asap, the assumption being that the loop is of the form
* while (!Lst_IsAtEnd (l)) {
* ...
* }
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
Boolean
Lst_IsAtEnd(Lst l)
{
List list = l;
return (!LstValid (l) || !list->isOpen ||
(list->atEnd == Head) || (list->atEnd == Tail));
}

View File

@ -1,75 +0,0 @@
/* $NetBSD: lstIsEmpty.c,v 1.11 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstIsEmpty.c,v 1.11 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstIsEmpty.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstIsEmpty.c,v 1.11 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstIsEmpty.c --
* A single function to decide if a list is empty
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_IsEmpty --
* Return TRUE if the given list is empty.
*
* Results:
* TRUE if the list is empty, FALSE otherwise.
*
* Side Effects:
* None.
*
* A list is considered empty if its firstPtr == NULL (or if
* the list itself is NULL).
*-----------------------------------------------------------------------
*/
Boolean
Lst_IsEmpty(Lst l)
{
return ( ! LstValid (l) || LstIsEmpty(l));
}

View File

@ -1,77 +0,0 @@
/* $NetBSD: lstLast.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstLast.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstLast.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstLast.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstLast.c --
* Return the last element of a list
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Last --
* Return the last node on the list l.
*
* Results:
* The requested node or NULL if the list is empty.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_Last(Lst l)
{
if (!LstValid(l) || LstIsEmpty (l)) {
return NULL;
} else {
return (l->lastPtr);
}
}

View File

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

View File

@ -1,120 +0,0 @@
/* $NetBSD: lstNext.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstNext.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstNext.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstNext.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstNext.c --
* Return the next node for a list.
* The sequential functions access the list in a slightly different way.
* CurPtr points to their idea of the current node in the list and they
* access the list based on it. Because the list is circular, Lst_Next
* and Lst_Prev will go around the list forever. Lst_IsAtEnd must be
* used to determine when to stop.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Next --
* Return the next node for the given list.
*
* Results:
* The next node or NULL if the list has yet to be opened. Also
* if the list is non-circular and the end has been reached, NULL
* is returned.
*
* Side Effects:
* the curPtr field is updated.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_Next(Lst l)
{
ListNode tln;
List list = l;
if ((LstValid (l) == FALSE) ||
(list->isOpen == FALSE)) {
return NULL;
}
list->prevPtr = list->curPtr;
if (list->curPtr == NULL) {
if (list->atEnd == Unknown) {
/*
* If we're just starting out, atEnd will be Unknown.
* Then we want to start this thing off in the right
* direction -- at the start with atEnd being Middle.
*/
list->curPtr = tln = list->firstPtr;
list->atEnd = Middle;
} else {
tln = NULL;
list->atEnd = Tail;
}
} else {
tln = list->curPtr->nextPtr;
list->curPtr = tln;
if (tln == list->firstPtr || tln == NULL) {
/*
* If back at the front, then we've hit the end...
*/
list->atEnd = Tail;
} else {
/*
* Reset to Middle if gone past first.
*/
list->atEnd = Middle;
}
}
return (tln);
}

View File

@ -1,87 +0,0 @@
/* $NetBSD: lstOpen.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstOpen.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstOpen.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstOpen.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstOpen.c --
* Open a list for sequential access. The sequential functions access the
* list in a slightly different way. CurPtr points to their idea of the
* current node in the list and they access the list based on it.
* If the list is circular, Lst_Next and Lst_Prev will go around
* the list forever. Lst_IsAtEnd must be used to determine when to stop.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Open --
* Open a list for sequential access. A list can still be searched,
* etc., without confusing these functions.
*
* Results:
* SUCCESS or FAILURE.
*
* Side Effects:
* isOpen is set TRUE and curPtr is set to NULL so the
* other sequential functions no it was just opened and can choose
* the first element accessed based on this.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_Open(Lst l)
{
if (LstValid (l) == FALSE) {
return (FAILURE);
}
(l)->isOpen = TRUE;
(l)->atEnd = LstIsEmpty (l) ? Head : Unknown;
(l)->curPtr = NULL;
return (SUCCESS);
}

View File

@ -1,79 +0,0 @@
/* $NetBSD: lstPrev.c,v 1.3 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstPrev.c,v 1.3 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstPrev.c,v 1.3 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstPrev.c --
* return the predecessor to a given node
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Prev --
* Return the predecessor to the given node on its list.
*
* Results:
* The predecessor of the node, if it exists (note that on a circular
* list, if the node is the only one in the list, it is its own
* predecessor).
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_Prev(LstNode ln)
{
if (ln == NULL) {
return NULL;
} else {
return (ln->prevPtr);
}
}

View File

@ -1,136 +0,0 @@
/* $NetBSD: lstRemove.c,v 1.16 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.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstRemove.c,v 1.16 2014/09/07 20:55:34 joerg 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.16 2014/09/07 20:55:34 joerg 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);
}

View File

@ -1,78 +0,0 @@
/* $NetBSD: lstReplace.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstReplace.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstReplace.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstReplace.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstReplace.c --
* Replace the datum in a node with a new datum
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Replace --
* Replace the datum in the given node with the new datum
*
* Results:
* SUCCESS or FAILURE.
*
* Side Effects:
* The datum field fo the node is altered.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_Replace(LstNode ln, void *d)
{
if (ln == NULL) {
return (FAILURE);
} else {
(ln)->datum = d;
return (SUCCESS);
}
}

View File

@ -1,79 +0,0 @@
/* $NetBSD: lstSucc.c,v 1.13 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstSucc.c,v 1.13 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstSucc.c,v 1.13 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstSucc.c --
* return the successor to a given node
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Succ --
* Return the successor to the given node on its list.
*
* Results:
* The successor of the node, if it exists (note that on a circular
* list, if the node is the only one in the list, it is its own
* successor).
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_Succ(LstNode ln)
{
if (ln == NULL) {
return NULL;
} else {
return (ln->nextPtr);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
.\" $NetBSD: make.1,v 1.249 2015/06/05 07:33:40 wiz Exp $ .\" $NetBSD: make.1,v 1.296 2021/02/04 21:42:46 rillig Exp $
.\" .\"
.\" Copyright (c) 1990, 1993 .\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved. .\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\" .\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\" .\"
.Dd June 4, 2015 .Dd December 22, 2020
.Dt MAKE 1 .Dt MAKE 1
.Os .Os
.Sh NAME .Sh NAME
@ -37,7 +37,7 @@
.Nd maintain program dependencies .Nd maintain program dependencies
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl BeikNnqrstWwX .Op Fl BeikNnqrSstWwX
.Op Fl C Ar directory .Op Fl C Ar directory
.Op Fl D Ar variable .Op Fl D Ar variable
.Op Fl d Ar flags .Op Fl d Ar flags
@ -48,6 +48,7 @@
.Op Fl m Ar directory .Op Fl m Ar directory
.Op Fl T Ar file .Op Fl T Ar file
.Op Fl V Ar variable .Op Fl V Ar variable
.Op Fl v Ar variable
.Op Ar variable=value .Op Ar variable=value
.Op Ar target ... .Op Ar target ...
.Sh DESCRIPTION .Sh DESCRIPTION
@ -98,7 +99,7 @@ is equivalent to
.It Fl D Ar variable .It Fl D Ar variable
Define Define
.Ar variable .Ar variable
to be 1, in the global context. to be 1, in the global scope.
.It Fl d Ar [-]flags .It Fl d Ar [-]flags
Turn on debugging, and specify which portions of Turn on debugging, and specify which portions of
.Nm .Nm
@ -165,8 +166,15 @@ Print the input graph after making everything, or before exiting
on error. on error.
.It Ar "g3" .It Ar "g3"
Print the input graph before exiting on error. Print the input graph before exiting on error.
.It Ar h
Print debugging information about hash table operations.
.It Ar j .It Ar j
Print debugging information about running multiple shells. 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 .It Ar l
Print commands in Makefiles regardless of whether or not they are prefixed by Print commands in Makefiles regardless of whether or not they are prefixed by
.Ql @ .Ql @
@ -206,7 +214,9 @@ Print debugging information about target list maintenance.
.It Ar V .It Ar V
Force the Force the
.Fl V .Fl V
option to print raw values of variables. option to print raw values of variables, overriding the default behavior
set via
.Va .MAKE.EXPAND_VARIABLES .
.It Ar v .It Ar v
Print debugging information about variable assignment. Print debugging information about variable assignment.
.It Ar x .It Ar x
@ -269,7 +279,7 @@ that do not depend on the target whose creation caused the error.
.It Fl m Ar directory .It Fl m Ar directory
Specify a directory in which to search for sys.mk and makefiles included Specify a directory in which to search for sys.mk and makefiles included
via the via the
.Ao Ar file Ac Ns -style .Li \&< Ns Ar file Ns Li \&> Ns -style
include statement. include statement.
The The
.Fl m .Fl m
@ -277,7 +287,7 @@ option can be used multiple times to form a search path.
This path will override the default system include path: /usr/share/mk. This path will override the default system include path: /usr/share/mk.
Furthermore the system include path will be appended to the search path used Furthermore the system include path will be appended to the search path used
for for
.Qo Ar file Qc Ns -style .Li \*q Ns Ar file Ns Li \*q Ns -style
include statements (see the include statements (see the
.Fl I .Fl I
option). option).
@ -293,7 +303,7 @@ then
will search for the specified file or directory named in the remaining part will search for the specified file or directory named in the remaining part
of the argument string. of the argument string.
The search starts with the current directory of The search starts with the current directory of
the Makefile and then works upward towards the root of the filesystem. the Makefile and then works upward towards the root of the file system.
If the search is successful, then the resulting directory replaces the If the search is successful, then the resulting directory replaces the
.Qq \&.../ .Qq \&.../
specification in the specification in the
@ -308,7 +318,8 @@ as an argument).
.It Fl n .It Fl n
Display the commands that would have been executed, but do not Display the commands that would have been executed, but do not
actually execute them unless the target depends on the .MAKE special 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 .It Fl N
Display the commands which would have been executed, but do not Display the commands which would have been executed, but do not
actually execute any of them; useful for debugging top-level makefiles actually execute any of them; useful for debugging top-level makefiles
@ -318,6 +329,10 @@ Do not execute any commands, but exit 0 if the specified targets are
up-to-date and 1, otherwise. up-to-date and 1, otherwise.
.It Fl r .It Fl r
Do not use the built-in rules specified in the system makefile. Do not use the built-in rules specified in the system makefile.
.It Fl S
Stop processing if an error is encountered.
This is the default behavior and the opposite of
.Fl k .
.It Fl s .It Fl s
Do not echo any commands as they are executed. Do not echo any commands as they are executed.
Equivalent to specifying Equivalent to specifying
@ -334,20 +349,39 @@ for each job started and completed.
Rather than re-building a target as specified in the makefile, create it Rather than re-building a target as specified in the makefile, create it
or update its modification time to make it appear up-to-date. or update its modification time to make it appear up-to-date.
.It Fl V Ar variable .It Fl V Ar variable
Print Print the value of
.Nm Ns 's .Ar variable .
idea of the value of
.Ar variable ,
in the global context.
Do not build any targets. Do not build any targets.
Multiple instances of this option may be specified; Multiple instances of this option may be specified;
the variables will be printed one per line, the variables will be printed one per line,
with a blank line for each null or undefined variable. with a blank line for each null or undefined variable.
The value printed is extracted from the global scope after all
makefiles have been read.
By default, the raw variable contents (which may
include additional unexpanded variable references) are shown.
If If
.Ar variable .Ar variable
contains a contains a
.Ql \&$ .Ql \&$
then the value will be expanded before printing. then the value will be recursively expanded to its complete resultant
text before printing.
The expanded value will also be printed if
.Va .MAKE.EXPAND_VARIABLES
is set to true and
the
.Fl dV
option has not been used to override it.
Note that loop-local and target-local variables, as well as values
taken temporarily by global variables during makefile processing, are
not accessible via this option.
The
.Fl dv
debug mode can be used to see these at the cost of generating
substantial extraneous output.
.It Fl v Ar variable
Like
.Fl V
but the variable is always expanded to its complete value.
.It Fl W .It Fl W
Treat any warnings during makefile parsing as errors. Treat any warnings during makefile parsing as errors.
.It Fl w .It Fl w
@ -390,37 +424,44 @@ or more sources.
This creates a relationship where the targets This creates a relationship where the targets
.Dq depend .Dq depend
on the sources on the sources
and are usually created from them. and are customarily created from them.
The exact relationship between the target and the source is determined A target is considered out-of-date if it does not exist, or if its
by the operator that separates them. modification time is less than that of any of its sources.
The three operators are as follows: 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 .Bl -tag -width flag
.It Ic \&: .It Ic \&:
A target is considered out-of-date if its modification time is less than Many dependency lines may name this target but only one may have
those of any of its sources. attached shell commands.
Sources for a target accumulate over dependency lines when this operator All sources named in all dependency lines are considered together,
is used. and if needed the attached shell commands are run to create or
The target is removed if re-create the target.
If
.Nm .Nm
is interrupted. is interrupted, the target is removed.
.It Ic \&! .It Ic \&!
Targets are always re-created, but not until all sources have been The same, but the target is always re-created whether or not it is out
examined and re-created as necessary. of date.
Sources for a target accumulate over dependency lines when this operator
is used.
The target is removed if
.Nm
is interrupted.
.It Ic \&:: .It Ic \&::
If no sources are specified, the target is always re-created. Any dependency line may have attached shell commands, but each one
Otherwise, a target is considered out-of-date if any of its sources has is handled independently: its sources are considered and the attached
been modified more recently than the target. shell commands are run if the target is out of date with respect to
Sources for a target do not accumulate over dependency lines when this (only) those sources.
operator is used. Thus, different groups of the attached shell commands may be run
The target will not be removed if 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 .Nm
is interrupted. is interrupted.
.El .El
All dependency lines mentioning a particular target must use the same
operator.
.Pp .Pp
Targets and sources may contain the shell wildcard values Targets and sources may contain the shell wildcard values
.Ql \&? , .Ql \&? ,
@ -586,7 +627,7 @@ This shorter form is not recommended.
.Pp .Pp
If the variable name contains a dollar, then the name itself is expanded first. If the variable name contains a dollar, then the name itself is expanded first.
This allows almost arbitrary variable names, however names containing dollar, 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 .Pp
If the result of expanding a variable contains a dollar sign If the result of expanding a variable contains a dollar sign
.Pq Ql \&$ .Pq Ql \&$
@ -657,7 +698,7 @@ The seven local variables are as follows:
.Bl -tag -width ".ARCHIVE" -offset indent .Bl -tag -width ".ARCHIVE" -offset indent
.It Va .ALLSRC .It Va .ALLSRC
The list of all sources for this target; also known as The list of all sources for this target; also known as
.Ql Va \&\*[Gt] . .Ql Va \&> .
.It Va .ARCHIVE .It Va .ARCHIVE
The name of the archive file; also known as The name of the archive file; also known as
.Ql Va \&! . .Ql Va \&! .
@ -666,7 +707,7 @@ In suffix-transformation rules, the name/path of the source from which the
target is to be transformed (the target is to be transformed (the
.Dq implied .Dq implied
source); also known as source); also known as
.Ql Va \&\*[Lt] . .Ql Va \&< .
It is not defined in explicit rules. It is not defined in explicit rules.
.It Va .MEMBER .It Va .MEMBER
The name of the archive member; also known as The name of the archive member; also known as
@ -685,12 +726,15 @@ or it will not be recognized.
.It Va .TARGET .It Va .TARGET
The name of the target; also known as The name of the target; also known as
.Ql Va @ . .Ql Va @ .
For compatibility with other makes this is an alias for
.Ic .ARCHIVE
in archive member rules.
.El .El
.Pp .Pp
The shorter forms The shorter forms
.Ql ( Va \*[Gt] , .Ql ( Va > ,
.Ql Va \&! , .Ql Va \&! ,
.Ql Va \*[Lt] , .Ql Va < ,
.Ql Va % , .Ql Va % ,
.Ql Va \&? , .Ql Va \&? ,
.Ql Va * , .Ql Va * ,
@ -773,6 +817,10 @@ from which generated dependencies are read.
A boolean that controls the default behavior of the A boolean that controls the default behavior of the
.Fl V .Fl V
option. option.
If true, variable values printed with
.Fl V
are fully expanded; if false, the raw variable contents (which may
include additional unexpanded variable references) are shown.
.It Va .MAKE.EXPORTED .It Va .MAKE.EXPORTED
The list of variables exported by The list of variables exported by
.Nm . .Nm .
@ -843,7 +891,7 @@ Can affect the mode that
.Nm .Nm
runs in. runs in.
It can contain a number of keywords: It can contain a number of keywords:
.Bl -hang -width ignore-cmd .Bl -hang -width missing-filemon=bf.
.It Pa compat .It Pa compat
Like Like
.Fl B , .Fl B ,
@ -867,8 +915,19 @@ will not create .meta files in
This can be overridden by setting This can be overridden by setting
.Va bf .Va bf
to a value which represents True. to a value which represents True.
.It Pa missing-meta= Ar bf
If
.Va bf
is True, then a missing .meta file makes the target out-of-date.
.It Pa missing-filemon= Ar bf
If
.Va bf
is True, then missing filemon data makes the target out-of-date.
.It Pa nofilemon
Do not use
.Xr filemon 4 .
.It Pa env .It Pa env
For debugging, it can be useful to inlcude the environment For debugging, it can be useful to include the environment
in the .meta file. in the .meta file.
.It Pa verbose .It Pa verbose
If in "meta" mode, print a clue about the target being built. If in "meta" mode, print a clue about the target being built.
@ -910,6 +969,12 @@ Provides a list of path prefixes that should be ignored;
because the contents are expected to change over time. because the contents are expected to change over time.
The default list includes: The default list includes:
.Ql Pa /dev /etc /proc /tmp /var/run /var/tmp .Ql Pa /dev /etc /proc /tmp /var/run /var/tmp
.It Va .MAKE.META.IGNORE_PATTERNS
Provides a list of patterns to match against pathnames.
Ignore any that match.
.It Va .MAKE.META.IGNORE_FILTER
Provides a list of variable modifiers to apply to each pathname.
Ignore if the expansion is an empty string.
.It Va .MAKE.META.PREFIX .It Va .MAKE.META.PREFIX
Defines the message printed for each meta file updated in "meta verbose" mode. Defines the message printed for each meta file updated in "meta verbose" mode.
The default value is: The default value is:
@ -918,7 +983,7 @@ The default value is:
This variable is used to record the names of variables assigned to This variable is used to record the names of variables assigned to
on the command line, so that they may be exported as part of on the command line, so that they may be exported as part of
.Ql Ev MAKEFLAGS . .Ql Ev MAKEFLAGS .
This behaviour can be disabled by assigning an empty value to This behavior can be disabled by assigning an empty value to
.Ql Va .MAKEOVERRIDES .Ql Va .MAKEOVERRIDES
within a makefile. within a makefile.
Extra variables can be exported from a makefile Extra variables can be exported from a makefile
@ -941,10 +1006,40 @@ The process-id of
.It Va .MAKE.PPID .It Va .MAKE.PPID
The parent process-id of The parent process-id of
.Nm . .Nm .
.It Va .MAKE.SAVE_DOLLARS
value should be a boolean that controls whether
.Ql $$
are preserved when doing
.Ql :=
assignments.
The default is true, for compatibility with other makes.
If set to false,
.Ql $$
becomes
.Ql $
per normal evaluation rules.
.It Va .MAKE.UID
The user-id running
.Nm .
.It Va .MAKE.GID
The group-id running
.Nm .
.It Va MAKE_PRINT_VAR_ON_ERROR .It Va MAKE_PRINT_VAR_ON_ERROR
When When
.Nm .Nm
stops due to an error, it prints its name and the value of stops due to an error, it sets
.Ql Va .ERROR_TARGET
to the name of the target that failed,
.Ql Va .ERROR_CMD
to the commands of the failed target,
and in "meta" mode, it also sets
.Ql Va .ERROR_CWD
to the
.Xr getcwd 3 ,
and
.Ql Va .ERROR_META_FILE
to the path of the meta file (if any) describing the failed target.
It then prints its name and the value of
.Ql Va .CURDIR .Ql Va .CURDIR
as well as the value of any variables named in as well as the value of any variables named in
.Ql Va MAKE_PRINT_VAR_ON_ERROR . .Ql Va MAKE_PRINT_VAR_ON_ERROR .
@ -1004,6 +1099,15 @@ to the specified directory if it exists, and set
and and
.Ql Ev PWD .Ql Ev PWD
to that directory before executing any targets. to that directory before executing any targets.
.Pp
Except in the case of an explicit
.Ql Ic .OBJDIR
target,
.Nm
will check that the specified directory is writable and ignore it if not.
This check can be skipped by setting the environment variable
.Ql Ev MAKE_OBJDIR_CHECK_WRITABLE
to "no".
. .
.It Va .PARSEDIR .It Va .PARSEDIR
A path to the directory of the current A path to the directory of the current
@ -1044,7 +1148,7 @@ sets
to the value of to the value of
.Ql Ev PWD .Ql Ev PWD
instead. instead.
This behaviour is disabled if This behavior is disabled if
.Ql Ev MAKEOBJDIRPREFIX .Ql Ev MAKEOBJDIRPREFIX
is set or is set or
.Ql Ev MAKEOBJDIR .Ql Ev MAKEOBJDIR
@ -1055,6 +1159,9 @@ is set to the value of
for all programs which for all programs which
.Nm .Nm
executes. executes.
.It Ev .SHELL
The pathname of the shell used to run target scripts.
It is read-only.
.It Ev .TARGETS .It Ev .TARGETS
The list of targets explicitly specified on the command line, if any. The list of targets explicitly specified on the command line, if any.
.It Ev VPATH .It Ev VPATH
@ -1100,7 +1207,7 @@ Replaces each word in the variable with its suffix.
.It Cm \&:H .It Cm \&:H
Replaces each word in the variable with everything but the last component. Replaces each word in the variable with everything but the last component.
.It Cm \&:M Ns Ar pattern .It Cm \&:M Ns Ar pattern
Select only those words that match Selects only those words that match
.Ar pattern . .Ar pattern .
The standard shell wildcard characters The standard shell wildcard characters
.Pf ( Ql * , .Pf ( Ql * ,
@ -1114,7 +1221,7 @@ The wildcard characters may be escaped with a backslash
As a consequence of the way values are split into words, matched, As a consequence of the way values are split into words, matched,
and then joined, a construct like and then joined, a construct like
.Dl ${VAR:M*} .Dl ${VAR:M*}
will normalise the inter-word spacing, removing all leading and will normalize the inter-word spacing, removing all leading and
trailing space, and converting multiple consecutive spaces trailing space, and converting multiple consecutive spaces
to single spaces. to single spaces.
. .
@ -1124,17 +1231,15 @@ This is identical to
but selects all words which do not match but selects all words which do not match
.Ar pattern . .Ar pattern .
.It Cm \&:O .It Cm \&:O
Order every word in variable alphabetically. Orders every word in variable alphabetically.
To sort words in .It Cm \&:Or
reverse order use the Orders every word in variable in reverse alphabetical order.
.Ql Cm \&:O:[-1..1]
combination of modifiers.
.It Cm \&:Ox .It Cm \&:Ox
Randomize words in variable. Shuffles the words in variable.
The results will be different each time you are referring to the The results will be different each time you are referring to the
modified variable; use the assignment with expansion modified variable; use the assignment with expansion
.Pq Ql Cm \&:= .Pq Ql Cm \&:=
to prevent such behaviour. to prevent such behavior.
For example, For example,
.Bd -literal -offset indent .Bd -literal -offset indent
LIST= uno due tre quattro LIST= uno due tre quattro
@ -1156,24 +1261,41 @@ due uno quattro tre
.Ed .Ed
.It Cm \&:Q .It Cm \&:Q
Quotes every shell meta-character in the variable, so that it can be passed Quotes every shell meta-character in the variable, so that it can be passed
safely to the shell.
.It Cm \&:q
Quotes every shell meta-character in the variable, and also doubles
.Sq $
characters so that it can be passed
safely through recursive invocations of safely through recursive invocations of
.Nm . .Nm .
This is equivalent to:
.Sq \&:S/\e\&$/&&/g:Q .
.It Cm \&:R .It Cm \&:R
Replaces each word in the variable with everything but its suffix. Replaces each word in the variable with everything but its suffix.
.It Cm \&:gmtime .It Cm \&:range[=count]
The value is an integer sequence representing the words of the original
value, or the supplied
.Va count .
.It Cm \&:gmtime[=utc]
The value is a format string for The value is a format string for
.Xr strftime 3 , .Xr strftime 3 ,
using the current using
.Xr gmtime 3 . .Xr gmtime 3 .
If a
.Va utc
value is not provided or is 0, the current time is used.
.It Cm \&:hash .It Cm \&:hash
Compute a 32bit 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 .It Cm \&:localtime[=utc]
The value is a format string for The value is a format string for
.Xr strftime 3 , .Xr strftime 3 ,
using the current using
.Xr localtime 3 . .Xr localtime 3 .
If a
.Va utc
value is not provided or is 0, the current time is used.
.It Cm \&:tA .It Cm \&:tA
Attempt to convert variable to an absolute path using Attempts to convert variable to an absolute path using
.Xr realpath 3 , .Xr realpath 3 ,
if that fails, the value is unchanged. if that fails, the value is unchanged.
.It Cm \&:tl .It Cm \&:tl
@ -1185,7 +1307,7 @@ This modifier sets the separator to the character
If If
.Ar c .Ar c
is omitted, then no separator is used. 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 .It Cm \&:tu
Converts variable to upper-case letters. Converts variable to upper-case letters.
.It Cm \&:tW .It Cm \&:tW
@ -1201,21 +1323,21 @@ See also
.Sm off .Sm off
.It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW .It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW
.Sm on .Sm on
Modify the first occurrence of Modifies the first occurrence of
.Ar old_string .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 . .Ar new_string .
If a If a
.Ql g .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. in each word are replaced.
If a If a
.Ql 1 .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. is affected.
If a If a
.Ql W .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 then the value is treated as a single word
(possibly containing embedded white space). (possibly containing embedded white space).
If If
@ -1232,7 +1354,7 @@ it is anchored at the end of each word.
Inside Inside
.Ar new_string , .Ar new_string ,
an ampersand an ampersand
.Pq Ql \*[Am] .Pq Ql &
is replaced by is replaced by
.Ar old_string .Ar old_string
(without any (without any
@ -1284,13 +1406,6 @@ as occur in the word or words it is found in; the
.Ql W .Ql W
modifier causes the value to be treated as a single word modifier causes the value to be treated as a single word
(possibly containing embedded white space). (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 .Pp
As for the As for the
.Cm \&:S .Cm \&:S
@ -1301,9 +1416,9 @@ and
are subjected to variable expansion before being parsed as are subjected to variable expansion before being parsed as
regular expressions. regular expressions.
.It Cm \&:T .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 .It Cm \&:u
Remove adjacent duplicate words (like Removes adjacent duplicate words (like
.Xr uniq 1 ) . .Xr uniq 1 ) .
.Sm off .Sm off
.It Cm \&:\&? Ar true_string Cm \&: Ar false_string .It Cm \&:\&? Ar true_string Cm \&: Ar false_string
@ -1319,7 +1434,7 @@ usually contain variable expansions.
A common error is trying to use expressions like A common error is trying to use expressions like
.Dl ${NUMBERS:M42:?match:no} .Dl ${NUMBERS:M42:?match:no}
which actually tests defined(NUMBERS), 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} . .Dl ${"${NUMBERS:M42}" != \&"\&":?match:no} .
.It Ar :old_string=new_string .It Ar :old_string=new_string
This is the This is the
@ -1341,6 +1456,29 @@ is the substring of
.Ar old_string .Ar old_string
to be replaced in to be replaced in
.Ar new_string . .Ar new_string .
If only
.Ar old_string
contains the pattern matching character
.Ar % ,
and
.Ar old_string
matches, then the result is the
.Ar new_string .
If only the
.Ar new_string
contains the pattern matching character
.Ar % ,
then it is not treated specially and it is printed as a literal
.Ar %
on match.
If there is more than one pattern matching character
.Ar ( % )
in either the
.Ar new_string
or
.Ar old_string ,
only the first instance is treated specially (as the pattern character);
all subsequent instances are treated as regular characters.
.Pp .Pp
Variable expansion occurs in the normal fashion inside both Variable expansion occurs in the normal fashion inside both
.Ar old_string .Ar old_string
@ -1357,11 +1495,10 @@ This is the loop expansion mechanism from the OSF Development
Environment (ODE) make. Environment (ODE) make.
Unlike Unlike
.Cm \&.for .Cm \&.for
loops expansion occurs at the time of loops, expansion occurs at the time of reference.
reference. Assigns
Assign
.Ar temp .Ar temp
to each word in the variable and evaluate to each word in the variable and evaluates
.Ar string . .Ar string .
The ODE convention is that The ODE convention is that
.Ar temp .Ar temp
@ -1371,8 +1508,29 @@ For example.
.Pp .Pp
However a single character variable is often more readable: However a single character variable is often more readable:
.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@} .Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
.It Cm \&:_[=var]
Saves the current variable value in
.Ql $_
or the named
.Va var
for later reference.
Example usage:
.Bd -literal -offset indent
M_cmpv.units = 1 1000 1000000
M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \&\\
\\* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh
.Dv .if ${VERSION:${M_cmpv}} < ${3.1.12:L:${M_cmpv}}
.Ed
Here
.Ql $_
is used to save the result of the
.Ql :S
modifier which is later referenced using the index values from
.Ql :range .
.It Cm \&:U Ns Ar newval .It Cm \&:U Ns Ar newval
If the variable is undefined If the variable is undefined,
.Ar newval .Ar newval
is the value. is the value.
If the variable is defined, the existing value is returned. If the variable is defined, the existing value is returned.
@ -1382,7 +1540,7 @@ It is handy for setting per-target CFLAGS for instance:
If a value is only required if the variable is undefined, use: If a value is only required if the variable is undefined, use:
.Dl ${VAR:D:Unewval} .Dl ${VAR:D:Unewval}
.It Cm \&:D Ns Ar newval .It Cm \&:D Ns Ar newval
If the variable is defined If the variable is defined,
.Ar newval .Ar newval
is the value. is the value.
.It Cm \&:L .It Cm \&:L
@ -1444,7 +1602,7 @@ value is divided into words.
.Pp .Pp
Ordinarily, a value is treated as a sequence of words Ordinarily, a value is treated as a sequence of words
delimited by white space. delimited by white space.
Some modifiers suppress this behaviour, Some modifiers suppress this behavior,
causing a value to be treated as a single word causing a value to be treated as a single word
(possibly containing embedded white space). (possibly containing embedded white space).
An empty value, or a value that consists entirely of white-space, An empty value, or a value that consists entirely of white-space,
@ -1482,6 +1640,11 @@ then the words are output in reverse order.
For example, For example,
.Ql Cm \&:[-1..1] .Ql Cm \&:[-1..1]
selects all the words from last to first. selects all the words from last to first.
If the list is already ordered, then this effectively reverses
the list, but it is more efficient to use
.Ql Cm \&:Or
instead of
.Ql Cm \&:O:[-1..1] .
.\" :[*] .\" :[*]
.It Cm \&* .It Cm \&*
Causes subsequent modifiers to treat the value as a single word Causes subsequent modifiers to treat the value as a single word
@ -1506,7 +1669,7 @@ Returns the number of words in the value.
.El \" :[range] .El \" :[range]
.El .El
.Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS .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 of the C programming language are provided in
.Nm . .Nm .
All such structures are identified by a line beginning with a single All such structures are identified by a line beginning with a single
@ -1514,9 +1677,9 @@ dot
.Pq Ql \&. .Pq Ql \&.
character. character.
Files are included with either Files are included with either
.Cm \&.include Aq Ar file .Cm \&.include \&< Ns Ar file Ns Cm \&>
or or
.Cm \&.include Pf \*q Ar file Ns \*q . .Cm \&.include \&\*q Ns Ar file Ns Cm \&\*q .
Variables between the angle brackets or double quotes are expanded Variables between the angle brackets or double quotes are expanded
to form the file name. to form the file name.
If angle brackets are used, the included makefile is expected to be in If angle brackets are used, the included makefile is expected to be in
@ -1530,12 +1693,20 @@ For compatibility with other versions of
.Nm .Nm
.Ql include file ... .Ql include file ...
is also accepted. is also accepted.
.Pp
If the include statement is written as If the include statement is written as
.Cm .-include .Cm .-include
or as or as
.Cm .sinclude .Cm .sinclude
then errors locating and/or opening include files are ignored. then errors locating and/or opening include files are ignored.
.Pp .Pp
If the include statement is written as
.Cm .dinclude
not only are errors locating and/or opening include files ignored,
but stale dependencies within the included file will be ignored
just like
.Va .MAKE.DEPENDFILE .
.Pp
Conditional expressions are also preceded by a single dot as the first Conditional expressions are also preceded by a single dot as the first
character of a line. character of a line.
The possible conditionals are as follows: The possible conditionals are as follows:
@ -1544,7 +1715,7 @@ The possible conditionals are as follows:
The message is printed along with the name of the makefile and line number, The message is printed along with the name of the makefile and line number,
then then
.Nm .Nm
will exit. will exit immediately.
.It Ic .export Ar variable ... .It Ic .export Ar variable ...
Export the specified global variable. Export the specified global variable.
If no variable list is provided, all globals are exported If no variable list is provided, all globals are exported
@ -1571,11 +1742,15 @@ This allows exporting a value to the environment which is different from that
used by used by
.Nm .Nm
internally. internally.
.It Ic .export-literal Ar variable ...
The same as
.Ql .export-env ,
except that variables in the value are not expanded.
.It Ic .info Ar message .It Ic .info Ar message
The message is printed along with the name of the makefile and line number. The message is printed along with the name of the makefile and line number.
.It Ic .undef Ar variable .It Ic .undef Ar variable ...
Un-define the specified global variable. Un-define the specified global variables.
Only global variables may be un-defined. Only global variables can be un-defined.
.It Ic .unexport Ar variable ... .It Ic .unexport Ar variable ...
The opposite of The opposite of
.Ql .export . .Ql .export .
@ -1663,7 +1838,7 @@ may be any one of the following:
.Bl -tag -width "Cm XX" .Bl -tag -width "Cm XX"
.It Cm \&|\&| .It Cm \&|\&|
Logical OR. Logical OR.
.It Cm \&\*[Am]\*[Am] .It Cm \&&&
Logical Logical
.Tn AND ; .Tn AND ;
of higher precedence than of higher precedence than
@ -1680,7 +1855,7 @@ The boolean operator
may be used to logically negate an entire may be used to logically negate an entire
conditional. conditional.
It is of higher precedence than It is of higher precedence than
.Ql Ic \&\*[Am]\*[Am] . .Ql Ic \&&& .
.Pp .Pp
The value of The value of
.Ar expression .Ar expression
@ -1715,7 +1890,7 @@ has been defined and has commands associated with it.
.Ar Expression .Ar Expression
may also be an arithmetic or string comparison. may also be an arithmetic or string comparison.
Variable expansion is Variable expansion is
performed on both sides of the comparison, after which the integral performed on both sides of the comparison, after which the numerical
values are compared. values are compared.
A value is interpreted as hexadecimal if it is A value is interpreted as hexadecimal if it is
preceded by 0x, otherwise it is decimal; octal numbers are not supported. preceded by 0x, otherwise it is decimal; octal numbers are not supported.
@ -1725,11 +1900,11 @@ variable expansion, either the left or right hand side of a
.Ql Ic == .Ql Ic ==
or or
.Ql Ic "!=" .Ql Ic "!="
operator is not an integral value, then operator is not a numerical value, then
string comparison is performed between the expanded string comparison is performed between the expanded
variables. variables.
If no relational operator is given, it is assumed that the expanded 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. of a string comparison.
.Pp .Pp
When When
@ -1751,7 +1926,8 @@ expression is applied.
Similarly, if the form is Similarly, if the form is
.Ql Ic .ifmake .Ql Ic .ifmake
or or
.Ql Ic .ifnmake , the .Ql Ic .ifnmake ,
the
.Dq make .Dq make
expression is applied. expression is applied.
.Pp .Pp
@ -1769,7 +1945,7 @@ The syntax of a for loop is:
.Pp .Pp
.Bl -tag -compact -width Ds .Bl -tag -compact -width Ds
.It Ic \&.for Ar variable Oo Ar variable ... Oc Ic in Ar expression .It Ic \&.for Ar variable Oo Ar variable ... Oc Ic in Ar expression
.It Aq make-rules .It Aq make-lines
.It Ic \&.endfor .It Ic \&.endfor
.El .El
.Pp .Pp
@ -1781,7 +1957,7 @@ On each iteration of the loop, one word is taken and assigned to each
in order, and these in order, and these
.Ic variables .Ic variables
are substituted into the are substituted into the
.Ic make-rules .Ic make-lines
inside the body of the for loop. inside the body of the for loop.
The number of words must come out even; that is, if there are three 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 iteration variables, the number of words provided must be a multiple
@ -1954,6 +2130,14 @@ variable of a target that inherits
.Ic .DEFAULT Ns 's .Ic .DEFAULT Ns 's
commands is set commands is set
to the target's own name. to the target's own name.
.It Ic .DELETE_ON_ERROR
If this target is present in the makefile, it globally causes make to
delete targets whose commands fail.
(By default, only targets whose commands are interrupted during
execution are deleted.
This is the historical behavior.)
This setting can be used to help prevent half-finished or malformed
targets from being left around and corrupting future rebuilds.
.It Ic .END .It Ic .END
Any command lines attached to this target are executed after everything Any command lines attached to this target are executed after everything
else is done. else is done.
@ -2068,7 +2252,7 @@ The sources are a set of
pairs. pairs.
.Bl -tag -width hasErrCtls .Bl -tag -width hasErrCtls
.It Ar name .It Ar name
This is the minimal specification, used to select one of the builtin This is the minimal specification, used to select one of the built-in
shell specs; shell specs;
.Ar sh , .Ar sh ,
.Ar ksh , .Ar ksh ,
@ -2274,9 +2458,9 @@ file).
.Sh BUGS .Sh BUGS
The The
.Nm .Nm
syntax is difficult to parse without actually acting of the data. syntax is difficult to parse without actually acting on the data.
For instance finding the end of a variable use should involve scanning each For instance, finding the end of a variable's use should involve scanning
the modifiers using the correct terminator for each field. each of the modifiers, using the correct terminator for each field.
In many places In many places
.Nm .Nm
just counts {} and () in order to find the end of a variable expansion. just counts {} and () in order to find the end of a variable expansion.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* $NetBSD: make_malloc.c,v 1.10 2012/06/20 17:46:28 sjg Exp $ */ /* $NetBSD: make_malloc.c,v 1.25 2021/01/19 20:51:46 rillig Exp $ */
/*- /*
* Copyright (c) 2009 The NetBSD Foundation, Inc. * Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
@ -26,36 +26,23 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef MAKE_NATIVE
#include <sys/cdefs.h>
__RCSID("$NetBSD: make_malloc.c,v 1.10 2012/06/20 17:46:28 sjg Exp $");
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h> #include <errno.h>
#include "make.h" #include "make.h"
#ifndef USE_EMALLOC MAKE_RCSID("$NetBSD: make_malloc.c,v 1.25 2021/01/19 20:51:46 rillig Exp $");
static void enomem(void) MAKE_ATTR_DEAD;
/* #ifndef USE_EMALLOC
* enomem --
* die when out of memory. /* die when out of memory. */
*/ static MAKE_ATTR_DEAD void
static void
enomem(void) enomem(void)
{ {
(void)fprintf(stderr, "%s: %s.\n", progname, strerror(ENOMEM)); (void)fprintf(stderr, "%s: %s.\n", progname, strerror(ENOMEM));
exit(2); exit(2);
} }
/* /* malloc, but die on error. */
* bmake_malloc --
* malloc, but die on error.
*/
void * void *
bmake_malloc(size_t len) bmake_malloc(size_t len)
{ {
@ -63,13 +50,10 @@ bmake_malloc(size_t len)
if ((p = malloc(len)) == NULL) if ((p = malloc(len)) == NULL)
enomem(); enomem();
return(p); return p;
} }
/* /* strdup, but die on error. */
* bmake_strdup --
* strdup, but die on error.
*/
char * char *
bmake_strdup(const char *str) bmake_strdup(const char *str)
{ {
@ -77,43 +61,33 @@ bmake_strdup(const char *str)
char *p; char *p;
len = strlen(str) + 1; len = strlen(str) + 1;
if ((p = malloc(len)) == NULL) p = bmake_malloc(len);
enomem();
return memcpy(p, str, len); return memcpy(p, str, len);
} }
/* /* Allocate a string starting from str with exactly len characters. */
* bmake_strndup --
* strndup, but die on error.
*/
char * char *
bmake_strndup(const char *str, size_t max_len) bmake_strldup(const char *str, size_t len)
{ {
size_t len; char *p = bmake_malloc(len + 1);
char *p;
if (str == NULL)
return NULL;
len = strlen(str);
if (len > max_len)
len = max_len;
p = bmake_malloc(len + 1);
memcpy(p, str, len); memcpy(p, str, len);
p[len] = '\0'; p[len] = '\0';
return p;
return(p);
} }
/* /* realloc, but die on error. */
* bmake_realloc --
* realloc, but die on error.
*/
void * void *
bmake_realloc(void *ptr, size_t size) bmake_realloc(void *ptr, size_t size)
{ {
if ((ptr = realloc(ptr, size)) == NULL) if ((ptr = realloc(ptr, size)) == NULL)
enomem(); enomem();
return(ptr); return ptr;
} }
#endif #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));
}

View File

@ -1,6 +1,6 @@
/* $NetBSD: make_malloc.h,v 1.4 2009/01/24 14:43:29 dsl Exp $ */ /* $NetBSD: make_malloc.h,v 1.16 2021/01/19 20:51:46 rillig Exp $ */
/*- /*
* Copyright (c) 2009 The NetBSD Foundation, Inc. * Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
@ -30,12 +30,27 @@
void *bmake_malloc(size_t); void *bmake_malloc(size_t);
void *bmake_realloc(void *, size_t); void *bmake_realloc(void *, size_t);
char *bmake_strdup(const char *); char *bmake_strdup(const char *);
char *bmake_strndup(const char *, size_t); char *bmake_strldup(const char *, size_t);
#else #else
#include <util.h> #include <util.h>
#define bmake_malloc(x) emalloc(x) #define bmake_malloc(n) emalloc(n)
#define bmake_realloc(x,y) erealloc(x,y) #define bmake_realloc(p, n) erealloc(p, n)
#define bmake_strdup(x) estrdup(x) #define bmake_strdup(s) estrdup(s)
#define bmake_strndup(x,y) estrndup(x,y) #define bmake_strldup(s, n) estrndup(s, n)
#endif #endif
char *bmake_strsedup(const char *, const char *);
/*
* Thin wrapper around free(3) to avoid the extra function call in case
* p is NULL, to save a few machine instructions.
*
* The case of a NULL pointer happens especially often after Var_Value,
* since only environment variables need to be freed, but not others.
*/
MAKE_INLINE void
bmake_free(void *p)
{
if (p != NULL)
free(p);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +1,23 @@
/* $NetBSD: meta.h,v 1.3 2013/03/23 05:31:29 sjg Exp $ */ /* $NetBSD: meta.h,v 1.9 2020/12/10 20:49:11 rillig Exp $ */
/* /*
* Things needed for 'meta' mode. * Things needed for 'meta' mode.
*/ */
/* /*
* Copyright (c) 2009-2010, Juniper Networks, Inc. * Copyright (c) 2009-2010, Juniper Networks, Inc.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 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 * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * 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.
* 3. Neither the name of the copyright holders nor the names of its * 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@ -28,28 +28,33 @@
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (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.
*/ */
typedef struct BuildMon { typedef struct BuildMon {
char meta_fname[MAXPATHLEN]; char meta_fname[MAXPATHLEN];
int filemon_fd; struct filemon *filemon;
int mon_fd; int mon_fd;
FILE *mfp; FILE *mfp;
} BuildMon; } BuildMon;
extern Boolean useMeta; struct Job;
struct Job; /* not defined yet */
void meta_init(void); void meta_init(void);
void meta_finish(void);
void meta_mode_init(const char *); void meta_mode_init(const char *);
void meta_job_start(struct Job *, GNode *); void meta_job_start(struct Job *, GNode *);
void meta_job_child(struct Job *); void meta_job_child(struct Job *);
void meta_job_error(struct Job *, GNode *, int, int); void meta_job_parent(struct Job *, pid_t);
int meta_job_fd(struct Job *);
int meta_job_event(struct Job *);
void meta_job_error(struct Job *, GNode *, Boolean, int);
void meta_job_output(struct Job *, char *, const char *); void meta_job_output(struct Job *, char *, const char *);
void meta_cmd_finish(void *); int meta_cmd_finish(void *);
void meta_job_finish(struct Job *); int meta_job_finish(struct Job *);
Boolean meta_oodate(GNode *, Boolean); Boolean meta_oodate(GNode *, Boolean);
void meta_compat_start(void); void meta_compat_start(void);
void meta_compat_child(void); void meta_compat_child(void);
void meta_compat_parent(void); void meta_compat_parent(pid_t);
extern Boolean useMeta;

View File

@ -1,6 +1,6 @@
/* $NetBSD: metachar.c,v 1.5 2015/06/19 08:03:35 mlelstv Exp $ */ /* $NetBSD: metachar.c,v 1.9 2021/01/19 20:51:46 rillig Exp $ */
/*- /*
* Copyright (c) 2015 The NetBSD Foundation, Inc. * Copyright (c) 2015 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
@ -37,52 +37,48 @@
#include <sys/cdefs.h> #include <sys/cdefs.h>
#endif #endif
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: metachar.c,v 1.5 2015/06/19 08:03:35 mlelstv Exp $");
#endif
#include "metachar.h" #include "metachar.h"
MAKE_RCSID("$NetBSD: metachar.c,v 1.9 2021/01/19 20:51:46 rillig Exp $");
/* /*
* The following array is used to make a fast determination of which * The following array is used to make a fast determination of which
* characters are interpreted specially by the shell. If a command * characters are interpreted specially by the shell. If a command
* contains any of these characters, it is executed by the shell, not * contains any of these characters, it is executed by the shell, not
* directly by us. * directly by us.
*
* perhaps move it to ctype?
*/ */
unsigned char _metachar[128] = { 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
// sp ! " # $ % & ' /* sp ! " # $ % & ' */
0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1,
// ( ) * + , - . / /* ( ) * + , - . / */
1, 1, 1, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0,
// 8 9 : ; < = > ? /* 8 9 : ; < = > ? */
0, 0, 0, 1, 1, 0, 1, 1, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
// X Y Z [ \ ] ^ _ /* X Y Z [ \ ] ^ _ */
0, 0, 0, 1, 1, 1, 1, 0, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
// x y z { | } ~ del /* x y z { | } ~ del */
0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0,
}; };

View File

@ -1,6 +1,6 @@
/* $NetBSD: metachar.h,v 1.4 2015/06/21 20:26:02 christos Exp $ */ /* $NetBSD: metachar.h,v 1.15 2021/01/19 20:51:46 rillig Exp $ */
/*- /*
* Copyright (c) 2015 The NetBSD Foundation, Inc. * Copyright (c) 2015 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
@ -28,34 +28,21 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _METACHAR_H #ifndef MAKE_METACHAR_H
#define _METACHAR_H #define MAKE_METACHAR_H
#include <ctype.h> #include "make.h"
extern unsigned char _metachar[]; extern unsigned char _metachar[];
#define ismeta(c) _metachar[(c) & 0x7f] #define is_shell_metachar(c) (_metachar[(c) & 0x7f] != 0)
static inline int MAKE_INLINE Boolean
hasmeta(const char *cmd) needshell(const char *cmd)
{ {
while (!ismeta(*cmd)) while (!is_shell_metachar(*cmd) && *cmd != ':' && *cmd != '=')
cmd++; cmd++;
return *cmd != '\0'; return *cmd != '\0';
} }
static inline int #endif /* MAKE_METACHAR_H */
needshell(const char *cmd, int white)
{
while (!ismeta(*cmd) && *cmd != ':' && *cmd != '=') {
if (white && isspace((unsigned char)*cmd))
break;
cmd++;
}
return *cmd != '\0';
}
#endif /* _METACHAR_H */

View File

@ -1,6 +1,6 @@
/* $NetBSD: nonints.h,v 1.68 2015/05/05 21:51:09 sjg Exp $ */ /* $NetBSD: nonints.h,v 1.206 2021/03/15 15:39:13 rillig Exp $ */
/*- /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
@ -34,7 +34,7 @@
* from: @(#)nonints.h 8.3 (Berkeley) 3/19/94 * from: @(#)nonints.h 8.3 (Berkeley) 3/19/94
*/ */
/*- /*
* Copyright (c) 1989 by Berkeley Softworks * Copyright (c) 1989 by Berkeley Softworks
* All rights reserved. * All rights reserved.
* *
@ -73,32 +73,51 @@
*/ */
/* arch.c */ /* arch.c */
ReturnStatus Arch_ParseArchive(char **, Lst, GNode *);
void Arch_Touch(GNode *);
void Arch_TouchLib(GNode *);
time_t Arch_MTime(GNode *);
time_t Arch_MemMTime(GNode *);
void Arch_FindLib(GNode *, Lst);
Boolean Arch_LibOODate(GNode *);
void Arch_Init(void); void Arch_Init(void);
void Arch_End(void); void Arch_End(void);
int Arch_IsLib(GNode *);
Boolean Arch_ParseArchive(char **, GNodeList *, GNode *);
void Arch_Touch(GNode *);
void Arch_TouchLib(GNode *);
void Arch_UpdateMTime(GNode *gn);
void Arch_UpdateMemberMTime(GNode *gn);
void Arch_FindLib(GNode *, SearchPath *);
Boolean Arch_LibOODate(GNode *);
Boolean Arch_IsLib(GNode *);
/* compat.c */ /* compat.c */
int CompatRunCommand(void *, void *); int Compat_RunCommand(const char *, GNode *, StringListNode *);
void Compat_Run(Lst); void Compat_Run(GNodeList *);
int Compat_Make(void *, void *); void Compat_Make(GNode *, GNode *);
/* cond.c */ /* cond.c */
struct If; CondEvalResult Cond_EvalCondition(const char *, Boolean *);
int Cond_EvalExpression(const struct If *, char *, Boolean *, int, Boolean); CondEvalResult Cond_EvalLine(const char *);
int Cond_Eval(char *);
void Cond_restore_depth(unsigned int); void Cond_restore_depth(unsigned int);
unsigned int Cond_save_depth(void); unsigned int Cond_save_depth(void);
/* dir.c; see also dir.h */
MAKE_INLINE const char *
str_basename(const char *pathname)
{
const char *lastSlash = strrchr(pathname, '/');
return lastSlash != NULL ? lastSlash + 1 : pathname;
}
MAKE_INLINE SearchPath *
SearchPath_New(void)
{
SearchPath *path = bmake_malloc(sizeof *path);
Lst_Init(&path->dirs);
return path;
}
void SearchPath_Free(SearchPath *);
/* for.c */ /* for.c */
int For_Eval(char *); int For_Eval(const char *);
int For_Accum(char *); Boolean For_Accum(const char *);
void For_Run(int); void For_Run(int);
/* job.c */ /* job.c */
@ -106,92 +125,301 @@ void JobReapChild(pid_t, int, Boolean);
/* main.c */ /* main.c */
void Main_ParseArgLine(const char *); void Main_ParseArgLine(const char *);
void MakeMode(const char *);
int main(int, char **);
char *Cmd_Exec(const char *, const char **); char *Cmd_Exec(const char *, const char **);
void Error(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2); void Error(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
void Fatal(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD; void Fatal(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD;
void Punt(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD; void Punt(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD;
void DieHorribly(void) MAKE_ATTR_DEAD; void DieHorribly(void) MAKE_ATTR_DEAD;
int PrintAddr(void *, void *);
void Finish(int) MAKE_ATTR_DEAD; void Finish(int) MAKE_ATTR_DEAD;
int eunlink(const char *); int eunlink(const char *);
void execError(const char *, const char *); void execDie(const char *, const char *);
char *getTmpdir(void); char *getTmpdir(void);
Boolean getBoolean(const char *, Boolean); Boolean ParseBoolean(const char *, Boolean);
char *cached_realpath(const char *, char *);
/* parse.c */ /* parse.c */
void Parse_Error(int, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
Boolean Parse_AnyExport(void);
Boolean Parse_IsVar(char *);
void Parse_DoVar(char *, GNode *);
void Parse_AddIncludeDir(char *);
void Parse_File(const char *, int);
void Parse_Init(void); void Parse_Init(void);
void Parse_End(void); void Parse_End(void);
void Parse_SetInput(const char *, int, int, char *(*)(void *, size_t *), void *);
Lst Parse_MainName(void); typedef enum VarAssignOp {
VAR_NORMAL, /* = */
VAR_SUBST, /* := */
VAR_SHELL, /* != or :sh= */
VAR_APPEND, /* += */
VAR_DEFAULT /* ?= */
} VarAssignOp;
typedef struct VarAssign {
char *varname; /* unexpanded */
VarAssignOp op;
const char *value; /* unexpanded */
} VarAssign;
typedef char *(*ReadMoreProc)(void *, size_t *);
void Parse_Error(ParseErrorLevel, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
Boolean Parse_IsVar(const char *, VarAssign *out_var);
void Parse_DoVar(VarAssign *, GNode *);
void Parse_AddIncludeDir(const char *);
void Parse_File(const char *, int);
void Parse_SetInput(const char *, int, int, ReadMoreProc, void *);
void Parse_MainName(GNodeList *);
int Parse_GetFatals(void);
/* str.c */ /* str.c */
char *str_concat(const char *, const char *, int);
char **brk_string(const char *, int *, Boolean, char **); /* A read-only string that may need to be freed after use. */
char *Str_FindSubstring(const char *, const char *); typedef struct FStr {
int Str_Match(const char *, const char *); const char *str;
char *Str_SYSVMatch(const char *, const char *, int *len); void *freeIt;
void Str_SYSVSubst(Buffer *, char *, char *, int); } FStr;
/* A modifiable string that may need to be freed after use. */
typedef struct MFStr {
char *str;
void *freeIt;
} MFStr;
typedef struct Words {
char **words;
size_t len;
void *freeIt;
} Words;
/* Return a string that is the sole owner of str. */
MAKE_INLINE FStr
FStr_InitOwn(char *str)
{
return (FStr){ str, str };
}
/* Return a string that refers to the shared str. */
MAKE_INLINE FStr
FStr_InitRefer(const char *str)
{
return (FStr){ str, NULL };
}
MAKE_INLINE void
FStr_Done(FStr *fstr)
{
free(fstr->freeIt);
#ifdef CLEANUP
fstr->str = NULL;
fstr->freeIt = NULL;
#endif
}
/* Return a string that is the sole owner of str. */
MAKE_INLINE MFStr
MFStr_InitOwn(char *str)
{
return (MFStr){ str, str };
}
/* Return a string that refers to the shared str. */
MAKE_INLINE MFStr
MFStr_InitRefer(char *str)
{
return (MFStr){ str, NULL };
}
MAKE_INLINE void
MFStr_Done(MFStr *mfstr)
{
free(mfstr->freeIt);
#ifdef CLEANUP
mfstr->str = NULL;
mfstr->freeIt = NULL;
#endif
}
Words Str_Words(const char *, Boolean);
MAKE_INLINE void
Words_Free(Words w)
{
free(w.words);
free(w.freeIt);
}
char *str_concat2(const char *, const char *);
char *str_concat3(const char *, const char *, const char *);
char *str_concat4(const char *, const char *, const char *, const char *);
Boolean Str_Match(const char *, const char *);
/* suff.c */ /* suff.c */
void Suff_ClearSuffixes(void);
Boolean Suff_IsTransform(char *);
GNode *Suff_AddTransform(char *);
int Suff_EndTransform(void *, void *);
void Suff_AddSuffix(char *, GNode **);
Lst Suff_GetPath(char *);
void Suff_DoPaths(void);
void Suff_AddInclude(char *);
void Suff_AddLib(char *);
void Suff_FindDeps(GNode *);
Lst Suff_FindPath(GNode *);
void Suff_SetNull(char *);
void Suff_Init(void); void Suff_Init(void);
void Suff_End(void); void Suff_End(void);
void Suff_ClearSuffixes(void);
Boolean Suff_IsTransform(const char *);
GNode *Suff_AddTransform(const char *);
void Suff_EndTransform(GNode *);
void Suff_AddSuffix(const char *, GNode **);
SearchPath *Suff_GetPath(const char *);
void Suff_DoPaths(void);
void Suff_AddInclude(const char *);
void Suff_AddLib(const char *);
void Suff_FindDeps(GNode *);
SearchPath *Suff_FindPath(GNode *);
void Suff_SetNull(const char *);
void Suff_PrintAll(void); void Suff_PrintAll(void);
/* targ.c */ /* targ.c */
void Targ_Init(void); void Targ_Init(void);
void Targ_End(void); void Targ_End(void);
Lst Targ_List(void);
GNode *Targ_NewGN(const char *); void Targ_Stats(void);
GNode *Targ_FindNode(const char *, int); GNodeList *Targ_List(void);
Lst Targ_FindList(Lst, int); GNode *GNode_New(const char *);
Boolean Targ_Ignore(GNode *); GNode *Targ_FindNode(const char *);
Boolean Targ_Silent(GNode *); GNode *Targ_GetNode(const char *);
Boolean Targ_Precious(GNode *); GNode *Targ_NewInternalNode(const char *);
GNode *Targ_GetEndNode(void);
void Targ_FindList(GNodeList *, StringList *);
Boolean Targ_Precious(const GNode *);
void Targ_SetMain(GNode *); void Targ_SetMain(GNode *);
int Targ_PrintCmd(void *, void *); void Targ_PrintCmds(GNode *);
int Targ_PrintNode(void *, void *); void Targ_PrintNode(GNode *, int);
char *Targ_FmtTime(time_t); void Targ_PrintNodes(GNodeList *, int);
const char *Targ_FmtTime(time_t);
void Targ_PrintType(int); void Targ_PrintType(int);
void Targ_PrintGraph(int); void Targ_PrintGraph(int);
void Targ_Propagate(void); void Targ_Propagate(void);
void Targ_Propagate_Wait(void); const char *GNodeMade_Name(GNodeMade);
/* var.c */ /* var.c */
void Var_Delete(const char *, GNode *);
void Var_Set(const char *, const char *, GNode *, int);
void Var_Append(const char *, const char *, GNode *);
Boolean Var_Exists(const char *, GNode *);
char *Var_Value(const char *, GNode *, char **);
char *Var_Parse(const char *, GNode *, Boolean, int *, void **);
char *Var_Subst(const char *, const char *, GNode *, Boolean);
char *Var_GetTail(const char *);
char *Var_GetHead(const char *);
void Var_Init(void); void Var_Init(void);
void Var_End(void); void Var_End(void);
typedef struct VarEvalFlags {
/*
* Expand and evaluate variables during parsing.
*
* Without this flag, the expression is only parsed, without
* evaluating any part of it.
*
* TODO: Document what Var_Parse and Var_Subst return when this flag
* is not set. As of 2021-03-15, they return unspecified,
* inconsistent results.
*/
Boolean wantRes: 1;
/*
* Treat undefined variables as errors.
* Must only be used in combination with wantRes.
*/
Boolean undefErr: 1;
/*
* Keep '$$' as '$$' instead of reducing it to a single '$'.
*
* Used in variable assignments using the ':=' operator. It allows
* multiple such assignments to be chained without accidentally
* expanding '$$file' to '$file' in the first assignment and
* interpreting it as '${f}' followed by 'ile' in the next assignment.
*/
Boolean keepDollar: 1;
/*
* Keep undefined variables as-is instead of expanding them to an
* empty string.
*
* Example for a ':=' assignment:
* CFLAGS = $(.INCLUDES)
* CFLAGS := -I.. $(CFLAGS)
* # If .INCLUDES (an undocumented special variable, by the
* # way) is still undefined, the updated CFLAGS becomes
* # "-I.. $(.INCLUDES)".
*/
Boolean keepUndef: 1;
/*
* Without this padding, GCC 9.3.0 on NetBSD 9.99.80 generates larger
* code than necessary (1.2 kB), masking out the unused bits from the
* int (since that is the default representation of Boolean in make),
* even for initializers consisting entirely of constants.
*/
Boolean : 0;
} VarEvalFlags;
#define VARE_PARSE_ONLY (VarEvalFlags) { FALSE, FALSE, FALSE, FALSE }
#define VARE_WANTRES (VarEvalFlags) { TRUE, FALSE, FALSE, FALSE }
#define VARE_UNDEFERR (VarEvalFlags) { TRUE, TRUE, FALSE, FALSE }
#define VARE_KEEP_DOLLAR_UNDEF (VarEvalFlags) { TRUE, FALSE, TRUE, TRUE }
typedef enum VarSetFlags {
VAR_SET_NONE = 0,
/* do not export */
VAR_SET_NO_EXPORT = 1 << 0,
/* Make the variable read-only. No further modification is possible,
* except for another call to Var_Set with the same flag. */
VAR_SET_READONLY = 1 << 1
} VarSetFlags;
/* The state of error handling returned by Var_Parse. */
typedef enum VarParseResult {
/* Both parsing and evaluation succeeded. */
VPR_OK,
/* Parsing or evaluating failed, with an error message. */
VPR_ERR,
/*
* Parsing succeeded, undefined expressions are allowed and the
* expression was still undefined after applying all modifiers.
* No error message is printed in this case.
*
* Some callers handle this case differently, so return this
* information to them, for now.
*
* TODO: Instead of having this special return value, rather ensure
* that VarEvalFlags.keepUndef is processed properly.
*/
VPR_UNDEF
} VarParseResult;
typedef enum VarExportMode {
/* .export-env */
VEM_ENV,
/* .export: Initial export or update an already exported variable. */
VEM_PLAIN,
/* .export-literal: Do not expand the variable value. */
VEM_LITERAL
} VarExportMode;
void Var_Delete(GNode *, const char *);
void Var_DeleteExpand(GNode *, const char *);
void Var_Undef(const char *);
void Var_Set(GNode *, const char *, const char *);
void Var_SetExpand(GNode *, const char *, const char *);
void Var_SetWithFlags(GNode *, const char *, const char *, VarSetFlags);
void Var_SetExpandWithFlags(GNode *, const char *, const char *, VarSetFlags);
void Var_Append(GNode *, const char *, const char *);
void Var_AppendExpand(GNode *, const char *, const char *);
Boolean Var_Exists(GNode *, const char *);
Boolean Var_ExistsExpand(GNode *, const char *);
FStr Var_Value(GNode *, const char *);
const char *GNode_ValueDirect(GNode *, const char *);
VarParseResult Var_Parse(const char **, GNode *, VarEvalFlags, FStr *);
VarParseResult Var_Subst(const char *, GNode *, VarEvalFlags, char **);
void Var_Stats(void);
void Var_Dump(GNode *); void Var_Dump(GNode *);
void Var_ExportVars(void); void Var_ReexportVars(void);
void Var_Export(char *, int); void Var_Export(VarExportMode, const char *);
void Var_UnExport(char *); void Var_ExportVars(const char *);
void Var_UnExport(Boolean, const char *);
void Global_Set(const char *, const char *);
void Global_SetExpand(const char *, const char *);
void Global_Append(const char *, const char *);
void Global_Delete(const char *);
/* util.c */ /* util.c */
void (*bmake_signal(int, void (*)(int)))(int); typedef void (*SignalProc)(int);
SignalProc bmake_signal(int, SignalProc);

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: pathnames.h,v 1.17 2009/04/11 09:41:18 apb Exp $ */ /* $NetBSD: pathnames.h,v 1.18 2020/11/29 09:27:40 rillig Exp $ */
/* /*
* Copyright (c) 1990, 1993 * Copyright (c) 1990, 1993
@ -39,15 +39,15 @@
#include <paths.h> #include <paths.h>
#endif #endif
#define _PATH_OBJDIR "obj" #define _PATH_OBJDIR "obj"
#define _PATH_OBJDIRPREFIX "/usr/obj" #define _PATH_OBJDIRPREFIX "/usr/obj"
#ifndef _PATH_DEFSHELLDIR #ifndef _PATH_DEFSHELLDIR
#define _PATH_DEFSHELLDIR "/bin" #define _PATH_DEFSHELLDIR "/bin"
#endif #endif
#define _PATH_DEFSYSMK "sys.mk" #define _PATH_DEFSYSMK "sys.mk"
#ifndef _PATH_DEFSYSPATH #ifndef _PATH_DEFSYSPATH
#define _PATH_DEFSYSPATH "/usr/share/mk" #define _PATH_DEFSYSPATH "/usr/share/mk"
#endif #endif
#ifndef _PATH_TMP #ifndef _PATH_TMP
#define _PATH_TMP "/tmp/" /* with trailing slash */ #define _PATH_TMP "/tmp/" /* with trailing slash */
#endif #endif

View File

@ -1,116 +0,0 @@
/* $NetBSD: sprite.h,v 1.11 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)sprite.h 8.1 (Berkeley) 6/6/93
*/
/*
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)sprite.h 8.1 (Berkeley) 6/6/93
*/
/*
* sprite.h --
*
* Common constants and type declarations for Sprite.
*/
#ifndef _SPRITE
#define _SPRITE
/*
* A boolean type is defined as an integer, not an enum. This allows a
* boolean argument to be an expression that isn't strictly 0 or 1 valued.
*/
typedef int Boolean;
#ifndef TRUE
#define TRUE 1
#endif /* TRUE */
#ifndef FALSE
#define FALSE 0
#endif /* FALSE */
/*
* Functions that must return a status can return a ReturnStatus to
* indicate success or type of failure.
*/
typedef int ReturnStatus;
/*
* The following statuses overlap with the first 2 generic statuses
* defined in status.h:
*
* SUCCESS There was no error.
* FAILURE There was a general error.
*/
#define SUCCESS 0x00000000
#define FAILURE 0x00000001
#endif /* _SPRITE */

View File

@ -1,6 +1,6 @@
/* $NetBSD: str.c,v 1.35 2014/02/12 01:35:56 sjg Exp $ */ /* $NetBSD: str.c,v 1.81 2021/02/01 22:36:28 rillig Exp $ */
/*- /*
* Copyright (c) 1988, 1989, 1990, 1993 * Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
@ -32,7 +32,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
/*- /*
* Copyright (c) 1989 by Berkeley Softworks * Copyright (c) 1989 by Berkeley Softworks
* All rights reserved. * All rights reserved.
* *
@ -68,186 +68,176 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: str.c,v 1.35 2014/02/12 01:35:56 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90";
#else
__RCSID("$NetBSD: str.c,v 1.35 2014/02/12 01:35:56 sjg Exp $");
#endif
#endif /* not lint */
#endif
#include "make.h" #include "make.h"
/*- /* "@(#)str.c 5.8 (Berkeley) 6/1/90" */
* str_concat -- MAKE_RCSID("$NetBSD: str.c,v 1.81 2021/02/01 22:36:28 rillig Exp $");
* concatenate the two strings, inserting a space or slash between them,
* freeing them if requested. /* Return the concatenation of s1 and s2, freshly allocated. */
*
* returns --
* the resulting string in allocated space.
*/
char * char *
str_concat(const char *s1, const char *s2, int flags) str_concat2(const char *s1, const char *s2)
{ {
int len1, len2; size_t len1 = strlen(s1);
char *result; size_t len2 = strlen(s2);
char *result = bmake_malloc(len1 + len2 + 1);
/* get the length of both strings */
len1 = strlen(s1);
len2 = strlen(s2);
/* allocate length plus separator plus EOS */
result = bmake_malloc((u_int)(len1 + len2 + 2));
/* copy first string into place */
memcpy(result, s1, len1); memcpy(result, s1, len1);
/* add separator character */
if (flags & STR_ADDSPACE) {
result[len1] = ' ';
++len1;
} else if (flags & STR_ADDSLASH) {
result[len1] = '/';
++len1;
}
/* copy second string plus EOS into place */
memcpy(result + len1, s2, len2 + 1); memcpy(result + len1, s2, len2 + 1);
return result;
return(result);
} }
/*- /* Return the concatenation of s1, s2 and s3, freshly allocated. */
* brk_string -- char *
* Fracture a string into an array of words (as delineated by tabs or str_concat3(const char *s1, const char *s2, const char *s3)
* spaces) taking quotation marks into account. Leading tabs/spaces
* are ignored.
*
* If expand is TRUE, quotes are removed and escape sequences
* such as \r, \t, etc... are expanded.
*
* returns --
* Pointer to the array of pointers to the words.
* Memory containing the actual words in *buffer.
* Both of these must be free'd by the caller.
* Number of words in *store_argc.
*/
char **
brk_string(const char *str, int *store_argc, Boolean expand, char **buffer)
{ {
int argc, ch; size_t len1 = strlen(s1);
char inquote, *start, *t; size_t len2 = strlen(s2);
const char *p; size_t len3 = strlen(s3);
int len; char *result = bmake_malloc(len1 + len2 + len3 + 1);
int argmax = 50, curlen = 0; memcpy(result, s1, len1);
char **argv; memcpy(result + len1, s2, len2);
memcpy(result + len1 + len2, s3, len3 + 1);
return result;
}
/* skip leading space chars. */ /* Return the concatenation of s1, s2, s3 and s4, freshly allocated. */
for (; *str == ' ' || *str == '\t'; ++str) char *
continue; str_concat4(const char *s1, const char *s2, const char *s3, const char *s4)
{
size_t len1 = strlen(s1);
size_t len2 = strlen(s2);
size_t len3 = strlen(s3);
size_t len4 = strlen(s4);
char *result = bmake_malloc(len1 + len2 + len3 + len4 + 1);
memcpy(result, s1, len1);
memcpy(result + len1, s2, len2);
memcpy(result + len1 + len2, s3, len3);
memcpy(result + len1 + len2 + len3, s4, len4 + 1);
return result;
}
/* allocate room for a copy of the string */ /*
if ((len = strlen(str) + 1) > curlen) * Fracture a string into an array of words (as delineated by tabs or spaces)
*buffer = bmake_malloc(curlen = len); * taking quotation marks into account.
*
* If expand is TRUE, quotes are removed and escape sequences such as \r, \t,
* etc... are expanded. In this case, return NULL on parse errors.
*
* Returns the fractured words, which must be freed later using Words_Free,
* unless the returned Words.words was NULL.
*/
Words
Str_Words(const char *str, Boolean expand)
{
size_t str_len;
char *words_buf;
size_t words_cap;
char **words;
size_t words_len;
char inquote;
char *word_start;
char *word_end;
const char *str_p;
/* /* XXX: why only hspace, not whitespace? */
* initial argmax based on len cpp_skip_hspace(&str); /* skip leading space chars. */
*/
argmax = MAX((len / 5), 50); /* words_buf holds the words, separated by '\0'. */
argv = bmake_malloc((argmax + 1) * sizeof(char *)); str_len = strlen(str);
words_buf = bmake_malloc(str_len + 1);
words_cap = str_len / 5 > 50 ? str_len / 5 : 50;
words = bmake_malloc((words_cap + 1) * sizeof(char *));
/* /*
* copy the string; at the same time, parse backslashes, * copy the string; at the same time, parse backslashes,
* quotes and build the argument list. * quotes and build the word list.
*/ */
argc = 0; words_len = 0;
inquote = '\0'; inquote = '\0';
for (p = str, start = t = *buffer;; ++p) { word_start = words_buf;
switch(ch = *p) { word_end = words_buf;
for (str_p = str;; str_p++) {
char ch = *str_p;
switch (ch) {
case '"': case '"':
case '\'': case '\'':
if (inquote) { if (inquote != '\0') {
if (inquote == ch) if (inquote == ch)
inquote = '\0'; inquote = '\0';
else else
break; break;
} } else {
else { inquote = ch;
inquote = (char) ch;
/* Don't miss "" or '' */ /* Don't miss "" or '' */
if (start == NULL && p[1] == inquote) { if (word_start == NULL && str_p[1] == inquote) {
if (!expand) { if (!expand) {
start = t; word_start = word_end;
*t++ = ch; *word_end++ = ch;
} else } else
start = t + 1; word_start = word_end + 1;
p++; str_p++;
inquote = '\0'; inquote = '\0';
break; break;
} }
} }
if (!expand) { if (!expand) {
if (!start) if (word_start == NULL)
start = t; word_start = word_end;
*t++ = ch; *word_end++ = ch;
} }
continue; continue;
case ' ': case ' ':
case '\t': case '\t':
case '\n': case '\n':
if (inquote) if (inquote != '\0')
break; break;
if (!start) if (word_start == NULL)
continue; continue;
/* FALLTHROUGH */ /* FALLTHROUGH */
case '\0': case '\0':
/* /*
* end of a token -- make sure there's enough argv * end of a token -- make sure there's enough words
* space and save off a pointer. * space and save off a pointer.
*/ */
if (!start) if (word_start == NULL)
goto done; goto done;
*t++ = '\0'; *word_end++ = '\0';
if (argc == argmax) { if (words_len == words_cap) {
argmax *= 2; /* ramp up fast */ size_t new_size;
argv = (char **)bmake_realloc(argv, words_cap *= 2; /* ramp up fast */
(argmax + 1) * sizeof(char *)); new_size = (words_cap + 1) * sizeof(char *);
words = bmake_realloc(words, new_size);
} }
argv[argc++] = start; words[words_len++] = word_start;
start = NULL; word_start = NULL;
if (ch == '\n' || ch == '\0') { if (ch == '\n' || ch == '\0') {
if (expand && inquote) { if (expand && inquote != '\0') {
free(argv); free(words);
free(*buffer); free(words_buf);
*buffer = NULL; return (Words){ NULL, 0, NULL };
return NULL;
} }
goto done; goto done;
} }
continue; continue;
case '\\': case '\\':
if (!expand) { if (!expand) {
if (!start) if (word_start == NULL)
start = t; word_start = word_end;
*t++ = '\\'; *word_end++ = '\\';
if (*(p+1) == '\0') /* catch '\' at end of line */ /* catch '\' at end of line */
if (str_p[1] == '\0')
continue; continue;
ch = *++p; ch = *++str_p;
break; break;
} }
switch (ch = *++p) { switch (ch = *++str_p) {
case '\0': case '\0':
case '\n': case '\n':
/* hmmm; fix it up as best we can */ /* hmmm; fix it up as best we can */
ch = '\\'; ch = '\\';
--p; str_p--;
break; break;
case 'b': case 'b':
ch = '\b'; ch = '\b';
@ -267,248 +257,119 @@ brk_string(const char *str, int *store_argc, Boolean expand, char **buffer)
} }
break; break;
} }
if (!start) if (word_start == NULL)
start = t; word_start = word_end;
*t++ = (char) ch; *word_end++ = ch;
} }
done: argv[argc] = NULL; done:
*store_argc = argc; words[words_len] = NULL; /* useful for argv */
return(argv); return (Words){ words, words_len, words_buf };
} }
/* /*
* Str_FindSubstring -- See if a string contains a particular substring. * Str_Match -- Test if a string matches a pattern like "*.[ch]".
* The following special characters are known *?\[] (as in fnmatch(3)).
* *
* Input: * XXX: this function does not detect or report malformed patterns.
* string String to search.
* substring Substring to find in string.
*
* Results: If string contains substring, the return value is the location of
* the first matching instance of substring in string. If string doesn't
* contain substring, the return value is NULL. Matching is done on an exact
* character-for-character basis with no wildcards or special characters.
*
* Side effects: None.
*/ */
char * Boolean
Str_FindSubstring(const char *string, const char *substring) Str_Match(const char *str, const char *pat)
{ {
const char *a, *b;
/*
* First scan quickly through the two strings looking for a single-
* character match. When it's found, then compare the rest of the
* substring.
*/
for (b = substring; *string != 0; string += 1) {
if (*string != *b)
continue;
a = string;
for (;;) {
if (*b == 0)
return UNCONST(string);
if (*a++ != *b++)
break;
}
b = substring;
}
return NULL;
}
/*
* Str_Match --
*
* See if a particular string matches a particular pattern.
*
* Results: Non-zero is returned if string matches pattern, 0 otherwise. The
* matching operation permits the following special characters in the
* pattern: *?\[] (see the man page for details on what these mean).
*
* XXX this function does not detect or report malformed patterns.
*
* Side effects: None.
*/
int
Str_Match(const char *string, const char *pattern)
{
char c2;
for (;;) { for (;;) {
/* /*
* See if we're at the end of both the pattern and the * See if we're at the end of both the pattern and the
* string. If, we succeeded. If we're at the end of the * string. If so, we succeeded. If we're at the end of the
* pattern but not at the end of the string, we failed. * pattern but not at the end of the string, we failed.
*/ */
if (*pattern == 0) if (*pat == '\0')
return(!*string); return *str == '\0';
if (*string == 0 && *pattern != '*') if (*str == '\0' && *pat != '*')
return(0); return FALSE;
/* /*
* Check for a "*" as the next pattern character. It matches * A '*' in the pattern matches any substring. We handle this
* any substring. We handle this by calling ourselves * by calling ourselves for each suffix of the string.
* recursively for each postfix of string, until either we
* match or we reach the end of the string.
*/ */
if (*pattern == '*') { if (*pat == '*') {
pattern += 1; pat++;
if (*pattern == 0) while (*pat == '*')
return(1); pat++;
while (*string != 0) { if (*pat == '\0')
if (Str_Match(string, pattern)) return TRUE;
return(1); while (*str != '\0') {
++string; if (Str_Match(str, pat))
return TRUE;
str++;
} }
return(0); return FALSE;
} }
/*
* Check for a "?" as the next pattern character. It matches /* A '?' in the pattern matches any single character. */
* any single character. if (*pat == '?')
*/
if (*pattern == '?')
goto thisCharOK; goto thisCharOK;
/* /*
* Check for a "[" as the next pattern character. It is * A '[' in the pattern matches a character from a list.
* followed by a list of characters that are acceptable, or * The '[' is followed by the list of acceptable characters,
* by a range (two characters separated by "-"). * or by ranges (two characters separated by '-'). In these
* character lists, the backslash is an ordinary character.
*/ */
if (*pattern == '[') { if (*pat == '[') {
++pattern; Boolean neg = pat[1] == '^';
pat += neg ? 2 : 1;
for (;;) { for (;;) {
if ((*pattern == ']') || (*pattern == 0)) if (*pat == ']' || *pat == '\0') {
return(0); if (neg)
if (*pattern == *string)
break;
if (pattern[1] == '-') {
c2 = pattern[2];
if (c2 == 0)
return(0);
if ((*pattern <= *string) &&
(c2 >= *string))
break; break;
if ((*pattern >= *string) && return FALSE;
(c2 <= *string))
break;
pattern += 2;
} }
++pattern; /*
* XXX: This naive comparison makes the
* control flow of the pattern parser
* dependent on the actual value of the
* string. This is unpredictable. It may be
* though that the code only looks wrong but
* actually all code paths result in the same
* behavior. This needs further tests.
*/
if (*pat == *str)
break;
if (pat[1] == '-') {
if (pat[2] == '\0')
return neg;
if (*pat <= *str && pat[2] >= *str)
break;
if (*pat >= *str && pat[2] <= *str)
break;
pat += 2;
}
pat++;
} }
while ((*pattern != ']') && (*pattern != 0)) if (neg && *pat != ']' && *pat != '\0')
++pattern; return FALSE;
while (*pat != ']' && *pat != '\0')
pat++;
if (*pat == '\0')
pat--;
goto thisCharOK; goto thisCharOK;
} }
/* /*
* If the next pattern character is '/', just strip off the * A backslash in the pattern matches the character following
* '/' so we do exact matching on the character that follows. * it exactly.
*/ */
if (*pattern == '\\') { if (*pat == '\\') {
++pattern; pat++;
if (*pattern == 0) if (*pat == '\0')
return(0); return FALSE;
} }
/*
* There's no special character. Just make sure that the if (*pat != *str)
* next characters of each string match. return FALSE;
*/
if (*pattern != *string) thisCharOK:
return(0); pat++;
thisCharOK: ++pattern; str++;
++string;
} }
} }
/*-
*-----------------------------------------------------------------------
* Str_SYSVMatch --
* Check word against pattern for a match (% is wild),
*
* Input:
* word Word to examine
* pattern Pattern to examine against
* len Number of characters to substitute
*
* Results:
* Returns the beginning position of a match or null. The number
* of characters matched is returned in len.
*
* Side Effects:
* None
*
*-----------------------------------------------------------------------
*/
char *
Str_SYSVMatch(const char *word, const char *pattern, int *len)
{
const char *p = pattern;
const char *w = word;
const char *m;
if (*p == '\0') {
/* Null pattern is the whole string */
*len = strlen(w);
return UNCONST(w);
}
if ((m = strchr(p, '%')) != NULL) {
/* check that the prefix matches */
for (; p != m && *w && *w == *p; w++, p++)
continue;
if (p != m)
return NULL; /* No match */
if (*++p == '\0') {
/* No more pattern, return the rest of the string */
*len = strlen(w);
return UNCONST(w);
}
}
m = w;
/* Find a matching tail */
do
if (strcmp(p, w) == 0) {
*len = w - m;
return UNCONST(m);
}
while (*w++ != '\0');
return NULL;
}
/*-
*-----------------------------------------------------------------------
* Str_SYSVSubst --
* Substitute '%' on the pattern with len characters from src.
* If the pattern does not contain a '%' prepend len characters
* from src.
*
* Results:
* None
*
* Side Effects:
* Places result on buf
*
*-----------------------------------------------------------------------
*/
void
Str_SYSVSubst(Buffer *buf, char *pat, char *src, int len)
{
char *m;
if ((m = strchr(pat, '%')) != NULL) {
/* Copy the prefix */
Buf_AddBytes(buf, m - pat, pat);
/* skip the % */
pat = m + 1;
}
/* Copy the pattern */
Buf_AddBytes(buf, len, src);
/* append the rest */
Buf_AddBytes(buf, strlen(pat), pat);
}

View File

@ -1,93 +0,0 @@
/* $NetBSD: strlist.c,v 1.4 2009/01/24 11:59:39 dsl Exp $ */
/*-
* Copyright (c) 2008 - 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: strlist.c,v 1.4 2009/01/24 11:59:39 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: strlist.c,v 1.4 2009/01/24 11:59:39 dsl Exp $");
#endif /* not lint */
#endif
#include <stddef.h>
#include <stdlib.h>
#include "strlist.h"
#include "make_malloc.h"
void
strlist_init(strlist_t *sl)
{
sl->sl_num = 0;
sl->sl_max = 0;
sl->sl_items = NULL;
}
void
strlist_clean(strlist_t *sl)
{
char *str;
int i;
STRLIST_FOREACH(str, sl, i)
free(str);
free(sl->sl_items);
sl->sl_num = 0;
sl->sl_max = 0;
sl->sl_items = NULL;
}
void
strlist_add_str(strlist_t *sl, char *str, unsigned int info)
{
unsigned int n;
strlist_item_t *items;
if (str == NULL)
return;
n = sl->sl_num + 1;
sl->sl_num = n;
items = sl->sl_items;
if (n >= sl->sl_max) {
items = bmake_realloc(items, (n + 7) * sizeof *sl->sl_items);
sl->sl_items = items;
sl->sl_max = n + 6;
}
items += n - 1;
items->si_str = str;
items->si_info = info;
items[1].si_str = NULL; /* STRLIST_FOREACH() terminator */
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,196 @@
#! /bin/sh
# $NetBSD: test-variants.sh,v 1.9 2021/02/15 07:42:35 rillig Exp $
#
# Build several variants of make and run the tests on them.
#
# The output of this test suite must be inspected manually to see the
# interesting details. The main purpose is to list the available build
# options.
set -eu
failed="no"
fail() {
echo "failed"
failed="yes"
}
testcase() {
echo "===> Running $*"
env -i PATH="$PATH" USETOOLS="no" "$@" \
sh -ce "make -s cleandir" \
&& env -i PATH="$PATH" USETOOLS="no" "$@" \
sh -ce "make -ks all" \
&& size *.o make \
&& env -i PATH="$PATH" USETOOLS="no" MALLOC_OPTIONS="JA" \
_MKMSG_TEST=":" "$@" \
sh -ce "make -s test" \
|| fail
}
testcase # just the plain default options
# See whether the Boolean type is only used as a single-bit type.
# By default it is aliased to int, and int is already used for any other
# purpose.
#
testcase USER_CPPFLAGS="-DUSE_DOUBLE_BOOLEAN"
# Ensure that variables of type Boolean are not assigned integers.
# The only valid values are TRUE and FALSE.
#
testcase USER_CPPFLAGS="-DUSE_UCHAR_BOOLEAN"
# Ensure that variables of type Boolean are not used as array index.
#
testcase USER_CPPFLAGS="-DUSE_CHAR_BOOLEAN"
# Try a different compiler, with slightly different warnings and error
# messages. One feature that is missing from GCC is a little stricter
# checks for enums.
#
testcase HAVE_LLVM="yes"
testcase USE_GCC8="yes"
testcase USE_GCC9="yes"
testcase USE_GCC10="yes" GCC10BASE="$HOME/pkg/gcc10"
# for selecting emalloc
testcase TOOLDIR=""
testcase USE_FILEMON="dev"
testcase USE_FILEMON="ktrace"
testcase USE_META="no"
testcase USER_CPPFLAGS="-DCLEANUP"
testcase USER_CPPFLAGS="-DDEBUG_REFCNT"
testcase USER_CPPFLAGS="-DDEBUG_HASH_LOOKUP"
testcase USER_CPPFLAGS="-DDEBUG_META_MODE"
testcase USER_CPPFLAGS="-DDEBUG_REALPATH_CACHE"
# Produces lots of debugging output.
#
#testcase USER_CPPFLAGS="-DDEBUG_SRC"
#testcase USER_CPPFLAGS="-UGMAKEEXPORT"
# NetBSD 8.0 x86_64
# In file included from arch.c:135:0:
# /usr/include/sys/param.h:357:0: error: "MAXPATHLEN" redefined [-Werror]
# #define MAXPATHLEN PATH_MAX
#testcase USER_CPPFLAGS="-DMAXPATHLEN=20"
# In this variant, the unit tests that use the :C modifier obviously fail.
#
testcase USER_CPPFLAGS="-DNO_REGEX"
# NetBSD 8.0 x86_64 says:
# In file included from /usr/include/sys/param.h:115:0,
# from arch.c:135:
# /usr/include/sys/syslimits.h:60:0: error: "PATH_MAX" redefined [-Werror]
# #define PATH_MAX 1024 /* max bytes in pathname */
#testcase USER_CPPFLAGS="-DPATH_MAX=20"
# config.h:124:0: error: "POSIX" redefined [-Werror]
#testcase USER_CPPFLAGS="-DPOSIX"
# config.h:115:0: error: "RECHECK" redefined [-Werror]
#testcase USER_CPPFLAGS="-DRECHECK"
# This higher optimization level may trigger additional "may be used
# uninitialized" errors. Could be combined with other compilers as well.
#
testcase USER_CFLAGS="-O3"
testcase USER_CFLAGS="-O0 -ggdb"
# The make source code is _intended_ to be compatible with C90.
# It uses some C99 features though.
# To really port it to C90, it would have to be in a C90 environment
# in which the system headers don't aggressively depend on C99.
#
# NetBSD 8.0 x86_64:
# /usr/include/sys/cdefs.h:618:22: error: ISO C90 does not support 'long long' [-Werror=long-long]
# /usr/include/sys/endian.h:205:1: error: use of C99 long long integer constant [-Werror=long-long]
# /usr/include/pthread_types.h:128:3: error: ISO C90 doesn't support unnamed structs/unions [-Werror=pedantic]
# var.c:3027:2: error: initializer element is not computable at load time [-Werror=pedantic]
# var.c:2532:5: error: ISO C does not support '__PRETTY_FUNCTION__' predefined identifier [-Werror=pedantic]
# var.c:1574:15: error: ISO C90 does not support the 'z' gnu_printf length modifier [-Werror=format=]
# var.c:137:33: error: anonymous variadic macros were introduced in C99 [-Werror=variadic-macros]
# parse.c:2473:22: error: format '%p' expects argument of type 'void *', but argument 7 has type 'char * (*)(void *, size_t *) {aka char * (*)(void *, long unsigned int *)}' [-Werror=format=]
#
#testcase USER_CFLAGS="-std=c90 -ansi -pedantic" USER_CPPFLAGS="-Dinline="
# Ensure that every inline function is declared as MAKE_ATTR_UNUSED.
testcase USER_CPPFLAGS="-Dinline="
testcase USER_CFLAGS="-std=c90" USER_CPPFLAGS="-Dinline="
#testcase USER_CFLAGS="-std=c90 -pedantic" USER_CPPFLAGS="-Dinline="
testcase USER_CFLAGS="-ansi" USER_CPPFLAGS="-Dinline="
# config.h does not allow overriding these features
#testcase USER_CPPFLAGS="-UUSE_IOVEC"
# Ensure that there are only side-effect-free conditions in the assert
# macro, or at least none that affect the outcome of the tests.
#
testcase USER_CPPFLAGS="-DNDEBUG"
# Only in native mode, make dares to use a shortcut in Compat_RunCommand
# that circumvents the shell and instead calls execvp directly.
# Another effect is that the shell is run with -q, which prevents the
# -x and -v flags from echoing the commands from profile files.
testcase USER_CPPFLAGS="-UMAKE_NATIVE -DHAVE_STRERROR -DHAVE_SETENV -DHAVE_VSNPRINTF"
# Running the code coverage using gcov takes a long time. Most of this
# time is spent in gcov_read_unsigned because gcov_open sets the .gcda
# file to unbuffered, which means that every single byte needs its own
# system call to be read.
#
# Combining USE_COVERAGE with USE_GCC10 or HAVE_LLVM does not work since
# these fail to link with the coverage library.
#
# Turning the optimization off is required because of:
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96622
#
#testcase USE_COVERAGE="yes" USER_CFLAGS="-O0 -ggdb"
testcase USE_FORT="yes"
# Ensure that the tests can be specified either as relative filenames or
# as absolute filenames.
testcase USE_ABSOLUTE_TESTNAMES="yes"
# This test is the result of reading through the GCC "Warning Options"
# documentation, noting down everything that sounded interesting.
#
testcase USE_GCC10=yes GCC10BASE=$HOME/pkg/gcc10 USER_CFLAGS="\
-Wmisleading-indentation -Wmissing-attributes -Wmissing-braces \
-Wextra -Wnonnull -Wnonnull-compare -Wnull-dereference -Wimplicit \
-Wimplicit-fallthrough=4 -Wignored-qualifiers -Wunused \
-Wunused-but-set-variable -Wunused-parameter -Wduplicated-branches \
-Wduplicated-cond -Wunused-macros -Wcast-function-type -Wconversion \
-Wenum-compare -Wmissing-field-initializers -Wredundant-decls \
-Wno-error=conversion -Wno-error=sign-conversion -Wno-error=unused-macros \
-Wno-error=unused-parameter -Wno-error=duplicated-branches"
for shell in /usr/pkg/bin/bash /usr/pkg/bin/dash; do
if [ -x "$shell" ]; then
testcase USER_CPPFLAGS=-DDEFSHELL_CUSTOM="\\\"$shell\\\""
fi
done
test "$failed" = "no"

View File

@ -1,6 +1,6 @@
/* $NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $ */ /* $NetBSD: trace.c,v 1.28 2021/02/05 05:15:12 rillig Exp $ */
/*- /*
* Copyright (c) 2000 The NetBSD Foundation, Inc. * Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
@ -29,17 +29,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $");
#endif /* not lint */
#endif
/*-
* trace.c -- * trace.c --
* handle logging of trace events generated by various parts of make. * handle logging of trace events generated by various parts of make.
* *
@ -54,16 +44,15 @@ __RCSID("$NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $");
#include <sys/time.h> #include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include "make.h" #include "make.h"
#include "job.h" #include "job.h"
#include "trace.h" #include "trace.h"
MAKE_RCSID("$NetBSD: trace.c,v 1.28 2021/02/05 05:15:12 rillig Exp $");
static FILE *trfile; static FILE *trfile;
static pid_t trpid; static pid_t trpid;
char *trwd; const char *trwd;
static const char *evname[] = { static const char *evname[] = {
"BEG", "BEG",
@ -77,10 +66,13 @@ static const char *evname[] = {
void void
Trace_Init(const char *pathname) Trace_Init(const char *pathname)
{ {
char *p1;
if (pathname != NULL) { if (pathname != NULL) {
FStr curDir;
trpid = getpid(); trpid = getpid();
trwd = Var_Value(".CURDIR", VAR_GLOBAL, &p1); /* XXX: This variable may get overwritten later, which
* would make trwd point to undefined behavior. */
curDir = Var_Value(SCOPE_GLOBAL, ".CURDIR");
trwd = curDir.str;
trfile = fopen(pathname, "a"); trfile = fopen(pathname, "a");
} }
@ -90,7 +82,7 @@ void
Trace_Log(TrEvent event, Job *job) Trace_Log(TrEvent event, Job *job)
{ {
struct timeval rightnow; struct timeval rightnow;
if (trfile == NULL) if (trfile == NULL)
return; return;
@ -101,8 +93,11 @@ Trace_Log(TrEvent event, Job *job)
jobTokensRunning, jobTokensRunning,
evname[event], trpid, trwd); evname[event], trpid, trwd);
if (job != NULL) { if (job != NULL) {
fprintf(trfile, " %s %d %x %x", job->node->name, char flags[4];
job->pid, job->flags, job->node->type);
Job_FlagsToString(job, flags, sizeof flags);
fprintf(trfile, " %s %d %s %x", job->node->name,
job->pid, flags, job->node->type);
} }
fputc('\n', trfile); fputc('\n', trfile);
fflush(trfile); fflush(trfile);

View File

@ -1,6 +1,6 @@
/* $NetBSD: trace.h,v 1.3 2008/04/28 20:24:14 martin Exp $ */ /* $NetBSD: trace.h,v 1.6 2021/01/19 20:51:46 rillig Exp $ */
/*- /*
* Copyright (c) 2000 The NetBSD Foundation, Inc. * Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
@ -29,12 +29,15 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
/*- /*
* trace.h -- * trace.h --
* Definitions pertaining to the tracing of jobs in parallel mode. * Definitions pertaining to the tracing of jobs in parallel mode.
*/ */
typedef enum { #ifndef MAKE_TRACE_H
#define MAKE_TRACE_H
typedef enum TrEvent {
MAKESTART, MAKESTART,
MAKEEND, MAKEEND,
MAKEERROR, MAKEERROR,
@ -47,3 +50,4 @@ void Trace_Init(const char *);
void Trace_Log(TrEvent, Job *); void Trace_Log(TrEvent, Job *);
void Trace_End(void); void Trace_End(void);
#endif

View File

@ -0,0 +1,3 @@
*.out
*.rawout
*.status

View File

@ -1,120 +1,696 @@
# $NetBSD: Makefile,v 1.52 2015/05/05 21:51:09 sjg Exp $ # $NetBSD: Makefile,v 1.273 2021/03/14 11:49:37 rillig Exp $
# #
# Unit tests for make(1) # Unit tests for make(1)
# The main targets are:
#
# all: run all the tests
# test: run 'all', and compare to expected results
# accept: move generated output to expected results
# #
# Adding a test case. # The main targets are:
#
# all:
# run all the tests
# test:
# run 'all', and compare to expected results
# accept:
# move generated output to expected results
#
# Settable variables
#
# TEST_MAKE
# The make program to be tested.
#
#
# Adding a test case
#
# Each feature should get its own set of tests in its own suitably # Each feature should get its own set of tests in its own suitably
# named makefile (*.mk), with its own set of expected results (*.exp), # named makefile (*.mk), with its own set of expected results (*.exp),
# and it should be added to the TESTNAMES list. # and it should be added to the TESTS list.
# #
# Any added files must also be added to src/distrib/sets/lists/tests/mi.
# To do that, just run "make sync-mi" in this directory.
#
# A few *.mk files are helper files for other tests (such as include-sub.mk)
# and are thus not added to TESTS. Such files must be ignored in
# src/tests/usr.bin/make/t_make.sh.
#
.MAIN: all .MAIN: all
UNIT_TESTS:= ${.PARSEDIR} # we use these below but we might be an older make
.PATH: ${UNIT_TESTS} .MAKE.OS?= ${uname -s:L:sh}
.MAKE.UID?= ${id -u:L:sh}
# Each test is in a sub-makefile. # Each test is in a sub-makefile.
# Keep the list sorted. # Keep the list sorted.
TESTNAMES= \ # Any test that is commented out must be ignored in
comment \ # src/tests/usr.bin/make/t_make.sh as well.
cond1 \ TESTS+= archive
cond2 \ TESTS+= archive-suffix
error \ TESTS+= cmd-errors
export \ TESTS+= cmd-errors-jobs
export-all \ TESTS+= cmd-errors-lint
export-env \ TESTS+= cmd-interrupt
doterror \ TESTS+= cmdline
dotwait \ TESTS+= cmdline-redirect-stdin
forloop \ TESTS+= cmdline-undefined
forsubst \ TESTS+= comment
hash \ TESTS+= compat-error
misc \ TESTS+= cond-cmp-numeric
moderrs \ TESTS+= cond-cmp-numeric-eq
modmatch \ TESTS+= cond-cmp-numeric-ge
modmisc \ TESTS+= cond-cmp-numeric-gt
modorder \ TESTS+= cond-cmp-numeric-le
modts \ TESTS+= cond-cmp-numeric-lt
modword \ TESTS+= cond-cmp-numeric-ne
order \ TESTS+= cond-cmp-string
posix \ TESTS+= cond-cmp-unary
qequals \ TESTS+= cond-eof
sunshcmd \ TESTS+= cond-func
sysv \ TESTS+= cond-func-commands
ternary \ TESTS+= cond-func-defined
unexport \ TESTS+= cond-func-empty
unexport-env \ TESTS+= cond-func-exists
varcmd \ TESTS+= cond-func-make
varmisc \ TESTS+= cond-func-make-main
varshell TESTS+= cond-func-target
TESTS+= cond-late
TESTS+= cond-op
TESTS+= cond-op-and
TESTS+= cond-op-and-lint
TESTS+= cond-op-not
TESTS+= cond-op-or
TESTS+= cond-op-or-lint
TESTS+= cond-op-parentheses
TESTS+= cond-short
TESTS+= cond-token-number
TESTS+= cond-token-plain
TESTS+= cond-token-string
TESTS+= cond-token-var
TESTS+= cond-undef-lint
TESTS+= cond1
TESTS+= counter
TESTS+= counter-append
TESTS+= dep
TESTS+= dep-colon
TESTS+= dep-colon-bug-cross-file
TESTS+= dep-double-colon
TESTS+= dep-double-colon-indep
TESTS+= dep-exclam
TESTS+= dep-none
TESTS+= dep-percent
TESTS+= dep-var
TESTS+= dep-wildcards
TESTS+= depsrc
TESTS+= depsrc-end
TESTS+= depsrc-exec
TESTS+= depsrc-ignore
TESTS+= depsrc-made
TESTS+= depsrc-make
TESTS+= depsrc-meta
TESTS+= depsrc-nometa
TESTS+= depsrc-nometa_cmp
TESTS+= depsrc-nopath
TESTS+= depsrc-notmain
TESTS+= depsrc-optional
TESTS+= depsrc-phony
TESTS+= depsrc-precious
TESTS+= depsrc-recursive
TESTS+= depsrc-silent
TESTS+= depsrc-use
TESTS+= depsrc-usebefore
TESTS+= depsrc-usebefore-double-colon
TESTS+= depsrc-wait
TESTS+= deptgt
TESTS+= deptgt-begin
TESTS+= deptgt-begin-fail
TESTS+= deptgt-begin-fail-indirect
TESTS+= deptgt-default
TESTS+= deptgt-delete_on_error
TESTS+= deptgt-end
TESTS+= deptgt-end-fail
TESTS+= deptgt-end-fail-all
TESTS+= deptgt-end-fail-indirect
TESTS+= deptgt-end-jobs
TESTS+= deptgt-error
TESTS+= deptgt-ignore
TESTS+= deptgt-interrupt
TESTS+= deptgt-main
TESTS+= deptgt-makeflags
TESTS+= deptgt-no_parallel
TESTS+= deptgt-nopath
TESTS+= deptgt-notparallel
TESTS+= deptgt-objdir
TESTS+= deptgt-order
TESTS+= deptgt-path
TESTS+= deptgt-path-suffix
TESTS+= deptgt-phony
TESTS+= deptgt-precious
TESTS+= deptgt-shell
TESTS+= deptgt-silent
TESTS+= deptgt-stale
TESTS+= deptgt-suffixes
TESTS+= dir
TESTS+= dir-expand-path
TESTS+= directive
TESTS+= directive-dinclude
TESTS+= directive-elif
TESTS+= directive-elifdef
TESTS+= directive-elifmake
TESTS+= directive-elifndef
TESTS+= directive-elifnmake
TESTS+= directive-else
TESTS+= directive-endfor
TESTS+= directive-endif
TESTS+= directive-error
TESTS+= directive-export
TESTS+= directive-export-env
TESTS+= directive-export-impl
TESTS+= directive-export-gmake
TESTS+= directive-export-literal
TESTS+= directive-for
TESTS+= directive-for-errors
TESTS+= directive-for-escape
TESTS+= directive-for-generating-endif
TESTS+= directive-for-lines
TESTS+= directive-for-null
TESTS+= directive-hyphen-include
TESTS+= directive-if
TESTS+= directive-if-nested
TESTS+= directive-ifdef
TESTS+= directive-ifmake
TESTS+= directive-ifndef
TESTS+= directive-ifnmake
TESTS+= directive-include
TESTS+= directive-include-fatal
TESTS+= directive-info
TESTS+= directive-misspellings
TESTS+= directive-sinclude
TESTS+= directive-undef
TESTS+= directive-unexport
TESTS+= directive-unexport-env
TESTS+= directive-warning
TESTS+= dollar
TESTS+= doterror
TESTS+= dotwait
TESTS+= envfirst
TESTS+= error
TESTS+= # escape # broken by reverting POSIX changes
TESTS+= export
TESTS+= export-all
TESTS+= export-env
TESTS+= export-variants
TESTS+= forloop
TESTS+= forsubst
TESTS+= gnode-submake
TESTS+= hanoi-include
TESTS+= impsrc
TESTS+= include-main
TESTS+= job-flags
TESTS+= job-output-long-lines
TESTS+= jobs-empty-commands
TESTS+= jobs-error-indirect
TESTS+= jobs-error-nested
TESTS+= jobs-error-nested-make
TESTS+= lint
TESTS+= make-exported
TESTS+= meta-cmd-cmp
TESTS+= moderrs
TESTS+= modmatch
TESTS+= modmisc
TESTS+= modts
TESTS+= modword
.if ${.MAKE.UID} > 0
TESTS+= objdir-writable
.endif
TESTS+= opt
TESTS+= opt-backwards
TESTS+= opt-chdir
TESTS+= opt-debug
TESTS+= opt-debug-all
TESTS+= opt-debug-archive
TESTS+= opt-debug-curdir
TESTS+= opt-debug-cond
TESTS+= opt-debug-dir
TESTS+= opt-debug-errors
TESTS+= opt-debug-file
TESTS+= opt-debug-for
TESTS+= opt-debug-graph1
TESTS+= opt-debug-graph2
TESTS+= opt-debug-graph3
TESTS+= opt-debug-hash
TESTS+= opt-debug-jobs
TESTS+= opt-debug-lint
TESTS+= opt-debug-loud
TESTS+= opt-debug-meta
TESTS+= opt-debug-making
TESTS+= opt-debug-no-rm
TESTS+= opt-debug-parse
TESTS+= opt-debug-suff
TESTS+= opt-debug-targets
TESTS+= opt-debug-varraw
TESTS+= opt-debug-var
TESTS+= opt-debug-x-trace
TESTS+= opt-define
TESTS+= opt-env
TESTS+= opt-file
TESTS+= opt-ignore
TESTS+= opt-include-dir
TESTS+= opt-jobs
TESTS+= opt-jobs-internal
TESTS+= opt-jobs-no-action
TESTS+= opt-keep-going
TESTS+= opt-keep-going-multiple
TESTS+= opt-m-include-dir
TESTS+= opt-no-action
TESTS+= opt-no-action-at-all
TESTS+= opt-no-action-runflags
TESTS+= opt-no-action-touch
TESTS+= opt-query
TESTS+= opt-raw
TESTS+= opt-silent
TESTS+= opt-touch
TESTS+= opt-touch-jobs
TESTS+= opt-tracefile
TESTS+= opt-var-expanded
TESTS+= opt-var-literal
TESTS+= opt-warnings-as-errors
TESTS+= opt-where-am-i
TESTS+= opt-x-reduce-exported
TESTS+= order
TESTS+= parse-var
TESTS+= phony-end
TESTS+= posix
TESTS+= # posix1 # broken by reverting POSIX changes
TESTS+= recursive
TESTS+= sh
TESTS+= sh-dots
TESTS+= sh-errctl
TESTS+= sh-flags
TESTS+= sh-jobs
TESTS+= sh-jobs-error
TESTS+= sh-leading-at
TESTS+= sh-leading-hyphen
TESTS+= sh-leading-plus
TESTS+= sh-meta-chars
TESTS+= sh-multi-line
TESTS+= sh-single-line
TESTS+= shell-csh
TESTS+= shell-custom
TESTS+= shell-ksh
TESTS+= shell-sh
TESTS+= suff-add-later
TESTS+= suff-clear-regular
TESTS+= suff-clear-single
TESTS+= suff-incomplete
TESTS+= suff-lookup
TESTS+= suff-main
TESTS+= suff-main-several
TESTS+= suff-phony
TESTS+= suff-rebuild
TESTS+= suff-self
TESTS+= suff-transform-debug
TESTS+= suff-transform-endless
TESTS+= suff-transform-expand
TESTS+= suff-transform-select
TESTS+= sunshcmd
TESTS+= ternary
TESTS+= unexport
TESTS+= unexport-env
TESTS+= use-inference
TESTS+= var-class
TESTS+= var-class-cmdline
TESTS+= var-class-env
TESTS+= var-class-global
TESTS+= var-class-local
TESTS+= var-class-local-legacy
TESTS+= var-eval-short
TESTS+= var-op
TESTS+= var-op-append
TESTS+= var-op-assign
TESTS+= var-op-default
TESTS+= var-op-expand
TESTS+= var-op-shell
TESTS+= var-op-sunsh
TESTS+= var-recursive
TESTS+= varcmd
TESTS+= vardebug
TESTS+= varfind
TESTS+= varmisc
TESTS+= varmod
TESTS+= varmod-assign
TESTS+= varmod-defined
TESTS+= varmod-edge
TESTS+= varmod-exclam-shell
TESTS+= varmod-extension
TESTS+= varmod-gmtime
TESTS+= varmod-hash
TESTS+= varmod-head
TESTS+= varmod-ifelse
TESTS+= varmod-indirect
TESTS+= varmod-l-name-to-value
TESTS+= varmod-localtime
TESTS+= varmod-loop
TESTS+= varmod-match
TESTS+= varmod-match-escape
TESTS+= varmod-no-match
TESTS+= varmod-order
TESTS+= varmod-order-reverse
TESTS+= varmod-order-shuffle
TESTS+= varmod-path
TESTS+= varmod-quote
TESTS+= varmod-quote-dollar
TESTS+= varmod-range
TESTS+= varmod-remember
TESTS+= varmod-root
TESTS+= varmod-select-words
TESTS+= varmod-shell
TESTS+= varmod-subst
TESTS+= varmod-subst-regex
TESTS+= varmod-sun-shell
TESTS+= varmod-sysv
TESTS+= varmod-tail
TESTS+= varmod-to-abs
TESTS+= varmod-to-lower
TESTS+= varmod-to-many-words
TESTS+= varmod-to-one-word
TESTS+= varmod-to-separator
TESTS+= varmod-to-upper
TESTS+= varmod-undefined
TESTS+= varmod-unique
TESTS+= varname
TESTS+= varname-dollar
TESTS+= varname-dot-alltargets
TESTS+= varname-dot-curdir
TESTS+= varname-dot-includes
TESTS+= varname-dot-includedfromdir
TESTS+= varname-dot-includedfromfile
TESTS+= varname-dot-libs
TESTS+= varname-dot-make-dependfile
TESTS+= varname-dot-make-expand_variables
TESTS+= varname-dot-make-exported
TESTS+= varname-dot-make-jobs
TESTS+= varname-dot-make-jobs-prefix
TESTS+= varname-dot-make-level
TESTS+= varname-dot-make-makefile_preference
TESTS+= varname-dot-make-makefiles
TESTS+= varname-dot-make-meta-bailiwick
TESTS+= varname-dot-make-meta-created
TESTS+= varname-dot-make-meta-files
TESTS+= varname-dot-make-meta-ignore_filter
TESTS+= varname-dot-make-meta-ignore_paths
TESTS+= varname-dot-make-meta-ignore_patterns
TESTS+= varname-dot-make-meta-prefix
TESTS+= varname-dot-make-mode
TESTS+= varname-dot-make-path_filemon
TESTS+= varname-dot-make-pid
TESTS+= varname-dot-make-ppid
TESTS+= varname-dot-make-save_dollars
TESTS+= varname-dot-makeflags
TESTS+= varname-dot-makeoverrides
TESTS+= varname-dot-newline
TESTS+= varname-dot-objdir
TESTS+= varname-dot-parsedir
TESTS+= varname-dot-parsefile
TESTS+= varname-dot-path
TESTS+= varname-dot-shell
TESTS+= varname-dot-targets
TESTS+= varname-empty
TESTS+= varname-make
TESTS+= varname-make_print_var_on_error
TESTS+= varname-make_print_var_on_error-jobs
TESTS+= varname-makefile
TESTS+= varname-makeflags
TESTS+= varname-pwd
TESTS+= varname-vpath
TESTS+= varparse-dynamic
TESTS+= varparse-errors
TESTS+= varparse-mod
TESTS+= varparse-undef-partial
TESTS+= varquote
# these tests were broken by referting POSIX chanegs # Ideas for more tests:
STRICT_POSIX_TESTS = \ # char-0020-space.mk
escape \ # char-005C-backslash.mk
impsrc \ # escape-cond-str.mk
phony-end \ # escape-cond-func-arg.mk
posix1 \ # escape-cond-func-arg.mk
suffixes # escape-varmod.mk
# escape-varmod-define.mk
# escape-varmod-match.mk
# escape-varname.mk
# escape-varassign-varname.mk
# escape-varassign-varname-cmdline.mk
# escape-varassign-value.mk
# escape-varassign-value-cmdline.mk
# escape-dependency-source.mk
# escape-dependency-target.mk
# escape-for-varname.mk
# escape-for-item.mk
# posix-*.mk (see posix.mk and posix1.mk)
# Override make flags for certain tests # Additional environment variables for some of the tests.
flags.doterror= # The base environment is -i PATH="$PATH".
flags.order=-j1 ENV.depsrc-optional+= TZ=UTC
ENV.envfirst= FROM_ENV=value-from-env
ENV.varmisc= FROM_ENV=env
ENV.varmisc+= FROM_ENV_BEFORE=env
ENV.varmisc+= FROM_ENV_AFTER=env
ENV.varmod-localtime+= TZ=Europe/Berlin
ENV.varname-vpath+= VPATH=varname-vpath.dir:varname-vpath.dir2
OUTFILES= ${TESTNAMES:S/$/.out/} # Override make flags for some of the tests; default is -k.
# If possible, write ".MAKEFLAGS: -dv" in the test .mk file instead of
# settings FLAGS.test=-dv here, since that is closer to the test code.
FLAGS.cond-func-make= via-cmdline
FLAGS.directive-ifmake= first second
FLAGS.doterror= # none, especially not -k
FLAGS.jobs-error-indirect= # none, especially not -k
FLAGS.jobs-error-nested= # none, especially not -k
FLAGS.jobs-error-nested-make= # none, especially not -k
FLAGS.varname-empty= -dv '$${:U}=cmdline-u' '=cmdline-plain'
# Some tests need extra postprocessing.
SED_CMDS.dir= ${:D remove output from -DCLEANUP mode }
SED_CMDS.dir+= -e '/^OpenDirs_Done:/d'
SED_CMDS.dir+= -e '/^CachedDir /d'
SED_CMDS.export= -e '/^[^=_A-Za-z0-9]*=/d'
SED_CMDS.export-all= ${SED_CMDS.export}
SED_CMDS.export-env= ${SED_CMDS.export}
SED_CMDS.job-output-long-lines= \
${:D Job separators on their own line are ok. } \
-e '/^--- job-[ab] ---$$/d' \
${:D Plain output lines are ok as well. } \
${:D They may come in multiples of 1024 or as 10000. } \
-e '/^aa*$$/d' \
-e '/^bb*$$/d' \
${:D The following lines should rather not occur since the job } \
${:D marker should always be at the beginning of the line. } \
-e '/^aa*--- job-b ---$$/d' \
-e '/^bb*--- job-a ---$$/d'
SED_CMDS.opt-debug-graph1= ${STD_SED_CMDS.dg1}
SED_CMDS.opt-debug-graph2= ${STD_SED_CMDS.dg2}
SED_CMDS.opt-debug-graph3= ${STD_SED_CMDS.dg3}
SED_CMDS.opt-debug-jobs= -e 's,([0-9][0-9]*),(<pid>),'
SED_CMDS.opt-debug-jobs+= -e 's,pid [0-9][0-9]*,pid <pid>,'
SED_CMDS.opt-debug-jobs+= -e 's,Process [0-9][0-9]*,Process <pid>,'
SED_CMDS.opt-debug-jobs+= -e 's,JobFinish: [0-9][0-9]*,JobFinish: <pid>,'
SED_CMDS.opt-debug-jobs+= -e 's,Command: ${.SHELL:T},Command: <shell>,'
# The "-q" may be there or not, see jobs.c, variable shells.
SED_CMDS.opt-debug-jobs+= -e 's,^\(.Command: <shell>\) -q,\1,'
SED_CMDS.opt-debug-lint+= ${STD_SED_CMDS.regex}
SED_CMDS.opt-jobs-no-action= ${STD_SED_CMDS.hide-from-output}
SED_CMDS.opt-no-action-runflags= ${STD_SED_CMDS.hide-from-output}
# For Compat_RunCommand, useShell == FALSE.
SED_CMDS.sh-dots= -e 's,^.*\.\.\.:.*,<not found: ...>,'
# For Compat_RunCommand, useShell == TRUE.
SED_CMDS.sh-dots+= -e 's,^make: exec(\(.*\)) failed (.*)$$,<not found: \1>,'
SED_CMDS.sh-dots+= -e 's,^\(\*\*\* Error code \)[1-9][0-9]*,\1<nonzero>,'
SED_CMDS.sh-errctl= ${STD_SED_CMDS.dj}
SED_CMDS.sh-flags= ${STD_SED_CMDS.hide-from-output}
SED_CMDS.suff-main+= ${STD_SED_CMDS.dg1}
SED_CMDS.suff-main-several+= ${STD_SED_CMDS.dg1}
SED_CMDS.suff-transform-debug+= ${STD_SED_CMDS.dg1}
SED_CMDS.var-op-shell+= ${STD_SED_CMDS.shell}
SED_CMDS.var-op-shell+= -e '/command/s,No such.*,not found,'
SED_CMDS.vardebug+= -e 's,${.SHELL},</path/to/shell>,'
SED_CMDS.varmod-subst-regex+= ${STD_SED_CMDS.regex}
SED_CMDS.varname-dot-parsedir= -e '/in some cases/ s,^make: "[^"]*,make: "<normalized>,'
SED_CMDS.varname-dot-parsefile= -e '/in some cases/ s,^make: "[^"]*,make: "<normalized>,'
SED_CMDS.varname-dot-shell= -e 's, = /[^ ]*, = (details omitted),g'
SED_CMDS.varname-dot-shell+= -e 's,"/[^" ]*","(details omitted)",g'
SED_CMDS.varname-dot-shell+= -e 's,\[/[^] ]*\],[(details omitted)],g'
SED_CMDS.varname-empty= -e 's,${.CURDIR},<curdir>,g'
SED_CMDS.varname-empty+= -e '/\.PARSEDIR/d'
SED_CMDS.varname-empty+= -e '/\.SHELL/d'
# Some tests need an additional round of postprocessing.
POSTPROC.deptgt-suffixes= awk '/^\#\*\*\* Suffixes/,/^never-stop/'
POSTPROC.gnode-submake= awk '/Input graph/, /^$$/'
# Some tests reuse other tests, which makes them unnecessarily fragile.
export-all.rawout: export.mk
unexport.rawout: export.mk
unexport-env.rawout: export.mk
# End of the configuration section.
# Some standard sed commands, to be used in the SED_CMDS above.
# Omit details such as process IDs from the output of the -dg1 option.
STD_SED_CMDS.dg1= -e 's,${.CURDIR}$$,<curdir>,'
STD_SED_CMDS.dg1+= -e 's, ${DEFSYSPATH:U/usr/share/mk}$$, <defsyspath>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.MAKE\.[A-Z_]* *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(MACHINE[_ARCH]* *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(MAKE *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg1+= -e 's,^\(\.SHELL *=\) .*,\1 <details omitted>,'
STD_SED_CMDS.dg2= ${STD_SED_CMDS.dg1}
STD_SED_CMDS.dg2+= -e 's,\(last modified\) ..:..:.. ... ..\, ....,\1 <timestamp>,'
STD_SED_CMDS.dg3= ${STD_SED_CMDS.dg2}
# Omit details such as process IDs from the output of the -dj option.
STD_SED_CMDS.dj= \
-e '/Process/d;/JobFinish:/d' \
-e 's,^\(Job_TokenWithdraw\)([0-9]*),\1(<pid>),' \
-e 's,^([0-9][0-9]*) \(withdrew token\),(<pid>) \1,' \
-e 's, \(pid\) [0-9][0-9]*, \1 <pid>,' \
-e 's,^\( Command:\) .*,\1 <shell>,'
# Reduce the noise for tests running with the -n option, since there is no
# other way to suppress the echoing of the commands.
STD_SED_CMDS.hide-from-output= \
-e '/^echo hide-from-output/d' \
-e 's,hide-from-output ,,' \
-e 's,hide-from-output,,'
# Normalize the output for error messages from the shell.
#
# $shell -c '...'
# NetBSD sh ...: not found
# NetBSD ksh ksh: ...: not found
# bash 5.0.18 bash: ...: command not found
# bash 5.1.0 bash: line 1: ...: command not found
# dash dash: 1: ...: not found
#
# $shell -c '< /nonexistent'
# NetBSD sh sh: cannot open /nonexistent: no such file
# NetBSD ksh ksh: cannot open /nonexistent: No such file or directory
# bash 5.0.18 bash: /nonexistent: No such file or directory
# bash 5.1.0 bash: line 1: /nonexistent: No such file or directory
# dash dash: 1: cannot open /nonexistent: No such file
#
# echo '< /nonexistent' | $shell
# NetBSD sh sh: cannot open /nonexistent: no such file
# NetBSD ksh ksh: <stdin>[1]: cannot open /nonexistent: No such file or directory
# bash 5.0.18 bash: line 1: /nonexistent: No such file or directory
# bash 5.1.0 bash: line 1: /nonexistent: No such file or directory
# dash dash: 1: cannot open /nonexistent: No such file
#
STD_SED_CMDS.shell+= -e 's,^${.SHELL:T}: line [0-9][0-9]*: ,,'
STD_SED_CMDS.shell+= -e 's,^${.SHELL:T}: [0-9][0-9]*: ,,'
STD_SED_CMDS.shell+= -e 's,^${.SHELL:T}: ,,'
# The actual error messages for a failed regcomp or regexec differ between the
# implementations.
STD_SED_CMDS.regex= \
-e 's,\(Regex compilation error:\).*,\1 (details omitted),'
# End of the configuration helpers section.
UNIT_TESTS:= ${.PARSEDIR}
.PATH: ${UNIT_TESTS}
.if ${USE_ABSOLUTE_TESTNAMES:Uno} == yes
OUTFILES= ${TESTS:@test@${.CURDIR:tA}/${test}.out@}
.else
OUTFILES= ${TESTS:=.out}
.endif
all: ${OUTFILES} all: ${OUTFILES}
CLEANFILES += *.rawout *.out *.status *.tmp *.core *.tmp CLEANFILES= *.rawout *.out *.status *.tmp *.core *.tmp
CLEANFILES += obj*.[och] lib*.a # posix1.mk CLEANFILES+= obj*.[och] lib*.a # posix1.mk
CLEANFILES += issue* .[ab]* # suffixes.mk CLEANFILES+= issue* .[ab]* # suffixes.mk
CLEANRECURSIVE += dir dummy # posix1.mk CLEANDIRS= dir dummy # posix1.mk
clean: clean:
rm -f ${CLEANFILES} rm -f ${CLEANFILES}
.if !empty(CLEANRECURSIVE) rm -rf ${CLEANDIRS}
rm -rf ${CLEANRECURSIVE}
.endif
TEST_MAKE?= ${.MAKE} TEST_MAKE?= ${.MAKE}
TOOL_SED?= sed TOOL_SED?= sed
# ensure consistent results from sort(1) # ensure consistent results from sort(1)
LC_ALL= C LC_ALL= C
LANG= C LANG= C
.export LANG LC_ALL .export LANG LC_ALL
# the tests are actually done with sub-makes.
# for many tests we need a TMPDIR that will not collide
# with other users.
.if ${.OBJDIR} != ${.CURDIR}
# easy
TMPDIR:= ${.OBJDIR}/tmp
.elif defined(TMPDIR)
TMPDIR:= ${TMPDIR}/uid${.MAKE.UID}
.else
TMPDIR:= /tmp/uid${.MAKE.UID}
.endif
# make sure it exists
.if !exist(${TMPDIR})
x!= echo; mkdir -p ${TMPDIR}
.endif
MAKE_TEST_ENV?= MALLOC_OPTIONS="JA" # for jemalloc
MAKE_TEST_ENV+= TMPDIR=${TMPDIR}
.if ${.MAKE.OS} == "NetBSD"
LIMIT_RESOURCES?= ulimit -v 200000
.endif
LIMIT_RESOURCES?= :
# Each test is run in a sub-make, to keep the tests for interfering with
# each other, and because they use different environment variables and
# command line options.
.SUFFIXES: .mk .rawout .out .SUFFIXES: .mk .rawout .out
.mk.rawout: .mk.rawout:
@echo ${TEST_MAKE} ${flags.${.TARGET:R}:U-k} -f ${.IMPSRC} @${_MKMSG_TEST:Uecho '# test '} ${.PREFIX}
-@cd ${.OBJDIR} && \ @set -eu; \
{ ${TEST_MAKE} ${flags.${.TARGET:R}:U-k} -f ${.IMPSRC} \ ${LIMIT_RESOURCES}; \
2>&1 ; echo $$? >${.TARGET:R}.status ; } > ${.TARGET}.tmp cd ${.OBJDIR}; \
env -i PATH="$$PATH" ${MAKE_TEST_ENV} ${ENV.${.PREFIX:T}} \
${TEST_MAKE} \
-r -C ${.CURDIR} -f ${.IMPSRC} \
${FLAGS.${.PREFIX:T}:U-k} \
> ${.TARGET}.tmp 2>&1 \
&& status=$$? || status=$$?; \
echo $$status > ${.TARGET:R}.status
@mv ${.TARGET}.tmp ${.TARGET} @mv ${.TARGET}.tmp ${.TARGET}
# We always pretend .MAKE was called 'make' # Postprocess the test output so that the results can be compared.
# and strip ${.CURDIR}/ from the output #
# and replace anything after 'stopped in' with unit-tests # always pretend .MAKE was called 'make'
# so the results can be compared. _SED_CMDS+= -e 's,^${TEST_MAKE:T:S,.,\\.,g}[][0-9]*:,make:,'
_SED_CMDS+= -e 's,${TEST_MAKE:S,.,\\.,g},make,'
_SED_CMDS+= -e 's,${TEST_MAKE:T:S,.,\\.,g}[][0-9]* warning,make warning,'
_SED_CMDS+= -e 's,^usage: ${TEST_MAKE:T:S,.,\\.,g} ,usage: make ,'
# replace anything after 'stopped in' with unit-tests
_SED_CMDS+= -e '/stopped/s, /.*, unit-tests,'
_SED_CMDS+= -e 's,${TMPDIR},TMPDIR,g'
# strip ${.CURDIR}/ from the output
_SED_CMDS+= -e 's,${.CURDIR:S,.,\\.,g}/,,g'
_SED_CMDS+= -e 's,${UNIT_TESTS:S,.,\\.,g}/,,g'
.rawout.out: .rawout.out:
@echo postprocess ${.TARGET} @${TOOL_SED} ${_SED_CMDS} ${SED_CMDS.${.PREFIX:T}} \
@${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}[][0-9]*:,make:,' \ < ${.IMPSRC} > ${.TARGET}.tmp1
-e 's,${TEST_MAKE:C/\./\\\./g},make,' \ @${POSTPROC.${.PREFIX:T}:Ucat} < ${.TARGET}.tmp1 > ${.TARGET}.tmp2
-e '/stopped/s, /.*, unit-tests,' \ @rm ${.TARGET}.tmp1
-e 's,${.CURDIR:C/\./\\\./g}/,,g' \ @echo "exit status `cat ${.TARGET:R}.status`" >> ${.TARGET}.tmp2
-e 's,${UNIT_TESTS:C/\./\\\./g}/,,g' \ @mv ${.TARGET}.tmp2 ${.TARGET}
< ${.IMPSRC} > ${.TARGET}.tmp
@echo "exit status `cat ${.TARGET:R}.status`" >> ${.TARGET}.tmp
@mv ${.TARGET}.tmp ${.TARGET}
# Compare all output files # Compare all output files
test: ${OUTFILES} .PHONY test: ${OUTFILES} .PHONY
@failed= ; \ @failed= ; \
for test in ${TESTNAMES}; do \ for test in ${TESTS}; do \
diff -u ${UNIT_TESTS}/$${test}.exp $${test}.out \ diff -u ${UNIT_TESTS}/$${test}.exp $${test}.out \
|| failed="$${failed}$${failed:+ }$${test}" ; \ || failed="$${failed}$${failed:+ }$${test}" ; \
done ; \ done ; \
@ -125,14 +701,34 @@ test: ${OUTFILES} .PHONY
fi fi
accept: accept:
@for test in ${TESTNAMES}; do \ @for test in ${TESTS}; do \
cmp -s ${UNIT_TESTS}/$${test}.exp $${test}.out \ cmp -s ${UNIT_TESTS}/$${test}.exp $${test}.out \
|| { echo "Replacing $${test}.exp" ; \ || { echo "Replacing $${test}.exp" ; \
cp $${test}.out ${UNIT_TESTS}/$${test}.exp ; } \ cp $${test}.out ${UNIT_TESTS}/$${test}.exp ; } \
done done
# Note: only works for adding tests.
# To remove a test, the $$mi file must be edited manually.
sync-mi:
@set -eu; \
cd "${MAKEFILE:tA:H}/../../.."; \
mi="distrib/sets/lists/tests/mi"; \
cvs update "$$mi"; \
testsdir="usr.bin/make/unit-tests"; \
fmt="./usr/tests/$$testsdir/%s\ttests-usr.bin-tests\tcompattestfile,atf\\n"; \
cat "$$mi" > "$$mi.tmp"; \
(cd "$$testsdir" && ls *.exp *.mk) | xargs printf "$$fmt" >> "$$mi.tmp"; \
distrib/sets/fmt-list "$$mi.tmp"; \
mv "$$mi.tmp" "$$mi"; \
cvs diff "$$mi" || true
.if exists(${TEST_MAKE}) .if exists(${TEST_MAKE})
${TESTNAMES:S/$/.rawout/}: ${TEST_MAKE} ${TESTS:=.rawout}: ${TEST_MAKE}
# in meta mode, we *know* if a target script is impacted
# by a makefile change.
.if ${.MAKE.MODE:Unormal:Mmeta} == ""
${TESTS:=.rawout}: ${.PARSEDIR}/Makefile
.endif
.endif .endif
.-include <bsd.obj.mk> .-include <bsd.obj.mk>

View File

@ -0,0 +1,2 @@
`all' is up to date.
exit status 0

View File

@ -0,0 +1,23 @@
# $NetBSD: archive-suffix.mk,v 1.3 2020/11/15 14:07:53 rillig Exp $
#
# Between 2020-08-23 and 2020-08-30, the below code produced an assertion
# failure in Var_SetWithFlags, triggered by Compat_Make, when setting the
# .IMPSRC of an archive node to its .TARGET.
#
# The code assumed that the .TARGET variable of every node would be set, but
# that is not guaranteed.
#
# Between 2016-03-15 and 2016-03-16 the behavior of the below code changed.
# Until 2016-03-15, it remade the target, starting with 2016-03-16 it says
# "`all' is up to date".
.SUFFIXES:
.SUFFIXES: .c .o
all: lib.a(obj1.o)
.c.o:
: making $@
obj1.c:
: $@

View File

@ -0,0 +1,28 @@
Making remove-archive
rm -f libprog.a
Making libprog.a out-of-date archive.mk modmisc.mk varmisc.mk
ar cru libprog.a archive.mk modmisc.mk varmisc.mk
ranlib libprog.a
Making create-archive out-of-date libprog.a
Making list-archive out-of-date libprog.a
ar t libprog.a
archive.mk
modmisc.mk
varmisc.mk
Making list-archive-wildcard out-of-date archive-suffix.mk archive.mk ternary.mk
list-archive-wildcard: archive-suffix.mk
list-archive-wildcard: archive.mk
list-archive-wildcard: ternary.mk
Making depend-on-existing-member out-of-date archive.mk
depend-on-existing-member
`depend-on-nonexistent-member' is up to date.
Making remove-archive
rm -f libprog.a
exit status 0

View File

@ -0,0 +1,60 @@
# $NetBSD: archive.mk,v 1.11 2020/11/15 14:07:53 rillig Exp $
#
# Very basic demonstration of handling archives, based on the description
# in PSD.doc/tutorial.ms.
#
# This test aims at covering the code, not at being an introduction to
# archive handling. That's why it deviates from the tutorial style of
# several other tests.
ARCHIVE= libprog.a
FILES= archive.mk modmisc.mk varmisc.mk
all:
.if ${.PARSEDIR:tA} != ${.CURDIR:tA}
@cd ${MAKEFILE:H} && cp ${FILES} [at]*.mk ${.CURDIR}
.endif
# The following targets create and remove files. The filesystem cache in
# dir.c would probably not handle this correctly, therefore each of the
# targets is run in its separate sub-make.
@${MAKE} -f ${MAKEFILE} remove-archive
@${MAKE} -f ${MAKEFILE} create-archive
@${MAKE} -f ${MAKEFILE} list-archive
@${MAKE} -f ${MAKEFILE} list-archive-wildcard
@${MAKE} -f ${MAKEFILE} depend-on-existing-member
@${MAKE} -f ${MAKEFILE} depend-on-nonexistent-member
@${MAKE} -f ${MAKEFILE} remove-archive
create-archive: ${ARCHIVE} pre post
# The indirect references with the $$ cover the code in Arch_ParseArchive
# that calls Var_Parse. It's an esoteric scenario since at the point where
# Arch_ParseArchive is called, the dependency line is already fully expanded.
#
${ARCHIVE}: $${:Ulibprog.a}(archive.mk modmisc.mk $${:Uvarmisc.mk}) pre post
ar cru ${.TARGET} ${.OODATE:O}
ranlib ${.TARGET}
list-archive: ${ARCHIVE} pre post
ar t ${.ALLSRC}
# XXX: I had expected that this dependency would select all *.mk files from
# the archive. Instead, the globbing is done in the current directory.
#
# To prevent an overly long file list, the pattern is restricted to [at]*.mk.
list-archive-wildcard: ${ARCHIVE}([at]*.mk) pre post
@printf '%s\n' ${.ALLSRC:O:@member@${.TARGET:Q}': '${member:Q}@}
depend-on-existing-member: ${ARCHIVE}(archive.mk) pre post
@echo $@
depend-on-nonexistent-member: ${ARCHIVE}(nonexistent.mk) pre post
@echo $@
remove-archive: pre post
rm -f ${ARCHIVE}
pre: .USEBEFORE
@echo Making ${.TARGET} ${.OODATE:C,.+,out-of-date,W} ${.OODATE:O}
post: .USE
@echo

View File

@ -0,0 +1,9 @@
: undefined eol
make: Unclosed variable "UNCLOSED"
: unclosed-variable
make: Unclosed variable expression (expecting '}') for "UNCLOSED"
: unclosed-modifier
make: Unknown modifier "Z"
: unknown-modifier eol
: end eol
exit status 0

View File

@ -0,0 +1,32 @@
# $NetBSD: cmd-errors-jobs.mk,v 1.1 2020/12/27 05:11:40 rillig Exp $
#
# Demonstrate how errors in variable expansions affect whether the commands
# are actually executed in jobs mode.
.MAKEFLAGS: -j1
all: undefined unclosed-variable unclosed-modifier unknown-modifier end
# Undefined variables are not an error. They expand to empty strings.
undefined:
: $@ ${UNDEFINED} eol
# XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors.
unclosed-variable:
: $@ ${UNCLOSED
# XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors.
unclosed-modifier:
: $@ ${UNCLOSED:
# XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors.
unknown-modifier:
: $@ ${UNKNOWN:Z} eol
end:
: $@ eol
# XXX: As of 2020-11-02, despite the parse errors, the exit status is 0.

View File

@ -0,0 +1,9 @@
: undefined
make: Unclosed variable "UNCLOSED"
: unclosed-variable
make: Unclosed variable expression (expecting '}') for "UNCLOSED"
: unclosed-modifier
make: Unknown modifier "Z"
: unknown-modifier
: end
exit status 2

View File

@ -0,0 +1,32 @@
# $NetBSD: cmd-errors-lint.mk,v 1.1 2020/11/02 20:43:27 rillig Exp $
#
# Demonstrate how errors in variable expansions affect whether the commands
# are actually executed.
.MAKEFLAGS: -dL
all: undefined unclosed-variable unclosed-modifier unknown-modifier end
# Undefined variables are not an error. They expand to empty strings.
undefined:
: $@ ${UNDEFINED}
# XXX: As of 2020-11-01, this obvious syntax error is not detected.
# XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors.
unclosed-variable:
: $@ ${UNCLOSED
# XXX: As of 2020-11-01, this obvious syntax error is not detected.
# XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors.
unclosed-modifier:
: $@ ${UNCLOSED:
# XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors.
unknown-modifier:
: $@ ${UNKNOWN:Z}
end:
: $@

View File

@ -0,0 +1,9 @@
: undefined eol
make: Unclosed variable "UNCLOSED"
: unclosed-variable
make: Unclosed variable expression (expecting '}') for "UNCLOSED"
: unclosed-modifier
make: Unknown modifier "Z"
: unknown-modifier eol
: end eol
exit status 0

View File

@ -0,0 +1,30 @@
# $NetBSD: cmd-errors.mk,v 1.4 2020/12/27 05:11:40 rillig Exp $
#
# Demonstrate how errors in variable expansions affect whether the commands
# are actually executed in compat mode.
all: undefined unclosed-variable unclosed-modifier unknown-modifier end
# Undefined variables are not an error. They expand to empty strings.
undefined:
: $@ ${UNDEFINED} eol
# XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors.
unclosed-variable:
: $@ ${UNCLOSED
# XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors.
unclosed-modifier:
: $@ ${UNCLOSED:
# XXX: As of 2020-11-01, this command is executed even though it contains
# parse errors.
unknown-modifier:
: $@ ${UNKNOWN:Z} eol
end:
: $@ eol
# XXX: As of 2020-11-02, despite the parse errors, the exit status is 0.

View File

@ -0,0 +1,9 @@
> cmd-interrupt-ordinary
make: *** cmd-interrupt-ordinary removed
interrupt-ordinary: ok
> cmd-interrupt-phony
make: *** cmd-interrupt-phony removed
interrupt-phony: ok
> cmd-interrupt-precious
interrupt-precious: ok
exit status 0

View File

@ -0,0 +1,50 @@
# $NetBSD: cmd-interrupt.mk,v 1.3 2020/11/15 14:07:53 rillig Exp $
#
# Tests for interrupting a command.
#
# If a command is interrupted (usually by the user, here by itself), the
# target is removed. This is to avoid having an unfinished target that
# would be newer than all of its sources and would therefore not be
# tried again in the next run.
#
# This happens for ordinary targets as well as for .PHONY targets, even
# though the .PHONY targets usually do not correspond to a file.
#
# To protect the target from being removed, the target has to be marked with
# the special source .PRECIOUS. These targets need to ensure for themselves
# that interrupting them does not leave an inconsistent state behind.
#
# See also:
# CompatDeleteTarget
all: clean-before interrupt-ordinary interrupt-phony interrupt-precious clean-after
clean-before clean-after: .PHONY
@rm -f cmd-interrupt-ordinary cmd-interrupt-phony cmd-interrupt-precious
interrupt-ordinary:
@${.MAKE} ${MAKEFLAGS} -f ${MAKEFILE} cmd-interrupt-ordinary || true
# The ././ is necessary to work around the file cache.
@echo ${.TARGET}: ${exists(././cmd-interrupt-ordinary) :? error : ok }
interrupt-phony: .PHONY
@${.MAKE} ${MAKEFLAGS} -f ${MAKEFILE} cmd-interrupt-phony || true
# The ././ is necessary to work around the file cache.
@echo ${.TARGET}: ${exists(././cmd-interrupt-phony) :? error : ok }
interrupt-precious: .PRECIOUS
@${.MAKE} ${MAKEFLAGS} -f ${MAKEFILE} cmd-interrupt-precious || true
# The ././ is necessary to work around the file cache.
@echo ${.TARGET}: ${exists(././cmd-interrupt-precious) :? ok : error }
cmd-interrupt-ordinary:
> ${.TARGET}
@kill -INT ${.MAKE.PID}
cmd-interrupt-phony: .PHONY
> ${.TARGET}
@kill -INT ${.MAKE.PID}
cmd-interrupt-precious: .PRECIOUS
> ${.TARGET}
@kill -INT ${.MAKE.PID}

View File

@ -0,0 +1,34 @@
# $NetBSD: cmdline-redirect-stdin.mk,v 1.1 2021/02/01 20:31:41 rillig Exp $
#
# Demonstrate that the '!=' assignment operator can read individual lines
# from make's stdin.
#
# This edge case is an implementation detail that has no practical
# application.
all: .PHONY
@printf '%s\n' "first line" "second line" \
| ${MAKE} -f ${MAKEFILE} read-lines
.if make(read-lines)
line1!= read line; echo "$$line"
line2!= read line; echo "$$line"
.if ${line1} != "first line"
. error line1="${line1}"
.elif ${line2} == ""
# If this branch is ever reached, the shell from the assignment to line1
# probably buffers its input. Most shells use unbuffered stdin, and this
# is actually specified by POSIX, which says that "The read utility shall
# read a single line from standard input". This is the reason why the shell
# reads its input byte by byte, which makes it terribly slow for practical
# applications.
. error The shell's read command does not read a single line.
.elif ${line2} != "second line"
. error line2="${line2}"
.endif
read-lines: .PHONY
.endif

View File

@ -0,0 +1,17 @@
The = assignment operator
make: "cmdline-undefined.mk" line 29: From the command line: Undefined is .
make: "cmdline-undefined.mk" line 30: From .MAKEFLAGS '=': Undefined is .
make: "cmdline-undefined.mk" line 31: From .MAKEFLAGS ':=': Undefined is .
make: "cmdline-undefined.mk" line 35: From the command line: Undefined is now defined.
make: "cmdline-undefined.mk" line 36: From .MAKEFLAGS '=': Undefined is now defined.
make: "cmdline-undefined.mk" line 37: From .MAKEFLAGS ':=': Undefined is now defined.
The := assignment operator
make: "cmdline-undefined.mk" line 29: From the command line: Undefined is .
make: "cmdline-undefined.mk" line 30: From .MAKEFLAGS '=': Undefined is .
make: "cmdline-undefined.mk" line 31: From .MAKEFLAGS ':=': Undefined is .
make: "cmdline-undefined.mk" line 35: From the command line: Undefined is now defined.
make: "cmdline-undefined.mk" line 36: From .MAKEFLAGS '=': Undefined is now defined.
make: "cmdline-undefined.mk" line 37: From .MAKEFLAGS ':=': Undefined is now defined.
exit status 0

View File

@ -0,0 +1,40 @@
# $NetBSD: cmdline-undefined.mk,v 1.2 2020/11/04 04:49:33 rillig Exp $
#
# Tests for undefined variable expressions in the command line.
all:
# When the command line is parsed, variable assignments using the
# '=' assignment operator do get their variable name expanded
# (which probably occurs rarely in practice, if at all), but their
# variable value is not expanded, as usual.
#
@echo 'The = assignment operator'
@${.MAKE} -f ${MAKEFILE} print-undefined \
CMDLINE='Undefined is $${UNDEFINED}.'
@echo
# The interesting case is using the ':=' assignment operator, which
# expands its right-hand side. But only those variables that are
# defined.
@echo 'The := assignment operator'
@${.MAKE} -f ${MAKEFILE} print-undefined \
CMDLINE:='Undefined is $${UNDEFINED}.'
@echo
.if make(print-undefined)
.MAKEFLAGS: MAKEFLAGS_ASSIGN='Undefined is $${UNDEFINED}.'
.MAKEFLAGS: MAKEFLAGS_SUBST:='Undefined is $${UNDEFINED}.'
.info From the command line: ${CMDLINE}
.info From .MAKEFLAGS '=': ${MAKEFLAGS_ASSIGN}
.info From .MAKEFLAGS ':=': ${MAKEFLAGS_SUBST}
UNDEFINED?= now defined
.info From the command line: ${CMDLINE}
.info From .MAKEFLAGS '=': ${MAKEFLAGS_ASSIGN}
.info From .MAKEFLAGS ':=': ${MAKEFLAGS_SUBST}
print-undefined:
.endif

View File

@ -0,0 +1,5 @@
makeobjdir-direct:
show-objdir: TMPDIR/6a8899d2-d227-4b55-9b6b-f3c8eeb83fd5
makeobjdir-indirect:
show-objdir: TMPDIR/a7b41170-53f8-4cc2-bc5c-e4c3dd93ec45/
exit status 0

View File

@ -0,0 +1,36 @@
# $NetBSD: cmdline.mk,v 1.3 2021/02/06 18:26:03 sjg Exp $
#
# Tests for command line parsing and related special variables.
TMPBASE?= ${TMPDIR:U/tmp/uid${.MAKE.UID}}
SUB1= a7b41170-53f8-4cc2-bc5c-e4c3dd93ec45 # just a random UUID
SUB2= 6a8899d2-d227-4b55-9b6b-f3c8eeb83fd5 # just a random UUID
MAKE_CMD= env TMPBASE=${TMPBASE}/${SUB1} ${.MAKE} -f ${MAKEFILE} -r
DIR2= ${TMPBASE}/${SUB2}
DIR12= ${TMPBASE}/${SUB1}/${SUB2}
all: prepare-dirs
all: makeobjdir-direct makeobjdir-indirect
prepare-dirs:
@rm -rf ${DIR2} ${DIR12}
@mkdir -p ${DIR2} ${DIR12}
# The .OBJDIR can be set via the MAKEOBJDIR command line variable.
# It must be a command line variable; an environment variable would not work.
makeobjdir-direct:
@echo $@:
@${MAKE_CMD} MAKEOBJDIR=${DIR2} show-objdir
# The .OBJDIR can be set via the MAKEOBJDIR command line variable,
# and that variable could even contain the usual modifiers.
# Since the .OBJDIR=MAKEOBJDIR assignment happens very early,
# the SUB2 variable in the modifier is not defined yet and is therefore empty.
# The SUB1 in the resulting path comes from the environment variable TMPBASE,
# see MAKE_CMD.
makeobjdir-indirect:
@echo $@:
@${MAKE_CMD} MAKEOBJDIR='$${TMPBASE}/$${SUB2}' show-objdir
show-objdir:
@echo $@: ${.OBJDIR:Q}

View File

@ -1,5 +1,6 @@
comment testing start echo This is a shell comment: # comment
this is foo This is a shell comment:
This is how a comment looks: # comment echo This is not a shell comment: '# comment'
comment testing done This is not a shell comment: # comment
A shell comment can#not start in the middle of a word.
exit status 0 exit status 0

View File

@ -1,31 +1,78 @@
# This is a comment # $NetBSD: comment.mk,v 1.3 2020/11/15 14:07:53 rillig Exp $
.if ${MACHINE_ARCH} == something #
FOO=bar # Demonstrate how comments are written in makefiles.
.endif
# This is a comment.
#\ #\
Multiline comment This is a multiline comment.
BAR=# defined # Another multiline comment \
FOOBAR= # defined
# This is an escaped comment \
that keeps going until the end of this line
# Another escaped comment \
that \ that \
goes \ goes \
on on and on.
# This is NOT an escaped comment due to the double backslashes \\ # Comments can be indented with spaces, but that is rather unusual.
all: hi foo bar
@echo comment testing done
hi: # Comments can be indented with a tab.
@echo comment testing start # These are not shell commands, they are just makefile comments.
foo: .if 1 # There can be comments after conditions.
@echo this is $@ .endif # And after the closing directive.
bar: VAR= # This comment makes the variable value empty.
@echo This is how a comment looks: '# comment' # ParseGetLine removes any whitespace before the
# comment.
.if ${VAR} != ""
. error
.endif
# The comment does not need to start at the beginning of a word (as in the
# shell), it can start anywhere.
VAR=# defined but empty
# The space before the comment is always trimmed.
VAR= value
.if ${VAR} != "value"
. error
.endif
# This comment ends with 2 backslashes. An even number of backslashes does
# not count as a line continuation, therefore the variable assignment that
# follows is actively interpreted. \\
VAR= not part of the comment
.if ${VAR} != "not part of the comment"
. error
.endif
# To escape a comment sign, precede it with a backslash.
VAR= \# # Both in the assignment.
.if ${VAR} != "\#" # And in the comparison.
. error
.endif
# Since 2012-03-24 the variable modifier :[#] does not need to be escaped.
# To keep the parsing code simple, any "[#" does not start a comment, even
# outside of a variable expression.
WORDS= ${VAR:[#]} [#
.if ${WORDS} != "1 [#"
. error
.endif
# An odd number of backslashes makes a line continuation, \\\
no matter if it is 3 or 5 \\\\\
or 9 backslashes. \\\\\\\\\
This is the last line of the comment.
VAR= no comment anymore
.if ${VAR} != "no comment anymore"
. error
.endif
all:
# In the commands associated with a target, the '#' does not start a makefile
# comment. The '#' is just passed to the shell, like any ordinary character.
echo This is a shell comment: # comment
# If the '#' were to start a makefile comment, the following shell command
# would have unbalanced quotes.
echo This is not a shell comment: '# comment'
@echo A shell comment can#not start in the middle of a word.

View File

@ -0,0 +1,15 @@
: Making success1 out of nothing.
: Making fail1 out of nothing.
false 'fail1' '${.TARGET}' '$${.TARGET}'
*** Error code 1 (continuing)
: Making success2 out of nothing.
: Making fail2 out of nothing.
false 'fail2' '${.TARGET}' '$${.TARGET}'
*** Error code 1 (continuing)
: Making success3 out of nothing.
Stop.
make: stopped in unit-tests
.ERROR target: <fail1>
.ERROR command: <>
exit status 1

View File

@ -0,0 +1,37 @@
# $NetBSD: compat-error.mk,v 1.3 2020/12/13 19:33:53 rillig Exp $
#
# Test detailed error handling in compat mode.
#
# Until 2020-12-13, .ERROR_TARGET was success3, which was wrong.
# Since compat.c 1.215 from 2020-12-13, it is 'fail1', which is the first
# failed top-level target. XXX: Even better would be if .ERROR_TARGET were
# the smallest target that caused the build to fail, even if it were a
# sub-sub-sub-dependency of a top-level target.
#
# XXX: As of 2020-12-13, .ERROR_CMD is empty, which is wrong.
#
# See also:
# Compat_Run
#
# The commit that added the NULL command to gn->commands:
# CVS: 1994.06.06.22.45.??
# Git: 26a8972fd7f982502c5fbfdabd34578b99d77ca5
# 1994: Lst_Replace (cmdNode, (ClientData) NULL);
# 2020: LstNode_SetNull(cmdNode);
#
# The commit that skipped NULL commands for .ERROR_CMD:
# CVS: 2016.08.11.19.53.??
# Git: 58b23478b7353d46457089e726b07a49197388e4
.MAKEFLAGS: success1 fail1 success2 fail2 success3
success1 success2 success3:
: Making ${.TARGET} out of nothing.
fail1 fail2:
: Making ${.TARGET} out of nothing.
false '${.TARGET}' '$${.TARGET}' '$$$${.TARGET}'
.ERROR:
@echo ${.TARGET} target: '<'${.ERROR_TARGET:Q}'>'
@echo ${.TARGET} command: '<'${.ERROR_CMD:Q}'>'

Some files were not shown because too many files have changed in this diff Show More