aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog240
-rw-r--r--FILES527
-rw-r--r--LICENSE1
-rw-r--r--Makefile42
-rw-r--r--VERSION2
-rw-r--r--arch.c505
-rw-r--r--bmake.1134
-rw-r--r--bmake.cat1136
-rw-r--r--bsd.after-import.mk21
-rw-r--r--buf.c216
-rw-r--r--buf.h62
-rw-r--r--compat.c136
-rw-r--r--cond.c621
-rw-r--r--dir.c1160
-rw-r--r--dir.h28
-rwxr-xr-xenum.c100
-rwxr-xr-xenum.h193
-rw-r--r--for.c157
-rw-r--r--hash.c277
-rw-r--r--hash.h81
-rw-r--r--job.c134
-rw-r--r--job.h17
-rw-r--r--lst.c641
-rw-r--r--lst.h194
-rw-r--r--lst.lib/Makefile0
-rw-r--r--lst.lib/lstAppend.c121
-rw-r--r--lst.lib/lstAtEnd.c79
-rw-r--r--lst.lib/lstAtFront.c76
-rw-r--r--lst.lib/lstClose.c85
-rw-r--r--lst.lib/lstConcat.c184
-rw-r--r--lst.lib/lstDatum.c76
-rw-r--r--lst.lib/lstDeQueue.c86
-rw-r--r--lst.lib/lstDestroy.c101
-rw-r--r--lst.lib/lstDupl.c107
-rw-r--r--lst.lib/lstEnQueue.c77
-rw-r--r--lst.lib/lstFind.c73
-rw-r--r--lst.lib/lstFindFrom.c89
-rw-r--r--lst.lib/lstFirst.c76
-rw-r--r--lst.lib/lstForEach.c75
-rw-r--r--lst.lib/lstForEachFrom.c124
-rw-r--r--lst.lib/lstInit.c85
-rw-r--r--lst.lib/lstInsert.c121
-rw-r--r--lst.lib/lstInt.h105
-rw-r--r--lst.lib/lstIsAtEnd.c86
-rw-r--r--lst.lib/lstIsEmpty.c74
-rw-r--r--lst.lib/lstLast.c76
-rw-r--r--lst.lib/lstMember.c77
-rw-r--r--lst.lib/lstNext.c119
-rw-r--r--lst.lib/lstOpen.c86
-rw-r--r--lst.lib/lstPrev.c78
-rw-r--r--lst.lib/lstRemove.c134
-rw-r--r--lst.lib/lstReplace.c77
-rw-r--r--lst.lib/lstSucc.c78
-rw-r--r--main.c376
-rw-r--r--make-conf.h10
-rw-r--r--make.1134
-rw-r--r--make.c452
-rw-r--r--make.h413
-rw-r--r--make_malloc.c50
-rw-r--r--make_malloc.h19
-rw-r--r--meta.c151
-rw-r--r--metachar.c36
-rw-r--r--metachar.h21
-rw-r--r--mk/ChangeLog301
-rw-r--r--mk/FILES1
-rw-r--r--mk/README8
-rw-r--r--mk/auto.dep.mk14
-rw-r--r--mk/auto.obj.mk12
-rw-r--r--mk/autoconf.mk10
-rw-r--r--mk/autodep.mk16
-rw-r--r--mk/compiler.mk8
-rw-r--r--mk/cython.mk8
-rw-r--r--mk/dirdeps-cache-update.mk179
-rw-r--r--mk/dirdeps-options.mk39
-rw-r--r--mk/dirdeps-targets.mk47
-rw-r--r--mk/dirdeps.mk132
-rw-r--r--mk/dpadd.mk30
-rw-r--r--mk/files.mk8
-rw-r--r--mk/gendirdeps.mk42
-rw-r--r--mk/host-target.mk4
-rw-r--r--mk/host.libnames.mk8
-rw-r--r--mk/inc.mk8
-rw-r--r--mk/init.mk14
-rw-r--r--mk/install-mk14
-rw-r--r--mk/install-new.mk8
-rw-r--r--mk/java.mk10
-rw-r--r--mk/lib.mk14
-rw-r--r--mk/libnames.mk8
-rw-r--r--mk/libs.mk20
-rw-r--r--mk/links.mk8
-rw-r--r--mk/manifest.mk16
-rw-r--r--mk/meta.autodep.mk10
-rw-r--r--mk/meta.stage.mk8
-rw-r--r--mk/meta.subdir.mk10
-rw-r--r--mk/meta.sys.mk14
-rwxr-xr-xmk/meta2deps.py48
-rwxr-xr-xmk/meta2deps.sh30
-rw-r--r--mk/mk-files.txt51
-rwxr-xr-xmk/mkopt.sh8
-rw-r--r--mk/obj.mk8
-rw-r--r--mk/options.mk12
-rw-r--r--mk/own.mk8
-rw-r--r--mk/prlist.mk8
-rw-r--r--mk/prog.mk4
-rw-r--r--mk/progs.mk17
-rw-r--r--mk/rst2htm.mk8
-rw-r--r--mk/scripts.mk8
-rw-r--r--mk/srctop.mk10
-rwxr-xr-xmk/stage-install.sh61
-rw-r--r--mk/sys.clean-env.mk10
-rw-r--r--mk/sys.debug.mk8
-rw-r--r--mk/sys.dependfile.mk8
-rw-r--r--mk/sys.mk11
-rw-r--r--mk/sys.vars.mk10
-rw-r--r--mk/sys/AIX.mk8
-rw-r--r--mk/sys/Darwin.mk4
-rw-r--r--mk/sys/Generic.mk8
-rw-r--r--mk/sys/HP-UX.mk10
-rw-r--r--mk/sys/IRIX.mk4
-rw-r--r--mk/sys/Linux.mk6
-rw-r--r--mk/sys/NetBSD.mk4
-rw-r--r--mk/sys/OSF1.mk6
-rw-r--r--mk/sys/OpenBSD.mk6
-rw-r--r--mk/sys/SunOS.mk4
-rw-r--r--mk/sys/UnixWare.mk4
-rw-r--r--mk/target-flags.mk12
-rw-r--r--mk/warnings.mk20
-rw-r--r--mk/whats.mk10
-rw-r--r--mk/yacc.mk8
-rw-r--r--nonints.h69
-rwxr-xr-xos.sh9
-rw-r--r--parse.c346
-rw-r--r--sprite.h116
-rw-r--r--str.c241
-rw-r--r--strlist.c20
-rw-r--r--strlist.h8
-rw-r--r--suff.c1235
-rw-r--r--targ.c444
-rw-r--r--trace.c12
-rw-r--r--unit-tests/Makefile358
-rwxr-xr-xunit-tests/archive-suffix.exp2
-rwxr-xr-xunit-tests/archive-suffix.mk23
-rw-r--r--unit-tests/archive.exp13
-rw-r--r--unit-tests/archive.mk45
-rwxr-xr-xunit-tests/cmd-interrupt.exp9
-rwxr-xr-xunit-tests/cmd-interrupt.mk50
-rw-r--r--unit-tests/cmdline.exp5
-rw-r--r--unit-tests/cmdline.mk37
-rw-r--r--unit-tests/cond-cmp-numeric-eq.exp1
-rwxr-xr-xunit-tests/cond-cmp-numeric-eq.mk53
-rw-r--r--unit-tests/cond-cmp-numeric-ge.exp1
-rwxr-xr-xunit-tests/cond-cmp-numeric-ge.mk75
-rw-r--r--unit-tests/cond-cmp-numeric-gt.exp1
-rwxr-xr-xunit-tests/cond-cmp-numeric-gt.mk73
-rw-r--r--unit-tests/cond-cmp-numeric-le.exp1
-rwxr-xr-xunit-tests/cond-cmp-numeric-le.mk75
-rw-r--r--unit-tests/cond-cmp-numeric-lt.exp1
-rwxr-xr-xunit-tests/cond-cmp-numeric-lt.mk73
-rw-r--r--unit-tests/cond-cmp-numeric-ne.exp1
-rwxr-xr-xunit-tests/cond-cmp-numeric-ne.mk49
-rw-r--r--unit-tests/cond-cmp-numeric.exp1
-rw-r--r--unit-tests/cond-cmp-numeric.mk8
-rw-r--r--unit-tests/cond-cmp-string.exp5
-rw-r--r--unit-tests/cond-cmp-string.mk39
-rw-r--r--unit-tests/cond-func-commands.exp1
-rw-r--r--unit-tests/cond-func-commands.mk36
-rw-r--r--unit-tests/cond-func-defined.exp5
-rw-r--r--unit-tests/cond-func-defined.mk33
-rw-r--r--unit-tests/cond-func-empty.exp1
-rw-r--r--unit-tests/cond-func-empty.mk8
-rw-r--r--unit-tests/cond-func-exists.exp1
-rw-r--r--unit-tests/cond-func-exists.mk42
-rw-r--r--unit-tests/cond-func-make.exp1
-rw-r--r--unit-tests/cond-func-make.mk8
-rw-r--r--unit-tests/cond-func-target.exp1
-rw-r--r--unit-tests/cond-func-target.mk38
-rw-r--r--unit-tests/cond-func.exp9
-rw-r--r--unit-tests/cond-func.mk63
-rw-r--r--unit-tests/cond-late.exp1
-rw-r--r--unit-tests/cond-late.mk10
-rw-r--r--unit-tests/cond-op-and.exp1
-rw-r--r--unit-tests/cond-op-and.mk27
-rw-r--r--unit-tests/cond-op-not.exp1
-rw-r--r--unit-tests/cond-op-not.mk22
-rw-r--r--unit-tests/cond-op-or.exp1
-rw-r--r--unit-tests/cond-op-or.mk27
-rw-r--r--unit-tests/cond-op-parentheses.exp1
-rw-r--r--unit-tests/cond-op-parentheses.mk8
-rw-r--r--unit-tests/cond-op.exp5
-rw-r--r--unit-tests/cond-op.mk60
-rw-r--r--unit-tests/cond-short.mk20
-rw-r--r--unit-tests/cond-token-number.exp1
-rw-r--r--unit-tests/cond-token-number.mk8
-rw-r--r--unit-tests/cond-token-plain.exp1
-rw-r--r--unit-tests/cond-token-plain.mk9
-rw-r--r--unit-tests/cond-token-string.exp1
-rw-r--r--unit-tests/cond-token-string.mk8
-rw-r--r--unit-tests/cond-token-var.exp7
-rw-r--r--unit-tests/cond-token-var.mk34
-rw-r--r--unit-tests/counter.exp88
-rw-r--r--unit-tests/counter.mk31
-rw-r--r--unit-tests/dep-colon.exp1
-rw-r--r--unit-tests/dep-colon.mk8
-rw-r--r--unit-tests/dep-double-colon.exp5
-rw-r--r--unit-tests/dep-double-colon.mk11
-rw-r--r--unit-tests/dep-exclam.exp1
-rw-r--r--unit-tests/dep-exclam.mk8
-rwxr-xr-xunit-tests/dep-none.exp4
-rwxr-xr-xunit-tests/dep-none.mk3
-rwxr-xr-xunit-tests/dep-var.exp2
-rwxr-xr-xunit-tests/dep-var.mk33
-rw-r--r--unit-tests/dep-wildcards.exp1
-rw-r--r--unit-tests/dep-wildcards.mk8
-rw-r--r--unit-tests/dep.exp1
-rw-r--r--unit-tests/dep.mk8
-rw-r--r--unit-tests/depsrc-exec.exp1
-rw-r--r--unit-tests/depsrc-exec.mk8
-rw-r--r--unit-tests/depsrc-ignore.exp11
-rw-r--r--unit-tests/depsrc-ignore.mk67
-rw-r--r--unit-tests/depsrc-made.exp1
-rw-r--r--unit-tests/depsrc-made.mk8
-rw-r--r--unit-tests/depsrc-make.exp1
-rw-r--r--unit-tests/depsrc-make.mk8
-rw-r--r--unit-tests/depsrc-meta.exp1
-rw-r--r--unit-tests/depsrc-meta.mk8
-rw-r--r--unit-tests/depsrc-nometa.exp1
-rw-r--r--unit-tests/depsrc-nometa.mk8
-rw-r--r--unit-tests/depsrc-nometa_cmp.exp1
-rw-r--r--unit-tests/depsrc-nometa_cmp.mk8
-rw-r--r--unit-tests/depsrc-nopath.exp1
-rw-r--r--unit-tests/depsrc-nopath.mk8
-rw-r--r--unit-tests/depsrc-notmain.exp1
-rw-r--r--unit-tests/depsrc-notmain.mk8
-rw-r--r--unit-tests/depsrc-optional.exp1
-rw-r--r--unit-tests/depsrc-optional.mk8
-rw-r--r--unit-tests/depsrc-phony.exp1
-rw-r--r--unit-tests/depsrc-phony.mk8
-rw-r--r--unit-tests/depsrc-precious.exp1
-rw-r--r--unit-tests/depsrc-precious.mk8
-rw-r--r--unit-tests/depsrc-recursive.exp1
-rw-r--r--unit-tests/depsrc-recursive.mk8
-rw-r--r--unit-tests/depsrc-silent.exp4
-rw-r--r--unit-tests/depsrc-silent.mk12
-rw-r--r--unit-tests/depsrc-use.exp6
-rw-r--r--unit-tests/depsrc-use.mk24
-rwxr-xr-xunit-tests/depsrc-usebefore-double-colon.exp2
-rwxr-xr-xunit-tests/depsrc-usebefore-double-colon.mk30
-rw-r--r--unit-tests/depsrc-usebefore.exp6
-rw-r--r--unit-tests/depsrc-usebefore.mk24
-rw-r--r--unit-tests/depsrc-wait.exp1
-rw-r--r--unit-tests/depsrc-wait.mk8
-rw-r--r--unit-tests/depsrc.exp1
-rw-r--r--unit-tests/depsrc.mk9
-rw-r--r--unit-tests/deptgt-begin.exp4
-rw-r--r--unit-tests/deptgt-begin.mk13
-rw-r--r--unit-tests/deptgt-default.exp1
-rw-r--r--unit-tests/deptgt-default.mk8
-rw-r--r--unit-tests/deptgt-delete_on_error.exp1
-rw-r--r--unit-tests/deptgt-delete_on_error.mk8
-rw-r--r--unit-tests/deptgt-end.exp4
-rw-r--r--unit-tests/deptgt-end.mk13
-rw-r--r--unit-tests/deptgt-error.exp1
-rw-r--r--unit-tests/deptgt-error.mk8
-rw-r--r--unit-tests/deptgt-ignore.exp1
-rw-r--r--unit-tests/deptgt-ignore.mk8
-rw-r--r--unit-tests/deptgt-interrupt.exp1
-rw-r--r--unit-tests/deptgt-interrupt.mk8
-rw-r--r--unit-tests/deptgt-main.exp1
-rw-r--r--unit-tests/deptgt-main.mk8
-rw-r--r--unit-tests/deptgt-makeflags.exp1
-rw-r--r--unit-tests/deptgt-makeflags.mk8
-rw-r--r--unit-tests/deptgt-no_parallel.exp1
-rw-r--r--unit-tests/deptgt-no_parallel.mk8
-rw-r--r--unit-tests/deptgt-nopath.exp1
-rw-r--r--unit-tests/deptgt-nopath.mk8
-rw-r--r--unit-tests/deptgt-notparallel.exp1
-rw-r--r--unit-tests/deptgt-notparallel.mk8
-rw-r--r--unit-tests/deptgt-objdir.exp1
-rw-r--r--unit-tests/deptgt-objdir.mk8
-rw-r--r--unit-tests/deptgt-order.exp1
-rw-r--r--unit-tests/deptgt-order.mk8
-rw-r--r--unit-tests/deptgt-path-suffix.exp1
-rw-r--r--unit-tests/deptgt-path-suffix.mk8
-rw-r--r--unit-tests/deptgt-path.exp1
-rw-r--r--unit-tests/deptgt-path.mk8
-rw-r--r--unit-tests/deptgt-phony.exp1
-rw-r--r--unit-tests/deptgt-phony.mk8
-rw-r--r--unit-tests/deptgt-precious.exp1
-rw-r--r--unit-tests/deptgt-precious.mk8
-rw-r--r--unit-tests/deptgt-shell.exp1
-rw-r--r--unit-tests/deptgt-shell.mk8
-rw-r--r--unit-tests/deptgt-silent.exp1
-rw-r--r--unit-tests/deptgt-silent.mk8
-rw-r--r--unit-tests/deptgt-stale.exp1
-rw-r--r--unit-tests/deptgt-stale.mk8
-rw-r--r--unit-tests/deptgt-suffixes.exp7
-rw-r--r--unit-tests/deptgt-suffixes.mk18
-rw-r--r--unit-tests/deptgt.exp1
-rw-r--r--unit-tests/deptgt.mk9
-rw-r--r--unit-tests/dir-expand-path.exp4
-rwxr-xr-xunit-tests/dir-expand-path.mk19
-rw-r--r--unit-tests/dir.exp19
-rw-r--r--unit-tests/dir.mk58
-rw-r--r--unit-tests/directive-elif.exp1
-rw-r--r--unit-tests/directive-elif.mk8
-rw-r--r--unit-tests/directive-elifdef.exp1
-rw-r--r--unit-tests/directive-elifdef.mk8
-rw-r--r--unit-tests/directive-elifmake.exp1
-rw-r--r--unit-tests/directive-elifmake.mk8
-rw-r--r--unit-tests/directive-elifndef.exp1
-rw-r--r--unit-tests/directive-elifndef.mk8
-rw-r--r--unit-tests/directive-elifnmake.exp1
-rw-r--r--unit-tests/directive-elifnmake.mk8
-rw-r--r--unit-tests/directive-else.exp8
-rw-r--r--unit-tests/directive-else.mk32
-rw-r--r--unit-tests/directive-endif.exp1
-rw-r--r--unit-tests/directive-endif.mk8
-rw-r--r--unit-tests/directive-error.exp1
-rw-r--r--unit-tests/directive-error.mk8
-rw-r--r--unit-tests/directive-export-env.exp1
-rw-r--r--unit-tests/directive-export-env.mk8
-rw-r--r--unit-tests/directive-export-literal.exp1
-rw-r--r--unit-tests/directive-export-literal.mk8
-rw-r--r--unit-tests/directive-export.exp1
-rw-r--r--unit-tests/directive-export.mk8
-rwxr-xr-xunit-tests/directive-for-generating-endif.exp7
-rwxr-xr-xunit-tests/directive-for-generating-endif.mk25
-rwxr-xr-xunit-tests/directive-for.exp1
-rwxr-xr-xunit-tests/directive-for.mk97
-rw-r--r--unit-tests/directive-if.exp1
-rw-r--r--unit-tests/directive-if.mk8
-rw-r--r--unit-tests/directive-ifdef.exp1
-rw-r--r--unit-tests/directive-ifdef.mk8
-rw-r--r--unit-tests/directive-ifmake.exp10
-rw-r--r--unit-tests/directive-ifmake.mk55
-rw-r--r--unit-tests/directive-ifndef.exp1
-rw-r--r--unit-tests/directive-ifndef.mk8
-rw-r--r--unit-tests/directive-ifnmake.exp1
-rw-r--r--unit-tests/directive-ifnmake.mk8
-rw-r--r--unit-tests/directive-info.exp1
-rw-r--r--unit-tests/directive-info.mk8
-rw-r--r--unit-tests/directive-undef.exp1
-rw-r--r--unit-tests/directive-undef.mk17
-rw-r--r--unit-tests/directive-unexport-env.exp1
-rw-r--r--unit-tests/directive-unexport-env.mk8
-rw-r--r--unit-tests/directive-unexport.exp1
-rw-r--r--unit-tests/directive-unexport.mk8
-rw-r--r--unit-tests/directive-warning.exp1
-rw-r--r--unit-tests/directive-warning.mk8
-rw-r--r--unit-tests/directive.exp1
-rw-r--r--unit-tests/directive.mk8
-rw-r--r--unit-tests/directives.exp42
-rw-r--r--unit-tests/directives.mk163
-rw-r--r--unit-tests/envfirst.exp1
-rw-r--r--unit-tests/envfirst.mk42
-rw-r--r--unit-tests/export-all.mk3
-rwxr-xr-xunit-tests/export-variants.exp1
-rwxr-xr-xunit-tests/export-variants.mk40
-rw-r--r--unit-tests/export.exp2
-rw-r--r--unit-tests/export.mk31
-rw-r--r--unit-tests/forloop.mk4
-rw-r--r--unit-tests/impsrc.exp16
-rw-r--r--unit-tests/impsrc.mk29
-rw-r--r--unit-tests/include-main.mk4
-rwxr-xr-xunit-tests/lint.exp4
-rwxr-xr-xunit-tests/lint.mk17
-rwxr-xr-xunit-tests/make-exported.exp3
-rwxr-xr-xunit-tests/make-exported.mk16
-rw-r--r--unit-tests/moderrs.exp129
-rw-r--r--unit-tests/moderrs.mk151
-rw-r--r--unit-tests/modmatch.exp3
-rw-r--r--unit-tests/modmatch.mk17
-rw-r--r--unit-tests/modmisc.exp40
-rw-r--r--unit-tests/modmisc.mk113
-rw-r--r--unit-tests/modorder.exp12
-rw-r--r--unit-tests/modorder.mk24
-rw-r--r--unit-tests/modts.exp37
-rw-r--r--unit-tests/modts.mk37
-rw-r--r--unit-tests/opt-backwards.exp1
-rw-r--r--unit-tests/opt-backwards.mk8
-rw-r--r--unit-tests/opt-chdir.exp1
-rw-r--r--unit-tests/opt-chdir.mk8
-rwxr-xr-xunit-tests/opt-debug-g1.exp15
-rwxr-xr-xunit-tests/opt-debug-g1.mk19
-rw-r--r--unit-tests/opt-debug.exp1
-rw-r--r--unit-tests/opt-debug.mk8
-rw-r--r--unit-tests/opt-define.exp1
-rw-r--r--unit-tests/opt-define.mk8
-rw-r--r--unit-tests/opt-env.exp1
-rw-r--r--unit-tests/opt-env.mk8
-rw-r--r--unit-tests/opt-file.exp1
-rw-r--r--unit-tests/opt-file.mk8
-rw-r--r--unit-tests/opt-ignore.exp12
-rw-r--r--unit-tests/opt-ignore.mk30
-rw-r--r--unit-tests/opt-include-dir.exp1
-rw-r--r--unit-tests/opt-include-dir.mk8
-rw-r--r--unit-tests/opt-jobs-internal.exp1
-rw-r--r--unit-tests/opt-jobs-internal.mk8
-rw-r--r--unit-tests/opt-jobs.exp1
-rw-r--r--unit-tests/opt-jobs.mk8
-rw-r--r--unit-tests/opt-keep-going.exp6
-rw-r--r--unit-tests/opt-keep-going.mk24
-rw-r--r--unit-tests/opt-m-include-dir.exp2
-rw-r--r--unit-tests/opt-m-include-dir.mk61
-rw-r--r--unit-tests/opt-no-action-at-all.exp1
-rw-r--r--unit-tests/opt-no-action-at-all.mk8
-rw-r--r--unit-tests/opt-no-action.exp13
-rw-r--r--unit-tests/opt-no-action.mk33
-rw-r--r--unit-tests/opt-query.exp2
-rw-r--r--unit-tests/opt-query.mk24
-rw-r--r--unit-tests/opt-raw.exp1
-rw-r--r--unit-tests/opt-raw.mk8
-rw-r--r--unit-tests/opt-silent.exp1
-rw-r--r--unit-tests/opt-silent.mk8
-rw-r--r--unit-tests/opt-touch.exp1
-rw-r--r--unit-tests/opt-touch.mk8
-rw-r--r--unit-tests/opt-tracefile.exp1
-rw-r--r--unit-tests/opt-tracefile.mk8
-rw-r--r--unit-tests/opt-var-expanded.exp3
-rw-r--r--unit-tests/opt-var-expanded.mk6
-rw-r--r--unit-tests/opt-var-literal.exp3
-rw-r--r--unit-tests/opt-var-literal.mk6
-rw-r--r--unit-tests/opt-warnings-as-errors.exp7
-rw-r--r--unit-tests/opt-warnings-as-errors.mk11
-rw-r--r--unit-tests/opt-where-am-i.exp1
-rw-r--r--unit-tests/opt-where-am-i.mk8
-rw-r--r--unit-tests/opt-x-reduce-exported.exp1
-rw-r--r--unit-tests/opt-x-reduce-exported.mk8
-rw-r--r--unit-tests/opt.exp1
-rw-r--r--unit-tests/opt.mk8
-rw-r--r--unit-tests/phony-end.exp2
-rw-r--r--unit-tests/posix1.mk4
-rw-r--r--unit-tests/recursive.exp5
-rw-r--r--unit-tests/recursive.mk37
-rwxr-xr-xunit-tests/sh-dots.exp15
-rwxr-xr-xunit-tests/sh-dots.mk37
-rw-r--r--unit-tests/sh-jobs-error.exp1
-rw-r--r--unit-tests/sh-jobs-error.mk9
-rw-r--r--unit-tests/sh-jobs.exp1
-rw-r--r--unit-tests/sh-jobs.mk9
-rw-r--r--unit-tests/sh-leading-at.exp5
-rw-r--r--unit-tests/sh-leading-at.mk10
-rw-r--r--unit-tests/sh-leading-hyphen.exp1
-rw-r--r--unit-tests/sh-leading-hyphen.mk9
-rw-r--r--unit-tests/sh-leading-plus.exp4
-rw-r--r--unit-tests/sh-leading-plus.mk8
-rw-r--r--unit-tests/sh-meta-chars.exp1
-rw-r--r--unit-tests/sh-meta-chars.mk11
-rw-r--r--unit-tests/sh-multi-line.exp1
-rw-r--r--unit-tests/sh-multi-line.mk9
-rw-r--r--unit-tests/sh-single-line.exp1
-rw-r--r--unit-tests/sh-single-line.mk12
-rw-r--r--unit-tests/sh.exp1
-rw-r--r--unit-tests/sh.mk9
-rw-r--r--unit-tests/sysv.exp1
-rw-r--r--unit-tests/sysv.mk11
-rw-r--r--unit-tests/unexport-env.mk3
-rw-r--r--unit-tests/unexport.mk13
-rw-r--r--unit-tests/use-inference.exp4
-rw-r--r--unit-tests/use-inference.mk35
-rw-r--r--unit-tests/var-class-cmdline.exp1
-rw-r--r--unit-tests/var-class-cmdline.mk8
-rw-r--r--unit-tests/var-class-env.exp1
-rw-r--r--unit-tests/var-class-env.mk8
-rw-r--r--unit-tests/var-class-global.exp1
-rw-r--r--unit-tests/var-class-global.mk8
-rw-r--r--unit-tests/var-class-local-legacy.exp1
-rw-r--r--unit-tests/var-class-local-legacy.mk8
-rw-r--r--unit-tests/var-class-local.exp1
-rw-r--r--unit-tests/var-class-local.mk8
-rw-r--r--unit-tests/var-class.exp1
-rw-r--r--unit-tests/var-class.mk9
-rw-r--r--unit-tests/var-op-append.exp1
-rw-r--r--unit-tests/var-op-append.mk9
-rw-r--r--unit-tests/var-op-assign.exp6
-rw-r--r--unit-tests/var-op-assign.mk89
-rw-r--r--unit-tests/var-op-default.exp1
-rw-r--r--unit-tests/var-op-default.mk9
-rw-r--r--unit-tests/var-op-expand.exp1
-rw-r--r--unit-tests/var-op-expand.mk9
-rw-r--r--unit-tests/var-op-shell.exp1
-rw-r--r--unit-tests/var-op-shell.mk9
-rw-r--r--unit-tests/var-op.exp1
-rw-r--r--unit-tests/var-op.mk8
-rw-r--r--unit-tests/vardebug.exp80
-rw-r--r--unit-tests/vardebug.mk59
-rw-r--r--unit-tests/varfind.exp15
-rw-r--r--unit-tests/varfind.mk31
-rw-r--r--unit-tests/varmisc.exp48
-rw-r--r--unit-tests/varmisc.mk147
-rw-r--r--unit-tests/varmod-assign.exp26
-rw-r--r--unit-tests/varmod-assign.mk81
-rw-r--r--unit-tests/varmod-defined.exp1
-rw-r--r--unit-tests/varmod-defined.mk28
-rw-r--r--unit-tests/varmod-edge.exp35
-rw-r--r--unit-tests/varmod-edge.mk27
-rw-r--r--unit-tests/varmod-exclam-shell.exp1
-rw-r--r--unit-tests/varmod-exclam-shell.mk28
-rw-r--r--unit-tests/varmod-extension.exp10
-rw-r--r--unit-tests/varmod-extension.mk9
-rw-r--r--unit-tests/varmod-gmtime.exp9
-rw-r--r--unit-tests/varmod-gmtime.mk35
-rw-r--r--unit-tests/varmod-hash.exp9
-rw-r--r--unit-tests/varmod-hash.mk10
-rw-r--r--unit-tests/varmod-head.exp10
-rw-r--r--unit-tests/varmod-head.mk9
-rw-r--r--unit-tests/varmod-ifelse.exp1
-rw-r--r--unit-tests/varmod-ifelse.mk9
-rw-r--r--unit-tests/varmod-l-name-to-value.exp1
-rw-r--r--unit-tests/varmod-l-name-to-value.mk31
-rw-r--r--unit-tests/varmod-localtime.exp4
-rw-r--r--unit-tests/varmod-localtime.mk9
-rw-r--r--unit-tests/varmod-loop.exp16
-rw-r--r--unit-tests/varmod-loop.mk63
-rwxr-xr-xunit-tests/varmod-match-escape.exp3
-rwxr-xr-xunit-tests/varmod-match-escape.mk20
-rw-r--r--unit-tests/varmod-match.exp5
-rw-r--r--unit-tests/varmod-match.mk22
-rw-r--r--unit-tests/varmod-no-match.exp1
-rw-r--r--unit-tests/varmod-no-match.mk9
-rw-r--r--unit-tests/varmod-order-reverse.exp1
-rw-r--r--unit-tests/varmod-order-reverse.mk13
-rw-r--r--unit-tests/varmod-order-shuffle.exp1
-rw-r--r--unit-tests/varmod-order-shuffle.mk39
-rw-r--r--unit-tests/varmod-order.exp7
-rw-r--r--unit-tests/varmod-order.mk19
-rw-r--r--unit-tests/varmod-path.exp4
-rw-r--r--unit-tests/varmod-path.mk35
-rw-r--r--unit-tests/varmod-quote-dollar.exp1
-rw-r--r--unit-tests/varmod-quote-dollar.mk10
-rw-r--r--unit-tests/varmod-quote.exp1
-rw-r--r--unit-tests/varmod-quote.mk9
-rw-r--r--unit-tests/varmod-range.exp8
-rw-r--r--unit-tests/varmod-range.mk10
-rw-r--r--unit-tests/varmod-remember.exp3
-rw-r--r--unit-tests/varmod-remember.mk12
-rw-r--r--unit-tests/varmod-root.exp10
-rw-r--r--unit-tests/varmod-root.mk9
-rw-r--r--unit-tests/varmod-select-words.exp1
-rw-r--r--unit-tests/varmod-select-words.mk9
-rw-r--r--unit-tests/varmod-shell.exp1
-rw-r--r--unit-tests/varmod-shell.mk9
-rw-r--r--unit-tests/varmod-subst-regex.exp23
-rw-r--r--unit-tests/varmod-subst-regex.mk87
-rw-r--r--unit-tests/varmod-subst.exp51
-rw-r--r--unit-tests/varmod-subst.mk153
-rw-r--r--unit-tests/varmod-sysv.exp8
-rw-r--r--unit-tests/varmod-sysv.mk61
-rw-r--r--unit-tests/varmod-tail.exp10
-rw-r--r--unit-tests/varmod-tail.mk9
-rw-r--r--unit-tests/varmod-to-abs.exp1
-rw-r--r--unit-tests/varmod-to-abs.mk9
-rw-r--r--unit-tests/varmod-to-lower.exp1
-rw-r--r--unit-tests/varmod-to-lower.mk19
-rw-r--r--unit-tests/varmod-to-many-words.exp1
-rw-r--r--unit-tests/varmod-to-many-words.mk9
-rw-r--r--unit-tests/varmod-to-one-word.exp1
-rw-r--r--unit-tests/varmod-to-one-word.mk9
-rw-r--r--unit-tests/varmod-to-separator.exp9
-rw-r--r--unit-tests/varmod-to-separator.mk118
-rw-r--r--unit-tests/varmod-to-upper.exp2
-rw-r--r--unit-tests/varmod-to-upper.mk21
-rw-r--r--unit-tests/varmod-undefined.exp1
-rw-r--r--unit-tests/varmod-undefined.mk55
-rw-r--r--unit-tests/varmod-unique.exp1
-rw-r--r--unit-tests/varmod-unique.mk39
-rw-r--r--unit-tests/varmod.exp1
-rw-r--r--unit-tests/varmod.mk8
-rw-r--r--unit-tests/varname-dollar.exp5
-rw-r--r--unit-tests/varname-dollar.mk29
-rw-r--r--unit-tests/varname-dot-alltargets.exp4
-rw-r--r--unit-tests/varname-dot-alltargets.mk25
-rw-r--r--unit-tests/varname-dot-curdir.exp1
-rw-r--r--unit-tests/varname-dot-curdir.mk8
-rw-r--r--unit-tests/varname-dot-includedfromdir.exp1
-rw-r--r--unit-tests/varname-dot-includedfromdir.mk8
-rw-r--r--unit-tests/varname-dot-includedfromfile.exp1
-rw-r--r--unit-tests/varname-dot-includedfromfile.mk8
-rwxr-xr-xunit-tests/varname-dot-includes.exp2
-rwxr-xr-xunit-tests/varname-dot-includes.mk20
-rwxr-xr-xunit-tests/varname-dot-libs.exp2
-rwxr-xr-xunit-tests/varname-dot-libs.mk20
-rw-r--r--unit-tests/varname-dot-make-dependfile.exp1
-rw-r--r--unit-tests/varname-dot-make-dependfile.mk8
-rw-r--r--unit-tests/varname-dot-make-expand_variables.exp1
-rw-r--r--unit-tests/varname-dot-make-expand_variables.mk8
-rw-r--r--unit-tests/varname-dot-make-exported.exp1
-rw-r--r--unit-tests/varname-dot-make-exported.mk8
-rw-r--r--unit-tests/varname-dot-make-jobs-prefix.exp1
-rw-r--r--unit-tests/varname-dot-make-jobs-prefix.mk8
-rw-r--r--unit-tests/varname-dot-make-jobs.exp1
-rw-r--r--unit-tests/varname-dot-make-jobs.mk8
-rw-r--r--unit-tests/varname-dot-make-level.exp1
-rw-r--r--unit-tests/varname-dot-make-level.mk8
-rw-r--r--unit-tests/varname-dot-make-makefile_preference.exp1
-rw-r--r--unit-tests/varname-dot-make-makefile_preference.mk8
-rw-r--r--unit-tests/varname-dot-make-makefiles.exp1
-rw-r--r--unit-tests/varname-dot-make-makefiles.mk8
-rw-r--r--unit-tests/varname-dot-make-meta-bailiwick.exp1
-rw-r--r--unit-tests/varname-dot-make-meta-bailiwick.mk8
-rw-r--r--unit-tests/varname-dot-make-meta-created.exp1
-rw-r--r--unit-tests/varname-dot-make-meta-created.mk8
-rw-r--r--unit-tests/varname-dot-make-meta-files.exp1
-rw-r--r--unit-tests/varname-dot-make-meta-files.mk8
-rw-r--r--unit-tests/varname-dot-make-meta-ignore_filter.exp1
-rw-r--r--unit-tests/varname-dot-make-meta-ignore_filter.mk8
-rw-r--r--unit-tests/varname-dot-make-meta-ignore_paths.exp1
-rw-r--r--unit-tests/varname-dot-make-meta-ignore_paths.mk8
-rw-r--r--unit-tests/varname-dot-make-meta-ignore_patterns.exp1
-rw-r--r--unit-tests/varname-dot-make-meta-ignore_patterns.mk8
-rw-r--r--unit-tests/varname-dot-make-meta-prefix.exp1
-rw-r--r--unit-tests/varname-dot-make-meta-prefix.mk8
-rw-r--r--unit-tests/varname-dot-make-mode.exp1
-rw-r--r--unit-tests/varname-dot-make-mode.mk8
-rw-r--r--unit-tests/varname-dot-make-path_filemon.exp1
-rw-r--r--unit-tests/varname-dot-make-path_filemon.mk8
-rw-r--r--unit-tests/varname-dot-make-pid.exp1
-rw-r--r--unit-tests/varname-dot-make-pid.mk8
-rw-r--r--unit-tests/varname-dot-make-ppid.exp1
-rw-r--r--unit-tests/varname-dot-make-ppid.mk8
-rw-r--r--unit-tests/varname-dot-make-save_dollars.exp1
-rw-r--r--unit-tests/varname-dot-make-save_dollars.mk8
-rw-r--r--unit-tests/varname-dot-makeoverrides.exp1
-rw-r--r--unit-tests/varname-dot-makeoverrides.mk8
-rw-r--r--unit-tests/varname-dot-newline.exp4
-rw-r--r--unit-tests/varname-dot-newline.mk23
-rw-r--r--unit-tests/varname-dot-objdir.exp1
-rw-r--r--unit-tests/varname-dot-objdir.mk8
-rw-r--r--unit-tests/varname-dot-parsedir.exp1
-rw-r--r--unit-tests/varname-dot-parsedir.mk8
-rw-r--r--unit-tests/varname-dot-parsefile.exp1
-rw-r--r--unit-tests/varname-dot-parsefile.mk8
-rw-r--r--unit-tests/varname-dot-path.exp1
-rw-r--r--unit-tests/varname-dot-path.mk8
-rwxr-xr-xunit-tests/varname-dot-shell.exp19
-rwxr-xr-xunit-tests/varname-dot-shell.mk25
-rw-r--r--unit-tests/varname-dot-targets.exp1
-rw-r--r--unit-tests/varname-dot-targets.mk8
-rw-r--r--unit-tests/varname-empty.exp11
-rwxr-xr-xunit-tests/varname-empty.mk26
-rw-r--r--unit-tests/varname-make.exp1
-rw-r--r--unit-tests/varname-make.mk8
-rw-r--r--unit-tests/varname-make_print_var_on_error.exp1
-rw-r--r--unit-tests/varname-make_print_var_on_error.mk8
-rw-r--r--unit-tests/varname-makeflags.exp1
-rw-r--r--unit-tests/varname-makeflags.mk8
-rw-r--r--unit-tests/varname-pwd.exp1
-rw-r--r--unit-tests/varname-pwd.mk8
-rw-r--r--unit-tests/varname-vpath.exp1
-rw-r--r--unit-tests/varname-vpath.mk8
-rw-r--r--unit-tests/varname.exp1
-rw-r--r--unit-tests/varname.mk8
-rw-r--r--unit-tests/varparse-dynamic.exp5
-rw-r--r--unit-tests/varparse-dynamic.mk14
-rw-r--r--util.c74
-rw-r--r--var.c4749
656 files changed, 14869 insertions, 10875 deletions
diff --git a/ChangeLog b/ChangeLog
index 20e2628b3bed..847c2e4c0f90 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,243 @@
+2020-09-02 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200902
+ Merge with NetBSD make, pick up
+ o use make_stat to ensure no confusion over valid fields
+ returned by cached_stat
+ o var.c: make VarQuote const-correct
+ o add unit tests for .for
+
+2020-09-01 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200901
+ Merge with NetBSD make, pick up
+ o rename Hash_Table fields
+ o make data types in Dir_HasWildcards more precise
+
+2020-08-31 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200831
+ Merge with NetBSD make, pick up
+ o suff.c: fix unbalanced Lst_Open/Lst_Close in SuffFindCmds
+ o lst.c: Lst_Open renable assert that list isn't open
+ o unit test for .TARGET dependent flags
+ o var.c: fix aliasing bug in VarUniq
+ o more unit tests for :u
+
+2020-08-30 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200830
+ Merge with NetBSD make, pick up
+ o allow for strict type checking for Boolean
+ o Var_Parse never returns NULL
+ o Var_Subst never returns NULL
+ o Lst_Find now takes boolean match function
+ o rename Lst_Memeber to Lst_FindDatum
+ o rename LstNode functions to match their type
+ o rename GNode.iParents to implicitParents
+ o fix assertion failure for .SUFFIXES in archives
+ o compat.c: clean up documentation for CompatInterrupt and Compat_Run
+ remove unreachable code from CompatRunCommand
+ o main.c: simplify getBoolean
+ o stc.c: replace brk_string with simpler Str_Words
+ o suff.c: add debug macros
+
+2020-08-28 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200828
+ Merge with NetBSD make, pick up
+ o lst.c: inline LstIsValid and LstNodeIsValid
+ o remove trailing S from Lst function names after migration complete
+ o more comment cleanup/clarification
+ o suff.c: clean up suffix handling
+ o more unit tests
+
+2020-08-26 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200826
+ Merge with NetBSD make, pick up
+ o enum.c: distinguish between bitsets containing flags and
+ ordinary enums
+ o var.c: fix error message for ::!= modifier with shell error
+ o fix bugs in -DCLEANUP mode
+
+2020-08-24 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200824
+ Merge with NetBSD make, pick up
+ o in debug mode, print GNode details in symbols
+
+2020-08-23 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200823
+ Merge with NetBSD make, pick up
+ o lst.c: more asserts,
+ make args to Lst_Find match others.
+ o var.c: pass flags to VarAdd
+ o arch.c: use Buffer
+ o str.c: brk_string return size_t for nwords
+ o more unit tests
+
+2020-08-22 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION):
+ Merge with NetBSD make, pick up
+ o var.c: support for read-only variables eg .SHELL
+ being the shell used to run scripts.
+ o lst.c: more simplification
+ o more documentation and style cleanup
+ o more unit tests
+ o ensure unit-test/Makefile is run by TEST_MAKE
+ o reduce duplication of header inclusion
+
+2020-08-21 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200821
+ Merge with NetBSD make, pick up
+ o lst.c: revert invalid assertion - but document it
+ o dir.c: split Dir_Init into two functions
+
+2020-08-20 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * lst.c: needs inttypes.h on Linux
+
+ * VERSION (_MAKE_VERSION): 20200820
+ Merge with NetBSD make, pick up
+ o make.1: clarify some passages
+ o var.c: more cleanup, clarify comments
+ o make_malloc.c: remove unreachable code
+ o cond.c: make CondGetString easier to debug
+ o simplify list usage
+ o unit-tests: more
+
+2020-08-16 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200816
+ Merge with NetBSD make, pick up
+ o refactor unit-tests to be more fine grained
+ not all tests moved yet
+
+2020-08-14 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200814
+ Merge with NetBSD make, pick up
+ o more str_concat variants
+ o more enums for flags
+ o var.c: cleanup for higher warnings level
+
+2020-08-10 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200810
+ Merge with NetBSD make, pick up
+ o more unit tests
+ o general comment and style cleanup
+
+2020-08-08 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200808
+ Merge with NetBSD make, pick up
+ o enum.[ch]: streamline, enums for use in flags and debug output
+ o cond.c: cleanup
+ o var.c: reduce duplicate code for modifiers
+ debug logging for Var_Parse
+ more detailed debug output
+ o more unit tests
+
+2020-08-06 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * unit-tests/Makefile: -r for recursive and include Makefile.inc
+ so I can run tests in meta mode
+ supress extra noise if in meta mode
+
+ * VERSION (_MAKE_VERSION): 20200806
+ Merge with NetBSD make, pick up
+ o parse.c: remove VARE_WANTRES for LINT
+ we just want to check parsing (for now).
+
+2020-08-05 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200805
+ Merge with NetBSD make, pick up
+ o make.1: Rework the description of dependence operators
+
+2020-08-03 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200803
+ Merge with NetBSD make, pick up
+ o revert some C99 usage, for max portability
+ o unit-tests/lint
+
+2020-08-02 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200802
+ Merge with NetBSD make, pick up
+ o more unit tests
+
+2020-08-01 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * Remove NetBSD specific plumbing from unit-tests/Makefile
+
+ * VERSION (_MAKE_VERSION): 20200801
+ Merge with NetBSD make, pick up
+ o make Var_Value return const
+ o size_t for buf sizes
+ o optimize some buffer operations - avoid strlen
+
+2020-07-31 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200731
+ Merge with NetBSD make, pick up
+ o var.c: fix undefinded behavior for incomplete :t modifier
+ fixes unit-test/moderrs on Ubuntu
+ o parse.c: When parsing variable assignments other than :=
+ if DEBUG(LINT) test substition of value, so we get a file and
+ line number in the resulting error.
+ o dir.c: fix parsing of nested braces in dependency lines
+ add unit-tests
+
+2020-07-30 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200730
+ Merge with NetBSD make, pick up
+ o var.c: minor cleanup
+ o unit-tests: more tests to improve code coverage
+
+2020-07-28 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200728
+ Merge with NetBSD make, pick up
+ o var.c: more optimizations
+
+2020-07-26 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200726
+ Merge with NetBSD make, pick up
+ o collapse lsd.lib into lst.c - reduce code size and allow inlining
+ o lots of function comment updates
+ o var.c: more optimizations
+ o make return of Var_Parse const
+
+2020-07-20 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200720
+ Merge with NetBSD make, pick up
+ o DEBUG_HASH report stats at end and tone down the noise
+ o var.c: each flag type gets its own prefix.
+ move SysV string matching to var.c
+ make ampersand in ${VAR:from=to&} an ordinary character
+ cleanup and simplify implementation of modifiers
+ o make.1: move documentation for assignment modifiers
+
+2020-07-18 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * VERSION (_MAKE_VERSION): 20200718
+ Merge with NetBSD make, pick up
+ o DEBUG_HASH to see how well the hash tables are working
+
+2020-07-11 Simon J Gerraty <sjg@beast.crufty.net>
+
+ * bsd.after-import.mk: make sure we update unit-tests/Makefile
+
2020-07-10 Simon J Gerraty <sjg@beast.crufty.net>
* configure.in: use AC_INCLUDES_DEFAULT rather than AC_HEADER_STDC
diff --git a/FILES b/FILES
index 0716bffa3c3b..33127290a76e 100644
--- a/FILES
+++ b/FILES
@@ -23,6 +23,8 @@ configure.in
dir.c
dir.h
dirname.c
+enum.c
+enum.h
filemon/filemon.h
filemon/filemon_dev.c
filemon/filemon_ktrace.c
@@ -34,36 +36,8 @@ hash.h
install-sh
job.c
job.h
+lst.c
lst.h
-lst.lib/Makefile
-lst.lib/lstAppend.c
-lst.lib/lstAtEnd.c
-lst.lib/lstAtFront.c
-lst.lib/lstClose.c
-lst.lib/lstConcat.c
-lst.lib/lstDatum.c
-lst.lib/lstDeQueue.c
-lst.lib/lstDestroy.c
-lst.lib/lstDupl.c
-lst.lib/lstEnQueue.c
-lst.lib/lstFind.c
-lst.lib/lstFindFrom.c
-lst.lib/lstFirst.c
-lst.lib/lstForEach.c
-lst.lib/lstForEachFrom.c
-lst.lib/lstInit.c
-lst.lib/lstInsert.c
-lst.lib/lstInt.h
-lst.lib/lstIsAtEnd.c
-lst.lib/lstIsEmpty.c
-lst.lib/lstLast.c
-lst.lib/lstMember.c
-lst.lib/lstNext.c
-lst.lib/lstOpen.c
-lst.lib/lstPrev.c
-lst.lib/lstRemove.c
-lst.lib/lstReplace.c
-lst.lib/lstSucc.c
machine.sh
main.c
make-bootstrap.sh.in
@@ -88,7 +62,6 @@ ranlib.h
realpath.c
setenv.c
sigcompat.c
-sprite.h
str.c
stresep.c
strlcpy.c
@@ -100,22 +73,234 @@ trace.c
trace.h
unit-tests/Makefile
unit-tests/Makefile.config.in
+unit-tests/archive.exp
+unit-tests/archive.mk
+unit-tests/archive-suffix.exp
+unit-tests/archive-suffix.mk
+unit-tests/cmd-interrupt.exp
+unit-tests/cmd-interrupt.mk
+unit-tests/cmdline.exp
+unit-tests/cmdline.mk
unit-tests/comment.exp
unit-tests/comment.mk
+unit-tests/cond-cmp-numeric-eq.exp
+unit-tests/cond-cmp-numeric-eq.mk
+unit-tests/cond-cmp-numeric-ge.exp
+unit-tests/cond-cmp-numeric-ge.mk
+unit-tests/cond-cmp-numeric-gt.exp
+unit-tests/cond-cmp-numeric-gt.mk
+unit-tests/cond-cmp-numeric-le.exp
+unit-tests/cond-cmp-numeric-le.mk
+unit-tests/cond-cmp-numeric-lt.exp
+unit-tests/cond-cmp-numeric-lt.mk
+unit-tests/cond-cmp-numeric-ne.exp
+unit-tests/cond-cmp-numeric-ne.mk
+unit-tests/cond-cmp-numeric.exp
+unit-tests/cond-cmp-numeric.mk
+unit-tests/cond-cmp-string.exp
+unit-tests/cond-cmp-string.mk
+unit-tests/cond-func.exp
+unit-tests/cond-func.mk
+unit-tests/cond-func-commands.exp
+unit-tests/cond-func-commands.mk
+unit-tests/cond-func-defined.exp
+unit-tests/cond-func-defined.mk
+unit-tests/cond-func-empty.exp
+unit-tests/cond-func-empty.mk
+unit-tests/cond-func-exists.exp
+unit-tests/cond-func-exists.mk
+unit-tests/cond-func-make.exp
+unit-tests/cond-func-make.mk
+unit-tests/cond-func-target.exp
+unit-tests/cond-func-target.mk
+unit-tests/cond-late.exp
+unit-tests/cond-late.mk
+unit-tests/cond-op-and.exp
+unit-tests/cond-op-and.mk
+unit-tests/cond-op-not.exp
+unit-tests/cond-op-not.mk
+unit-tests/cond-op-or.exp
+unit-tests/cond-op-or.mk
+unit-tests/cond-op-parentheses.exp
+unit-tests/cond-op-parentheses.mk
+unit-tests/cond-op.exp
+unit-tests/cond-op.mk
+unit-tests/cond-short.exp
+unit-tests/cond-short.mk
+unit-tests/cond-token-number.exp
+unit-tests/cond-token-number.mk
+unit-tests/cond-token-plain.exp
+unit-tests/cond-token-plain.mk
+unit-tests/cond-token-string.exp
+unit-tests/cond-token-string.mk
+unit-tests/cond-token-var.exp
+unit-tests/cond-token-var.mk
unit-tests/cond1.exp
unit-tests/cond1.mk
unit-tests/cond2.exp
unit-tests/cond2.mk
-unit-tests/cond-late.mk
-unit-tests/cond-late.exp
-unit-tests/cond-short.mk
-unit-tests/cond-short.exp
+unit-tests/counter.exp
+unit-tests/counter.mk
+unit-tests/dep-colon.exp
+unit-tests/dep-colon.mk
+unit-tests/dep-double-colon.exp
+unit-tests/dep-double-colon.mk
+unit-tests/dep-exclam.exp
+unit-tests/dep-exclam.mk
+unit-tests/dep-none.exp
+unit-tests/dep-none.mk
+unit-tests/dep-var.exp
+unit-tests/dep-var.mk
+unit-tests/dep-wildcards.exp
+unit-tests/dep-wildcards.mk
+unit-tests/dep.exp
+unit-tests/dep.mk
+unit-tests/depsrc-exec.exp
+unit-tests/depsrc-exec.mk
+unit-tests/depsrc-ignore.exp
+unit-tests/depsrc-ignore.mk
+unit-tests/depsrc-made.exp
+unit-tests/depsrc-made.mk
+unit-tests/depsrc-make.exp
+unit-tests/depsrc-make.mk
+unit-tests/depsrc-meta.exp
+unit-tests/depsrc-meta.mk
+unit-tests/depsrc-nometa.exp
+unit-tests/depsrc-nometa.mk
+unit-tests/depsrc-nometa_cmp.exp
+unit-tests/depsrc-nometa_cmp.mk
+unit-tests/depsrc-nopath.exp
+unit-tests/depsrc-nopath.mk
+unit-tests/depsrc-notmain.exp
+unit-tests/depsrc-notmain.mk
+unit-tests/depsrc-optional.exp
+unit-tests/depsrc-optional.mk
+unit-tests/depsrc-phony.exp
+unit-tests/depsrc-phony.mk
+unit-tests/depsrc-precious.exp
+unit-tests/depsrc-precious.mk
+unit-tests/depsrc-recursive.exp
+unit-tests/depsrc-recursive.mk
+unit-tests/depsrc-silent.exp
+unit-tests/depsrc-silent.mk
+unit-tests/depsrc-use.exp
+unit-tests/depsrc-use.mk
+unit-tests/depsrc-usebefore.exp
+unit-tests/depsrc-usebefore.mk
+unit-tests/depsrc-usebefore-double-colon.exp
+unit-tests/depsrc-usebefore-double-colon.mk
+unit-tests/depsrc-wait.exp
+unit-tests/depsrc-wait.mk
+unit-tests/depsrc.exp
+unit-tests/depsrc.mk
+unit-tests/deptgt-begin.exp
+unit-tests/deptgt-begin.mk
+unit-tests/deptgt-default.exp
+unit-tests/deptgt-default.mk
+unit-tests/deptgt-delete_on_error.exp
+unit-tests/deptgt-delete_on_error.mk
+unit-tests/deptgt-end.exp
+unit-tests/deptgt-end.mk
+unit-tests/deptgt-error.exp
+unit-tests/deptgt-error.mk
+unit-tests/deptgt-ignore.exp
+unit-tests/deptgt-ignore.mk
+unit-tests/deptgt-interrupt.exp
+unit-tests/deptgt-interrupt.mk
+unit-tests/deptgt-main.exp
+unit-tests/deptgt-main.mk
+unit-tests/deptgt-makeflags.exp
+unit-tests/deptgt-makeflags.mk
+unit-tests/deptgt-no_parallel.exp
+unit-tests/deptgt-no_parallel.mk
+unit-tests/deptgt-nopath.exp
+unit-tests/deptgt-nopath.mk
+unit-tests/deptgt-notparallel.exp
+unit-tests/deptgt-notparallel.mk
+unit-tests/deptgt-objdir.exp
+unit-tests/deptgt-objdir.mk
+unit-tests/deptgt-order.exp
+unit-tests/deptgt-order.mk
+unit-tests/deptgt-path-suffix.exp
+unit-tests/deptgt-path-suffix.mk
+unit-tests/deptgt-path.exp
+unit-tests/deptgt-path.mk
+unit-tests/deptgt-phony.exp
+unit-tests/deptgt-phony.mk
+unit-tests/deptgt-precious.exp
+unit-tests/deptgt-precious.mk
+unit-tests/deptgt-shell.exp
+unit-tests/deptgt-shell.mk
+unit-tests/deptgt-silent.exp
+unit-tests/deptgt-silent.mk
+unit-tests/deptgt-stale.exp
+unit-tests/deptgt-stale.mk
+unit-tests/deptgt-suffixes.exp
+unit-tests/deptgt-suffixes.mk
+unit-tests/deptgt.exp
+unit-tests/deptgt.mk
+unit-tests/dir.exp
+unit-tests/dir.mk
+unit-tests/dir-expand-path.exp
+unit-tests/dir-expand-path.mk
+unit-tests/directive-elif.exp
+unit-tests/directive-elif.mk
+unit-tests/directive-elifdef.exp
+unit-tests/directive-elifdef.mk
+unit-tests/directive-elifmake.exp
+unit-tests/directive-elifmake.mk
+unit-tests/directive-elifndef.exp
+unit-tests/directive-elifndef.mk
+unit-tests/directive-elifnmake.exp
+unit-tests/directive-elifnmake.mk
+unit-tests/directive-else.exp
+unit-tests/directive-else.mk
+unit-tests/directive-endif.exp
+unit-tests/directive-endif.mk
+unit-tests/directive-error.exp
+unit-tests/directive-error.mk
+unit-tests/directive-export-env.exp
+unit-tests/directive-export-env.mk
+unit-tests/directive-export-literal.exp
+unit-tests/directive-export-literal.mk
+unit-tests/directive-export.exp
+unit-tests/directive-export.mk
+unit-tests/directive-for.exp
+unit-tests/directive-for.mk
+unit-tests/directive-for-generating-endif.exp
+unit-tests/directive-for-generating-endif.mk
+unit-tests/directive-if.exp
+unit-tests/directive-if.mk
+unit-tests/directive-ifdef.exp
+unit-tests/directive-ifdef.mk
+unit-tests/directive-ifmake.exp
+unit-tests/directive-ifmake.mk
+unit-tests/directive-ifndef.exp
+unit-tests/directive-ifndef.mk
+unit-tests/directive-ifnmake.exp
+unit-tests/directive-ifnmake.mk
+unit-tests/directive-info.exp
+unit-tests/directive-info.mk
+unit-tests/directive-undef.exp
+unit-tests/directive-undef.mk
+unit-tests/directive-unexport-env.exp
+unit-tests/directive-unexport-env.mk
+unit-tests/directive-unexport.exp
+unit-tests/directive-unexport.mk
+unit-tests/directive-warning.exp
+unit-tests/directive-warning.mk
+unit-tests/directive.exp
+unit-tests/directive.mk
+unit-tests/directives.exp
+unit-tests/directives.mk
unit-tests/dollar.exp
unit-tests/dollar.mk
unit-tests/doterror.exp
unit-tests/doterror.mk
unit-tests/dotwait.exp
unit-tests/dotwait.mk
+unit-tests/envfirst.exp
+unit-tests/envfirst.mk
unit-tests/error.exp
unit-tests/error.mk
unit-tests/escape.exp
@@ -124,6 +309,8 @@ unit-tests/export-all.exp
unit-tests/export-all.mk
unit-tests/export-env.exp
unit-tests/export-env.mk
+unit-tests/export-variants.exp
+unit-tests/export-variants.mk
unit-tests/export.exp
unit-tests/export.mk
unit-tests/forloop.exp
@@ -138,6 +325,10 @@ unit-tests/include-main.exp
unit-tests/include-main.mk
unit-tests/include-sub.mk
unit-tests/include-subsub.mk
+unit-tests/lint.exp
+unit-tests/lint.mk
+unit-tests/make-exported.exp
+unit-tests/make-exported.mk
unit-tests/misc.exp
unit-tests/misc.mk
unit-tests/moderrs.exp
@@ -146,12 +337,62 @@ unit-tests/modmatch.exp
unit-tests/modmatch.mk
unit-tests/modmisc.exp
unit-tests/modmisc.mk
-unit-tests/modorder.exp
-unit-tests/modorder.mk
unit-tests/modts.exp
unit-tests/modts.mk
unit-tests/modword.exp
unit-tests/modword.mk
+unit-tests/opt-backwards.exp
+unit-tests/opt-backwards.mk
+unit-tests/opt-chdir.exp
+unit-tests/opt-chdir.mk
+unit-tests/opt-debug.exp
+unit-tests/opt-debug.mk
+unit-tests/opt-debug-g1.exp
+unit-tests/opt-debug-g1.mk
+unit-tests/opt-define.exp
+unit-tests/opt-define.mk
+unit-tests/opt-env.exp
+unit-tests/opt-env.mk
+unit-tests/opt-file.exp
+unit-tests/opt-file.mk
+unit-tests/opt-ignore.exp
+unit-tests/opt-ignore.mk
+unit-tests/opt-include-dir.exp
+unit-tests/opt-include-dir.mk
+unit-tests/opt-jobs-internal.exp
+unit-tests/opt-jobs-internal.mk
+unit-tests/opt-jobs.exp
+unit-tests/opt-jobs.mk
+unit-tests/opt-keep-going.exp
+unit-tests/opt-keep-going.mk
+unit-tests/opt-m-include-dir.exp
+unit-tests/opt-m-include-dir.mk
+unit-tests/opt-no-action-at-all.exp
+unit-tests/opt-no-action-at-all.mk
+unit-tests/opt-no-action.exp
+unit-tests/opt-no-action.mk
+unit-tests/opt-query.exp
+unit-tests/opt-query.mk
+unit-tests/opt-raw.exp
+unit-tests/opt-raw.mk
+unit-tests/opt-silent.exp
+unit-tests/opt-silent.mk
+unit-tests/opt-touch.exp
+unit-tests/opt-touch.mk
+unit-tests/opt-tracefile.exp
+unit-tests/opt-tracefile.mk
+unit-tests/opt-var-expanded.exp
+unit-tests/opt-var-expanded.mk
+unit-tests/opt-var-literal.exp
+unit-tests/opt-var-literal.mk
+unit-tests/opt-warnings-as-errors.exp
+unit-tests/opt-warnings-as-errors.mk
+unit-tests/opt-where-am-i.exp
+unit-tests/opt-where-am-i.mk
+unit-tests/opt-x-reduce-exported.exp
+unit-tests/opt-x-reduce-exported.mk
+unit-tests/opt.exp
+unit-tests/opt.mk
unit-tests/order.exp
unit-tests/order.mk
unit-tests/phony-end.exp
@@ -162,6 +403,28 @@ unit-tests/posix1.exp
unit-tests/posix1.mk
unit-tests/qequals.exp
unit-tests/qequals.mk
+unit-tests/recursive.exp
+unit-tests/recursive.mk
+unit-tests/sh-dots.exp
+unit-tests/sh-dots.mk
+unit-tests/sh-jobs-error.exp
+unit-tests/sh-jobs-error.mk
+unit-tests/sh-jobs.exp
+unit-tests/sh-jobs.mk
+unit-tests/sh-leading-at.exp
+unit-tests/sh-leading-at.mk
+unit-tests/sh-leading-hyphen.exp
+unit-tests/sh-leading-hyphen.mk
+unit-tests/sh-leading-plus.exp
+unit-tests/sh-leading-plus.mk
+unit-tests/sh-meta-chars.exp
+unit-tests/sh-meta-chars.mk
+unit-tests/sh-multi-line.exp
+unit-tests/sh-multi-line.mk
+unit-tests/sh-single-line.exp
+unit-tests/sh-single-line.mk
+unit-tests/sh.exp
+unit-tests/sh.mk
unit-tests/suffixes.exp
unit-tests/suffixes.mk
unit-tests/sunshcmd.exp
@@ -174,12 +437,204 @@ unit-tests/unexport-env.exp
unit-tests/unexport-env.mk
unit-tests/unexport.exp
unit-tests/unexport.mk
+unit-tests/use-inference.exp
+unit-tests/use-inference.mk
+unit-tests/var-class-cmdline.exp
+unit-tests/var-class-cmdline.mk
+unit-tests/var-class-env.exp
+unit-tests/var-class-env.mk
+unit-tests/var-class-global.exp
+unit-tests/var-class-global.mk
+unit-tests/var-class-local-legacy.exp
+unit-tests/var-class-local-legacy.mk
+unit-tests/var-class-local.exp
+unit-tests/var-class-local.mk
+unit-tests/var-class.exp
+unit-tests/var-class.mk
+unit-tests/var-op-append.exp
+unit-tests/var-op-append.mk
+unit-tests/var-op-assign.exp
+unit-tests/var-op-assign.mk
+unit-tests/var-op-default.exp
+unit-tests/var-op-default.mk
+unit-tests/var-op-expand.exp
+unit-tests/var-op-expand.mk
+unit-tests/var-op-shell.exp
+unit-tests/var-op-shell.mk
+unit-tests/var-op.exp
+unit-tests/var-op.mk
unit-tests/varcmd.exp
unit-tests/varcmd.mk
+unit-tests/vardebug.exp
+unit-tests/vardebug.mk
+unit-tests/varfind.exp
+unit-tests/varfind.mk
unit-tests/varmisc.exp
unit-tests/varmisc.mk
+unit-tests/varmod-assign.exp
+unit-tests/varmod-assign.mk
+unit-tests/varmod-defined.exp
+unit-tests/varmod-defined.mk
unit-tests/varmod-edge.exp
unit-tests/varmod-edge.mk
+unit-tests/varmod-exclam-shell.exp
+unit-tests/varmod-exclam-shell.mk
+unit-tests/varmod-extension.exp
+unit-tests/varmod-extension.mk
+unit-tests/varmod-gmtime.exp
+unit-tests/varmod-gmtime.mk
+unit-tests/varmod-hash.exp
+unit-tests/varmod-hash.mk
+unit-tests/varmod-head.exp
+unit-tests/varmod-head.mk
+unit-tests/varmod-ifelse.exp
+unit-tests/varmod-ifelse.mk
+unit-tests/varmod-l-name-to-value.exp
+unit-tests/varmod-l-name-to-value.mk
+unit-tests/varmod-localtime.exp
+unit-tests/varmod-localtime.mk
+unit-tests/varmod-loop.exp
+unit-tests/varmod-loop.mk
+unit-tests/varmod-match-escape.exp
+unit-tests/varmod-match-escape.mk
+unit-tests/varmod-match.exp
+unit-tests/varmod-match.mk
+unit-tests/varmod-no-match.exp
+unit-tests/varmod-no-match.mk
+unit-tests/varmod-order-reverse.exp
+unit-tests/varmod-order-reverse.mk
+unit-tests/varmod-order-shuffle.exp
+unit-tests/varmod-order-shuffle.mk
+unit-tests/varmod-order.exp
+unit-tests/varmod-order.mk
+unit-tests/varmod-path.exp
+unit-tests/varmod-path.mk
+unit-tests/varmod-quote-dollar.exp
+unit-tests/varmod-quote-dollar.mk
+unit-tests/varmod-quote.exp
+unit-tests/varmod-quote.mk
+unit-tests/varmod-range.exp
+unit-tests/varmod-range.mk
+unit-tests/varmod-remember.exp
+unit-tests/varmod-remember.mk
+unit-tests/varmod-root.exp
+unit-tests/varmod-root.mk
+unit-tests/varmod-select-words.exp
+unit-tests/varmod-select-words.mk
+unit-tests/varmod-shell.exp
+unit-tests/varmod-shell.mk
+unit-tests/varmod-subst-regex.exp
+unit-tests/varmod-subst-regex.mk
+unit-tests/varmod-subst.exp
+unit-tests/varmod-subst.mk
+unit-tests/varmod-sysv.exp
+unit-tests/varmod-sysv.mk
+unit-tests/varmod-tail.exp
+unit-tests/varmod-tail.mk
+unit-tests/varmod-to-abs.exp
+unit-tests/varmod-to-abs.mk
+unit-tests/varmod-to-lower.exp
+unit-tests/varmod-to-lower.mk
+unit-tests/varmod-to-many-words.exp
+unit-tests/varmod-to-many-words.mk
+unit-tests/varmod-to-one-word.exp
+unit-tests/varmod-to-one-word.mk
+unit-tests/varmod-to-separator.exp
+unit-tests/varmod-to-separator.mk
+unit-tests/varmod-to-upper.exp
+unit-tests/varmod-to-upper.mk
+unit-tests/varmod-undefined.exp
+unit-tests/varmod-undefined.mk
+unit-tests/varmod-unique.exp
+unit-tests/varmod-unique.mk
+unit-tests/varmod.exp
+unit-tests/varmod.mk
+unit-tests/varname-dollar.exp
+unit-tests/varname-dollar.mk
+unit-tests/varname-dot-alltargets.exp
+unit-tests/varname-dot-alltargets.mk
+unit-tests/varname-dot-curdir.exp
+unit-tests/varname-dot-curdir.mk
+unit-tests/varname-dot-includes.exp
+unit-tests/varname-dot-includes.mk
+unit-tests/varname-dot-includedfromdir.exp
+unit-tests/varname-dot-includedfromdir.mk
+unit-tests/varname-dot-includedfromfile.exp
+unit-tests/varname-dot-includedfromfile.mk
+unit-tests/varname-dot-libs.exp
+unit-tests/varname-dot-libs.mk
+unit-tests/varname-dot-make-dependfile.exp
+unit-tests/varname-dot-make-dependfile.mk
+unit-tests/varname-dot-make-expand_variables.exp
+unit-tests/varname-dot-make-expand_variables.mk
+unit-tests/varname-dot-make-exported.exp
+unit-tests/varname-dot-make-exported.mk
+unit-tests/varname-dot-make-jobs-prefix.exp
+unit-tests/varname-dot-make-jobs-prefix.mk
+unit-tests/varname-dot-make-jobs.exp
+unit-tests/varname-dot-make-jobs.mk
+unit-tests/varname-dot-make-level.exp
+unit-tests/varname-dot-make-level.mk
+unit-tests/varname-dot-make-makefile_preference.exp
+unit-tests/varname-dot-make-makefile_preference.mk
+unit-tests/varname-dot-make-makefiles.exp
+unit-tests/varname-dot-make-makefiles.mk
+unit-tests/varname-dot-make-meta-bailiwick.exp
+unit-tests/varname-dot-make-meta-bailiwick.mk
+unit-tests/varname-dot-make-meta-created.exp
+unit-tests/varname-dot-make-meta-created.mk
+unit-tests/varname-dot-make-meta-files.exp
+unit-tests/varname-dot-make-meta-files.mk
+unit-tests/varname-dot-make-meta-ignore_filter.exp
+unit-tests/varname-dot-make-meta-ignore_filter.mk
+unit-tests/varname-dot-make-meta-ignore_paths.exp
+unit-tests/varname-dot-make-meta-ignore_paths.mk
+unit-tests/varname-dot-make-meta-ignore_patterns.exp
+unit-tests/varname-dot-make-meta-ignore_patterns.mk
+unit-tests/varname-dot-make-meta-prefix.exp
+unit-tests/varname-dot-make-meta-prefix.mk
+unit-tests/varname-dot-make-mode.exp
+unit-tests/varname-dot-make-mode.mk
+unit-tests/varname-dot-make-path_filemon.exp
+unit-tests/varname-dot-make-path_filemon.mk
+unit-tests/varname-dot-make-pid.exp
+unit-tests/varname-dot-make-pid.mk
+unit-tests/varname-dot-make-ppid.exp
+unit-tests/varname-dot-make-ppid.mk
+unit-tests/varname-dot-make-save_dollars.exp
+unit-tests/varname-dot-make-save_dollars.mk
+unit-tests/varname-dot-makeoverrides.exp
+unit-tests/varname-dot-makeoverrides.mk
+unit-tests/varname-dot-newline.exp
+unit-tests/varname-dot-newline.mk
+unit-tests/varname-dot-objdir.exp
+unit-tests/varname-dot-objdir.mk
+unit-tests/varname-dot-parsedir.exp
+unit-tests/varname-dot-parsedir.mk
+unit-tests/varname-dot-parsefile.exp
+unit-tests/varname-dot-parsefile.mk
+unit-tests/varname-dot-path.exp
+unit-tests/varname-dot-path.mk
+unit-tests/varname-dot-shell.exp
+unit-tests/varname-dot-shell.mk
+unit-tests/varname-dot-targets.exp
+unit-tests/varname-dot-targets.mk
+unit-tests/varname-empty.exp
+unit-tests/varname-empty.mk
+unit-tests/varname-make.exp
+unit-tests/varname-make.mk
+unit-tests/varname-make_print_var_on_error.exp
+unit-tests/varname-make_print_var_on_error.mk
+unit-tests/varname-makeflags.exp
+unit-tests/varname-makeflags.mk
+unit-tests/varname-pwd.exp
+unit-tests/varname-pwd.mk
+unit-tests/varname-vpath.exp
+unit-tests/varname-vpath.mk
+unit-tests/varname.exp
+unit-tests/varname.mk
+unit-tests/varparse-dynamic.exp
+unit-tests/varparse-dynamic.mk
unit-tests/varquote.exp
unit-tests/varquote.mk
unit-tests/varshell.exp
diff --git a/LICENSE b/LICENSE
index dbad0ec06a4d..283dd20cccd0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -3,6 +3,7 @@ original contributors or assignees.
Including:
Copyright (c) 1993-2020, Simon J Gerraty
+ Copyright (c) 2020, Roland Illig <rillig@NetBSD.org>
Copyright (c) 2009-2016, Juniper Networks, Inc.
Copyright (c) 2009, John Birrell.
Copyright (c) 1997-2020 The NetBSD Foundation, Inc.
diff --git a/Makefile b/Makefile
index c329017b13ef..7277d9554de4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.107 2020/06/07 21:18:46 sjg Exp $
+# $Id: Makefile,v 1.112 2020/08/28 16:26:17 sjg Exp $
PROG= bmake
@@ -8,9 +8,11 @@ SRCS= \
compat.c \
cond.c \
dir.c \
+ enum.c \
for.c \
hash.c \
job.c \
+ lst.c \
main.c \
make.c \
make_malloc.c \
@@ -25,36 +27,6 @@ SRCS= \
util.c \
var.c
-# from lst.lib/
-SRCS+= \
- lstAppend.c \
- lstAtEnd.c \
- lstAtFront.c \
- lstClose.c \
- lstConcat.c \
- lstDatum.c \
- lstDeQueue.c \
- lstDestroy.c \
- lstDupl.c \
- lstEnQueue.c \
- lstFind.c \
- lstFindFrom.c \
- lstFirst.c \
- lstForEach.c \
- lstForEachFrom.c \
- lstInit.c \
- lstInsert.c \
- lstIsAtEnd.c \
- lstIsEmpty.c \
- lstLast.c \
- lstMember.c \
- lstNext.c \
- lstOpen.c \
- lstPrev.c \
- lstRemove.c \
- lstReplace.c \
- lstSucc.c
-
.-include "VERSION"
.-include "Makefile.inc"
@@ -97,7 +69,6 @@ COPTS.filemon_dev.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
.endif # USE_FILEMON
.PATH: ${srcdir}
-.PATH: ${srcdir}/lst.lib
.if make(obj) || make(clean)
SUBDIR+= unit-tests
@@ -109,7 +80,7 @@ SUBDIR+= unit-tests
# list of OS's which are derrived from BSD4.4
BSD44_LIST= NetBSD FreeBSD OpenBSD DragonFly MirBSD Bitrig
# we are...
-OS!= uname -s
+OS := ${.MAKE.OS:U${uname -s:L:sh}}
# are we 4.4BSD ?
isBSD44:=${BSD44_LIST:M${OS}}
@@ -237,5 +208,8 @@ install-mk:
# end-delete2
# A simple unit-test driver to help catch regressions
+TEST_MAKE ?= ${.OBJDIR}/${PROG:T}
accept test:
- cd ${.CURDIR}/unit-tests && MAKEFLAGS= ${.MAKE} -r -m / TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}
+ cd ${.CURDIR}/unit-tests && \
+ MAKEFLAGS= ${TEST_MAKE} -r -m / ${.TARGET} ${TESTS:DTESTS=${TESTS:Q}}
+
diff --git a/VERSION b/VERSION
index 3c8b783c2861..b13b442cd4a4 100644
--- a/VERSION
+++ b/VERSION
@@ -1,2 +1,2 @@
# keep this compatible with sh and make
-_MAKE_VERSION=20200710
+_MAKE_VERSION=20200902
diff --git a/arch.c b/arch.c
index 9db7ce2bd14b..fa54908d8817 100644
--- a/arch.c
+++ b/arch.c
@@ -1,4 +1,4 @@
-/* $NetBSD: arch.c,v 1.73 2020/07/03 08:02:55 rillig Exp $ */
+/* $NetBSD: arch.c,v 1.107 2020/08/30 11:15:05 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: arch.c,v 1.73 2020/07/03 08:02:55 rillig Exp $";
+static char rcsid[] = "$NetBSD: arch.c,v 1.107 2020/08/30 11:15:05 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94";
#else
-__RCSID("$NetBSD: arch.c,v 1.73 2020/07/03 08:02:55 rillig Exp $");
+__RCSID("$NetBSD: arch.c,v 1.107 2020/08/30 11:15:05 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -94,7 +94,7 @@ __RCSID("$NetBSD: arch.c,v 1.73 2020/07/03 08:02:55 rillig Exp $");
* The interface to this module is:
* Arch_ParseArchive Given an archive specification, return a list
* of GNode's, one for each member in the spec.
- * FAILURE is returned if the specification is
+ * FALSE is returned if the specification is
* invalid for some reason.
*
* Arch_Touch Alter the modification time of the archive
@@ -184,12 +184,9 @@ typedef struct Arch {
size_t fnamesize; /* Size of the string table */
} Arch;
-static int ArchFindArchive(const void *, const void *);
-#ifdef CLEANUP
-static void ArchFree(void *);
-#endif
-static struct ar_hdr *ArchStatMember(char *, char *, Boolean);
-static FILE *ArchFindMember(char *, char *, struct ar_hdr *, const char *);
+static struct ar_hdr *ArchStatMember(const char *, const char *, Boolean);
+static FILE *ArchFindMember(const char *, const char *,
+ struct ar_hdr *, const char *);
#if defined(__svr4__) || defined(__SVR4) || defined(__ELF__)
#define SVR4ARCHIVES
static int ArchSVR4Entry(Arch *, char *, size_t, FILE *);
@@ -225,19 +222,6 @@ static int ArchSVR4Entry(Arch *, char *, size_t, FILE *);
#define AR_MAX_NAME_LEN (sizeof(arh.AR_NAME)-1)
#ifdef CLEANUP
-/*-
- *-----------------------------------------------------------------------
- * ArchFree --
- * Free memory used by an archive
- *
- * Results:
- * None.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
static void
ArchFree(void *ap)
{
@@ -272,23 +256,18 @@ ArchFree(void *ap)
* ctxt Context in which to expand variables
*
* Results:
- * SUCCESS if it was a valid specification. The linePtr is updated
+ * TRUE if it was a valid specification. The linePtr is updated
* to point to the first non-space after the archive spec. The
* nodes for the members are placed on the given list.
- *
- * Side Effects:
- * Some nodes may be created. The given list is extended.
- *
*-----------------------------------------------------------------------
*/
-ReturnStatus
+Boolean
Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
{
char *cp; /* Pointer into line */
GNode *gn; /* New node */
char *libName; /* Library-part of specification */
char *memName; /* Member-part of specification */
- char *nameBuf; /* temporary place for node name */
char saveChar; /* Ending delimiter of member-name */
Boolean subLibName; /* TRUE if libName should have/had
* variable substitution performed on it */
@@ -304,26 +283,25 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
* so we can safely advance beyond it...
*/
int length;
- void *freeIt;
- char *result;
-
- result = Var_Parse(cp, ctxt, VARF_UNDEFERR|VARF_WANTRES,
- &length, &freeIt);
- free(freeIt);
-
- if (result == var_Error) {
- return FAILURE;
- } else {
- subLibName = TRUE;
- }
-
- cp += length-1;
+ void *result_freeIt;
+ const char *result;
+ Boolean isError;
+
+ result = Var_Parse(cp, ctxt, VARE_UNDEFERR|VARE_WANTRES,
+ &length, &result_freeIt);
+ isError = result == var_Error;
+ free(result_freeIt);
+ if (isError)
+ return FALSE;
+
+ subLibName = TRUE;
+ cp += length - 1;
}
}
*cp++ = '\0';
if (subLibName) {
- libName = Var_Subst(NULL, libName, ctxt, VARF_UNDEFERR|VARF_WANTRES);
+ libName = Var_Subst(libName, ctxt, VARE_UNDEFERR|VARE_WANTRES);
}
@@ -347,18 +325,18 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
*/
int length;
void *freeIt;
- char *result;
+ const char *result;
+ Boolean isError;
- result = Var_Parse(cp, ctxt, VARF_UNDEFERR|VARF_WANTRES,
+ result = Var_Parse(cp, ctxt, VARE_UNDEFERR|VARE_WANTRES,
&length, &freeIt);
+ isError = result == var_Error;
free(freeIt);
- if (result == var_Error) {
- return FAILURE;
- } else {
- doSubst = TRUE;
- }
+ if (isError)
+ return FALSE;
+ doSubst = TRUE;
cp += length;
} else {
cp++;
@@ -372,7 +350,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
*/
if (*cp == '\0') {
printf("No closing parenthesis in archive specification\n");
- return FAILURE;
+ return FALSE;
}
/*
@@ -401,20 +379,15 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
char *buf;
char *sacrifice;
char *oldMemName = memName;
- size_t sz;
- memName = Var_Subst(NULL, memName, ctxt,
- VARF_UNDEFERR|VARF_WANTRES);
+ memName = Var_Subst(memName, ctxt, VARE_UNDEFERR | VARE_WANTRES);
/*
* Now form an archive spec and recurse to deal with nested
* variables and multi-word variable values.... The results
* are just placed at the end of the nodeLst we're returning.
*/
- sz = strlen(memName)+strlen(libName)+3;
- buf = sacrifice = bmake_malloc(sz);
-
- snprintf(buf, sz, "%s(%s)", libName, memName);
+ buf = sacrifice = str_concat4(libName, "(", memName, ")");
if (strchr(memName, '$') && strcmp(memName, oldMemName) == 0) {
/*
@@ -426,42 +399,43 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
if (gn == NULL) {
free(buf);
- return FAILURE;
+ return FALSE;
} else {
gn->type |= OP_ARCHV;
- (void)Lst_AtEnd(nodeLst, gn);
+ Lst_Append(nodeLst, gn);
}
- } else if (Arch_ParseArchive(&sacrifice, nodeLst, ctxt)!=SUCCESS) {
+ } else if (!Arch_ParseArchive(&sacrifice, nodeLst, ctxt)) {
/*
- * Error in nested call -- free buffer and return FAILURE
+ * Error in nested call -- free buffer and return FALSE
* ourselves.
*/
free(buf);
- return FAILURE;
+ return FALSE;
}
/*
* Free buffer and continue with our work.
*/
free(buf);
} else if (Dir_HasWildcards(memName)) {
- Lst members = Lst_Init(FALSE);
- char *member;
- size_t sz = MAXPATHLEN, nsz;
- nameBuf = bmake_malloc(sz);
+ Lst members = Lst_Init();
+ Buffer nameBuf;
+ Buf_Init(&nameBuf, 0);
Dir_Expand(memName, dirSearchPath, members);
while (!Lst_IsEmpty(members)) {
- member = (char *)Lst_DeQueue(members);
- nsz = strlen(libName) + strlen(member) + 3;
- if (sz > nsz)
- nameBuf = bmake_realloc(nameBuf, sz = nsz * 2);
+ char *member = Lst_Dequeue(members);
- snprintf(nameBuf, sz, "%s(%s)", libName, member);
+ Buf_Empty(&nameBuf);
+ Buf_AddStr(&nameBuf, libName);
+ Buf_AddStr(&nameBuf, "(");
+ Buf_AddStr(&nameBuf, member);
+ Buf_AddStr(&nameBuf, ")");
free(member);
- gn = Targ_FindNode(nameBuf, TARG_CREATE);
+
+ gn = Targ_FindNode(Buf_GetAll(&nameBuf, NULL), TARG_CREATE);
if (gn == NULL) {
- free(nameBuf);
- return FAILURE;
+ Buf_Destroy(&nameBuf, TRUE);
+ return FALSE;
} else {
/*
* We've found the node, but have to make sure the rest of
@@ -471,19 +445,24 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
* end of the provided list.
*/
gn->type |= OP_ARCHV;
- (void)Lst_AtEnd(nodeLst, gn);
+ Lst_Append(nodeLst, gn);
}
}
- Lst_Destroy(members, NULL);
- free(nameBuf);
+ Lst_Free(members);
+ Buf_Destroy(&nameBuf, TRUE);
} else {
- size_t sz = strlen(libName) + strlen(memName) + 3;
- nameBuf = bmake_malloc(sz);
- snprintf(nameBuf, sz, "%s(%s)", libName, memName);
- gn = Targ_FindNode(nameBuf, TARG_CREATE);
- free(nameBuf);
+ Buffer nameBuf;
+
+ Buf_Init(&nameBuf, 0);
+ Buf_AddStr(&nameBuf, libName);
+ Buf_AddStr(&nameBuf, "(");
+ Buf_AddStr(&nameBuf, memName);
+ Buf_AddStr(&nameBuf, ")");
+
+ gn = Targ_FindNode(Buf_GetAll(&nameBuf, NULL), TARG_CREATE);
+ Buf_Destroy(&nameBuf, TRUE);
if (gn == NULL) {
- return FAILURE;
+ return FALSE;
} else {
/*
* We've found the node, but have to make sure the rest of the
@@ -493,7 +472,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
* provided list.
*/
gn->type |= OP_ARCHV;
- (void)Lst_AtEnd(nodeLst, gn);
+ Lst_Append(nodeLst, gn);
}
}
if (doSubst) {
@@ -520,31 +499,15 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
} while (*cp != '\0' && isspace ((unsigned char)*cp));
*linePtr = cp;
- return SUCCESS;
+ return TRUE;
}
-/*-
- *-----------------------------------------------------------------------
- * ArchFindArchive --
- * See if the given archive is the one we are looking for. Called
- * From ArchStatMember and ArchFindMember via Lst_Find.
- *
- * Input:
- * ar Current list element
- * archName Name we want
- *
- * Results:
- * 0 if it is, non-zero if it isn't.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-static int
-ArchFindArchive(const void *ar, const void *archName)
+/* See if the given archive is the one we are looking for.
+ * Called via Lst_Find. */
+static Boolean
+ArchFindArchive(const void *ar, const void *desiredName)
{
- return strcmp(archName, ((const Arch *)ar)->name);
+ return strcmp(((const Arch *)ar)->name, desiredName) == 0;
}
/*-
@@ -565,24 +528,20 @@ ArchFindArchive(const void *ar, const void *archName)
* archive members. This is mostly because we have no assurances that
* The archive will remain constant after we read all the headers, so
* there's not much point in remembering the position...
- *
- * Side Effects:
- *
*-----------------------------------------------------------------------
*/
static struct ar_hdr *
-ArchStatMember(char *archive, char *member, Boolean hash)
+ArchStatMember(const char *archive, const char *member, Boolean hash)
{
FILE * arch; /* Stream to archive */
- int size; /* Size of archive member */
- char *cp; /* Useful character pointer */
+ size_t size; /* Size of archive member */
char magic[SARMAG];
LstNode ln; /* Lst member containing archive descriptor */
Arch *ar; /* Archive descriptor */
Hash_Entry *he; /* Entry containing member's description */
struct ar_hdr arh; /* archive-member header for reading archive */
char memName[MAXPATHLEN+1];
- /* Current member name while hashing. */
+ /* Current member name while hashing. */
/*
* Because of space constraints and similar things, files are archived
@@ -590,14 +549,14 @@ ArchStatMember(char *archive, char *member, Boolean hash)
* to point 'member' to the final component, if there is one, to make
* the comparisons easier...
*/
- cp = strrchr(member, '/');
- if (cp != NULL) {
- member = cp + 1;
+ const char *base = strrchr(member, '/');
+ if (base != NULL) {
+ member = base + 1;
}
- ln = Lst_Find(archives, archive, ArchFindArchive);
+ ln = Lst_Find(archives, ArchFindArchive, archive);
if (ln != NULL) {
- ar = (Arch *)Lst_Datum(ln);
+ ar = LstNode_Datum(ln);
he = Hash_FindEntry(&ar->members, member);
@@ -610,8 +569,7 @@ ArchStatMember(char *archive, char *member, Boolean hash)
if (len > AR_MAX_NAME_LEN) {
len = AR_MAX_NAME_LEN;
- strncpy(copy, member, AR_MAX_NAME_LEN);
- copy[AR_MAX_NAME_LEN] = '\0';
+ snprintf(copy, sizeof copy, "%s", member);
}
if ((he = Hash_FindEntry(&ar->members, copy)) != NULL)
return (struct ar_hdr *)Hash_GetValue(he);
@@ -653,7 +611,7 @@ ArchStatMember(char *archive, char *member, Boolean hash)
* can handle...
*/
if ((fread(magic, SARMAG, 1, arch) != 1) ||
- (strncmp(magic, ARMAG, SARMAG) != 0)) {
+ (strncmp(magic, ARMAG, SARMAG) != 0)) {
fclose(arch);
return NULL;
}
@@ -673,6 +631,8 @@ ArchStatMember(char *archive, char *member, Boolean hash)
*/
goto badarch;
} else {
+ char *nameend;
+
/*
* We need to advance the stream's pointer to the start of the
* next header. Files are padded with newlines to an even-byte
@@ -680,13 +640,14 @@ ArchStatMember(char *archive, char *member, Boolean hash)
* 'size' field of the header and round it up during the seek.
*/
arh.AR_SIZE[sizeof(arh.AR_SIZE)-1] = '\0';
- size = (int)strtol(arh.AR_SIZE, NULL, 10);
+ size = (size_t)strtol(arh.ar_size, NULL, 10);
memcpy(memName, arh.AR_NAME, sizeof(arh.AR_NAME));
- for (cp = &memName[AR_MAX_NAME_LEN]; *cp == ' '; cp--) {
- continue;
+ nameend = memName + AR_MAX_NAME_LEN;
+ while (*nameend == ' ') {
+ nameend--;
}
- cp[1] = '\0';
+ nameend[1] = '\0';
#ifdef SVR4ARCHIVES
/*
@@ -706,8 +667,8 @@ ArchStatMember(char *archive, char *member, Boolean hash)
}
}
else {
- if (cp[0] == '/')
- cp[0] = '\0';
+ if (nameend[0] == '/')
+ nameend[0] = '\0';
}
#endif
@@ -719,11 +680,11 @@ ArchStatMember(char *archive, char *member, Boolean hash)
if (strncmp(memName, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 &&
isdigit((unsigned char)memName[sizeof(AR_EFMT1) - 1])) {
- unsigned int elen = atoi(&memName[sizeof(AR_EFMT1)-1]);
+ int elen = atoi(&memName[sizeof(AR_EFMT1)-1]);
- if (elen > MAXPATHLEN)
+ if ((unsigned int)elen > MAXPATHLEN)
goto badarch;
- if (fread(memName, elen, 1, arch) != 1)
+ if (fread(memName, (size_t)elen, 1, arch) != 1)
goto badarch;
memName[elen] = '\0';
if (fseek(arch, -elen, SEEK_CUR) != 0)
@@ -738,13 +699,13 @@ ArchStatMember(char *archive, char *member, Boolean hash)
Hash_SetValue(he, bmake_malloc(sizeof(struct ar_hdr)));
memcpy(Hash_GetValue(he), &arh, sizeof(struct ar_hdr));
}
- if (fseek(arch, (size + 1) & ~1, SEEK_CUR) != 0)
+ if (fseek(arch, ((long)size + 1) & ~1, SEEK_CUR) != 0)
goto badarch;
}
fclose(arch);
- (void)Lst_AtEnd(archives, ar);
+ Lst_Append(archives, ar);
/*
* Now that the archive has been read and cached, we can look into
@@ -774,17 +735,14 @@ badarch:
* If it is "//", then load the table of filenames
* If it is "/<offset>", then try to substitute the long file name
* from offset of a table previously read.
+ * If a table is read, the file pointer is moved to the next archive
+ * member.
*
* Results:
* -1: Bad data in archive
* 0: A table was loaded from the file
* 1: Name was successfully substituted from table
* 2: Name was not successfully substituted from table
- *
- * Side Effects:
- * If a table is read, the file pointer is moved to the next archive
- * member
- *
*-----------------------------------------------------------------------
*/
static int
@@ -834,7 +792,7 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
}
if (DEBUG(ARCH)) {
fprintf(debug_file, "Found svr4 archive name table with %lu entries\n",
- (unsigned long)entry);
+ (unsigned long)entry);
}
return 0;
}
@@ -861,8 +819,7 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
fprintf(debug_file, "Replaced %s with %s\n", name, &ar->fnametab[entry]);
}
- (void)strncpy(name, &ar->fnametab[entry], MAXPATHLEN);
- name[MAXPATHLEN] = '\0';
+ snprintf(name, MAXPATHLEN + 1, "%s", &ar->fnametab[entry]);
return 1;
}
#endif
@@ -874,6 +831,7 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
* Locate a member of an archive, given the path of the archive and
* the path of the desired member. If the archive is to be modified,
* the mode should be "r+", if not, it should be "r".
+ * The passed struct ar_hdr structure is filled in.
*
* Input:
* archive Path to the archive
@@ -886,21 +844,17 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
* An FILE *, opened for reading and writing, positioned at the
* start of the member's struct ar_hdr, or NULL if the member was
* nonexistent. The current struct ar_hdr for member.
- *
- * Side Effects:
- * The passed struct ar_hdr structure is filled in.
- *
*-----------------------------------------------------------------------
*/
static FILE *
-ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr,
+ArchFindMember(const char *archive, const char *member, struct ar_hdr *arhPtr,
const char *mode)
{
FILE * arch; /* Stream to archive */
int size; /* Size of archive member */
- char *cp; /* Useful character pointer */
char magic[SARMAG];
size_t len, tlen;
+ const char * base;
arch = fopen(archive, mode);
if (arch == NULL) {
@@ -912,7 +866,7 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr,
* can handle...
*/
if ((fread(magic, SARMAG, 1, arch) != 1) ||
- (strncmp(magic, ARMAG, SARMAG) != 0)) {
+ (strncmp(magic, ARMAG, SARMAG) != 0)) {
fclose(arch);
return NULL;
}
@@ -923,9 +877,9 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr,
* to point 'member' to the final component, if there is one, to make
* the comparisons easier...
*/
- cp = strrchr(member, '/');
- if (cp != NULL) {
- member = cp + 1;
+ base = strrchr(member, '/');
+ if (base != NULL) {
+ member = base + 1;
}
len = tlen = strlen(member);
if (len > sizeof(arhPtr->AR_NAME)) {
@@ -958,7 +912,7 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr,
* the file at the actual member, rather than its header, but
* not here...
*/
- if (fseek(arch, -sizeof(struct ar_hdr), SEEK_CUR) != 0) {
+ if (fseek(arch, -(long)sizeof(struct ar_hdr), SEEK_CUR) != 0) {
fclose(arch);
return NULL;
}
@@ -974,14 +928,14 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr,
sizeof(AR_EFMT1) - 1) == 0 &&
isdigit((unsigned char)arhPtr->AR_NAME[sizeof(AR_EFMT1) - 1])) {
- unsigned int elen = atoi(&arhPtr->AR_NAME[sizeof(AR_EFMT1)-1]);
+ int elen = atoi(&arhPtr->AR_NAME[sizeof(AR_EFMT1)-1]);
char ename[MAXPATHLEN + 1];
- if (elen > MAXPATHLEN) {
+ if ((unsigned int)elen > MAXPATHLEN) {
fclose(arch);
return NULL;
}
- if (fread(ename, elen, 1, arch) != 1) {
+ if (fread(ename, (size_t)elen, 1, arch) != 1) {
fclose(arch);
return NULL;
}
@@ -991,7 +945,7 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr,
}
if (strncmp(ename, member, len) == 0) {
/* Found as extended name */
- if (fseek(arch, -sizeof(struct ar_hdr) - elen,
+ if (fseek(arch, -(long)sizeof(struct ar_hdr) - elen,
SEEK_CUR) != 0) {
fclose(arch);
return NULL;
@@ -1035,18 +989,15 @@ skip:
*-----------------------------------------------------------------------
* Arch_Touch --
* Touch a member of an archive.
+ * The modification time of the entire archive is also changed.
+ * For a library, this could necessitate the re-ranlib'ing of the
+ * whole thing.
*
* Input:
* gn Node of member to touch
*
* Results:
* The 'time' field of the member's header is updated.
- *
- * Side Effects:
- * The modification time of the entire archive is also changed.
- * For a library, this could necessitate the re-ranlib'ing of the
- * whole thing.
- *
*-----------------------------------------------------------------------
*/
void
@@ -1060,8 +1011,8 @@ Arch_Touch(GNode *gn)
Var_Value(MEMBER, gn, &p2),
&arh, "r+");
- free(p1);
- free(p2);
+ bmake_free(p1);
+ bmake_free(p2);
snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now);
@@ -1071,37 +1022,24 @@ Arch_Touch(GNode *gn)
}
}
-/*-
- *-----------------------------------------------------------------------
- * Arch_TouchLib --
- * Given a node which represents a library, touch the thing, making
- * sure that the table of contents also is touched.
+/* Given a node which represents a library, touch the thing, making sure that
+ * the table of contents also is touched.
+ *
+ * Both the modification time of the library and of the RANLIBMAG member are
+ * set to 'now'.
*
* Input:
* gn The node of the library to touch
- *
- * Results:
- * None.
- *
- * Side Effects:
- * Both the modification time of the library and of the RANLIBMAG
- * member are set to 'now'.
- *
- *-----------------------------------------------------------------------
*/
void
-#if !defined(RANLIBMAG)
-Arch_TouchLib(GNode *gn MAKE_ATTR_UNUSED)
-#else
Arch_TouchLib(GNode *gn)
-#endif
{
#ifdef RANLIBMAG
FILE * arch; /* Stream open to archive */
struct ar_hdr arh; /* Header describing table of contents */
struct utimbuf times; /* Times for utime() call */
- arch = ArchFindMember(gn->path, UNCONST(RANLIBMAG), &arh, "r+");
+ arch = ArchFindMember(gn->path, RANLIBMAG, &arh, "r+");
snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now);
if (arch != NULL) {
@@ -1111,25 +1049,16 @@ Arch_TouchLib(GNode *gn)
times.actime = times.modtime = now;
utime(gn->path, &times);
}
+#else
+ (void)gn;
#endif
}
-/*-
- *-----------------------------------------------------------------------
- * Arch_MTime --
- * Return the modification time of a member of an archive.
+/* Return the modification time of a member of an archive. The mtime field
+ * of the given node is filled in with the value returned by the function.
*
* Input:
* gn Node describing archive member
- *
- * Results:
- * The modification time(seconds).
- *
- * Side Effects:
- * The mtime field of the given node is filled in with the value
- * returned by the function.
- *
- *-----------------------------------------------------------------------
*/
time_t
Arch_MTime(GNode *gn)
@@ -1142,8 +1071,8 @@ Arch_MTime(GNode *gn)
Var_Value(MEMBER, gn, &p2),
TRUE);
- free(p1);
- free(p2);
+ bmake_free(p1);
+ bmake_free(p2);
if (arhPtr != NULL) {
modTime = (time_t)strtol(arhPtr->AR_DATE, NULL, 10);
@@ -1155,34 +1084,17 @@ Arch_MTime(GNode *gn)
return modTime;
}
-/*-
- *-----------------------------------------------------------------------
- * Arch_MemMTime --
- * Given a non-existent archive member's node, get its modification
- * time from its archived form, if it exists.
- *
- * Results:
- * The modification time.
- *
- * Side Effects:
- * The mtime field is filled in.
- *
- *-----------------------------------------------------------------------
- */
+/* Given a non-existent archive member's node, get its modification time from
+ * its archived form, if it exists. gn->mtime is filled in as well. */
time_t
Arch_MemMTime(GNode *gn)
{
LstNode ln;
GNode *pgn;
- char *nameStart,
- *nameEnd;
- if (Lst_Open(gn->parents) != SUCCESS) {
- gn->mtime = 0;
- return 0;
- }
+ Lst_Open(gn->parents);
while ((ln = Lst_Next(gn->parents)) != NULL) {
- pgn = (GNode *)Lst_Datum(ln);
+ pgn = LstNode_Datum(ln);
if (pgn->type & OP_ARCHV) {
/*
@@ -1192,12 +1104,13 @@ Arch_MemMTime(GNode *gn)
* child. We keep searching its parents in case some other
* parent requires this child to exist...
*/
- nameStart = strchr(pgn->name, '(') + 1;
- nameEnd = strchr(nameStart, ')');
+ const char *nameStart = strchr(pgn->name, '(') + 1;
+ const char *nameEnd = strchr(nameStart, ')');
+ size_t nameLen = (size_t)(nameEnd - nameStart);
if ((pgn->flags & REMAKE) &&
- strncmp(nameStart, gn->name, nameEnd - nameStart) == 0) {
- gn->mtime = Arch_MTime(pgn);
+ strncmp(nameStart, gn->name, nameLen) == 0) {
+ gn->mtime = Arch_MTime(pgn);
}
} else if (pgn->flags & REMAKE) {
/*
@@ -1214,29 +1127,20 @@ Arch_MemMTime(GNode *gn)
return gn->mtime;
}
-/*-
- *-----------------------------------------------------------------------
- * Arch_FindLib --
- * Search for a library along the given search path.
+/* Search for a library along the given search path.
+ *
+ * The node's 'path' field is set to the found path (including the
+ * actual file name, not -l...). If the system can handle the -L
+ * flag when linking (or we cannot find the library), we assume that
+ * the user has placed the .LIBS variable in the final linking
+ * command (or the linker will know where to find it) and set the
+ * TARGET variable for this node to be the node's name. Otherwise,
+ * we set the TARGET variable to be the full path of the library,
+ * as returned by Dir_FindFile.
*
* Input:
* gn Node of library to find
* path Search path
- *
- * Results:
- * None.
- *
- * Side Effects:
- * The node's 'path' field is set to the found path (including the
- * actual file name, not -l...). If the system can handle the -L
- * flag when linking (or we cannot find the library), we assume that
- * the user has placed the .LIBRARIES variable in the final linking
- * command (or the linker will know where to find it) and set the
- * TARGET variable for this node to be the node's name. Otherwise,
- * we set the TARGET variable to be the full path of the library,
- * as returned by Dir_FindFile.
- *
- *-----------------------------------------------------------------------
*/
void
Arch_FindLib(GNode *gn, Lst path)
@@ -1258,44 +1162,38 @@ Arch_FindLib(GNode *gn, Lst path)
#endif /* LIBRARIES */
}
-/*-
- *-----------------------------------------------------------------------
- * Arch_LibOODate --
- * Decide if a node with the OP_LIB attribute is out-of-date. Called
- * from Make_OODate to make its life easier.
- *
- * There are several ways for a library to be out-of-date that are
- * not available to ordinary files. In addition, there are ways
- * that are open to regular files that are not available to
- * libraries. A library that is only used as a source is never
- * considered out-of-date by itself. This does not preclude the
- * library's modification time from making its parent be out-of-date.
- * A library will be considered out-of-date for any of these reasons,
- * given that it is a target on a dependency line somewhere:
- * Its modification time is less than that of one of its
- * sources (gn->mtime < gn->cmgn->mtime).
- * Its modification time is greater than the time at which the
- * make began (i.e. it's been modified in the course
- * of the make, probably by archiving).
- * The modification time of one of its sources is greater than
- * the one of its RANLIBMAG member (i.e. its table of contents
- * is out-of-date). We don't compare of the archive time
- * vs. TOC time because they can be too close. In my
- * opinion we should not bother with the TOC at all since
- * this is used by 'ar' rules that affect the data contents
- * of the archive, not by ranlib rules, which affect the
- * TOC.
+/* Decide if a node with the OP_LIB attribute is out-of-date. Called from
+ * Make_OODate to make its life easier.
+ * The library will be hashed if it hasn't been already.
+ *
+ * There are several ways for a library to be out-of-date that are
+ * not available to ordinary files. In addition, there are ways
+ * that are open to regular files that are not available to
+ * libraries. A library that is only used as a source is never
+ * considered out-of-date by itself. This does not preclude the
+ * library's modification time from making its parent be out-of-date.
+ * A library will be considered out-of-date for any of these reasons,
+ * given that it is a target on a dependency line somewhere:
+ *
+ * Its modification time is less than that of one of its sources
+ * (gn->mtime < gn->cmgn->mtime).
+ *
+ * Its modification time is greater than the time at which the make
+ * began (i.e. it's been modified in the course of the make, probably
+ * by archiving).
+ *
+ * The modification time of one of its sources is greater than the one
+ * of its RANLIBMAG member (i.e. its table of contents is out-of-date).
+ * We don't compare of the archive time vs. TOC time because they can be
+ * too close. In my opinion we should not bother with the TOC at all
+ * since this is used by 'ar' rules that affect the data contents of the
+ * archive, not by ranlib rules, which affect the TOC.
*
* Input:
* gn The library's graph node
*
* Results:
* TRUE if the library is out-of-date. FALSE otherwise.
- *
- * Side Effects:
- * The library will be hashed if it hasn't been already.
- *
- *-----------------------------------------------------------------------
*/
Boolean
Arch_LibOODate(GNode *gn)
@@ -1315,7 +1213,7 @@ Arch_LibOODate(GNode *gn)
struct ar_hdr *arhPtr; /* Header for __.SYMDEF */
int modTimeTOC; /* The table-of-contents's mod time */
- arhPtr = ArchStatMember(gn->path, UNCONST(RANLIBMAG), FALSE);
+ arhPtr = ArchStatMember(gn->path, RANLIBMAG, FALSE);
if (arhPtr != NULL) {
modTimeTOC = (int)strtol(arhPtr->AR_DATE, NULL, 10);
@@ -1340,40 +1238,14 @@ Arch_LibOODate(GNode *gn)
return oodate;
}
-/*-
- *-----------------------------------------------------------------------
- * Arch_Init --
- * Initialize things for this module.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * The 'archives' list is initialized.
- *
- *-----------------------------------------------------------------------
- */
+/* Initialize things for this module. */
void
Arch_Init(void)
{
- archives = Lst_Init(FALSE);
+ archives = Lst_Init();
}
-
-
-/*-
- *-----------------------------------------------------------------------
- * Arch_End --
- * Cleanup things for this module.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * The 'archives' list is freed
- *
- *-----------------------------------------------------------------------
- */
+/* Clean up things for this module. */
void
Arch_End(void)
{
@@ -1382,35 +1254,22 @@ Arch_End(void)
#endif
}
-/*-
- *-----------------------------------------------------------------------
- * Arch_IsLib --
- * Check if the node is a library
- *
- * Results:
- * True or False.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-int
+Boolean
Arch_IsLib(GNode *gn)
{
static const char armag[] = "!<arch>\n";
- char buf[sizeof(armag)-1];
+ char buf[sizeof armag - 1];
int fd;
if ((fd = open(gn->path, O_RDONLY)) == -1)
return FALSE;
- if (read(fd, buf, sizeof(buf)) != sizeof(buf)) {
+ if (read(fd, buf, sizeof buf) != sizeof buf) {
(void)close(fd);
return FALSE;
}
(void)close(fd);
- return memcmp(buf, armag, sizeof(buf)) == 0;
+ return memcmp(buf, armag, sizeof buf) == 0;
}
diff --git a/bmake.1 b/bmake.1
index c468cfe053d7..2cc452f2d171 100644
--- a/bmake.1
+++ b/bmake.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: make.1,v 1.282 2020/06/06 20:28:42 wiz Exp $
+.\" $NetBSD: make.1,v 1.289 2020/08/28 17:15:04 rillig Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
-.Dd June 5, 2020
+.Dd August 28, 2020
.Dt BMAKE 1
.Os
.Sh NAME
@@ -166,8 +166,15 @@ Print the input graph after making everything, or before exiting
on error.
.It Ar "g3"
Print the input graph before exiting on error.
+.It Ar h
+Print debugging information about hash table operations.
.It Ar j
Print debugging information about running multiple shells.
+.It Ar L
+Turn on lint checks.
+This will throw errors for variable assignments that do not parse
+correctly, at the time of assignment so the file and line number
+are available.
.It Ar l
Print commands in Makefiles regardless of whether or not they are prefixed by
.Ql @
@@ -311,7 +318,8 @@ as an argument).
.It Fl n
Display the commands that would have been executed, but do not
actually execute them unless the target depends on the .MAKE special
-source (see below).
+source (see below) or the command is prefixed with
+.Ql Ic + .
.It Fl N
Display the commands which would have been executed, but do not
actually execute any of them; useful for debugging top-level makefiles
@@ -412,37 +420,44 @@ or more sources.
This creates a relationship where the targets
.Dq depend
on the sources
-and are usually created from them.
-The exact relationship between the target and the source is determined
-by the operator that separates them.
-The three operators are as follows:
+and are customarily created from them.
+A target is considered out-of-date if it does not exist, or if its
+modification time is less than that of any of its sources.
+An out-of-date target will be re-created, but not until all sources
+have been examined and themselves re-created as needed.
+Three operators may be used:
.Bl -tag -width flag
.It Ic \&:
-A target is considered out-of-date if its modification time is less than
-those of any of its sources.
-Sources for a target accumulate over dependency lines when this operator
-is used.
-The target is removed if
+Many dependency lines may name this target but only one may have
+attached shell commands.
+All sources named in all dependency lines are considered together,
+and if needed the attached shell commands are run to create or
+re-create the target.
+If
.Nm
-is interrupted.
+is interrupted, the target is removed.
.It Ic \&!
-Targets are always re-created, but not until all sources have been
-examined and re-created as necessary.
-Sources for a target accumulate over dependency lines when this operator
-is used.
-The target is removed if
-.Nm
-is interrupted.
+The same, but the target is always re-created whether or not it is out
+of date.
.It Ic \&::
-If no sources are specified, the target is always re-created.
-Otherwise, a target is considered out-of-date if any of its sources has
-been modified more recently than the target.
-Sources for a target do not accumulate over dependency lines when this
-operator is used.
-The target will not be removed if
+Any dependency line may have attached shell commands, but each one
+is handled independently: its sources are considered and the attached
+shell commands are run if the target is out of date with respect to
+(only) those sources.
+Thus, different groups of the attached shell commands may be run
+depending on the circumstances.
+Furthermore, unlike
+.Ic \&:,
+for dependency lines with no sources, the attached shell
+commands are always run.
+Also unlike
+.Ic \&:,
+the target will not be removed if
.Nm
is interrupted.
.El
+All dependency lines mentioning a particular target must use the same
+operator.
.Pp
Targets and sources may contain the shell wildcard values
.Ql \&? ,
@@ -608,7 +623,7 @@ This shorter form is not recommended.
.Pp
If the variable name contains a dollar, then the name itself is expanded first.
This allows almost arbitrary variable names, however names containing dollar,
-braces, parenthesis, or whitespace are really best avoided!
+braces, parentheses, or whitespace are really best avoided!
.Pp
If the result of expanding a variable contains a dollar sign
.Pq Ql \&$
@@ -1126,6 +1141,9 @@ is set to the value of
for all programs which
.Nm
executes.
+.It Ev .SHELL
+The pathname of the shell used to run target scripts.
+It is read-only.
.It Ev .TARGETS
The list of targets explicitly specified on the command line, if any.
.It Ev VPATH
@@ -1171,7 +1189,7 @@ Replaces each word in the variable with its suffix.
.It Cm \&:H
Replaces each word in the variable with everything but the last component.
.It Cm \&:M Ns Ar pattern
-Select only those words that match
+Selects only those words that match
.Ar pattern .
The standard shell wildcard characters
.Pf ( Ql * ,
@@ -1195,11 +1213,11 @@ This is identical to
but selects all words which do not match
.Ar pattern .
.It Cm \&:O
-Order every word in variable alphabetically.
+Orders every word in variable alphabetically.
.It Cm \&:Or
-Order every word in variable in reverse alphabetical order.
+Orders every word in variable in reverse alphabetical order.
.It Cm \&:Ox
-Randomize words in variable.
+Shuffles the words in variable.
The results will be different each time you are referring to the
modified variable; use the assignment with expansion
.Pq Ql Cm \&:=
@@ -1249,7 +1267,7 @@ If a
.Va utc
value is not provided or is 0, the current time is used.
.It Cm \&:hash
-Compute a 32-bit hash of the value and encode it as hex digits.
+Computes a 32-bit hash of the value and encode it as hex digits.
.It Cm \&:localtime[=utc]
The value is a format string for
.Xr strftime 3 ,
@@ -1259,7 +1277,7 @@ If a
.Va utc
value is not provided or is 0, the current time is used.
.It Cm \&:tA
-Attempt to convert variable to an absolute path using
+Attempts to convert variable to an absolute path using
.Xr realpath 3 ,
if that fails, the value is unchanged.
.It Cm \&:tl
@@ -1271,7 +1289,7 @@ This modifier sets the separator to the character
If
.Ar c
is omitted, then no separator is used.
-The common escapes (including octal numeric codes), work as expected.
+The common escapes (including octal numeric codes) work as expected.
.It Cm \&:tu
Converts variable to upper-case letters.
.It Cm \&:tW
@@ -1287,21 +1305,21 @@ See also
.Sm off
.It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW
.Sm on
-Modify the first occurrence of
+Modifies the first occurrence of
.Ar old_string
-in the variable's value, replacing it with
+in each word of the variable's value, replacing it with
.Ar new_string .
If a
.Ql g
-is appended to the last slash of the pattern, all occurrences
+is appended to the last delimiter of the pattern, all occurrences
in each word are replaced.
If a
.Ql 1
-is appended to the last slash of the pattern, only the first word
+is appended to the last delimiter of the pattern, only the first occurrence
is affected.
If a
.Ql W
-is appended to the last slash of the pattern,
+is appended to the last delimiter of the pattern,
then the value is treated as a single word
(possibly containing embedded white space).
If
@@ -1370,13 +1388,6 @@ as occur in the word or words it is found in; the
.Ql W
modifier causes the value to be treated as a single word
(possibly containing embedded white space).
-Note that
-.Ql 1
-and
-.Ql g
-are orthogonal; the former specifies whether multiple words are
-potentially affected, the latter whether multiple substitutions can
-potentially occur within each affected word.
.Pp
As for the
.Cm \&:S
@@ -1387,9 +1398,9 @@ and
are subjected to variable expansion before being parsed as
regular expressions.
.It Cm \&:T
-Replaces each word in the variable with its last component.
+Replaces each word in the variable with its last path component.
.It Cm \&:u
-Remove adjacent duplicate words (like
+Removes adjacent duplicate words (like
.Xr uniq 1 ) .
.Sm off
.It Cm \&:\&? Ar true_string Cm \&: Ar false_string
@@ -1405,7 +1416,7 @@ usually contain variable expansions.
A common error is trying to use expressions like
.Dl ${NUMBERS:M42:?match:no}
which actually tests defined(NUMBERS),
-to determine is any words match "42" you need to use something like:
+to determine if any words match "42" you need to use something like:
.Dl ${"${NUMBERS:M42}" != \&"\&":?match:no} .
.It Ar :old_string=new_string
This is the
@@ -1449,7 +1460,7 @@ in either the
or
.Ar old_string ,
only the first instance is treated specially (as the pattern character);
-all subsequent instances are treated as regular characters
+all subsequent instances are treated as regular characters.
.Pp
Variable expansion occurs in the normal fashion inside both
.Ar old_string
@@ -1466,11 +1477,10 @@ This is the loop expansion mechanism from the OSF Development
Environment (ODE) make.
Unlike
.Cm \&.for
-loops expansion occurs at the time of
-reference.
-Assign
+loops, expansion occurs at the time of reference.
+Assigns
.Ar temp
-to each word in the variable and evaluate
+to each word in the variable and evaluates
.Ar string .
The ODE convention is that
.Ar temp
@@ -1481,7 +1491,7 @@ For example.
However a single character variable is often more readable:
.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
.It Cm \&:_[=var]
-Save the current variable value in
+Saves the current variable value in
.Ql $_
or the named
.Va var
@@ -1502,7 +1512,7 @@ is used to save the result of the
modifier which is later referenced using the index values from
.Ql :range .
.It Cm \&:U Ns Ar newval
-If the variable is undefined
+If the variable is undefined,
.Ar newval
is the value.
If the variable is defined, the existing value is returned.
@@ -1512,7 +1522,7 @@ It is handy for setting per-target CFLAGS for instance:
If a value is only required if the variable is undefined, use:
.Dl ${VAR:D:Unewval}
.It Cm \&:D Ns Ar newval
-If the variable is defined
+If the variable is defined,
.Ar newval
is the value.
.It Cm \&:L
@@ -1641,7 +1651,7 @@ Returns the number of words in the value.
.El \" :[range]
.El
.Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS
-Makefile inclusion, conditional structures and for loops reminiscent
+Makefile inclusion, conditional structures and for loops reminiscent
of the C programming language are provided in
.Nm .
All such structures are identified by a line beginning with a single
@@ -1687,7 +1697,7 @@ The possible conditionals are as follows:
The message is printed along with the name of the makefile and line number,
then
.Nm
-will exit.
+will exit immediately.
.It Ic .export Ar variable ...
Export the specified global variable.
If no variable list is provided, all globals are exported
@@ -1876,7 +1886,7 @@ operator is not an integral value, then
string comparison is performed between the expanded
variables.
If no relational operator is given, it is assumed that the expanded
-variable is being compared against 0 or an empty string in the case
+variable is being compared against 0, or an empty string in the case
of a string comparison.
.Pp
When
@@ -1917,7 +1927,7 @@ The syntax of a for loop is:
.Pp
.Bl -tag -compact -width Ds
.It Ic \&.for Ar variable Oo Ar variable ... Oc Ic in Ar expression
-.It Aq make-rules
+.It Aq make-lines
.It Ic \&.endfor
.El
.Pp
@@ -1929,7 +1939,7 @@ On each iteration of the loop, one word is taken and assigned to each
in order, and these
.Ic variables
are substituted into the
-.Ic make-rules
+.Ic make-lines
inside the body of the for loop.
The number of words must come out even; that is, if there are three
iteration variables, the number of words provided must be a multiple
diff --git a/bmake.cat1 b/bmake.cat1
index feb93698e34f..564e811737da 100644
--- a/bmake.cat1
+++ b/bmake.cat1
@@ -89,9 +89,15 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
g3 Print the input graph before exiting on error.
+ h Print debugging information about hash table operations.
+
j Print debugging information about running multiple
shells.
+ 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.
+
l Print commands in Makefiles regardless of whether or not
they are prefixed by `@' or other "quiet" flags. Also
known as "loud" behavior.
@@ -188,7 +194,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
-n Display the commands that would have been executed, but do not
actually execute them unless the target depends on the .MAKE spe-
- cial source (see below).
+ cial source (see below) or the command is prefixed with `+'.
-N Display the commands which would have been executed, but do not
actually execute any of them; useful for debugging top-level
@@ -260,25 +266,31 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
FILE DEPENDENCY SPECIFICATIONS
Dependency lines consist of one or more targets, an operator, and zero or
more sources. This creates a relationship where the targets ``depend''
- on the sources and are usually created from them. The exact relationship
- between the target and the source is determined by the operator that sep-
- arates them. The three operators are as follows:
-
- : A target is considered out-of-date if its modification time is less
- than those of any of its sources. Sources for a target accumulate
- over dependency lines when this operator is used. The target is
- removed if bmake is interrupted.
-
- ! Targets are always re-created, but not until all sources have been
- examined and re-created as necessary. Sources for a target accumu-
- late over dependency lines when this operator is used. The target
- is removed if bmake is interrupted.
-
- :: If no sources are specified, the target is always re-created. Oth-
- erwise, a target is considered out-of-date if any of its sources
- has been modified more recently than the target. Sources for a
- target do not accumulate over dependency lines when this operator
- is used. The target will not be removed if bmake is interrupted.
+ on the sources and are customarily created from them. A target is con-
+ sidered out-of-date if it does not exist, or if its modification time is
+ less than that of any of its sources. An out-of-date target will be re-
+ created, but not until all sources have been examined and themselves re-
+ created as needed. Three operators may be used:
+
+ : Many dependency lines may name this target but only one may have
+ attached shell commands. All sources named in all dependency lines
+ are considered together, and if needed the attached shell commands
+ are run to create or re-create the target. If bmake is inter-
+ rupted, the target is removed.
+
+ ! The same, but the target is always re-created whether or not it is
+ out of date.
+
+ :: Any dependency line may have attached shell commands, but each one
+ is handled independently: its sources are considered and the
+ attached shell commands are run if the target is out of date with
+ respect to (only) those sources. Thus, different groups of the
+ attached shell commands may be run depending on the circumstances.
+ Furthermore, unlike :, for dependency lines with no sources, the
+ attached shell commands are always run. Also unlike :, the target
+ will not be removed if bmake is interrupted.
+ All dependency lines mentioning a particular target must use the same
+ operator.
Targets and sources may contain the shell wildcard values `?', `*', `[]',
and `{}'. The values `?', `*', and `[]' may only be used as part of the
@@ -374,7 +386,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
If the variable name contains a dollar, then the name itself is expanded
first. This allows almost arbitrary variable names, however names con-
- taining dollar, braces, parenthesis, or whitespace are really best
+ taining dollar, braces, parentheses, or whitespace are really best
avoided!
If the result of expanding a variable contains a dollar sign (`$') the
@@ -729,6 +741,9 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
contains a variable transform. `PWD' is set to the value
of `.OBJDIR' for all programs which bmake executes.
+ .SHELL The pathname of the shell used to run target scripts. It
+ is read-only.
+
.TARGETS The list of targets explicitly specified on the command
line, if any.
@@ -765,7 +780,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
ponent.
:Mpattern
- Select only those words that match pattern. The standard shell
+ Selects only those words that match pattern. The standard shell
wildcard characters (`*', `?', and `[]') may be used. The wildcard
characters may be escaped with a backslash (`\'). As a consequence
of the way values are split into words, matched, and then joined, a
@@ -779,11 +794,11 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
This is identical to `:M', but selects all words which do not match
pattern.
- :O Order every word in variable alphabetically.
+ :O Orders every word in variable alphabetically.
- :Or Order every word in variable in reverse alphabetical order.
+ :Or Orders every word in variable in reverse alphabetical order.
- :Ox Randomize words in variable. The results will be different each
+ :Ox Shuffles the words in variable. The results will be different each
time you are referring to the modified variable; use the assignment
with expansion (`:=') to prevent such behavior. For example,
@@ -821,13 +836,13 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
utc value is not provided or is 0, the current time is used.
:hash
- Compute a 32-bit hash of the value and encode it as hex digits.
+ Computes a 32-bit hash of the value and encode it as hex digits.
:localtime[=utc]
The value is a format string for strftime(3), using localtime(3).
If a utc value is not provided or is 0, the current time is used.
- :tA Attempt to convert variable to an absolute path using realpath(3),
+ :tA Attempts to convert variable to an absolute path using realpath(3),
if that fails, the value is unchanged.
:tl Converts variable to lower-case letters.
@@ -836,7 +851,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
Words in the variable are normally separated by a space on expan-
sion. This modifier sets the separator to the character c. If c is
omitted, then no separator is used. The common escapes (including
- octal numeric codes), work as expected.
+ octal numeric codes) work as expected.
:tu Converts variable to upper-case letters.
@@ -847,20 +862,20 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
white space. See also `:[@]'.
:S/old_string/new_string/[1gW]
- Modify the first occurrence of old_string in the variable's value,
- replacing it with new_string. If a `g' is appended to the last
- slash of the pattern, all occurrences in each word are replaced. If
- a `1' is appended to the last slash of the pattern, only the first
- word is affected. If a `W' is appended to the last slash of the
- pattern, then the value is treated as a single word (possibly con-
- taining embedded white space). If old_string begins with a caret
- (`^'), old_string is anchored at the beginning of each word. If
- old_string ends with a dollar sign (`$'), it is anchored at the end
- of each word. Inside new_string, an ampersand (`&') is replaced by
- old_string (without any `^' or `$'). Any character may be used as a
- delimiter for the parts of the modifier string. The anchoring,
- ampersand and delimiter characters may be escaped with a backslash
- (`\').
+ Modifies the first occurrence of old_string in each word of the
+ variable's value, replacing it with new_string. If a `g' is
+ appended to the last delimiter of the pattern, all occurrences in
+ each word are replaced. If a `1' is appended to the last delimiter
+ of the pattern, only the first occurrence is affected. If a `W' is
+ appended to the last delimiter of the pattern, then the value is
+ treated as a single word (possibly containing embedded white space).
+ If old_string begins with a caret (`^'), old_string is anchored at
+ the beginning of each word. If old_string ends with a dollar sign
+ (`$'), it is anchored at the end of each word. Inside new_string,
+ an ampersand (`&') is replaced by old_string (without any `^' or
+ `$'). Any character may be used as a delimiter for the parts of the
+ modifier string. The anchoring, ampersand and delimiter characters
+ may be escaped with a backslash (`\').
Variable expansion occurs in the normal fashion inside both
old_string and new_string with the single exception that a backslash
@@ -878,16 +893,13 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
instances of the search pattern pattern as occur in the word or
words it is found in; the `W' modifier causes the value to be
treated as a single word (possibly containing embedded white space).
- Note that `1' and `g' are orthogonal; the former specifies whether
- multiple words are potentially affected, the latter whether multiple
- substitutions can potentially occur within each affected word.
As for the :S modifier, the pattern and replacement are subjected to
variable expansion before being parsed as regular expressions.
- :T Replaces each word in the variable with its last component.
+ :T Replaces each word in the variable with its last path component.
- :u Remove adjacent duplicate words (like uniq(1)).
+ :u Removes adjacent duplicate words (like uniq(1)).
:?true_string:false_string
If the variable name (not its value), when parsed as a .if condi-
@@ -898,7 +910,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
variable expansions. A common error is trying to use expressions
like
${NUMBERS:M42:?match:no}
- which actually tests defined(NUMBERS), to determine is any words
+ which actually tests defined(NUMBERS), to determine if any words
match "42" you need to use something like:
${"${NUMBERS:M42}" != "":?match:no}.
@@ -916,7 +928,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
pattern matching character (%) in either the new_string or
old_string, only the first instance is treated specially (as the
pattern character); all subsequent instances are treated as regular
- characters
+ characters.
Variable expansion occurs in the normal fashion inside both
old_string and new_string with the single exception that a backslash
@@ -925,17 +937,17 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
:@temp@string@
This is the loop expansion mechanism from the OSF Development Envi-
- ronment (ODE) make. Unlike .for loops expansion occurs at the time
- of reference. Assign temp to each word in the variable and evaluate
- string. The ODE convention is that temp should start and end with a
- period. For example.
+ ronment (ODE) make. Unlike .for loops, expansion occurs at the time
+ of reference. Assigns temp to each word in the variable and evalu-
+ ates string. The ODE convention is that temp should start and end
+ with a period. For example.
${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@}
However a single character variable is often more readable:
${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
:_[=var]
- Save the current variable value in `$_' or the named var for later
+ Saves the current variable value in `$_' or the named var for later
reference. Example usage:
M_cmpv.units = 1 1000 1000000
@@ -948,7 +960,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
later referenced using the index values from `:range'.
:Unewval
- If the variable is undefined newval is the value. If the variable
+ If the variable is undefined, newval is the value. If the variable
is defined, the existing value is returned. This is another ODE
make feature. It is handy for setting per-target CFLAGS for
instance:
@@ -957,7 +969,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
${VAR:D:Unewval}
:Dnewval
- If the variable is defined newval is the value.
+ If the variable is defined, newval is the value.
:L The name of the variable is the value.
@@ -1033,7 +1045,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
# Returns the number of words in the value.
INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS
- Makefile inclusion, conditional structures and for loops reminiscent of
+ Makefile inclusion, conditional structures and for loops reminiscent of
the C programming language are provided in bmake. All such structures
are identified by a line beginning with a single dot (`.') character.
Files are included with either .include <file> or .include "file". Vari-
@@ -1057,7 +1069,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
.error message
The message is printed along with the name of the makefile and
- line number, then bmake will exit.
+ line number, then bmake will exit immediately.
.export variable ...
Export the specified global variable. If no variable list is
@@ -1191,7 +1203,7 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
variable expansion, either the left or right hand side of a `==' or `!='
operator is not an integral value, then string comparison is performed
between the expanded variables. If no relational operator is given, it
- is assumed that the expanded variable is being compared against 0 or an
+ is assumed that the expanded variable is being compared against 0, or an
empty string in the case of a string comparison.
When bmake is evaluating one of these conditional expressions, and it
@@ -1210,12 +1222,12 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
The syntax of a for loop is:
.for variable [variable ...] in expression
- <make-rules>
+ <make-lines>
.endfor
After the for expression is evaluated, it is split into words. On each
iteration of the loop, one word is taken and assigned to each variable,
- in order, and these variables are substituted into the make-rules inside
+ in order, and these variables are substituted into the make-lines inside
the body of the for loop. The number of words must come out even; that
is, if there are three iteration variables, the number of words provided
must be a multiple of three.
@@ -1556,4 +1568,4 @@ BMAKE(1) FreeBSD General Commands Manual BMAKE(1)
There is no way of escaping a space character in a filename.
-FreeBSD 11.3 June 5, 2020 FreeBSD 11.3
+FreeBSD 11.3 August 28, 2020 FreeBSD 11.3
diff --git a/bsd.after-import.mk b/bsd.after-import.mk
index 23f30aa6c638..0d48f3c26648 100644
--- a/bsd.after-import.mk
+++ b/bsd.after-import.mk
@@ -1,4 +1,4 @@
-# $Id: bsd.after-import.mk,v 1.15 2018/12/30 17:14:24 sjg Exp $
+# $Id: bsd.after-import.mk,v 1.16 2020/07/12 03:39:01 sjg Exp $
# This makefile is for use when integrating bmake into a BSD build
# system. Use this makefile after importing bmake.
@@ -9,7 +9,7 @@
# The goal is to allow the benefits of autoconf without
# the overhead of running configure.
-all: _makefile
+all: _makefile _utmakefile
all: after-import
# we rely on bmake
@@ -37,7 +37,9 @@ SRCTOP := ${srctop}
.endif
# This lets us match what boot-strap does
-.if !defined(HOST_OS)
+.if defined(.MAKE.OS)
+HOST_OS:= ${.MAKE.OS}
+.elif !defined(HOST_OS)
HOST_OS!= uname
.endif
@@ -107,5 +109,18 @@ _makefile: bootstrap ${MAKEFILE}
@cmp -s ${.TARGET} ${.CURDIR}/Makefile || \
mv ${.TARGET} ${.CURDIR}/Makefile
+_utmakefile: bootstrap ${MAKEFILE}
+ @echo Generating ${.CURDIR}/unit-tests/Makefile
+ @mkdir -p ${.CURDIR}/unit-tests
+ @(echo '# This is a generated file, do NOT edit!'; \
+ echo '# See ${_this:S,${SRCTOP}/,,}'; \
+ echo '#'; echo '# $$${HOST_OS}$$'; \
+ ${MAKEFILE_SED} \
+ -e '/^UNIT_TESTS/s,=.*,= $${srcdir},' \
+ ${BMAKE_SRC}/unit-tests/Makefile ) > ${.TARGET}
+ @cmp -s ${.TARGET} ${.CURDIR}/unit-tests/Makefile || \
+ mv ${.TARGET} ${.CURDIR}/unit-tests/Makefile
+
+
.include <bsd.obj.mk>
diff --git a/buf.c b/buf.c
index 360b8cedde13..f96d8fbf9792 100644
--- a/buf.c
+++ b/buf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: buf.c,v 1.26 2020/07/03 08:02:55 rillig Exp $ */
+/* $NetBSD: buf.c,v 1.37 2020/08/23 08:21:50 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,173 +70,123 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: buf.c,v 1.26 2020/07/03 08:02:55 rillig Exp $";
+static char rcsid[] = "$NetBSD: buf.c,v 1.37 2020/08/23 08:21:50 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: buf.c,v 1.26 2020/07/03 08:02:55 rillig Exp $");
+__RCSID("$NetBSD: buf.c,v 1.37 2020/08/23 08:21:50 rillig Exp $");
#endif
#endif /* not lint */
#endif
-/*-
- * buf.c --
- * Functions for automatically-expanded buffers.
- */
-
-#include "make.h"
-#include "buf.h"
-
-#ifndef max
-#define max(a,b) ((a) > (b) ? (a) : (b))
-#endif
+/* Functions for automatically-expanded null-terminated buffers. */
-#define BUF_DEF_SIZE 256 /* Default buffer size */
+#include <limits.h>
+#include "make.h"
-/*-
- *-----------------------------------------------------------------------
- * Buf_Expand_1 --
- * Extend buffer for single byte add.
- *
- *-----------------------------------------------------------------------
- */
+/* Extend the buffer for adding a single byte. */
void
Buf_Expand_1(Buffer *bp)
{
- bp->size += max(bp->size, 16);
+ bp->size += MAX(bp->size, 16);
bp->buffer = bmake_realloc(bp->buffer, bp->size);
}
-/*-
- *-----------------------------------------------------------------------
- * Buf_AddBytes --
- * Add a number of bytes to the buffer.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * Guess what?
- *
- *-----------------------------------------------------------------------
- */
+/* Add the given bytes to the buffer. */
void
-Buf_AddBytes(Buffer *bp, int numBytes, const Byte *bytesPtr)
+Buf_AddBytes(Buffer *bp, const char *bytesPtr, size_t numBytes)
{
- int count = bp->count;
- Byte *ptr;
+ size_t count = bp->count;
+ char *ptr;
if (__predict_false(count + numBytes >= bp->size)) {
- bp->size += max(bp->size, numBytes + 16);
+ bp->size += MAX(bp->size, numBytes + 16);
bp->buffer = bmake_realloc(bp->buffer, bp->size);
}
ptr = bp->buffer + count;
bp->count = count + numBytes;
- ptr[numBytes] = 0;
memcpy(ptr, bytesPtr, numBytes);
+ ptr[numBytes] = '\0';
}
-/*-
- *-----------------------------------------------------------------------
- * Buf_GetAll --
- * Get all the available data at once.
- *
- * Results:
- * A pointer to the data and the number of bytes available.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-Byte *
-Buf_GetAll(Buffer *bp, int *numBytesPtr)
+/* Add the bytes between start and end to the buffer. */
+void
+Buf_AddBytesBetween(Buffer *bp, const char *start, const char *end)
{
+ Buf_AddBytes(bp, start, (size_t)(end - start));
+}
+
+/* Add the given string to the buffer. */
+void
+Buf_AddStr(Buffer *bp, const char *str)
+{
+ Buf_AddBytes(bp, str, strlen(str));
+}
+/* Add the given number to the buffer. */
+void
+Buf_AddInt(Buffer *bp, int n)
+{
+ enum {
+ bits = sizeof(int) * CHAR_BIT,
+ max_octal_digits = (bits + 2) / 3,
+ max_decimal_digits = /* at most */ max_octal_digits,
+ max_sign_chars = 1,
+ buf_size = max_sign_chars + max_decimal_digits + 1
+ };
+ char buf[buf_size];
+
+ size_t len = (size_t)snprintf(buf, sizeof buf, "%d", n);
+ Buf_AddBytes(bp, buf, len);
+}
+
+/* Get the data (usually a string) from the buffer.
+ * The returned data is valid until the next modifying operation
+ * on the buffer.
+ *
+ * Returns the pointer to the data and optionally the length of the
+ * data in the buffer. */
+char *
+Buf_GetAll(Buffer *bp, size_t *numBytesPtr)
+{
if (numBytesPtr != NULL)
*numBytesPtr = bp->count;
-
return bp->buffer;
}
-/*-
- *-----------------------------------------------------------------------
- * Buf_Empty --
- * Throw away bytes in a buffer.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * The bytes are discarded.
- *
- *-----------------------------------------------------------------------
- */
+/* Mark the buffer as empty, so it can be filled with data again. */
void
Buf_Empty(Buffer *bp)
{
-
bp->count = 0;
- *bp->buffer = 0;
+ bp->buffer[0] = '\0';
}
-/*-
- *-----------------------------------------------------------------------
- * Buf_Init --
- * Initialize a buffer. If no initial size is given, a reasonable
- * default is used.
- *
- * Input:
- * size Initial size for the buffer
- *
- * Results:
- * A buffer to be given to other functions in this library.
- *
- * Side Effects:
- * The buffer is created, the space allocated and pointers
- * initialized.
- *
- *-----------------------------------------------------------------------
- */
+/* Initialize a buffer.
+ * If the given initial size is 0, a reasonable default is used. */
void
-Buf_Init(Buffer *bp, int size)
+Buf_Init(Buffer *bp, size_t size)
{
if (size <= 0) {
- size = BUF_DEF_SIZE;
+ size = 256;
}
bp->size = size;
bp->count = 0;
bp->buffer = bmake_malloc(size);
- *bp->buffer = 0;
+ bp->buffer[0] = '\0';
}
-/*-
- *-----------------------------------------------------------------------
- * Buf_Destroy --
- * Nuke a buffer and all its resources.
- *
- * Input:
- * buf Buffer to destroy
- * freeData TRUE if the data should be destroyed
- *
- * Results:
- * Data buffer, NULL if freed
- *
- * Side Effects:
- * The buffer is freed.
- *
- *-----------------------------------------------------------------------
- */
-Byte *
+/* Reset the buffer.
+ * If freeData is TRUE, the data from the buffer is freed as well.
+ * Otherwise it is kept and returned. */
+char *
Buf_Destroy(Buffer *buf, Boolean freeData)
{
- Byte *data;
-
- data = buf->buffer;
+ char *data = buf->buffer;
if (freeData) {
free(data);
data = NULL;
@@ -249,42 +199,24 @@ Buf_Destroy(Buffer *buf, Boolean freeData)
return data;
}
-
-/*-
- *-----------------------------------------------------------------------
- * Buf_DestroyCompact --
- * Nuke a buffer and return its data.
- *
- * Input:
- * buf Buffer to destroy
- *
- * Results:
- * Data buffer
- *
- * Side Effects:
- * If the buffer size is much greater than its content,
- * a new buffer will be allocated and the old one freed.
- *
- *-----------------------------------------------------------------------
- */
#ifndef BUF_COMPACT_LIMIT
-# define BUF_COMPACT_LIMIT 128 /* worthwhile saving */
+# define BUF_COMPACT_LIMIT 128 /* worthwhile saving */
#endif
-Byte *
+/* Reset the buffer and return its data.
+ *
+ * If the buffer size is much greater than its content,
+ * a new buffer will be allocated and the old one freed. */
+char *
Buf_DestroyCompact(Buffer *buf)
{
#if BUF_COMPACT_LIMIT > 0
- Byte *data;
-
if (buf->size - buf->count >= BUF_COMPACT_LIMIT) {
/* We trust realloc to be smart */
- data = bmake_realloc(buf->buffer, buf->count + 1);
- if (data) {
- data[buf->count] = 0;
- Buf_Destroy(buf, FALSE);
- return data;
- }
+ char *data = bmake_realloc(buf->buffer, buf->count + 1);
+ data[buf->count] = '\0';
+ Buf_Destroy(buf, FALSE);
+ return data;
}
#endif
return Buf_Destroy(buf, FALSE);
diff --git a/buf.h b/buf.h
index 7bd2d2b7940b..1dc3cdbf58f3 100644
--- a/buf.h
+++ b/buf.h
@@ -1,4 +1,4 @@
-/* $NetBSD: buf.h,v 1.19 2017/05/31 22:02:06 maya Exp $ */
+/* $NetBSD: buf.h,v 1.28 2020/09/01 17:38:26 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -72,48 +72,54 @@
* from: @(#)buf.h 8.1 (Berkeley) 6/6/93
*/
-/*-
- * buf.h --
- * Header for users of the buf library.
- */
+/* Automatically growing null-terminated buffers of characters. */
#ifndef MAKE_BUF_H
#define MAKE_BUF_H
-typedef char Byte;
+#include <stddef.h>
+/* An automatically growing null-terminated buffer of characters. */
typedef struct Buffer {
- int size; /* Current size of the buffer */
- int count; /* Number of bytes in buffer */
- Byte *buffer; /* The buffer itself (zero terminated) */
+ size_t size; /* Allocated size of the buffer, including the null */
+ size_t count; /* Number of bytes in buffer, excluding the null */
+ char *buffer; /* The buffer itself (always null-terminated) */
} Buffer;
-/* If we aren't on netbsd, __predict_false() might not be defined. */
+/* If we aren't on NetBSD, __predict_false() might not be defined. */
#ifndef __predict_false
#define __predict_false(x) (x)
#endif
-/* Buf_AddByte adds a single byte to a buffer. */
-#define Buf_AddByte(bp, byte) do { \
- int _count = ++(bp)->count; \
- char *_ptr; \
- if (__predict_false(_count >= (bp)->size)) \
- Buf_Expand_1(bp); \
- _ptr = (bp)->buffer + _count; \
- _ptr[-1] = (byte); \
- _ptr[0] = 0; \
- } while (0)
+void Buf_Expand_1(Buffer *);
-#define BUF_ERROR 256
+/* Buf_AddByte adds a single byte to a buffer. */
+static inline void MAKE_ATTR_UNUSED
+Buf_AddByte(Buffer *bp, char byte)
+{
+ size_t count = ++bp->count;
+ char *ptr;
+ if (__predict_false(count >= bp->size))
+ Buf_Expand_1(bp);
+ ptr = bp->buffer + count;
+ ptr[-1] = byte;
+ ptr[0] = 0;
+}
-#define Buf_Size(bp) ((bp)->count)
+static inline size_t MAKE_ATTR_UNUSED
+Buf_Size(const Buffer *bp)
+{
+ return bp->count;
+}
-void Buf_Expand_1(Buffer *);
-void Buf_AddBytes(Buffer *, int, const Byte *);
-Byte *Buf_GetAll(Buffer *, int *);
+void Buf_AddBytes(Buffer *, const char *, size_t);
+void Buf_AddBytesBetween(Buffer *, const char *, const char *);
+void Buf_AddStr(Buffer *, const char *);
+void Buf_AddInt(Buffer *, int);
+char *Buf_GetAll(Buffer *, size_t *);
void Buf_Empty(Buffer *);
-void Buf_Init(Buffer *, int);
-Byte *Buf_Destroy(Buffer *, Boolean);
-Byte *Buf_DestroyCompact(Buffer *);
+void Buf_Init(Buffer *, size_t);
+char *Buf_Destroy(Buffer *, Boolean);
+char *Buf_DestroyCompact(Buffer *);
#endif /* MAKE_BUF_H */
diff --git a/compat.c b/compat.c
index cd88884736f1..150696ad6713 100644
--- a/compat.c
+++ b/compat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: compat.c,v 1.113 2020/07/03 08:13:23 rillig Exp $ */
+/* $NetBSD: compat.c,v 1.139 2020/08/30 20:08:47 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: compat.c,v 1.113 2020/07/03 08:13:23 rillig Exp $";
+static char rcsid[] = "$NetBSD: compat.c,v 1.139 2020/08/30 20:08:47 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: compat.c,v 1.113 2020/07/03 08:13:23 rillig Exp $");
+__RCSID("$NetBSD: compat.c,v 1.139 2020/08/30 20:08:47 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -129,34 +129,24 @@ static void
CompatDeleteTarget(GNode *gn)
{
if ((gn != NULL) && !Targ_Precious (gn)) {
- char *p1;
- char *file = Var_Value(TARGET, gn, &p1);
+ char *p1;
+ const char *file = Var_Value(TARGET, gn, &p1);
if (!noExecute && eunlink(file) != -1) {
Error("*** %s removed", file);
}
- free(p1);
+ bmake_free(p1);
}
}
-/*-
- *-----------------------------------------------------------------------
- * CompatInterrupt --
- * Interrupt the creation of the current target and remove it if
- * it ain't precious.
- *
- * Results:
- * None.
+/* Interrupt the creation of the current target and remove it if it ain't
+ * precious. Then exit.
*
- * Side Effects:
- * The target is removed and the process exits. If .INTERRUPT exists,
- * its commands are run first WITH INTERRUPTS IGNORED..
+ * If .INTERRUPT exists, its commands are run first WITH INTERRUPTS IGNORED.
*
* XXX: is .PRECIOUS supposed to inhibit .INTERRUPT? I doubt it, but I've
* left the logic alone for now. - dholland 20160826
- *
- *-----------------------------------------------------------------------
*/
static void
CompatInterrupt(int signo)
@@ -190,7 +180,7 @@ CompatInterrupt(int signo)
kill(myPid, signo);
}
}
-
+
/*-
*-----------------------------------------------------------------------
* CompatRunCommand --
@@ -215,7 +205,7 @@ CompatRunCommand(void *cmdp, void *gnp)
char *cmdStart; /* Start of expanded command */
char *cp, *bp;
Boolean silent, /* Don't print command */
- doIt; /* Execute even if -n */
+ doIt; /* Execute even if -n */
volatile Boolean errCheck; /* Check errors */
WAIT_T reason; /* Reason for child's death */
int status; /* Description of child's death */
@@ -224,21 +214,17 @@ CompatRunCommand(void *cmdp, void *gnp)
LstNode cmdNode; /* Node where current command is located */
const char ** volatile av; /* Argument vector for thing to exec */
char ** volatile mav;/* Copy of the argument vector for freeing */
- int argc; /* Number of arguments in av or 0 if not
- * dynamically allocated */
- Boolean local; /* TRUE if command should be executed
- * locally */
Boolean useShell; /* TRUE if command should be executed
* using a shell */
char * volatile cmd = (char *)cmdp;
GNode *gn = (GNode *)gnp;
- silent = gn->type & OP_SILENT;
+ silent = (gn->type & OP_SILENT) != 0;
errCheck = !(gn->type & OP_IGNORE);
doIt = FALSE;
- cmdNode = Lst_Member(gn->commands, cmd);
- cmdStart = Var_Subst(NULL, cmd, gn, VARF_WANTRES);
+ cmdNode = Lst_FindDatum(gn->commands, cmd);
+ cmdStart = Var_Subst(cmd, gn, VARE_WANTRES);
/*
* brk_string will return an argv with a NULL in av[0], thus causing
@@ -252,10 +238,11 @@ CompatRunCommand(void *cmdp, void *gnp)
return 0;
}
cmd = cmdStart;
- Lst_Replace(cmdNode, cmdStart);
+ LstNode_Set(cmdNode, cmdStart);
if ((gn->type & OP_SAVE_CMDS) && (gn != ENDNode)) {
- (void)Lst_AtEnd(ENDNode->commands, cmdStart);
+ assert(ENDNode != NULL);
+ Lst_Append(ENDNode->commands, cmdStart);
return 0;
}
if (strcmp(cmdStart, "...") == 0) {
@@ -266,7 +253,7 @@ CompatRunCommand(void *cmdp, void *gnp)
while ((*cmd == '@') || (*cmd == '-') || (*cmd == '+')) {
switch (*cmd) {
case '@':
- silent = DEBUG(LOUD) ? FALSE : TRUE;
+ silent = !DEBUG(LOUD);
break;
case '-':
errCheck = FALSE;
@@ -330,7 +317,6 @@ CompatRunCommand(void *cmdp, void *gnp)
if (DEBUG(JOB))
fprintf(debug_file, "Execute: '%s'\n", cmd);
-again:
if (useShell) {
/*
* We need to pass the command off to the shell, typically
@@ -352,9 +338,8 @@ again:
else
shargv[shargc++] = "-c";
shargv[shargc++] = cmd;
- shargv[shargc++] = NULL;
+ shargv[shargc] = NULL;
av = shargv;
- argc = 0;
bp = NULL;
mav = NULL;
} else {
@@ -362,16 +347,12 @@ again:
* No meta-characters, so no need to exec a shell. Break the command
* into words to form an argument vector we can execute.
*/
- mav = brk_string(cmd, &argc, TRUE, &bp);
- if (mav == NULL) {
- useShell = 1;
- goto again;
- }
+ Words words = Str_Words(cmd, FALSE);
+ mav = words.words;
+ bp = words.freeIt;
av = (void *)mav;
}
- local = TRUE;
-
#ifdef USE_META
if (useMeta) {
meta_compat_start();
@@ -392,10 +373,7 @@ again:
meta_compat_child();
}
#endif
- if (local)
- (void)execvp(av[0], (char *const *)UNCONST(av));
- else
- (void)execv(av[0], (char *const *)UNCONST(av));
+ (void)execvp(av[0], (char *const *)UNCONST(av));
execError("exec", av[0]);
_exit(1);
}
@@ -403,7 +381,9 @@ again:
free(mav);
free(bp);
- Lst_Replace(cmdNode, NULL);
+ /* XXX: Memory management looks suspicious here. */
+ /* XXX: Setting a list item to NULL is unexpected. */
+ LstNode_SetNull(cmdNode);
#ifdef USE_META
if (useMeta) {
@@ -436,18 +416,18 @@ again:
#endif
if (status != 0) {
if (DEBUG(ERROR)) {
- fprintf(debug_file, "\n*** Failed target: %s\n*** Failed command: ",
+ fprintf(debug_file, "\n*** Failed target: %s\n*** Failed command: ",
gn->name);
- for (cp = cmd; *cp; ) {
- if (isspace((unsigned char)*cp)) {
+ for (cp = cmd; *cp; ) {
+ if (isspace((unsigned char)*cp)) {
fprintf(debug_file, " ");
- while (isspace((unsigned char)*cp))
+ while (isspace((unsigned char)*cp))
cp++;
} else {
fprintf(debug_file, "%c", *cp);
- cp++;
+ cp++;
}
- }
+ }
fprintf(debug_file, "\n");
}
printf("*** Error code %d", status);
@@ -502,7 +482,7 @@ again:
return status;
}
-
+
/*-
*-----------------------------------------------------------------------
* Compat_Make --
@@ -544,14 +524,14 @@ Compat_Make(void *gnp, void *pgnp)
Lst_ForEach(gn->children, Compat_Make, gn);
if ((gn->flags & REMAKE) == 0) {
gn->made = ABORTED;
- pgn->flags &= ~REMAKE;
+ pgn->flags &= ~(unsigned)REMAKE;
goto cohorts;
}
- if (Lst_Member(gn->iParents, pgn) != NULL) {
+ if (Lst_FindDatum(gn->implicitParents, pgn) != NULL) {
char *p1;
Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn);
- free(p1);
+ bmake_free(p1);
}
/*
@@ -614,7 +594,7 @@ Compat_Make(void *gnp, void *pgnp)
Lst_ForEach(gn->commands, CompatRunCommand, gn);
curTarg = NULL;
} else {
- Job_Touch(gn, gn->type & OP_SILENT);
+ Job_Touch(gn, (gn->type & OP_SILENT) != 0);
}
} else {
gn->made = ERROR;
@@ -640,7 +620,7 @@ Compat_Make(void *gnp, void *pgnp)
Make_TimeStamp(pgn, gn);
}
} else if (keepgoing) {
- pgn->flags &= ~REMAKE;
+ pgn->flags &= ~(unsigned)REMAKE;
} else {
PrintOnError(gn, "\nStop.");
exit(1);
@@ -650,18 +630,19 @@ Compat_Make(void *gnp, void *pgnp)
* Already had an error when making this beastie. Tell the parent
* to abort.
*/
- pgn->flags &= ~REMAKE;
+ pgn->flags &= ~(unsigned)REMAKE;
} else {
- if (Lst_Member(gn->iParents, pgn) != NULL) {
+ if (Lst_FindDatum(gn->implicitParents, pgn) != NULL) {
char *p1;
- Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn);
- free(p1);
+ const char *target = Var_Value(TARGET, gn, &p1);
+ Var_Set(IMPSRC, target != NULL ? target : "", pgn);
+ bmake_free(p1);
}
switch(gn->made) {
case BEINGMADE:
Error("Graph cycles through %s", gn->name);
gn->made = ERROR;
- pgn->flags &= ~REMAKE;
+ pgn->flags &= ~(unsigned)REMAKE;
break;
case MADE:
if ((gn->type & OP_EXEC) == 0) {
@@ -683,22 +664,11 @@ cohorts:
Lst_ForEach(gn->cohorts, Compat_Make, pgnp);
return 0;
}
-
-/*-
- *-----------------------------------------------------------------------
- * Compat_Run --
- * Initialize this mode and start making.
+
+/* Initialize this module and start making.
*
* Input:
- * targs List of target nodes to re-create
- *
- * Results:
- * None.
- *
- * Side Effects:
- * Guess what?
- *
- *-----------------------------------------------------------------------
+ * targs The target nodes to re-create
*/
void
Compat_Run(Lst targs)
@@ -732,10 +702,10 @@ Compat_Run(Lst targs)
gn = Targ_FindNode(".BEGIN", TARG_NOCREATE);
if (gn != NULL) {
Compat_Make(gn, gn);
- if (gn->made == ERROR) {
- PrintOnError(gn, "\nStop.");
- exit(1);
- }
+ if (gn->made == ERROR) {
+ PrintOnError(gn, "\nStop.");
+ exit(1);
+ }
}
}
@@ -756,8 +726,8 @@ Compat_Run(Lst targs)
* could not be made due to errors.
*/
errors = 0;
- while (!Lst_IsEmpty (targs)) {
- gn = (GNode *)Lst_DeQueue(targs);
+ while (!Lst_IsEmpty(targs)) {
+ gn = Lst_Dequeue(targs);
Compat_Make(gn, gn);
if (gn->made == UPTODATE) {
diff --git a/cond.c b/cond.c
index 321d9a92e75b..7aa072d4eb22 100644
--- a/cond.c
+++ b/cond.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cond.c,v 1.79 2020/07/09 22:34:08 sjg Exp $ */
+/* $NetBSD: cond.c,v 1.106 2020/08/29 13:38:48 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: cond.c,v 1.79 2020/07/09 22:34:08 sjg Exp $";
+static char rcsid[] = "$NetBSD: cond.c,v 1.106 2020/08/29 13:38:48 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)cond.c 8.2 (Berkeley) 1/2/94";
#else
-__RCSID("$NetBSD: cond.c,v 1.79 2020/07/09 22:34:08 sjg Exp $");
+__RCSID("$NetBSD: cond.c,v 1.106 2020/08/29 13:38:48 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -91,14 +91,10 @@ __RCSID("$NetBSD: cond.c,v 1.79 2020/07/09 22:34:08 sjg Exp $");
*
*/
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h> /* For strtoul() error checking */
+#include <errno.h>
-#include "make.h"
-#include "hash.h"
-#include "dir.h"
-#include "buf.h"
+#include "make.h"
+#include "dir.h"
/*
* The parsing of conditional expressions is based on this grammar:
@@ -121,8 +117,7 @@ __RCSID("$NetBSD: cond.c,v 1.79 2020/07/09 22:34:08 sjg Exp $");
* T -> ! T
* op -> == | != | > | < | >= | <=
*
- * 'symbol' is some other symbol to which the default function (condDefProc)
- * is applied.
+ * 'symbol' is some other symbol to which the default function is applied.
*
* Tokens are scanned from the 'condExpr' string. The scanner (CondToken)
* will return TOK_AND for '&' and '&&', TOK_OR for '|' and '||',
@@ -141,46 +136,16 @@ typedef enum {
TOK_LPAREN, TOK_RPAREN, TOK_EOF, TOK_NONE, TOK_ERROR
} Token;
-/*-
- * Structures to handle elegantly the different forms of #if's. The
- * last two fields are stored in condInvert and condDefProc, respectively.
- */
-static void CondPushBack(Token);
-static int CondGetArg(Boolean, char **, char **, const char *);
-static Boolean CondDoDefined(int, const char *);
-static int CondStrMatch(const void *, const void *);
-static Boolean CondDoMake(int, const char *);
-static Boolean CondDoExists(int, const char *);
-static Boolean CondDoTarget(int, const char *);
-static Boolean CondDoCommands(int, const char *);
-static Boolean CondCvtArg(char *, double *);
-static Token CondToken(Boolean);
-static Token CondT(Boolean);
-static Token CondF(Boolean);
static Token CondE(Boolean);
-static int do_Cond_EvalExpression(Boolean *);
+static CondEvalResult do_Cond_EvalExpression(Boolean *);
-static const struct If {
- const char *form; /* Form of if */
- int formlen; /* Length of form */
- Boolean doNot; /* TRUE if default function should be negated */
- Boolean (*defProc)(int, const char *); /* Default function to apply */
-} ifs[] = {
- { "def", 3, FALSE, CondDoDefined },
- { "ndef", 4, TRUE, CondDoDefined },
- { "make", 4, FALSE, CondDoMake },
- { "nmake", 5, TRUE, CondDoMake },
- { "", 0, FALSE, CondDoDefined },
- { NULL, 0, FALSE, NULL }
-};
-
-static const struct If *if_info; /* Info for current statement */
-static char *condExpr; /* The expression to parse */
-static Token condPushBack=TOK_NONE; /* Single push-back token used in
+static const struct If *if_info; /* Info for current statement */
+static const char *condExpr; /* The expression to parse */
+static Token condPushBack = TOK_NONE; /* Single push-back token used in
* parsing */
-static unsigned int cond_depth = 0; /* current .if nesting level */
-static unsigned int cond_min_depth = 0; /* depth at makefile open */
+static unsigned int cond_depth = 0; /* current .if nesting level */
+static unsigned int cond_min_depth = 0; /* depth at makefile open */
/*
* Indicate when we should be strict about lhs of comparisons.
@@ -194,58 +159,38 @@ static Boolean lhsStrict;
static int
istoken(const char *str, const char *tok, size_t len)
{
- return strncmp(str, tok, len) == 0 && !isalpha((unsigned char)str[len]);
+ return strncmp(str, tok, len) == 0 && !isalpha((unsigned char)str[len]);
}
-/*-
- *-----------------------------------------------------------------------
- * CondPushBack --
- * Push back the most recent token read. We only need one level of
- * this, so the thing is just stored in 'condPushback'.
- *
- * Input:
- * t Token to push back into the "stream"
- *
- * Results:
- * None.
- *
- * Side Effects:
- * condPushback is overwritten.
- *
- *-----------------------------------------------------------------------
- */
+/* Push back the most recent token read. We only need one level of
+ * this, so the thing is just stored in 'condPushback'. */
static void
CondPushBack(Token t)
{
condPushBack = t;
}
-
+
/*-
- *-----------------------------------------------------------------------
- * CondGetArg --
- * Find the argument of a built-in function.
+ * Parse the argument of a built-in function.
*
* Results:
- * The length of the argument and the address of the argument.
- *
- * Side Effects:
- * The pointer is set to point to the closing parenthesis of the
- * function call.
- *
- *-----------------------------------------------------------------------
+ * The length of the argument.
+ * *argPtr receives the argument as string.
+ * *linePtr is updated to point behind the ')' of the function call.
*/
static int
-CondGetArg(Boolean doEval, char **linePtr, char **argPtr, const char *func)
+CondGetArg(Boolean doEval, const char **linePtr, char **argPtr,
+ const char *func)
{
- char *cp;
- int argLen;
- Buffer buf;
- int paren_depth;
- char ch;
+ const char *cp;
+ Buffer buf;
+ int paren_depth;
+ char ch;
+ size_t argLen;
cp = *linePtr;
if (func != NULL)
- /* Skip opening '(' - verfied by caller */
+ /* Skip opening '(' - verified by caller */
cp++;
if (*cp == '\0') {
@@ -283,23 +228,19 @@ CondGetArg(Boolean doEval, char **linePtr, char **argPtr, const char *func)
* variable, so we don't do it too. Nor do we return an error,
* though perhaps we should...
*/
- char *cp2;
- int len;
- void *freeIt;
-
- cp2 = Var_Parse(cp, VAR_CMD, VARF_UNDEFERR|
- (doEval ? VARF_WANTRES : 0),
- &len, &freeIt);
- Buf_AddBytes(&buf, strlen(cp2), cp2);
+ int len;
+ void *freeIt;
+ VarEvalFlags eflags = VARE_UNDEFERR | (doEval ? VARE_WANTRES : 0);
+ const char *cp2 = Var_Parse(cp, VAR_CMD, eflags, &len, &freeIt);
+ Buf_AddStr(&buf, cp2);
free(freeIt);
cp += len;
continue;
}
if (ch == '(')
paren_depth++;
- else
- if (ch == ')' && --paren_depth < 0)
- break;
+ else if (ch == ')' && --paren_depth < 0)
+ break;
Buf_AddByte(&buf, *cp);
cp++;
}
@@ -313,105 +254,49 @@ CondGetArg(Boolean doEval, char **linePtr, char **argPtr, const char *func)
if (func != NULL && *cp++ != ')') {
Parse_Error(PARSE_WARNING, "Missing closing parenthesis for %s()",
- func);
+ func);
return 0;
}
*linePtr = cp;
return argLen;
}
-
-/*-
- *-----------------------------------------------------------------------
- * CondDoDefined --
- * Handle the 'defined' function for conditionals.
- *
- * Results:
- * TRUE if the given variable is defined.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
+
+/* Test whether the given variable is defined. */
static Boolean
CondDoDefined(int argLen MAKE_ATTR_UNUSED, const char *arg)
{
- char *p1;
- Boolean result;
-
- if (Var_Value(arg, VAR_CMD, &p1) != NULL) {
- result = TRUE;
- } else {
- result = FALSE;
- }
-
- free(p1);
+ char *freeIt;
+ Boolean result = Var_Value(arg, VAR_CMD, &freeIt) != NULL;
+ bmake_free(freeIt);
return result;
}
-
-/*-
- *-----------------------------------------------------------------------
- * CondStrMatch --
- * Front-end for Str_Match so it returns 0 on match and non-zero
- * on mismatch. Callback function for CondDoMake via Lst_Find
- *
- * Results:
- * 0 if string matches pattern
- *
- * Side Effects:
- * None
- *
- *-----------------------------------------------------------------------
- */
-static int
-CondStrMatch(const void *string, const void *pattern)
+
+/* Wrapper around Str_Match, to be used by Lst_Find. */
+static Boolean
+CondFindStrMatch(const void *string, const void *pattern)
{
- return !Str_Match(string, pattern);
+ return Str_Match(string, pattern);
}
-
-/*-
- *-----------------------------------------------------------------------
- * CondDoMake --
- * Handle the 'make' function for conditionals.
- *
- * Results:
- * TRUE if the given target is being made.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
+
+/* See if the given target is being made. */
static Boolean
CondDoMake(int argLen MAKE_ATTR_UNUSED, const char *arg)
{
- return Lst_Find(create, arg, CondStrMatch) != NULL;
+ return Lst_Find(create, CondFindStrMatch, arg) != NULL;
}
-
-/*-
- *-----------------------------------------------------------------------
- * CondDoExists --
- * See if the given file exists.
- *
- * Results:
- * TRUE if the file exists and FALSE if it does not.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
+
+/* See if the given file exists. */
static Boolean
CondDoExists(int argLen MAKE_ATTR_UNUSED, const char *arg)
{
Boolean result;
- char *path;
+ char *path;
path = Dir_FindFile(arg, dirSearchPath);
if (DEBUG(COND)) {
fprintf(debug_file, "exists(%s) result is \"%s\"\n",
- arg, path ? path : "");
+ arg, path ? path : "");
}
if (path != NULL) {
result = TRUE;
@@ -421,68 +306,39 @@ CondDoExists(int argLen MAKE_ATTR_UNUSED, const char *arg)
}
return result;
}
-
-/*-
- *-----------------------------------------------------------------------
- * CondDoTarget --
- * See if the given node exists and is an actual target.
- *
- * Results:
- * TRUE if the node exists as a target and FALSE if it does not.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
+
+/* See if the given node exists and is an actual target. */
static Boolean
CondDoTarget(int argLen MAKE_ATTR_UNUSED, const char *arg)
{
- GNode *gn;
+ GNode *gn;
gn = Targ_FindNode(arg, TARG_NOCREATE);
return gn != NULL && !OP_NOP(gn->type);
}
-/*-
- *-----------------------------------------------------------------------
- * CondDoCommands --
- * See if the given node exists and is an actual target with commands
- * associated with it.
- *
- * Results:
- * TRUE if the node exists as a target and has commands associated with
- * it and FALSE if it does not.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
+/* See if the given node exists and is an actual target with commands
+ * associated with it. */
static Boolean
CondDoCommands(int argLen MAKE_ATTR_UNUSED, const char *arg)
{
- GNode *gn;
+ GNode *gn;
gn = Targ_FindNode(arg, TARG_NOCREATE);
return gn != NULL && !OP_NOP(gn->type) && !Lst_IsEmpty(gn->commands);
}
-
+
/*-
- *-----------------------------------------------------------------------
- * CondCvtArg --
- * Convert the given number into a double.
- * We try a base 10 or 16 integer conversion first, if that fails
- * then we try a floating point conversion instead.
+ * Convert the given number into a double.
+ * We try a base 10 or 16 integer conversion first, if that fails
+ * then we try a floating point conversion instead.
*
* Results:
* Sets 'value' to double value of string.
- * Returns 'true' if the convertion suceeded
- *
- *-----------------------------------------------------------------------
+ * Returns TRUE if the conversion succeeded.
*/
static Boolean
-CondCvtArg(char *str, double *value)
+CondCvtArg(const char *str, double *value)
{
char *eptr, ech;
unsigned long l_val;
@@ -510,33 +366,28 @@ CondCvtArg(char *str, double *value)
}
/*-
- *-----------------------------------------------------------------------
- * CondGetString --
- * Get a string from a variable reference or an optionally quoted
- * string. This is called for the lhs and rhs of string compares.
+ * Get a string from a variable reference or an optionally quoted
+ * string. This is called for the lhs and rhs of string compares.
*
* Results:
- * Sets freeIt if needed,
- * Sets quoted if string was quoted,
- * Returns NULL on error,
- * else returns string - absent any quotes.
+ * Returns the string, absent any quotes, or NULL on error.
+ * Sets quoted if the string was quoted.
+ * Sets freeIt if needed.
*
* Side Effects:
- * Moves condExpr to end of this token.
- *
- *
- *-----------------------------------------------------------------------
+ * Moves condExpr past the end of this token.
*/
/* coverity:[+alloc : arg-*2] */
-static char *
+static const char *
CondGetString(Boolean doEval, Boolean *quoted, void **freeIt, Boolean strictLHS)
{
Buffer buf;
- char *cp;
- char *str;
- int len;
- int qt;
- char *start;
+ const char *cp;
+ const char *str;
+ int len;
+ Boolean qt;
+ const char *start;
+ VarEvalFlags eflags;
Buf_Init(&buf, 0);
str = NULL;
@@ -573,9 +424,9 @@ CondGetString(Boolean doEval, Boolean *quoted, void **freeIt, Boolean strictLHS)
break;
case '$':
/* if we are in quotes, then an undefined variable is ok */
- str = Var_Parse(condExpr, VAR_CMD,
- ((!qt && doEval) ? VARF_UNDEFERR : 0) |
- (doEval ? VARF_WANTRES : 0), &len, freeIt);
+ eflags = ((!qt && doEval) ? VARE_UNDEFERR : 0) |
+ (doEval ? VARE_WANTRES : 0);
+ str = Var_Parse(condExpr, VAR_CMD, eflags, &len, freeIt);
if (str == var_Error) {
if (*freeIt) {
free(*freeIt);
@@ -596,7 +447,7 @@ CondGetString(Boolean doEval, Boolean *quoted, void **freeIt, Boolean strictLHS)
*/
if ((condExpr == start + len) &&
(*condExpr == '\0' ||
- isspace((unsigned char) *condExpr) ||
+ isspace((unsigned char)*condExpr) ||
strchr("!=><)", *condExpr))) {
goto cleanup;
}
@@ -610,12 +461,12 @@ CondGetString(Boolean doEval, Boolean *quoted, void **freeIt, Boolean strictLHS)
free(*freeIt);
*freeIt = NULL;
}
- str = NULL; /* not finished yet */
- condExpr--; /* don't skip over next char */
+ str = NULL; /* not finished yet */
+ condExpr--; /* don't skip over next char */
break;
default:
if (strictLHS && !qt && *start != '$' &&
- !isdigit((unsigned char) *start)) {
+ !isdigit((unsigned char)*start)) {
/* lhs must be quoted, a variable reference or number */
if (*freeIt) {
free(*freeIt);
@@ -628,43 +479,51 @@ CondGetString(Boolean doEval, Boolean *quoted, void **freeIt, Boolean strictLHS)
break;
}
}
- got_str:
- str = Buf_GetAll(&buf, NULL);
- *freeIt = str;
- cleanup:
+got_str:
+ *freeIt = Buf_GetAll(&buf, NULL);
+ str = *freeIt;
+cleanup:
Buf_Destroy(&buf, FALSE);
return str;
}
-
+
+/* The different forms of #if's. */
+static const struct If {
+ const char *form; /* Form of if */
+ size_t formlen; /* Length of form */
+ Boolean doNot; /* TRUE if default function should be negated */
+ Boolean (*defProc)(int, const char *); /* Default function to apply */
+} ifs[] = {
+ { "def", 3, FALSE, CondDoDefined },
+ { "ndef", 4, TRUE, CondDoDefined },
+ { "make", 4, FALSE, CondDoMake },
+ { "nmake", 5, TRUE, CondDoMake },
+ { "", 0, FALSE, CondDoDefined },
+ { NULL, 0, FALSE, NULL }
+};
+
/*-
- *-----------------------------------------------------------------------
- * CondToken --
- * Return the next token from the input.
- *
- * Results:
- * A Token for the next lexical token in the stream.
+ * Return the next token from the input.
*
* Side Effects:
* condPushback will be set back to TOK_NONE if it is used.
- *
- *-----------------------------------------------------------------------
*/
static Token
compare_expression(Boolean doEval)
{
- Token t;
- char *lhs;
- char *rhs;
- char *op;
- void *lhsFree;
- void *rhsFree;
+ Token t;
+ const char *lhs;
+ const char *rhs;
+ const char *op;
+ void *lhsFree;
+ void *rhsFree;
Boolean lhsQuoted;
Boolean rhsQuoted;
- double left, right;
+ double left, right;
t = TOK_ERROR;
rhs = NULL;
- lhsFree = rhsFree = FALSE;
+ lhsFree = rhsFree = NULL;
lhsQuoted = rhsQuoted = FALSE;
/*
@@ -678,7 +537,7 @@ compare_expression(Boolean doEval)
/*
* Skip whitespace to get to the operator
*/
- while (isspace((unsigned char) *condExpr))
+ while (isspace((unsigned char)*condExpr))
condExpr++;
/*
@@ -688,39 +547,39 @@ compare_expression(Boolean doEval)
*/
op = condExpr;
switch (*condExpr) {
- case '!':
- case '=':
- case '<':
- case '>':
- if (condExpr[1] == '=') {
- condExpr += 2;
- } else {
- condExpr += 1;
- }
- break;
- default:
- if (!doEval) {
- t = TOK_FALSE;
- goto done;
- }
- /* For .ifxxx "..." check for non-empty string. */
- if (lhsQuoted) {
- t = lhs[0] != 0;
- goto done;
- }
- /* For .ifxxx <number> compare against zero */
- if (CondCvtArg(lhs, &left)) {
- t = left != 0.0;
- goto done;
- }
- /* For .if ${...} check for non-empty string (defProc is ifdef). */
- if (if_info->form[0] == 0) {
- t = lhs[0] != 0;
- goto done;
- }
- /* Otherwise action default test ... */
- t = if_info->defProc(strlen(lhs), lhs) != if_info->doNot;
+ case '!':
+ case '=':
+ case '<':
+ case '>':
+ if (condExpr[1] == '=') {
+ condExpr += 2;
+ } else {
+ condExpr += 1;
+ }
+ break;
+ default:
+ if (!doEval) {
+ t = TOK_FALSE;
goto done;
+ }
+ /* For .ifxxx "..." check for non-empty string. */
+ if (lhsQuoted) {
+ t = lhs[0] != 0;
+ goto done;
+ }
+ /* For .ifxxx <number> compare against zero */
+ if (CondCvtArg(lhs, &left)) {
+ t = left != 0.0;
+ goto done;
+ }
+ /* For .if ${...} check for non-empty string (defProc is ifdef). */
+ if (if_info->form[0] == 0) {
+ t = lhs[0] != 0;
+ goto done;
+ }
+ /* Otherwise action default test ... */
+ t = if_info->defProc(strlen(lhs), lhs) != if_info->doNot;
+ goto done;
}
while (isspace((unsigned char)*condExpr))
@@ -742,16 +601,16 @@ compare_expression(Boolean doEval)
}
if (rhsQuoted || lhsQuoted) {
-do_string_compare:
+ do_string_compare:
if (((*op != '!') && (*op != '=')) || (op[1] != '=')) {
Parse_Error(PARSE_WARNING,
- "String comparison operator should be either == or !=");
+ "String comparison operator should be either == or !=");
goto done;
}
if (DEBUG(COND)) {
fprintf(debug_file, "lhs = \"%s\", rhs = \"%s\", op = %.2s\n",
- lhs, rhs, op);
+ lhs, rhs, op);
}
/*
* Null-terminate rhs and perform the comparison.
@@ -773,9 +632,9 @@ do_string_compare:
if (DEBUG(COND)) {
fprintf(debug_file, "left = %f, right = %f, op = %.2s\n", left,
- right, op);
+ right, op);
}
- switch(op[0]) {
+ switch (op[0]) {
case '!':
if (op[1] != '=') {
Parse_Error(PARSE_WARNING,
@@ -816,21 +675,23 @@ done:
}
static int
-get_mpt_arg(Boolean doEval, char **linePtr, char **argPtr, const char *func MAKE_ATTR_UNUSED)
+get_mpt_arg(Boolean doEval, const char **linePtr, char **argPtr,
+ const char *func MAKE_ATTR_UNUSED)
{
/*
* Use Var_Parse to parse the spec in parens and return
* TOK_TRUE if the resulting string is empty.
*/
- int length;
- void *freeIt;
- char *val;
- char *cp = *linePtr;
+ int length;
+ void *val_freeIt;
+ const char *val;
+ const char *cp = *linePtr;
/* We do all the work here and return the result as the length */
*argPtr = NULL;
- val = Var_Parse(cp - 1, VAR_CMD, doEval ? VARF_WANTRES : 0, &length, &freeIt);
+ val = Var_Parse(cp - 1, VAR_CMD, doEval ? VARE_WANTRES : 0, &length,
+ &val_freeIt);
/*
* Advance *linePtr to beyond the closing ). Note that
* we subtract one because 'length' is calculated from 'cp - 1'.
@@ -838,12 +699,12 @@ get_mpt_arg(Boolean doEval, char **linePtr, char **argPtr, const char *func MAKE
*linePtr = cp - 1 + length;
if (val == var_Error) {
- free(freeIt);
+ free(val_freeIt);
return -1;
}
/* A variable is empty when it just contains spaces... 4/15/92, christos */
- while (isspace(*(unsigned char *)val))
+ while (isspace((unsigned char)val[0]))
val++;
/*
@@ -851,7 +712,7 @@ get_mpt_arg(Boolean doEval, char **linePtr, char **argPtr, const char *func MAKE
* true/false here.
*/
length = *val ? 2 : 1;
- free(freeIt);
+ free(val_freeIt);
return length;
}
@@ -865,32 +726,32 @@ static Token
compare_function(Boolean doEval)
{
static const struct fn_def {
- const char *fn_name;
- int fn_name_len;
- int (*fn_getarg)(Boolean, char **, char **, const char *);
- Boolean (*fn_proc)(int, const char *);
+ const char *fn_name;
+ size_t fn_name_len;
+ int (*fn_getarg)(Boolean, const char **, char **, const char *);
+ Boolean (*fn_proc)(int, const char *);
} fn_defs[] = {
- { "defined", 7, CondGetArg, CondDoDefined },
- { "make", 4, CondGetArg, CondDoMake },
- { "exists", 6, CondGetArg, CondDoExists },
- { "empty", 5, get_mpt_arg, CondDoEmpty },
- { "target", 6, CondGetArg, CondDoTarget },
- { "commands", 8, CondGetArg, CondDoCommands },
- { NULL, 0, NULL, NULL },
+ { "defined", 7, CondGetArg, CondDoDefined },
+ { "make", 4, CondGetArg, CondDoMake },
+ { "exists", 6, CondGetArg, CondDoExists },
+ { "empty", 5, get_mpt_arg, CondDoEmpty },
+ { "target", 6, CondGetArg, CondDoTarget },
+ { "commands", 8, CondGetArg, CondDoCommands },
+ { NULL, 0, NULL, NULL },
};
const struct fn_def *fn_def;
- Token t;
- char *arg = NULL;
- int arglen;
- char *cp = condExpr;
- char *cp1;
+ Token t;
+ char *arg = NULL;
+ int arglen;
+ const char *cp = condExpr;
+ const char *cp1;
for (fn_def = fn_defs; fn_def->fn_name != NULL; fn_def++) {
if (!istoken(cp, fn_def->fn_name, fn_def->fn_name_len))
continue;
cp += fn_def->fn_name_len;
/* There can only be whitespace before the '(' */
- while (isspace(*(unsigned char *)cp))
+ while (isspace((unsigned char)*cp))
cp++;
if (*cp != '(')
break;
@@ -921,7 +782,7 @@ compare_function(Boolean doEval)
* expression.
*/
arglen = CondGetArg(doEval, &cp, &arg, NULL);
- for (cp1 = cp; isspace(*(unsigned char *)cp1); cp1++)
+ for (cp1 = cp; isspace((unsigned char)*cp1); cp1++)
continue;
if (*cp1 == '=' || *cp1 == '!')
return compare_expression(doEval);
@@ -1015,7 +876,7 @@ CondToken(Boolean doEval)
static Token
CondT(Boolean doEval)
{
- Token t;
+ Token t;
t = CondToken(doEval);
@@ -1045,7 +906,7 @@ CondT(Boolean doEval)
}
return t;
}
-
+
/*-
*-----------------------------------------------------------------------
* CondF --
@@ -1063,7 +924,7 @@ CondT(Boolean doEval)
static Token
CondF(Boolean doEval)
{
- Token l, o;
+ Token l, o;
l = CondT(doEval);
if (l != TOK_ERROR) {
@@ -1091,7 +952,7 @@ CondF(Boolean doEval)
}
return l;
}
-
+
/*-
*-----------------------------------------------------------------------
* CondE --
@@ -1109,7 +970,7 @@ CondF(Boolean doEval)
static Token
CondE(Boolean doEval)
{
- Token l, o;
+ Token l, o;
l = CondF(doEval);
if (l != TOK_ERROR) {
@@ -1139,6 +1000,31 @@ CondE(Boolean doEval)
return l;
}
+static CondEvalResult
+do_Cond_EvalExpression(Boolean *value)
+{
+
+ switch (CondE(TRUE)) {
+ case TOK_TRUE:
+ if (CondToken(TRUE) == TOK_EOF) {
+ *value = TRUE;
+ return COND_PARSE;
+ }
+ break;
+ case TOK_FALSE:
+ if (CondToken(TRUE) == TOK_EOF) {
+ *value = FALSE;
+ return COND_PARSE;
+ }
+ break;
+ default:
+ case TOK_ERROR:
+ break;
+ }
+
+ return COND_INVALID;
+}
+
/*-
*-----------------------------------------------------------------------
* Cond_EvalExpression --
@@ -1153,16 +1039,16 @@ CondE(Boolean doEval)
* (*value) is set to the boolean value of the condition
*
* Side Effects:
- * None.
- *
+ * Any effects from evaluating the variables.
*-----------------------------------------------------------------------
*/
-int
-Cond_EvalExpression(const struct If *info, char *line, Boolean *value, int eprint, Boolean strictLHS)
+CondEvalResult
+Cond_EvalExpression(const struct If *info, char *line, Boolean *value,
+ int eprint, Boolean strictLHS)
{
static const struct If *dflt_info;
const struct If *sv_if_info = if_info;
- char *sv_condExpr = condExpr;
+ const char *sv_condExpr = condExpr;
Token sv_condPushBack = condPushBack;
int rval;
@@ -1173,7 +1059,7 @@ Cond_EvalExpression(const struct If *info, char *line, Boolean *value, int eprin
if (info == NULL && (info = dflt_info) == NULL) {
/* Scan for the entry for .if - it can't be first */
- for (info = ifs; ; info++)
+ for (info = ifs;; info++)
if (info->form[0] == 0)
break;
dflt_info = info;
@@ -1196,32 +1082,7 @@ Cond_EvalExpression(const struct If *info, char *line, Boolean *value, int eprin
return rval;
}
-static int
-do_Cond_EvalExpression(Boolean *value)
-{
-
- switch (CondE(TRUE)) {
- case TOK_TRUE:
- if (CondToken(TRUE) == TOK_EOF) {
- *value = TRUE;
- return COND_PARSE;
- }
- break;
- case TOK_FALSE:
- if (CondToken(TRUE) == TOK_EOF) {
- *value = FALSE;
- return COND_PARSE;
- }
- break;
- default:
- case TOK_ERROR:
- break;
- }
-
- return COND_INVALID;
-}
-
/*-
*-----------------------------------------------------------------------
* Cond_Eval --
@@ -1241,35 +1102,31 @@ do_Cond_EvalExpression(Boolean *value)
* COND_SKIP if should skip lines after the conditional
* COND_INVALID if not a valid conditional.
*
- * Side Effects:
- * None.
- *
* Note that the states IF_ACTIVE and ELSE_ACTIVE are only different in order
- * to detect splurious .else lines (as are SKIP_TO_ELSE and SKIP_TO_ENDIF)
+ * to detect spurious .else lines (as are SKIP_TO_ELSE and SKIP_TO_ENDIF),
* otherwise .else could be treated as '.elif 1'.
- *
*-----------------------------------------------------------------------
*/
-int
+CondEvalResult
Cond_Eval(char *line)
{
-#define MAXIF 128 /* maximum depth of .if'ing */
-#define MAXIF_BUMP 32 /* how much to grow by */
+ enum { MAXIF = 128 }; /* maximum depth of .if'ing */
+ enum { MAXIF_BUMP = 32 }; /* how much to grow by */
enum if_states {
IF_ACTIVE, /* .if or .elif part active */
ELSE_ACTIVE, /* .else part active */
SEARCH_FOR_ELIF, /* searching for .elif/else to execute */
- SKIP_TO_ELSE, /* has been true, but not seen '.else' */
+ SKIP_TO_ELSE, /* has been true, but not seen '.else' */
SKIP_TO_ENDIF /* nothing else to execute */
};
static enum if_states *cond_state = NULL;
static unsigned int max_if_depth = MAXIF;
const struct If *ifp;
- Boolean isElif;
- Boolean value;
- int level; /* Level at which to report errors. */
- enum if_states state;
+ Boolean isElif;
+ Boolean value;
+ int level; /* Level at which to report errors. */
+ enum if_states state;
level = PARSE_FATAL;
if (!cond_state) {
@@ -1292,7 +1149,8 @@ Cond_Eval(char *line)
}
/* Return state for previous conditional */
cond_depth--;
- return cond_state[cond_depth] <= ELSE_ACTIVE ? COND_PARSE : COND_SKIP;
+ return cond_state[cond_depth] <= ELSE_ACTIVE
+ ? COND_PARSE : COND_SKIP;
}
/* Quite likely this is 'else' or 'elif' */
@@ -1336,7 +1194,7 @@ Cond_Eval(char *line)
* function is, etc. -- by looking in the table of valid "ifs"
*/
line += 2;
- for (ifp = ifs; ; ifp++) {
+ for (ifp = ifs;; ifp++) {
if (ifp->form == NULL)
return COND_INVALID;
if (istoken(ifp->form, line, ifp->formlen)) {
@@ -1372,8 +1230,8 @@ Cond_Eval(char *line)
* can need more than the default.
*/
max_if_depth += MAXIF_BUMP;
- cond_state = bmake_realloc(cond_state, max_if_depth *
- sizeof(*cond_state));
+ cond_state = bmake_realloc(cond_state,
+ max_if_depth * sizeof(*cond_state));
}
state = cond_state[cond_depth];
cond_depth++;
@@ -1400,21 +1258,6 @@ Cond_Eval(char *line)
return COND_PARSE;
}
-
-
-/*-
- *-----------------------------------------------------------------------
- * Cond_End --
- * Make sure everything's clean at the end of a makefile.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * Parse_Error will be called if open conditionals are around.
- *
- *-----------------------------------------------------------------------
- */
void
Cond_restore_depth(unsigned int saved_depth)
{
diff --git a/dir.c b/dir.c
index 5c5e7e5c14f2..4a561deca6fc 100644
--- a/dir.c
+++ b/dir.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dir.c,v 1.76 2020/07/03 08:13:23 rillig Exp $ */
+/* $NetBSD: dir.c,v 1.135 2020/09/02 04:32:13 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: dir.c,v 1.76 2020/07/03 08:13:23 rillig Exp $";
+static char rcsid[] = "$NetBSD: dir.c,v 1.135 2020/09/02 04:32:13 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94";
#else
-__RCSID("$NetBSD: dir.c,v 1.76 2020/07/03 08:13:23 rillig Exp $");
+__RCSID("$NetBSD: dir.c,v 1.135 2020/09/02 04:32:13 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -143,10 +143,20 @@ __RCSID("$NetBSD: dir.c,v 1.76 2020/07/03 08:13:23 rillig Exp $");
#include <stdio.h>
#include "make.h"
-#include "hash.h"
#include "dir.h"
#include "job.h"
+
+#define DIR_DEBUG0(fmt) \
+ if (!DEBUG(DIR)) (void) 0; else fprintf(debug_file, fmt)
+
+#define DIR_DEBUG1(fmt, arg1) \
+ if (!DEBUG(DIR)) (void) 0; else fprintf(debug_file, fmt, arg1)
+
+#define DIR_DEBUG2(fmt, arg1, arg2) \
+ if (!DEBUG(DIR)) (void) 0; else fprintf(debug_file, fmt, arg1, arg2)
+
+
/*
* A search path consists of a Lst of Path structures. A Path structure
* has in it the name of the directory and a hash table of all the files
@@ -217,37 +227,35 @@ __RCSID("$NetBSD: dir.c,v 1.76 2020/07/03 08:13:23 rillig Exp $");
* in a cache for when Dir_MTime was actually called.
*/
-Lst dirSearchPath; /* main search path */
+Lst dirSearchPath; /* main search path */
-static Lst openDirectories; /* the list of all open directories */
+static Lst openDirectories; /* the list of all open directories */
/*
* Variables for gathering statistics on the efficiency of the hashing
* mechanism.
*/
-static int hits, /* Found in directory cache */
- misses, /* Sad, but not evil misses */
- nearmisses, /* Found under search path */
- bigmisses; /* Sought by itself */
-
-static Path *dot; /* contents of current directory */
-static Path *cur; /* contents of current directory, if not dot */
-static Path *dotLast; /* a fake path entry indicating we need to
- * look for . last */
-static Hash_Table mtimes; /* Results of doing a last-resort stat in
- * Dir_FindFile -- if we have to go to the
- * system to find the file, we might as well
- * have its mtime on record. XXX: If this is done
- * way early, there's a chance other rules will
- * have already updated the file, in which case
- * we'll update it again. Generally, there won't
- * be two rules to update a single file, so this
- * should be ok, but... */
-
-static Hash_Table lmtimes; /* same as mtimes but for lstat */
-
-static int DirFindName(const void *, const void *);
-static int DirMatchFiles(const char *, Path *, Lst);
+static int hits; /* Found in directory cache */
+static int misses; /* Sad, but not evil misses */
+static int nearmisses; /* Found under search path */
+static int bigmisses; /* Sought by itself */
+
+static Path *dot; /* contents of current directory */
+static Path *cur; /* contents of current directory, if not dot */
+static Path *dotLast; /* a fake path entry indicating we need to
+ * look for . last */
+
+/* Results of doing a last-resort stat in Dir_FindFile -- if we have to go to
+ * the system to find the file, we might as well have its mtime on record.
+ *
+ * XXX: If this is done way early, there's a chance other rules will have
+ * already updated the file, in which case we'll update it again. Generally,
+ * there won't be two rules to update a single file, so this should be ok,
+ * but... */
+static Hash_Table mtimes;
+
+static Hash_Table lmtimes; /* same as mtimes but for lstat */
+
static void DirExpandCurly(const char *, const char *, Lst, Lst);
static void DirExpandInt(const char *, Lst, Lst);
static int DirPrintWord(void *, void *);
@@ -259,23 +267,28 @@ static char *DirLookupAbs(Path *, const char *, const char *);
/*
- * We use stat(2) a lot, cache the results
+ * We use stat(2) a lot, cache the results.
* mtime and mode are all we care about.
*/
struct cache_st {
- time_t lmtime; /* lstat */
- time_t mtime; /* stat */
- mode_t mode;
+ time_t lmtime; /* lstat */
+ time_t mtime; /* stat */
+ mode_t mode;
};
/* minimize changes below */
-#define CST_LSTAT 1
-#define CST_UPDATE 2
+typedef enum {
+ CST_LSTAT = 0x01, /* call lstat(2) instead of stat(2) */
+ CST_UPDATE = 0x02 /* ignore existing cached entry */
+} CachedStatsFlags;
+/* Returns 0 and the result of stat(2) or lstat(2) in *mst, or -1 on error. */
static int
-cached_stats(Hash_Table *htp, const char *pathname, struct stat *st, int flags)
+cached_stats(Hash_Table *htp, const char *pathname, struct make_stat *mst,
+ CachedStatsFlags flags)
{
Hash_Entry *entry;
+ struct stat sys_st;
struct cache_st *cst;
int rc;
@@ -284,83 +297,74 @@ cached_stats(Hash_Table *htp, const char *pathname, struct stat *st, int flags)
entry = Hash_FindEntry(htp, pathname);
- if (entry && (flags & CST_UPDATE) == 0) {
- cst = entry->clientPtr;
+ if (entry && !(flags & CST_UPDATE)) {
+ cst = Hash_GetValue(entry);
- memset(st, 0, sizeof(*st));
- st->st_mode = cst->mode;
- st->st_mtime = (flags & CST_LSTAT) ? cst->lmtime : cst->mtime;
- if (st->st_mtime) {
- if (DEBUG(DIR)) {
- fprintf(debug_file, "Using cached time %s for %s\n",
- Targ_FmtTime(st->st_mtime), pathname);
- }
+ mst->mst_mode = cst->mode;
+ mst->mst_mtime = (flags & CST_LSTAT) ? cst->lmtime : cst->mtime;
+ if (mst->mst_mtime) {
+ DIR_DEBUG2("Using cached time %s for %s\n",
+ Targ_FmtTime(mst->mst_mtime), pathname);
return 0;
}
}
- rc = (flags & CST_LSTAT) ? lstat(pathname, st) : stat(pathname, st);
+ rc = (flags & CST_LSTAT)
+ ? lstat(pathname, &sys_st)
+ : stat(pathname, &sys_st);
if (rc == -1)
return -1;
- if (st->st_mtime == 0)
- st->st_mtime = 1; /* avoid confusion with missing file */
+ if (sys_st.st_mtime == 0)
+ sys_st.st_mtime = 1; /* avoid confusion with missing file */
+
+ mst->mst_mode = sys_st.st_mode;
+ mst->mst_mtime = sys_st.st_mtime;
- if (!entry)
+ if (entry == NULL)
entry = Hash_CreateEntry(htp, pathname, NULL);
- if (!entry->clientPtr) {
- entry->clientPtr = bmake_malloc(sizeof(*cst));
- memset(entry->clientPtr, 0, sizeof(*cst));
+ if (Hash_GetValue(entry) == NULL) {
+ Hash_SetValue(entry, bmake_malloc(sizeof(*cst)));
+ memset(Hash_GetValue(entry), 0, sizeof(*cst));
}
- cst = entry->clientPtr;
- if ((flags & CST_LSTAT)) {
- cst->lmtime = st->st_mtime;
+ cst = Hash_GetValue(entry);
+ if (flags & CST_LSTAT) {
+ cst->lmtime = sys_st.st_mtime;
} else {
- cst->mtime = st->st_mtime;
- }
- cst->mode = st->st_mode;
- if (DEBUG(DIR)) {
- fprintf(debug_file, " Caching %s for %s\n",
- Targ_FmtTime(st->st_mtime), pathname);
+ cst->mtime = sys_st.st_mtime;
}
+ cst->mode = sys_st.st_mode;
+ DIR_DEBUG2(" Caching %s for %s\n",
+ Targ_FmtTime(sys_st.st_mtime), pathname);
return 0;
}
int
-cached_stat(const char *pathname, void *st)
+cached_stat(const char *pathname, struct make_stat *st)
{
return cached_stats(&mtimes, pathname, st, 0);
}
int
-cached_lstat(const char *pathname, void *st)
+cached_lstat(const char *pathname, struct make_stat *st)
{
return cached_stats(&lmtimes, pathname, st, CST_LSTAT);
}
-/*-
- *-----------------------------------------------------------------------
- * Dir_Init --
- * initialize things for this module
- *
- * Results:
- * none
- *
- * Side Effects:
- * some directories may be opened.
- *-----------------------------------------------------------------------
- */
+/* Initialize things for this module. */
void
-Dir_Init(const char *cdname)
+Dir_Init(void)
+{
+ dirSearchPath = Lst_Init();
+ openDirectories = Lst_Init();
+ Hash_InitTable(&mtimes, 0);
+ Hash_InitTable(&lmtimes, 0);
+}
+
+void
+Dir_InitDir(const char *cdname)
{
- if (!cdname) {
- dirSearchPath = Lst_Init(FALSE);
- openDirectories = Lst_Init(FALSE);
- Hash_InitTable(&mtimes, 0);
- Hash_InitTable(&lmtimes, 0);
- return;
- }
Dir_InitCur(cdname);
dotLast = bmake_malloc(sizeof(Path));
@@ -371,7 +375,7 @@ Dir_Init(const char *cdname)
}
/*
- * Called by Dir_Init() and whenever .CURDIR is assigned to.
+ * Called by Dir_InitDir and whenever .CURDIR is assigned to.
*/
void
Dir_InitCur(const char *cdname)
@@ -397,18 +401,8 @@ Dir_InitCur(const char *cdname)
}
}
-/*-
- *-----------------------------------------------------------------------
- * Dir_InitDot --
- * (re)initialize "dot" (current/object directory) path hash
- *
- * Results:
- * none
- *
- * Side Effects:
- * some directories may be opened.
- *-----------------------------------------------------------------------
- */
+/* (Re)initialize "dot" (current/object directory) path hash.
+ * Some directories may be opened. */
void
Dir_InitDot(void)
{
@@ -416,8 +410,8 @@ Dir_InitDot(void)
LstNode ln;
/* Remove old entry from openDirectories, but do not destroy. */
- ln = Lst_Member(openDirectories, dot);
- (void)Lst_Remove(openDirectories, ln);
+ ln = Lst_FindDatum(openDirectories, dot);
+ Lst_Remove(openDirectories, ln);
}
dot = Dir_AddDir(NULL, ".");
@@ -432,21 +426,10 @@ Dir_InitDot(void)
* to make sure it's not destroyed.
*/
dot->refCount += 1;
- Dir_SetPATH(); /* initialize */
+ Dir_SetPATH(); /* initialize */
}
-/*-
- *-----------------------------------------------------------------------
- * Dir_End --
- * cleanup things for this module
- *
- * Results:
- * none
- *
- * Side Effects:
- * none
- *-----------------------------------------------------------------------
- */
+/* Clean up things for this module. */
void
Dir_End(void)
{
@@ -460,9 +443,9 @@ Dir_End(void)
Dir_Destroy(dotLast);
Dir_Destroy(dot);
Dir_ClearPath(dirSearchPath);
- Lst_Destroy(dirSearchPath, NULL);
+ Lst_Free(dirSearchPath);
Dir_ClearPath(openDirectories);
- Lst_Destroy(openDirectories, NULL);
+ Lst_Free(openDirectories);
Hash_DeleteTable(&mtimes);
#endif
}
@@ -475,122 +458,100 @@ Dir_End(void)
void
Dir_SetPATH(void)
{
- LstNode ln; /* a list element */
+ LstNode ln; /* a list element */
Path *p;
- Boolean hasLastDot = FALSE; /* true we should search dot last */
+ Boolean hasLastDot = FALSE; /* true if we should search dot last */
Var_Delete(".PATH", VAR_GLOBAL);
- if (Lst_Open(dirSearchPath) == SUCCESS) {
- if ((ln = Lst_First(dirSearchPath)) != NULL) {
- p = (Path *)Lst_Datum(ln);
- if (p == dotLast) {
- hasLastDot = TRUE;
- Var_Append(".PATH", dotLast->name, VAR_GLOBAL);
- }
+ Lst_Open(dirSearchPath);
+ if ((ln = Lst_First(dirSearchPath)) != NULL) {
+ p = LstNode_Datum(ln);
+ if (p == dotLast) {
+ hasLastDot = TRUE;
+ Var_Append(".PATH", dotLast->name, VAR_GLOBAL);
}
+ }
- if (!hasLastDot) {
- if (dot)
- Var_Append(".PATH", dot->name, VAR_GLOBAL);
- if (cur)
- Var_Append(".PATH", cur->name, VAR_GLOBAL);
- }
+ if (!hasLastDot) {
+ if (dot)
+ Var_Append(".PATH", dot->name, VAR_GLOBAL);
+ if (cur)
+ Var_Append(".PATH", cur->name, VAR_GLOBAL);
+ }
- while ((ln = Lst_Next(dirSearchPath)) != NULL) {
- p = (Path *)Lst_Datum(ln);
- if (p == dotLast)
- continue;
- if (p == dot && hasLastDot)
- continue;
- Var_Append(".PATH", p->name, VAR_GLOBAL);
- }
+ while ((ln = Lst_Next(dirSearchPath)) != NULL) {
+ p = LstNode_Datum(ln);
+ if (p == dotLast)
+ continue;
+ if (p == dot && hasLastDot)
+ continue;
+ Var_Append(".PATH", p->name, VAR_GLOBAL);
+ }
- if (hasLastDot) {
- if (dot)
- Var_Append(".PATH", dot->name, VAR_GLOBAL);
- if (cur)
- Var_Append(".PATH", cur->name, VAR_GLOBAL);
- }
- Lst_Close(dirSearchPath);
+ if (hasLastDot) {
+ if (dot)
+ Var_Append(".PATH", dot->name, VAR_GLOBAL);
+ if (cur)
+ Var_Append(".PATH", cur->name, VAR_GLOBAL);
}
+ Lst_Close(dirSearchPath);
}
-/*-
- *-----------------------------------------------------------------------
- * DirFindName --
- * See if the Path structure describes the same directory as the
- * given one by comparing their names. Called from Dir_AddDir via
- * Lst_Find when searching the list of open directories.
- *
- * Input:
- * p Current name
- * dname Desired name
- *
- * Results:
- * 0 if it is the same. Non-zero otherwise
- *
- * Side Effects:
- * None
- *-----------------------------------------------------------------------
- */
-static int
-DirFindName(const void *p, const void *dname)
+/* See if the Path structure describes the same directory as the
+ * given one by comparing their names. Called from Dir_AddDir via
+ * Lst_Find when searching the list of open directories. */
+static Boolean
+DirFindName(const void *p, const void *desiredName)
{
- return strcmp(((const Path *)p)->name, dname);
+ return strcmp(((const Path *)p)->name, desiredName) == 0;
}
-/*-
- *-----------------------------------------------------------------------
- * Dir_HasWildcards --
- * see if the given name has any wildcard characters in it
- * be careful not to expand unmatching brackets or braces.
- * XXX: This code is not 100% correct. ([^]] fails etc.)
- * I really don't think that make(1) should be expanding
- * patterns, because then you have to set a mechanism for
- * escaping the expansion!
+/* See if the given name has any wildcard characters in it. Be careful not to
+ * expand unmatching brackets or braces.
+ *
+ * XXX: This code is not 100% correct ([^]] fails etc.). I really don't think
+ * that make(1) should be expanding patterns, because then you have to set a
+ * mechanism for escaping the expansion!
*
* Input:
* name name to check
*
* Results:
* returns TRUE if the word should be expanded, FALSE otherwise
- *
- * Side Effects:
- * none
- *-----------------------------------------------------------------------
*/
Boolean
-Dir_HasWildcards(char *name)
+Dir_HasWildcards(const char *name)
{
- char *cp;
- int wild = 0, brace = 0, bracket = 0;
+ const char *cp;
+ Boolean wild = FALSE;
+ int braces = 0, brackets = 0;
for (cp = name; *cp; cp++) {
- switch(*cp) {
+ switch (*cp) {
case '{':
- brace++;
- wild = 1;
- break;
+ braces++;
+ wild = TRUE;
+ break;
case '}':
- brace--;
- break;
+ braces--;
+ break;
case '[':
- bracket++;
- wild = 1;
- break;
+ brackets++;
+ wild = TRUE;
+ break;
case ']':
- bracket--;
- break;
+ brackets--;
+ break;
case '?':
case '*':
- wild = 1;
- break;
+ wild = TRUE;
+ break;
default:
- break;
+ break;
}
}
- return wild && bracket == 0 && brace == 0;
+ return wild && brackets == 0 && braces == 0;
}
/*-
@@ -607,20 +568,17 @@ Dir_HasWildcards(char *name)
* p Directory to search
* expansion Place to store the results
*
- * Results:
- * Always returns 0
- *
* Side Effects:
* File names are added to the expansions lst. The directory will be
* fully hashed when this is done.
*-----------------------------------------------------------------------
*/
-static int
+static void
DirMatchFiles(const char *pattern, Path *p, Lst expansions)
{
- Hash_Search search; /* Index into the directory's table */
- Hash_Entry *entry; /* Current entry in the table */
- Boolean isDot; /* TRUE if the directory being searched is . */
+ Hash_Search search; /* Index into the directory's table */
+ Hash_Entry *entry; /* Current entry in the table */
+ Boolean isDot; /* TRUE if the directory being searched is . */
isDot = (*p->name == '.' && p->name[1] == '\0');
@@ -638,13 +596,75 @@ DirMatchFiles(const char *pattern, Path *p, Lst expansions)
((entry->name[0] != '.') ||
(pattern[0] == '.')))
{
- (void)Lst_AtEnd(expansions,
- (isDot ? bmake_strdup(entry->name) :
- str_concat(p->name, entry->name,
- STR_ADDSLASH)));
+ Lst_Append(expansions,
+ (isDot ? bmake_strdup(entry->name) :
+ str_concat3(p->name, "/", entry->name)));
}
}
- return 0;
+}
+
+/* Find the next closing brace in the string, taking nested braces into
+ * account. */
+static const char *
+closing_brace(const char *p)
+{
+ int nest = 0;
+ while (*p != '\0') {
+ if (*p == '}' && nest == 0)
+ break;
+ if (*p == '{')
+ nest++;
+ if (*p == '}')
+ nest--;
+ p++;
+ }
+ return p;
+}
+
+/* Find the next closing brace or comma in the string, taking nested braces
+ * into account. */
+static const char *
+separator_comma(const char *p)
+{
+ int nest = 0;
+ while (*p != '\0') {
+ if ((*p == '}' || *p == ',') && nest == 0)
+ break;
+ if (*p == '{')
+ nest++;
+ if (*p == '}')
+ nest--;
+ p++;
+ }
+ return p;
+}
+
+static Boolean
+contains_wildcard(const char *p)
+{
+ for (; *p != '\0'; p++) {
+ switch (*p) {
+ case '*':
+ case '?':
+ case '{':
+ case '[':
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static char *
+concat3(const char *a, size_t a_len, const char *b, size_t b_len,
+ const char *c, size_t c_len)
+{
+ size_t s_len = a_len + b_len + c_len;
+ char *s = bmake_malloc(s_len + 1);
+ memcpy(s, a, a_len);
+ memcpy(s + a_len, b, b_len);
+ memcpy(s + a_len + b_len, c, c_len);
+ s[s_len] = '\0';
+ return s;
}
/*-
@@ -672,91 +692,41 @@ DirMatchFiles(const char *pattern, Path *p, Lst expansions)
static void
DirExpandCurly(const char *word, const char *brace, Lst path, Lst expansions)
{
- const char *end; /* Character after the closing brace */
- const char *cp; /* Current position in brace clause */
- const char *start; /* Start of current piece of brace clause */
- int bracelevel; /* Number of braces we've seen. If we see a
- * right brace when this is 0, we've hit the
- * end of the clause. */
- char *file; /* Current expansion */
- int otherLen; /* The length of the other pieces of the
- * expansion (chars before and after the
- * clause in 'word') */
- char *cp2; /* Pointer for checking for wildcards in
- * expansion before calling Dir_Expand */
-
- start = brace+1;
+ const char *prefix, *middle, *piece, *middle_end, *suffix;
+ size_t prefix_len, suffix_len;
- /*
- * Find the end of the brace clause first, being wary of nested brace
- * clauses.
- */
- for (end = start, bracelevel = 0; *end != '\0'; end++) {
- if (*end == '{') {
- bracelevel++;
- } else if ((*end == '}') && (bracelevel-- == 0)) {
- break;
- }
- }
- if (*end == '\0') {
- Error("Unterminated {} clause \"%s\"", start);
+ /* Split the word into prefix '{' middle '}' suffix. */
+
+ middle = brace + 1;
+ middle_end = closing_brace(middle);
+ if (*middle_end == '\0') {
+ Error("Unterminated {} clause \"%s\"", middle);
return;
- } else {
- end++;
}
- otherLen = brace - word + strlen(end);
- for (cp = start; cp < end; cp++) {
- /*
- * Find the end of this piece of the clause.
- */
- bracelevel = 0;
- while (*cp != ',') {
- if (*cp == '{') {
- bracelevel++;
- } else if ((*cp == '}') && (bracelevel-- <= 0)) {
- break;
- }
- cp++;
- }
- /*
- * Allocate room for the combination and install the three pieces.
- */
- file = bmake_malloc(otherLen + cp - start + 1);
- if (brace != word) {
- strncpy(file, word, brace-word);
- }
- if (cp != start) {
- strncpy(&file[brace-word], start, cp-start);
- }
- strcpy(&file[(brace-word)+(cp-start)], end);
+ prefix = word;
+ prefix_len = (size_t)(brace - prefix);
+ suffix = middle_end + 1;
+ suffix_len = strlen(suffix);
- /*
- * See if the result has any wildcards in it. If we find one, call
- * Dir_Expand right away, telling it to place the result on our list
- * of expansions.
- */
- for (cp2 = file; *cp2 != '\0'; cp2++) {
- switch(*cp2) {
- case '*':
- case '?':
- case '{':
- case '[':
- Dir_Expand(file, path, expansions);
- goto next;
- }
- }
- if (*cp2 == '\0') {
- /*
- * Hit the end w/o finding any wildcards, so stick the expansion
- * on the end of the list.
- */
- (void)Lst_AtEnd(expansions, file);
- } else {
- next:
+ /* Split the middle into pieces, separated by commas. */
+
+ piece = middle;
+ while (piece < middle_end + 1) {
+ const char *piece_end = separator_comma(piece);
+ size_t piece_len = (size_t)(piece_end - piece);
+
+ char *file = concat3(prefix, prefix_len, piece, piece_len,
+ suffix, suffix_len);
+
+ if (contains_wildcard(file)) {
+ Dir_Expand(file, path, expansions);
free(file);
+ } else {
+ Lst_Append(expansions, file);
}
- start = cp+1;
+
+ piece = piece_end + 1; /* skip over the comma or closing brace */
}
}
@@ -784,32 +754,18 @@ DirExpandCurly(const char *word, const char *brace, Lst path, Lst expansions)
static void
DirExpandInt(const char *word, Lst path, Lst expansions)
{
- LstNode ln; /* Current node */
- Path *p; /* Directory in the node */
+ LstNode ln; /* Current node */
- if (Lst_Open(path) == SUCCESS) {
- while ((ln = Lst_Next(path)) != NULL) {
- p = (Path *)Lst_Datum(ln);
- DirMatchFiles(word, p, expansions);
- }
- Lst_Close(path);
+ Lst_Open(path);
+ while ((ln = Lst_Next(path)) != NULL) {
+ Path *p = LstNode_Datum(ln);
+ DirMatchFiles(word, p, expansions);
}
+ Lst_Close(path);
}
-/*-
- *-----------------------------------------------------------------------
- * DirPrintWord --
- * Print a word in the list of expansions. Callback for Dir_Expand
- * when DEBUG(DIR), via Lst_ForEach.
- *
- * Results:
- * === 0
- *
- * Side Effects:
- * The passed word is printed, followed by a space.
- *
- *-----------------------------------------------------------------------
- */
+/* Print a word in the list of expansions.
+ * Callback for Dir_Expand when DEBUG(DIR), via Lst_ForEach. */
static int
DirPrintWord(void *word, void *dummy MAKE_ATTR_UNUSED)
{
@@ -836,16 +792,18 @@ DirPrintWord(void *word, void *dummy MAKE_ATTR_UNUSED)
*
* Side Effects:
* Directories may be opened. Who knows?
+ * Undefined behavior if the word is really in read-only memory.
*-----------------------------------------------------------------------
*/
void
Dir_Expand(const char *word, Lst path, Lst expansions)
{
- const char *cp;
+ const char *cp;
- if (DEBUG(DIR)) {
- fprintf(debug_file, "Expanding \"%s\"... ", word);
- }
+ assert(path != NULL);
+ assert(expansions != NULL);
+
+ DIR_DEBUG1("Expanding \"%s\"... ", word);
cp = strchr(word, '{');
if (cp) {
@@ -872,13 +830,12 @@ Dir_Expand(const char *word, Lst path, Lst expansions)
/*
* Back up to the start of the component
*/
- char *dirpath;
-
while (cp > word && *cp != '/') {
cp--;
}
if (cp != word) {
char sc;
+ char *dirpath;
/*
* If the glob isn't in the first component, try and find
* all the components up to the one with a wildcard.
@@ -898,10 +855,10 @@ Dir_Expand(const char *word, Lst path, Lst expansions)
char *dp = &dirpath[strlen(dirpath) - 1];
if (*dp == '/')
*dp = '\0';
- path = Lst_Init(FALSE);
+ path = Lst_Init();
(void)Dir_AddDir(path, dirpath);
- DirExpandInt(cp+1, path, expansions);
- Lst_Destroy(path, NULL);
+ DirExpandInt(cp + 1, path, expansions);
+ Lst_Free(path);
}
} else {
/*
@@ -948,21 +905,17 @@ Dir_Expand(const char *word, Lst path, Lst expansions)
*/
static char *
DirLookup(Path *p, const char *name MAKE_ATTR_UNUSED, const char *cp,
- Boolean hasSlash MAKE_ATTR_UNUSED)
+ Boolean hasSlash MAKE_ATTR_UNUSED)
{
- char *file; /* the current filename to check */
+ char *file; /* the current filename to check */
- if (DEBUG(DIR)) {
- fprintf(debug_file, " %s ...\n", p->name);
- }
+ DIR_DEBUG1(" %s ...\n", p->name);
if (Hash_FindEntry(&p->files, cp) == NULL)
return NULL;
- file = str_concat(p->name, cp, STR_ADDSLASH);
- if (DEBUG(DIR)) {
- fprintf(debug_file, " returning %s\n", file);
- }
+ file = str_concat3(p->name, "/", cp);
+ DIR_DEBUG1(" returning %s\n", file);
p->hits += 1;
hits += 1;
return file;
@@ -986,11 +939,11 @@ DirLookup(Path *p, const char *name MAKE_ATTR_UNUSED, const char *cp,
static char *
DirLookupSubdir(Path *p, const char *name)
{
- struct stat stb; /* Buffer for stat, if necessary */
- char *file; /* the current filename to check */
+ struct make_stat mst;
+ char *file; /* the current filename to check */
if (p != dot) {
- file = str_concat(p->name, name, STR_ADDSLASH);
+ file = str_concat3(p->name, "/", name);
} else {
/*
* Checking in dot -- DON'T put a leading ./ on the thing.
@@ -998,11 +951,9 @@ DirLookupSubdir(Path *p, const char *name)
file = bmake_strdup(name);
}
- if (DEBUG(DIR)) {
- fprintf(debug_file, "checking %s ...\n", file);
- }
+ DIR_DEBUG1("checking %s ...\n", file);
- if (cached_stat(file, &stb) == 0) {
+ if (cached_stat(file, &mst) == 0) {
nearmisses += 1;
return file;
}
@@ -1028,40 +979,34 @@ DirLookupSubdir(Path *p, const char *name)
static char *
DirLookupAbs(Path *p, const char *name, const char *cp)
{
- char *p1; /* pointer into p->name */
- const char *p2; /* pointer into name */
+ char *p1; /* pointer into p->name */
+ const char *p2; /* pointer into name */
- if (DEBUG(DIR)) {
- fprintf(debug_file, " %s ...\n", p->name);
- }
+ DIR_DEBUG1(" %s ...\n", p->name);
- /*
- * If the file has a leading path component and that component
- * exactly matches the entire name of the current search
- * directory, we can attempt another cache lookup. And if we don't
- * have a hit, we can safely assume the file does not exist at all.
- */
- for (p1 = p->name, p2 = name; *p1 && *p1 == *p2; p1++, p2++) {
- continue;
- }
- if (*p1 != '\0' || p2 != cp - 1) {
- return NULL;
- }
+ /*
+ * If the file has a leading path component and that component
+ * exactly matches the entire name of the current search
+ * directory, we can attempt another cache lookup. And if we don't
+ * have a hit, we can safely assume the file does not exist at all.
+ */
+ for (p1 = p->name, p2 = name; *p1 && *p1 == *p2; p1++, p2++) {
+ continue;
+ }
+ if (*p1 != '\0' || p2 != cp - 1) {
+ return NULL;
+ }
- if (Hash_FindEntry(&p->files, cp) == NULL) {
- if (DEBUG(DIR)) {
- fprintf(debug_file, " must be here but isn't -- returning\n");
- }
- /* Return empty string: terminates search */
- return bmake_strdup("");
- }
+ if (Hash_FindEntry(&p->files, cp) == NULL) {
+ DIR_DEBUG0(" must be here but isn't -- returning\n");
+ /* Return empty string: terminates search */
+ return bmake_strdup("");
+ }
- p->hits += 1;
- hits += 1;
- if (DEBUG(DIR)) {
- fprintf(debug_file, " returning %s\n", name);
- }
- return bmake_strdup(name);
+ p->hits += 1;
+ hits += 1;
+ DIR_DEBUG1(" returning %s\n", name);
+ return bmake_strdup(name);
}
/*-
@@ -1081,25 +1026,20 @@ static char *
DirFindDot(Boolean hasSlash MAKE_ATTR_UNUSED, const char *name, const char *cp)
{
- if (Hash_FindEntry(&dot->files, cp) != NULL) {
- if (DEBUG(DIR)) {
- fprintf(debug_file, " in '.'\n");
- }
- hits += 1;
- dot->hits += 1;
- return bmake_strdup(name);
- }
- if (cur &&
- Hash_FindEntry(&cur->files, cp) != NULL) {
- if (DEBUG(DIR)) {
- fprintf(debug_file, " in ${.CURDIR} = %s\n", cur->name);
- }
- hits += 1;
- cur->hits += 1;
- return str_concat(cur->name, cp, STR_ADDSLASH);
- }
+ if (Hash_FindEntry(&dot->files, cp) != NULL) {
+ DIR_DEBUG0(" in '.'\n");
+ hits += 1;
+ dot->hits += 1;
+ return bmake_strdup(name);
+ }
+ if (cur && Hash_FindEntry(&cur->files, cp) != NULL) {
+ DIR_DEBUG1(" in ${.CURDIR} = %s\n", cur->name);
+ hits += 1;
+ cur->hits += 1;
+ return str_concat3(cur->name, "/", cp);
+ }
- return NULL;
+ return NULL;
}
/*-
@@ -1127,14 +1067,14 @@ DirFindDot(Boolean hasSlash MAKE_ATTR_UNUSED, const char *name, const char *cp)
char *
Dir_FindFile(const char *name, Lst path)
{
- LstNode ln; /* a list element */
- char *file; /* the current filename to check */
- Path *p; /* current path member */
- const char *cp; /* Terminal name of file */
- Boolean hasLastDot = FALSE; /* true we should search dot last */
- Boolean hasSlash; /* true if 'name' contains a / */
- struct stat stb; /* Buffer for stat, if necessary */
- const char *trailing_dot = ".";
+ LstNode ln; /* a list element */
+ char *file; /* the current filename to check */
+ Path *p; /* current path member */
+ const char *cp; /* Terminal name of file */
+ Boolean hasLastDot = FALSE; /* true we should search dot last */
+ Boolean hasSlash; /* true if 'name' contains a / */
+ struct make_stat mst; /* Buffer for stat, if necessary */
+ const char *trailing_dot = ".";
/*
* Find the final component of the name and note whether it has a
@@ -1149,29 +1089,23 @@ Dir_FindFile(const char *name, Lst path)
cp = name;
}
- if (DEBUG(DIR)) {
- fprintf(debug_file, "Searching for %s ...", name);
- }
+ DIR_DEBUG1("Searching for %s ...", name);
- if (Lst_Open(path) == FAILURE) {
- if (DEBUG(DIR)) {
- fprintf(debug_file, "couldn't open path, file not found\n");
- }
+ if (path == NULL) {
+ DIR_DEBUG0("couldn't open path, file not found\n");
misses += 1;
return NULL;
}
+ Lst_Open(path);
if ((ln = Lst_First(path)) != NULL) {
- p = (Path *)Lst_Datum(ln);
+ p = LstNode_Datum(ln);
if (p == dotLast) {
hasLastDot = TRUE;
- if (DEBUG(DIR))
- fprintf(debug_file, "[dot last]...");
+ DIR_DEBUG0("[dot last]...");
}
}
- if (DEBUG(DIR)) {
- fprintf(debug_file, "\n");
- }
+ DIR_DEBUG0("\n");
/*
* If there's no leading directory components or if the leading
@@ -1179,41 +1113,39 @@ Dir_FindFile(const char *name, Lst path)
* of each of the directories on the search path.
*/
if (!hasSlash || (cp - name == 2 && *name == '.')) {
- /*
- * We look through all the directories on the path seeking one which
- * contains the final component of the given name. If such a beast
- * is found, we concatenate the directory name and the final
- * component and return the resulting string. If we don't find any
- * such thing, we go on to phase two...
- *
- * No matter what, we always look for the file in the current
- * directory before anywhere else (unless we found the magic
- * DOTLAST path, in which case we search it last) and we *do not*
- * add the ./ to it if it exists.
- * This is so there are no conflicts between what the user
- * specifies (fish.c) and what pmake finds (./fish.c).
- */
- if (!hasLastDot &&
- (file = DirFindDot(hasSlash, name, cp)) != NULL) {
- Lst_Close(path);
- return file;
- }
+ /*
+ * We look through all the directories on the path seeking one which
+ * contains the final component of the given name. If such a beast
+ * is found, we concatenate the directory name and the final
+ * component and return the resulting string. If we don't find any
+ * such thing, we go on to phase two...
+ *
+ * No matter what, we always look for the file in the current
+ * directory before anywhere else (unless we found the magic
+ * DOTLAST path, in which case we search it last) and we *do not*
+ * add the ./ to it if it exists.
+ * This is so there are no conflicts between what the user
+ * specifies (fish.c) and what pmake finds (./fish.c).
+ */
+ if (!hasLastDot && (file = DirFindDot(hasSlash, name, cp)) != NULL) {
+ Lst_Close(path);
+ return file;
+ }
- while ((ln = Lst_Next(path)) != NULL) {
- p = (Path *)Lst_Datum(ln);
- if (p == dotLast)
- continue;
- if ((file = DirLookup(p, name, cp, hasSlash)) != NULL) {
- Lst_Close(path);
- return file;
- }
+ while ((ln = Lst_Next(path)) != NULL) {
+ p = LstNode_Datum(ln);
+ if (p == dotLast)
+ continue;
+ if ((file = DirLookup(p, name, cp, hasSlash)) != NULL) {
+ Lst_Close(path);
+ return file;
}
+ }
- if (hasLastDot &&
- (file = DirFindDot(hasSlash, name, cp)) != NULL) {
- Lst_Close(path);
- return file;
- }
+ if (hasLastDot && (file = DirFindDot(hasSlash, name, cp)) != NULL) {
+ Lst_Close(path);
+ return file;
+ }
}
Lst_Close(path);
@@ -1232,9 +1164,7 @@ Dir_FindFile(const char *name, Lst path)
* This phase is only performed if the file is *not* absolute.
*/
if (!hasSlash) {
- if (DEBUG(DIR)) {
- fprintf(debug_file, " failed.\n");
- }
+ DIR_DEBUG0(" failed.\n");
misses += 1;
return NULL;
}
@@ -1245,30 +1175,28 @@ Dir_FindFile(const char *name, Lst path)
}
if (name[0] != '/') {
- Boolean checkedDot = FALSE;
+ Boolean checkedDot = FALSE;
- if (DEBUG(DIR)) {
- fprintf(debug_file, " Trying subdirectories...\n");
- }
+ DIR_DEBUG0(" Trying subdirectories...\n");
if (!hasLastDot) {
- if (dot) {
- checkedDot = TRUE;
- if ((file = DirLookupSubdir(dot, name)) != NULL)
- return file;
- }
- if (cur && (file = DirLookupSubdir(cur, name)) != NULL)
- return file;
+ if (dot) {
+ checkedDot = TRUE;
+ if ((file = DirLookupSubdir(dot, name)) != NULL)
+ return file;
+ }
+ if (cur && (file = DirLookupSubdir(cur, name)) != NULL)
+ return file;
}
- (void)Lst_Open(path);
+ Lst_Open(path);
while ((ln = Lst_Next(path)) != NULL) {
- p = (Path *)Lst_Datum(ln);
+ p = LstNode_Datum(ln);
if (p == dotLast)
continue;
if (p == dot) {
- if (checkedDot)
- continue;
+ if (checkedDot)
+ continue;
checkedDot = TRUE;
}
if ((file = DirLookupSubdir(p, name)) != NULL) {
@@ -1279,13 +1207,13 @@ Dir_FindFile(const char *name, Lst path)
Lst_Close(path);
if (hasLastDot) {
- if (dot && !checkedDot) {
- checkedDot = TRUE;
- if ((file = DirLookupSubdir(dot, name)) != NULL)
- return file;
- }
- if (cur && (file = DirLookupSubdir(cur, name)) != NULL)
- return file;
+ if (dot && !checkedDot) {
+ checkedDot = TRUE;
+ if ((file = DirLookupSubdir(dot, name)) != NULL)
+ return file;
+ }
+ if (cur && (file = DirLookupSubdir(cur, name)) != NULL)
+ return file;
}
if (checkedDot) {
@@ -1293,9 +1221,7 @@ Dir_FindFile(const char *name, Lst path)
* Already checked by the given name, since . was in the path,
* so no point in proceeding...
*/
- if (DEBUG(DIR)) {
- fprintf(debug_file, " Checked . already, returning NULL\n");
- }
+ DIR_DEBUG0(" Checked . already, returning NULL\n");
return NULL;
}
@@ -1310,12 +1236,10 @@ Dir_FindFile(const char *name, Lst path)
* file does not exist at all. This is signified by DirLookupAbs()
* returning an empty string.
*/
- if (DEBUG(DIR)) {
- fprintf(debug_file, " Trying exact path matches...\n");
- }
+ DIR_DEBUG0(" Trying exact path matches...\n");
- if (!hasLastDot && cur && ((file = DirLookupAbs(cur, name, cp))
- != NULL)) {
+ if (!hasLastDot && cur &&
+ ((file = DirLookupAbs(cur, name, cp)) != NULL)) {
if (file[0] == '\0') {
free(file);
return NULL;
@@ -1323,9 +1247,9 @@ Dir_FindFile(const char *name, Lst path)
return file;
}
- (void)Lst_Open(path);
+ Lst_Open(path);
while ((ln = Lst_Next(path)) != NULL) {
- p = (Path *)Lst_Datum(ln);
+ p = LstNode_Datum(ln);
if (p == dotLast)
continue;
if ((file = DirLookupAbs(p, name, cp)) != NULL) {
@@ -1339,8 +1263,8 @@ Dir_FindFile(const char *name, Lst path)
}
Lst_Close(path);
- if (hasLastDot && cur && ((file = DirLookupAbs(cur, name, cp))
- != NULL)) {
+ if (hasLastDot && cur &&
+ ((file = DirLookupAbs(cur, name, cp)) != NULL)) {
if (file[0] == '\0') {
free(file);
return NULL;
@@ -1380,7 +1304,7 @@ Dir_FindFile(const char *name, Lst path)
if (ln == NULL) {
return NULL;
} else {
- p = (Path *)Lst_Datum(ln);
+ p = LstNode_Datum(ln);
}
if (Hash_FindEntry(&p->files, cp) != NULL) {
@@ -1389,18 +1313,14 @@ Dir_FindFile(const char *name, Lst path)
return NULL;
}
#else /* !notdef */
- if (DEBUG(DIR)) {
- fprintf(debug_file, " Looking for \"%s\" ...\n", name);
- }
+ DIR_DEBUG1(" Looking for \"%s\" ...\n", name);
bigmisses += 1;
- if (cached_stat(name, &stb) == 0) {
+ if (cached_stat(name, &mst) == 0) {
return bmake_strdup(name);
}
- if (DEBUG(DIR)) {
- fprintf(debug_file, " failed. Returning NULL\n");
- }
+ DIR_DEBUG0(" failed. Returning NULL\n");
return NULL;
#endif /* notdef */
}
@@ -1416,7 +1336,7 @@ Dir_FindFile(const char *name, Lst path)
* here starting directory
* search_path the path we are looking for
* result the result of a successful search is placed here
- * rlen the length of the result buffer
+ * result_len the length of the result buffer
* (typically MAXPATHLEN + 1)
*
* Results:
@@ -1426,62 +1346,57 @@ Dir_FindFile(const char *name, Lst path)
* Side Effects:
*-----------------------------------------------------------------------
*/
-int
-Dir_FindHereOrAbove(char *here, char *search_path, char *result, int rlen) {
-
- struct stat st;
- char dirbase[MAXPATHLEN + 1], *db_end;
- char try[MAXPATHLEN + 1], *try_end;
-
- /* copy out our starting point */
- snprintf(dirbase, sizeof(dirbase), "%s", here);
- db_end = dirbase + strlen(dirbase);
-
- /* loop until we determine a result */
- while (1) {
+Boolean
+Dir_FindHereOrAbove(const char *here, const char *search_path,
+ char *result, int result_len)
+{
+ struct make_stat mst;
+ char dirbase[MAXPATHLEN + 1], *dirbase_end;
+ char try[MAXPATHLEN + 1], *try_end;
- /* try and stat(2) it ... */
- snprintf(try, sizeof(try), "%s/%s", dirbase, search_path);
- if (cached_stat(try, &st) != -1) {
- /*
- * success! if we found a file, chop off
- * the filename so we return a directory.
- */
- if ((st.st_mode & S_IFMT) != S_IFDIR) {
- try_end = try + strlen(try);
- while (try_end > try && *try_end != '/')
- try_end--;
- if (try_end > try)
- *try_end = 0; /* chop! */
- }
+ /* copy out our starting point */
+ snprintf(dirbase, sizeof(dirbase), "%s", here);
+ dirbase_end = dirbase + strlen(dirbase);
- /*
- * done!
- */
- snprintf(result, rlen, "%s", try);
- return 1;
- }
+ /* loop until we determine a result */
+ while (TRUE) {
- /*
- * nope, we didn't find it. if we used up dirbase we've
- * reached the root and failed.
- */
- if (db_end == dirbase)
- break; /* failed! */
+ /* try and stat(2) it ... */
+ snprintf(try, sizeof(try), "%s/%s", dirbase, search_path);
+ if (cached_stat(try, &mst) != -1) {
+ /*
+ * success! if we found a file, chop off
+ * the filename so we return a directory.
+ */
+ if ((mst.mst_mode & S_IFMT) != S_IFDIR) {
+ try_end = try + strlen(try);
+ while (try_end > try && *try_end != '/')
+ try_end--;
+ if (try_end > try)
+ *try_end = '\0'; /* chop! */
+ }
- /*
- * truncate dirbase from the end to move up a dir
- */
- while (db_end > dirbase && *db_end != '/')
- db_end--;
- *db_end = 0; /* chop! */
+ snprintf(result, result_len, "%s", try);
+ return TRUE;
+ }
- } /* while (1) */
+ /*
+ * nope, we didn't find it. if we used up dirbase we've
+ * reached the root and failed.
+ */
+ if (dirbase_end == dirbase)
+ break; /* failed! */
/*
- * we failed...
+ * truncate dirbase from the end to move up a dir
*/
- return 0;
+ while (dirbase_end > dirbase && *dirbase_end != '/')
+ dirbase_end--;
+ *dirbase_end = '\0'; /* chop! */
+
+ } /* while (TRUE) */
+
+ return FALSE;
}
/*-
@@ -1505,8 +1420,8 @@ Dir_FindHereOrAbove(char *here, char *search_path, char *result, int rlen) {
int
Dir_MTime(GNode *gn, Boolean recheck)
{
- char *fullName; /* the full pathname of name */
- struct stat stb; /* buffer for finding the mod time */
+ char *fullName; /* the full pathname of name */
+ struct make_stat mst; /* buffer for finding the mod time */
if (gn->type & OP_ARCHV) {
return Arch_MTime(gn);
@@ -1519,7 +1434,7 @@ Dir_MTime(GNode *gn, Boolean recheck)
else {
fullName = Dir_FindFile(gn->name, Suff_FindPath(gn));
if (fullName == NULL && gn->flags & FROM_DEPEND &&
- !Lst_IsEmpty(gn->iParents)) {
+ !Lst_IsEmpty(gn->implicitParents)) {
char *cp;
cp = strrchr(gn->name, '/');
@@ -1539,15 +1454,15 @@ Dir_MTime(GNode *gn, Boolean recheck)
gn->path = bmake_strdup(fullName);
if (!Job_RunTarget(".STALE", gn->fname))
fprintf(stdout,
- "%s: %s, %d: ignoring stale %s for %s, "
- "found %s\n", progname, gn->fname, gn->lineno,
- makeDependfile, gn->name, fullName);
+ "%s: %s, %d: ignoring stale %s for %s, "
+ "found %s\n", progname, gn->fname,
+ gn->lineno,
+ makeDependfile, gn->name, fullName);
}
}
}
- if (DEBUG(DIR))
- fprintf(debug_file, "Found '%s' as '%s'\n",
- gn->name, fullName ? fullName : "(not found)" );
+ DIR_DEBUG2("Found '%s' as '%s'\n",
+ gn->name, fullName ? fullName : "(not found)");
}
} else {
fullName = gn->path;
@@ -1557,13 +1472,13 @@ Dir_MTime(GNode *gn, Boolean recheck)
fullName = bmake_strdup(gn->name);
}
- if (cached_stats(&mtimes, fullName, &stb, recheck ? CST_UPDATE : 0) < 0) {
+ if (cached_stats(&mtimes, fullName, &mst, recheck ? CST_UPDATE : 0) < 0) {
if (gn->type & OP_MEMBER) {
if (fullName != gn->path)
free(fullName);
return Arch_MemMTime(gn);
} else {
- stb.st_mtime = 0;
+ mst.mst_mtime = 0;
}
}
@@ -1571,7 +1486,7 @@ Dir_MTime(GNode *gn, Boolean recheck)
gn->path = fullName;
}
- gn->mtime = stb.st_mtime;
+ gn->mtime = mst.mst_mtime;
return gn->mtime;
}
@@ -1585,6 +1500,8 @@ Dir_MTime(GNode *gn, Boolean recheck)
* Input:
* path the path to which the directory should be
* added
+ * XXX: Why would this ever be NULL, and what does
+ * that mean?
* name the name of the directory to add
*
* Results:
@@ -1598,78 +1515,70 @@ Dir_MTime(GNode *gn, Boolean recheck)
Path *
Dir_AddDir(Lst path, const char *name)
{
- LstNode ln = NULL; /* node in case Path structure is found */
- Path *p = NULL; /* pointer to new Path structure */
- DIR *d; /* for reading directory */
- struct dirent *dp; /* entry in directory */
+ LstNode ln = NULL; /* node in case Path structure is found */
+ Path *p = NULL; /* pointer to new Path structure */
+ DIR *d; /* for reading directory */
+ struct dirent *dp; /* entry in directory */
- if (strcmp(name, ".DOTLAST") == 0) {
- ln = Lst_Find(path, name, DirFindName);
+ if (path != NULL && strcmp(name, ".DOTLAST") == 0) {
+ ln = Lst_Find(path, DirFindName, name);
if (ln != NULL)
- return (Path *)Lst_Datum(ln);
- else {
- dotLast->refCount += 1;
- (void)Lst_AtFront(path, dotLast);
- }
+ return LstNode_Datum(ln);
+
+ dotLast->refCount++;
+ Lst_Prepend(path, dotLast);
}
- if (path)
- ln = Lst_Find(openDirectories, name, DirFindName);
+ if (path != NULL)
+ ln = Lst_Find(openDirectories, DirFindName, name);
if (ln != NULL) {
- p = (Path *)Lst_Datum(ln);
- if (path && Lst_Member(path, p) == NULL) {
+ p = LstNode_Datum(ln);
+ if (Lst_FindDatum(path, p) == NULL) {
p->refCount += 1;
- (void)Lst_AtEnd(path, p);
- }
- } else {
- if (DEBUG(DIR)) {
- fprintf(debug_file, "Caching %s ...", name);
+ Lst_Append(path, p);
}
+ return p;
+ }
+
+ DIR_DEBUG1("Caching %s ...", name);
- if ((d = opendir(name)) != NULL) {
- p = bmake_malloc(sizeof(Path));
- p->name = bmake_strdup(name);
- p->hits = 0;
- p->refCount = 1;
- Hash_InitTable(&p->files, -1);
+ if ((d = opendir(name)) != NULL) {
+ p = bmake_malloc(sizeof(Path));
+ p->name = bmake_strdup(name);
+ p->hits = 0;
+ p->refCount = 1;
+ Hash_InitTable(&p->files, -1);
- while ((dp = readdir(d)) != NULL) {
+ while ((dp = readdir(d)) != NULL) {
#if defined(sun) && defined(d_ino) /* d_ino is a sunos4 #define for d_fileno */
- /*
- * The sun directory library doesn't check for a 0 inode
- * (0-inode slots just take up space), so we have to do
- * it ourselves.
- */
- if (dp->d_fileno == 0) {
- continue;
- }
-#endif /* sun && d_ino */
- (void)Hash_CreateEntry(&p->files, dp->d_name, NULL);
+ /*
+ * The sun directory library doesn't check for a 0 inode
+ * (0-inode slots just take up space), so we have to do
+ * it ourselves.
+ */
+ if (dp->d_fileno == 0) {
+ continue;
}
- (void)closedir(d);
- (void)Lst_AtEnd(openDirectories, p);
- if (path != NULL)
- (void)Lst_AtEnd(path, p);
- }
- if (DEBUG(DIR)) {
- fprintf(debug_file, "done\n");
+#endif /* sun && d_ino */
+ (void)Hash_CreateEntry(&p->files, dp->d_name, NULL);
}
+ (void)closedir(d);
+ Lst_Append(openDirectories, p);
+ if (path != NULL)
+ Lst_Append(path, p);
}
+ DIR_DEBUG0("done\n");
return p;
}
/*-
*-----------------------------------------------------------------------
* Dir_CopyDir --
- * Callback function for duplicating a search path via Lst_Duplicate.
+ * Callback function for duplicating a search path via Lst_Copy.
* Ups the reference count for the directory.
*
* Results:
* Returns the Path it was given.
- *
- * Side Effects:
- * The refCount of the path is incremented.
- *
*-----------------------------------------------------------------------
*/
void *
@@ -1704,25 +1613,23 @@ Dir_CopyDir(void *p)
char *
Dir_MakeFlags(const char *flag, Lst path)
{
- char *str; /* the string which will be returned */
- char *s1, *s2;/* the current directory preceded by 'flag' */
- LstNode ln; /* the node of the current directory */
- Path *p; /* the structure describing the current directory */
+ Buffer buf;
+ LstNode ln; /* the node of the current directory */
- str = bmake_strdup("");
+ Buf_Init(&buf, 0);
- if (Lst_Open(path) == SUCCESS) {
+ if (path != NULL) {
+ Lst_Open(path);
while ((ln = Lst_Next(path)) != NULL) {
- p = (Path *)Lst_Datum(ln);
- s2 = str_concat(flag, p->name, 0);
- str = str_concat(s1 = str, s2, STR_ADDSPACE);
- free(s1);
- free(s2);
+ Path *p = LstNode_Datum(ln);
+ Buf_AddStr(&buf, " ");
+ Buf_AddStr(&buf, flag);
+ Buf_AddStr(&buf, p->name);
}
Lst_Close(path);
}
- return str;
+ return Buf_Destroy(&buf, FALSE);
}
/*-
@@ -1746,14 +1653,14 @@ Dir_MakeFlags(const char *flag, Lst path)
void
Dir_Destroy(void *pp)
{
- Path *p = (Path *)pp;
+ Path *p = (Path *)pp;
p->refCount -= 1;
if (p->refCount == 0) {
- LstNode ln;
+ LstNode ln;
- ln = Lst_Member(openDirectories, p);
- (void)Lst_Remove(openDirectories, ln);
+ ln = Lst_FindDatum(openDirectories, p);
+ Lst_Remove(openDirectories, ln);
Hash_DeleteTable(&p->files);
free(p->name);
@@ -1781,9 +1688,8 @@ Dir_Destroy(void *pp)
void
Dir_ClearPath(Lst path)
{
- Path *p;
while (!Lst_IsEmpty(path)) {
- p = (Path *)Lst_DeQueue(path);
+ Path *p = Lst_Dequeue(path);
Dir_Destroy(p);
}
}
@@ -1811,37 +1717,43 @@ void
Dir_Concat(Lst path1, Lst path2)
{
LstNode ln;
- Path *p;
+ Path *p;
- for (ln = Lst_First(path2); ln != NULL; ln = Lst_Succ(ln)) {
- p = (Path *)Lst_Datum(ln);
- if (Lst_Member(path1, p) == NULL) {
+ for (ln = Lst_First(path2); ln != NULL; ln = LstNode_Next(ln)) {
+ p = LstNode_Datum(ln);
+ if (Lst_FindDatum(path1, p) == NULL) {
p->refCount += 1;
- (void)Lst_AtEnd(path1, p);
+ Lst_Append(path1, p);
}
}
}
+static int
+percentage(int num, int den)
+{
+ return den != 0 ? num * 100 / den : 0;
+}
+
/********** DEBUG INFO **********/
void
Dir_PrintDirectories(void)
{
- LstNode ln;
- Path *p;
+ LstNode ln;
fprintf(debug_file, "#*** Directory Cache:\n");
- fprintf(debug_file, "# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n",
- hits, misses, nearmisses, bigmisses,
- (hits+bigmisses+nearmisses ?
- hits * 100 / (hits + bigmisses + nearmisses) : 0));
+ fprintf(debug_file,
+ "# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n",
+ hits, misses, nearmisses, bigmisses,
+ percentage(hits, hits + bigmisses + nearmisses));
fprintf(debug_file, "# %-20s referenced\thits\n", "directory");
- if (Lst_Open(openDirectories) == SUCCESS) {
- while ((ln = Lst_Next(openDirectories)) != NULL) {
- p = (Path *)Lst_Datum(ln);
- fprintf(debug_file, "# %-20s %10d\t%4d\n", p->name, p->refCount, p->hits);
- }
- Lst_Close(openDirectories);
+
+ Lst_Open(openDirectories);
+ while ((ln = Lst_Next(openDirectories)) != NULL) {
+ Path *p = LstNode_Datum(ln);
+ fprintf(debug_file, "# %-20s %10d\t%4d\n", p->name, p->refCount,
+ p->hits);
}
+ Lst_Close(openDirectories);
}
static int
diff --git a/dir.h b/dir.h
index 52ab35e2fd25..10da0eb8ba78 100644
--- a/dir.h
+++ b/dir.h
@@ -1,4 +1,4 @@
-/* $NetBSD: dir.h,v 1.18 2017/05/31 22:02:06 maya Exp $ */
+/* $NetBSD: dir.h,v 1.23 2020/09/02 04:08:54 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -72,29 +72,34 @@
* from: @(#)dir.h 8.1 (Berkeley) 6/6/93
*/
-/* dir.h --
- */
-
#ifndef MAKE_DIR_H
#define MAKE_DIR_H
-typedef struct Path {
+/* A cache of a directory, remembering all the files that exist in that
+ * directory. */
+typedef struct {
char *name; /* Name of directory */
int refCount; /* Number of paths with this directory */
int hits; /* the number of times a file in this
* directory has been found */
- Hash_Table files; /* Hash table of files in directory */
+ Hash_Table files; /* Hash set of files in directory */
} Path;
-void Dir_Init(const char *);
+struct make_stat {
+ time_t mst_mtime;
+ mode_t mst_mode;
+};
+
+void Dir_Init(void);
+void Dir_InitDir(const char *);
void Dir_InitCur(const char *);
void Dir_InitDot(void);
void Dir_End(void);
void Dir_SetPATH(void);
-Boolean Dir_HasWildcards(char *);
+Boolean Dir_HasWildcards(const char *);
void Dir_Expand(const char *, Lst, Lst);
char *Dir_FindFile(const char *, Lst);
-int Dir_FindHereOrAbove(char *, char *, char *, int);
+Boolean Dir_FindHereOrAbove(const char *, const char *, char *, int);
int Dir_MTime(GNode *, Boolean);
Path *Dir_AddDir(Lst, const char *);
char *Dir_MakeFlags(const char *, Lst);
@@ -103,6 +108,9 @@ void Dir_Concat(Lst, Lst);
void Dir_PrintDirectories(void);
void Dir_PrintPath(Lst);
void Dir_Destroy(void *);
-void * Dir_CopyDir(void *);
+void *Dir_CopyDir(void *);
+
+int cached_lstat(const char *, struct make_stat *);
+int cached_stat(const char *, struct make_stat *);
#endif /* MAKE_DIR_H */
diff --git a/enum.c b/enum.c
new file mode 100755
index 000000000000..9dec4f3a5f6a
--- /dev/null
+++ b/enum.c
@@ -0,0 +1,100 @@
+/* $NetBSD: enum.c,v 1.6 2020/09/01 20:34:51 rillig Exp $ */
+
+/*
+ Copyright (c) 2020 Roland Illig <rillig@NetBSD.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: enum.c,v 1.6 2020/09/01 20:34:51 rillig Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: enum.c,v 1.6 2020/09/01 20:34:51 rillig Exp $");
+#endif
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "enum.h"
+
+/* Convert a bitset into a string representation, showing the names of the
+ * individual bits.
+ *
+ * Optionally, shortcuts for groups of bits can be added. To have an effect,
+ * they need to be listed before their individual bits. */
+const char *
+Enum_FlagsToString(char *buf, size_t buf_size,
+ int value, const EnumToStringSpec *spec)
+{
+ const char *buf_start = buf;
+ const char *sep = "";
+ size_t sep_len = 0;
+
+ for (; spec->es_value != 0; spec++) {
+ size_t name_len;
+
+ if ((value & spec->es_value) != spec->es_value)
+ continue;
+ value &= ~spec->es_value;
+
+ assert(buf_size >= sep_len + 1);
+ memcpy(buf, sep, sep_len);
+ buf += sep_len;
+ buf_size -= sep_len;
+
+ name_len = strlen(spec->es_name);
+ assert(buf_size >= name_len + 1);
+ memcpy(buf, spec->es_name, name_len);
+ buf += name_len;
+ buf_size -= name_len;
+
+ sep = ENUM__SEP;
+ sep_len = sizeof ENUM__SEP - 1;
+ }
+
+ /* If this assertion fails, the listed enum values are incomplete. */
+ assert(value == 0);
+
+ if (buf == buf_start)
+ return "none";
+
+ assert(buf_size >= 1);
+ buf[0] = '\0';
+ return buf_start;
+}
+
+/* Convert a fixed-value enum into a string representation. */
+const char *
+Enum_ValueToString(int value, const EnumToStringSpec *spec)
+{
+ for (; spec->es_name[0] != '\0'; spec++) {
+ if (value == spec->es_value)
+ return spec->es_name;
+ }
+ abort(/* unknown enum value */);
+}
diff --git a/enum.h b/enum.h
new file mode 100755
index 000000000000..d6a94f11e7cd
--- /dev/null
+++ b/enum.h
@@ -0,0 +1,193 @@
+/* $NetBSD: enum.h,v 1.9 2020/09/01 20:34:51 rillig Exp $ */
+
+/*
+ Copyright (c) 2020 Roland Illig <rillig@NetBSD.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MAKE_ENUM_H
+#define MAKE_ENUM_H
+
+/* Generate string representations for bitmasks and simple enums. */
+
+#include <stddef.h>
+
+typedef struct {
+ int es_value;
+ const char *es_name;
+} EnumToStringSpec;
+
+const char *Enum_FlagsToString(char *, size_t, int, const EnumToStringSpec *);
+const char *Enum_ValueToString(int, const EnumToStringSpec *);
+
+/* For Enum_FlagsToString, the separator between flags. */
+#define ENUM__SEP "|"
+
+/* Generate the string that joins all possible flags, to see how large the
+ * buffer must be. */
+#define ENUM__JOIN_STR_1(v1) \
+ #v1
+#define ENUM__JOIN_STR_2(v1, v2) \
+ ENUM__JOIN_STR_1(v1) ENUM__SEP \
+ ENUM__JOIN_STR_1(v2)
+#define ENUM__JOIN_STR_4(v1, v2, v3, v4) \
+ ENUM__JOIN_STR_2(v1, v2) ENUM__SEP \
+ ENUM__JOIN_STR_2(v3, v4)
+#define ENUM__JOIN_STR_8(v1, v2, v3, v4, v5, v6, v7, v8) \
+ ENUM__JOIN_STR_4(v1, v2, v3, v4) ENUM__SEP \
+ ENUM__JOIN_STR_4(v5, v6, v7, v8)
+#define ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
+ v09, v10, v11, v12, v13, v14, v15, v16) \
+ ENUM__JOIN_STR_8(v01, v02, v03, v04, v05, v06, v07, v08) ENUM__SEP \
+ ENUM__JOIN_STR_8(v09, v10, v11, v12, v13, v14, v15, v16)
+
+#define ENUM__JOIN_2(part1, part2) \
+ part1 ENUM__SEP part2
+#define ENUM__JOIN_3(part1, part2, part3) \
+ part1 ENUM__SEP part2 ENUM__SEP part3
+#define ENUM__JOIN_4(part1, part2, part3, part4) \
+ part1 ENUM__SEP part2 ENUM__SEP part3 ENUM__SEP part4
+#define ENUM__JOIN_5(part1, part2, part3, part4, part5) \
+ part1 ENUM__SEP part2 ENUM__SEP part3 ENUM__SEP part4 ENUM__SEP part5
+
+/* List the pairs of enum value and corresponding name. */
+#define ENUM__SPEC_1(v1) \
+ { v1, #v1 }
+#define ENUM__SPEC_2(v1, v2) \
+ ENUM__SPEC_1(v1), \
+ ENUM__SPEC_1(v2)
+#define ENUM__SPEC_4(v1, v2, v3, v4) \
+ ENUM__SPEC_2(v1, v2), \
+ ENUM__SPEC_2(v3, v4)
+#define ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8) \
+ ENUM__SPEC_4(v1, v2, v3, v4), \
+ ENUM__SPEC_4(v5, v6, v7, v8)
+#define ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
+ v09, v10, v11, v12, v13, v14, v15, v16) \
+ ENUM__SPEC_8(v01, v02, v03, v04, v05, v06, v07, v08), \
+ ENUM__SPEC_8(v09, v10, v11, v12, v13, v14, v15, v16)
+
+#define ENUM__SPECS_2(part1, part2) \
+ { part1, part2, { 0, "" } }
+#define ENUM__SPECS_3(part1, part2, part3) \
+ { part1, part2, part3, { 0, "" } }
+#define ENUM__SPECS_4(part1, part2, part3, part4) \
+ { part1, part2, part3, part4, { 0, "" } }
+#define ENUM__SPECS_5(part1, part2, part3, part4, part5) \
+ { part1, part2, part3, part4, part5, { 0, "" } }
+
+/* Declare the necessary data structures for calling Enum_ValueToString. */
+#define ENUM__VALUE_RTTI(typnam, specs) \
+ static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs
+
+/* Declare the necessary data structures for calling Enum_FlagsToString. */
+#define ENUM__FLAGS_RTTI(typnam, specs, joined) \
+ static const EnumToStringSpec typnam ## _ ## ToStringSpecs[] = specs; \
+ enum { typnam ## _ ## ToStringSize = sizeof joined }
+
+/* Declare the necessary data structures for calling Enum_FlagsToString
+ * for an enum with 3 flags. */
+#define ENUM_FLAGS_RTTI_3(typnam, v1, v2, v3) \
+ ENUM__FLAGS_RTTI(typnam, \
+ ENUM__SPECS_2( \
+ ENUM__SPEC_2(v1, v2), \
+ ENUM__SPEC_1(v3)), \
+ ENUM__JOIN_2( \
+ ENUM__JOIN_STR_2(v1, v2), \
+ ENUM__JOIN_STR_1(v3)))
+
+/* Declare the necessary data structures for calling Enum_FlagsToString
+ * for an enum with 8 flags. */
+#define ENUM_FLAGS_RTTI_8(typnam, v1, v2, v3, v4, v5, v6, v7, v8) \
+ ENUM__FLAGS_RTTI(typnam, \
+ ENUM__SPECS_2( \
+ ENUM__SPEC_4(v1, v2, v3, v4), \
+ ENUM__SPEC_4(v5, v6, v7, v8)), \
+ ENUM__JOIN_2( \
+ ENUM__JOIN_STR_4(v1, v2, v3, v4), \
+ ENUM__JOIN_STR_4(v5, v6, v7, v8)))
+
+/* Declare the necessary data structures for calling Enum_ValueToString
+ * for an enum with 8 constants. */
+#define ENUM_VALUE_RTTI_8(typnam, v1, v2, v3, v4, v5, v6, v7, v8) \
+ ENUM__VALUE_RTTI(typnam, \
+ ENUM__SPECS_2( \
+ ENUM__SPEC_4(v1, v2, v3, v4), \
+ ENUM__SPEC_4(v5, v6, v7, v8)))
+
+/* Declare the necessary data structures for calling Enum_FlagsToString
+ * for an enum with 10 flags. */
+#define ENUM_FLAGS_RTTI_10(typnam, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) \
+ ENUM__FLAGS_RTTI(typnam, \
+ ENUM__SPECS_2( \
+ ENUM__SPEC_8(v1, v2, v3, v4, v5, v6, v7, v8), \
+ ENUM__SPEC_2(v9, v10)), \
+ ENUM__JOIN_2( \
+ ENUM__JOIN_STR_8(v1, v2, v3, v4, v5, v6, v7, v8), \
+ ENUM__JOIN_STR_2(v9, v10)))
+
+/* Declare the necessary data structures for calling Enum_FlagsToString
+ * for an enum with 31 flags. */
+#define ENUM_FLAGS_RTTI_31(typnam, \
+ v01, v02, v03, v04, v05, v06, v07, v08, \
+ v09, v10, v11, v12, v13, v14, v15, v16, \
+ v17, v18, v19, v20, v21, v22, v23, v24, \
+ v25, v26, v27, v28, v29, v30, v31) \
+ ENUM__FLAGS_RTTI(typnam, \
+ ENUM__SPECS_5( \
+ ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
+ v09, v10, v11, v12, v13, v14, v15, v16), \
+ ENUM__SPEC_8(v17, v18, v19, v20, v21, v22, v23, v24), \
+ ENUM__SPEC_4(v25, v26, v27, v28), \
+ ENUM__SPEC_2(v29, v30), \
+ ENUM__SPEC_1(v31)), \
+ ENUM__JOIN_5( \
+ ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
+ v09, v10, v11, v12, v13, v14, v15, v16), \
+ ENUM__JOIN_STR_8(v17, v18, v19, v20, v21, v22, v23, v24), \
+ ENUM__JOIN_STR_4(v25, v26, v27, v28), \
+ ENUM__JOIN_STR_2(v29, v30), \
+ ENUM__JOIN_STR_1(v31)))
+
+/* Declare the necessary data structures for calling Enum_FlagsToString
+ * for an enum with 32 flags. */
+#define ENUM_FLAGS_RTTI_32(typnam, \
+ v01, v02, v03, v04, v05, v06, v07, v08, \
+ v09, v10, v11, v12, v13, v14, v15, v16, \
+ v17, v18, v19, v20, v21, v22, v23, v24, \
+ v25, v26, v27, v28, v29, v30, v31, v32) \
+ ENUM__FLAGS_RTTI(typnam, \
+ ENUM__SPECS_2( \
+ ENUM__SPEC_16(v01, v02, v03, v04, v05, v06, v07, v08, \
+ v09, v10, v11, v12, v13, v14, v15, v16), \
+ ENUM__SPEC_16(v17, v18, v19, v20, v21, v22, v23, v24, \
+ v25, v26, v27, v28, v29, v30, v31, v32)), \
+ ENUM__JOIN_2( \
+ ENUM__JOIN_STR_16(v01, v02, v03, v04, v05, v06, v07, v08, \
+ v09, v10, v11, v12, v13, v14, v15, v16), \
+ ENUM__JOIN_STR_16(v17, v18, v19, v20, v21, v22, v23, v24, \
+ v25, v26, v27, v28, v29, v30, v31, v32)))
+
+#endif
diff --git a/for.c b/for.c
index f20a0f58b06b..2e9963f2a7f6 100644
--- a/for.c
+++ b/for.c
@@ -1,4 +1,4 @@
-/* $NetBSD: for.c,v 1.54 2020/07/03 08:13:23 rillig Exp $ */
+/* $NetBSD: for.c,v 1.67 2020/08/30 19:56:02 rillig Exp $ */
/*
* Copyright (c) 1992, The Regents of the University of California.
@@ -30,14 +30,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: for.c,v 1.54 2020/07/03 08:13:23 rillig Exp $";
+static char rcsid[] = "$NetBSD: for.c,v 1.67 2020/08/30 19:56:02 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: for.c,v 1.54 2020/07/03 08:13:23 rillig Exp $");
+__RCSID("$NetBSD: for.c,v 1.67 2020/08/30 19:56:02 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -52,13 +52,7 @@ __RCSID("$NetBSD: for.c,v 1.54 2020/07/03 08:13:23 rillig Exp $");
*
*/
-#include <assert.h>
-#include <ctype.h>
-
#include "make.h"
-#include "hash.h"
-#include "dir.h"
-#include "buf.h"
#include "strlist.h"
#define FOR_SUB_ESCAPE_CHAR 1
@@ -83,34 +77,22 @@ __RCSID("$NetBSD: for.c,v 1.54 2020/07/03 08:13:23 rillig Exp $");
* For_Run.
*/
-static int forLevel = 0; /* Nesting level */
+static int forLevel = 0; /* Nesting level */
/*
* State of a for loop.
*/
-typedef struct _For {
- Buffer buf; /* Body of loop */
- strlist_t vars; /* Iteration variables */
- strlist_t items; /* Substitution items */
- char *parse_buf;
- int short_var;
- int sub_next;
+typedef struct {
+ Buffer buf; /* Body of loop */
+ strlist_t vars; /* Iteration variables */
+ strlist_t items; /* Substitution items */
+ char *parse_buf;
+ int short_var;
+ int sub_next;
} For;
-static For *accumFor; /* Loop being accumulated */
-
-
-
-static char *
-make_str(const char *ptr, int len)
-{
- char *new_ptr;
+static For *accumFor; /* Loop being accumulated */
- new_ptr = bmake_malloc(len + 1);
- memcpy(new_ptr, ptr, len);
- new_ptr[len] = 0;
- return new_ptr;
-}
static void
For_Free(For *arg)
@@ -148,14 +130,13 @@ For_Eval(char *line)
{
For *new_for;
char *ptr = line, *sub;
- int len;
+ size_t len;
int escapes;
unsigned char ch;
- char **words, *word_buf;
- int n, nwords;
+ Words words;
/* Skip the '.' and any following whitespace */
- for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
+ for (ptr++; *ptr && isspace((unsigned char)*ptr); ptr++)
continue;
/*
@@ -163,8 +144,8 @@ For_Eval(char *line)
* a for.
*/
if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' ||
- !isspace((unsigned char) ptr[3])) {
- if (ptr[0] == 'e' && strncmp(ptr+1, "ndfor", 5) == 0) {
+ !isspace((unsigned char)ptr[3])) {
+ if (ptr[0] == 'e' && strncmp(ptr + 1, "ndfor", 5) == 0) {
Parse_Error(PARSE_FATAL, "for-less endfor");
return -1;
}
@@ -181,7 +162,7 @@ For_Eval(char *line)
/* Grab the variables. Terminate on "in". */
for (;; ptr += len) {
- while (*ptr && isspace((unsigned char) *ptr))
+ while (*ptr && isspace((unsigned char)*ptr))
ptr++;
if (*ptr == '\0') {
Parse_Error(PARSE_FATAL, "missing `in' in for");
@@ -196,7 +177,7 @@ For_Eval(char *line)
}
if (len == 1)
new_for->short_var = 1;
- strlist_add_str(&new_for->vars, make_str(ptr, len), len);
+ strlist_add_str(&new_for->vars, bmake_strldup(ptr, len), len);
}
if (strlist_num(&new_for->vars) == 0) {
@@ -205,7 +186,7 @@ For_Eval(char *line)
return -1;
}
- while (*ptr && isspace((unsigned char) *ptr))
+ while (*ptr && isspace((unsigned char)*ptr))
ptr++;
/*
@@ -216,23 +197,25 @@ For_Eval(char *line)
* We can't do the escapes here - because we don't know whether
* we are substuting into ${...} or $(...).
*/
- sub = Var_Subst(NULL, ptr, VAR_GLOBAL, VARF_WANTRES);
+ sub = Var_Subst(ptr, VAR_GLOBAL, VARE_WANTRES);
/*
* Split into words allowing for quoted strings.
*/
- words = brk_string(sub, &nwords, FALSE, &word_buf);
+ words = Str_Words(sub, FALSE);
free(sub);
- if (words != NULL) {
- for (n = 0; n < nwords; n++) {
- ptr = words[n];
+ {
+ size_t n;
+
+ for (n = 0; n < words.len; n++) {
+ ptr = words.words[n];
if (!*ptr)
continue;
escapes = 0;
while ((ch = *ptr++)) {
- switch(ch) {
+ switch (ch) {
case ':':
case '$':
case '\\':
@@ -250,17 +233,17 @@ For_Eval(char *line)
* We have to dup words[n] to maintain the semantics of
* strlist.
*/
- strlist_add_str(&new_for->items, bmake_strdup(words[n]), escapes);
+ strlist_add_str(&new_for->items, bmake_strdup(words.words[n]),
+ escapes);
}
- free(words);
- free(word_buf);
+ Words_Free(words);
if ((len = strlist_num(&new_for->items)) > 0 &&
len % (n = strlist_num(&new_for->vars))) {
Parse_Error(PARSE_FATAL,
- "Wrong number of words (%d) in .for substitution list"
- " with %d vars", len, n);
+ "Wrong number of words (%zu) in .for substitution list"
+ " with %zu vars", len, n);
/*
* Return 'success' so that the body of the .for loop is
* accumulated.
@@ -288,49 +271,35 @@ For_Accum(char *line)
if (*ptr == '.') {
- for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
+ for (ptr++; *ptr && isspace((unsigned char)*ptr); ptr++)
continue;
if (strncmp(ptr, "endfor", 6) == 0 &&
- (isspace((unsigned char) ptr[6]) || !ptr[6])) {
+ (isspace((unsigned char)ptr[6]) || !ptr[6])) {
if (DEBUG(FOR))
(void)fprintf(debug_file, "For: end for %d\n", forLevel);
if (--forLevel <= 0)
return 0;
} else if (strncmp(ptr, "for", 3) == 0 &&
- isspace((unsigned char) ptr[3])) {
+ isspace((unsigned char)ptr[3])) {
forLevel++;
if (DEBUG(FOR))
(void)fprintf(debug_file, "For: new loop %d\n", forLevel);
}
}
- Buf_AddBytes(&accumFor->buf, strlen(line), line);
+ Buf_AddStr(&accumFor->buf, line);
Buf_AddByte(&accumFor->buf, '\n');
return 1;
}
-
-/*-
- *-----------------------------------------------------------------------
- * For_Run --
- * Run the for loop, imitating the actions of an include file
- *
- * Results:
- * None.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-static int
+static size_t
for_var_len(const char *var)
{
char ch, var_start, var_end;
int depth;
- int len;
+ size_t len;
var_start = *var;
if (var_start == 0)
@@ -360,24 +329,24 @@ for_var_len(const char *var)
static void
for_substitute(Buffer *cmds, strlist_t *items, unsigned int item_no, char ech)
{
- const char *item = strlist_str(items, item_no);
- int len;
char ch;
+ const char *item = strlist_str(items, item_no);
+
/* If there were no escapes, or the only escape is the other variable
* terminator, then just substitute the full string */
if (!(strlist_info(items, item_no) &
- (ech == ')' ? ~FOR_SUB_ESCAPE_BRACE : ~FOR_SUB_ESCAPE_PAREN))) {
- Buf_AddBytes(cmds, strlen(item), item);
+ (ech == ')' ? ~FOR_SUB_ESCAPE_BRACE : ~FOR_SUB_ESCAPE_PAREN))) {
+ Buf_AddStr(cmds, item);
return;
}
/* Escape ':', '$', '\\' and 'ech' - removed by :U processing */
while ((ch = *item++) != 0) {
if (ch == '$') {
- len = for_var_len(item);
+ size_t len = for_var_len(item);
if (len != 0) {
- Buf_AddBytes(cmds, len + 1, item - 1);
+ Buf_AddBytes(cmds, item - 1, len + 1);
item += len;
continue;
}
@@ -392,13 +361,14 @@ static char *
For_Iterate(void *v_arg, size_t *ret_len)
{
For *arg = v_arg;
- int i, len;
+ int i;
char *var;
char *cp;
char *cmd_cp;
char *body_end;
char ch;
Buffer cmds;
+ size_t cmd_len;
if (arg->sub_next + strlist_num(&arg->vars) > strlist_num(&arg->items)) {
/* No more iterations */
@@ -421,9 +391,9 @@ For_Iterate(void *v_arg, size_t *ret_len)
* to contrive a makefile where an unwanted substitution happens.
*/
- cmd_cp = Buf_GetAll(&arg->buf, &len);
- body_end = cmd_cp + len;
- Buf_Init(&cmds, len + 256);
+ cmd_cp = Buf_GetAll(&arg->buf, &cmd_len);
+ body_end = cmd_cp + cmd_len;
+ Buf_Init(&cmds, cmd_len + 256);
for (cp = cmd_cp; (cp = strchr(cp, '$')) != NULL;) {
char ech;
ch = *++cp;
@@ -431,15 +401,15 @@ For_Iterate(void *v_arg, size_t *ret_len)
cp++;
/* Check variable name against the .for loop variables */
STRLIST_FOREACH(var, &arg->vars, i) {
- len = strlist_info(&arg->vars, i);
- if (memcmp(cp, var, len) != 0)
+ size_t vlen = strlist_info(&arg->vars, i);
+ if (memcmp(cp, var, vlen) != 0)
continue;
- if (cp[len] != ':' && cp[len] != ech && cp[len] != '\\')
+ if (cp[vlen] != ':' && cp[vlen] != ech && cp[vlen] != '\\')
continue;
/* Found a variable match. Replace with :U<value> */
- Buf_AddBytes(&cmds, cp - cmd_cp, cmd_cp);
- Buf_AddBytes(&cmds, 2, ":U");
- cp += len;
+ Buf_AddBytesBetween(&cmds, cmd_cp, cp);
+ Buf_AddStr(&cmds, ":U");
+ cp += vlen;
cmd_cp = cp;
for_substitute(&cmds, &arg->items, arg->sub_next + i, ech);
break;
@@ -457,15 +427,15 @@ For_Iterate(void *v_arg, size_t *ret_len)
if (var[0] != ch || var[1] != 0)
continue;
/* Found a variable match. Replace with ${:U<value>} */
- Buf_AddBytes(&cmds, cp - cmd_cp, cmd_cp);
- Buf_AddBytes(&cmds, 3, "{:U");
+ Buf_AddBytesBetween(&cmds, cmd_cp, cp);
+ Buf_AddStr(&cmds, "{:U");
cmd_cp = ++cp;
for_substitute(&cmds, &arg->items, arg->sub_next + i, /*{*/ '}');
- Buf_AddBytes(&cmds, 1, "}");
+ Buf_AddByte(&cmds, '}');
break;
}
}
- Buf_AddBytes(&cmds, body_end - cmd_cp, cmd_cp);
+ Buf_AddBytesBetween(&cmds, cmd_cp, body_end);
cp = Buf_Destroy(&cmds, FALSE);
if (DEBUG(FOR))
@@ -478,6 +448,7 @@ For_Iterate(void *v_arg, size_t *ret_len)
return cp;
}
+/* Run the for loop, imitating the actions of an include file. */
void
For_Run(int lineno)
{
@@ -487,9 +458,9 @@ For_Run(int lineno)
accumFor = NULL;
if (strlist_num(&arg->items) == 0) {
- /* Nothing to expand - possibly due to an earlier syntax error. */
- For_Free(arg);
- return;
+ /* Nothing to expand - possibly due to an earlier syntax error. */
+ For_Free(arg);
+ return;
}
Parse_SetInput(NULL, lineno, -1, For_Iterate, arg);
diff --git a/hash.c b/hash.c
index f2bbebc9ece7..290bed6b3f5a 100644
--- a/hash.c
+++ b/hash.c
@@ -1,4 +1,4 @@
-/* $NetBSD: hash.c,v 1.22 2020/07/03 17:03:09 rillig Exp $ */
+/* $NetBSD: hash.c,v 1.29 2020/09/01 21:11:31 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: hash.c,v 1.22 2020/07/03 17:03:09 rillig Exp $";
+static char rcsid[] = "$NetBSD: hash.c,v 1.29 2020/09/01 21:11:31 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: hash.c,v 1.22 2020/07/03 17:03:09 rillig Exp $");
+__RCSID("$NetBSD: hash.c,v 1.29 2020/09/01 21:11:31 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -89,9 +89,7 @@ __RCSID("$NetBSD: hash.c,v 1.22 2020/07/03 17:03:09 rillig Exp $");
* table. Hash tables grow automatically as the amount of
* information increases.
*/
-#include "sprite.h"
#include "make.h"
-#include "hash.h"
/*
* Forward references to local procedures that are used before they're
@@ -107,29 +105,26 @@ static void RebuildTable(Hash_Table *);
#define rebuildLimit 3
-/*
- *---------------------------------------------------------
- *
- * Hash_InitTable --
- *
- * This routine just sets up the hash table.
+/* The hash function(s) */
+
+#ifndef HASH
+/* The default: this one matches Gosling's emacs */
+#define HASH(h, key, p) do { \
+ for (h = 0, p = key; *p;) \
+ h = (h << 5) - h + *p++; \
+ } while (0)
+
+#endif
+
+/* Sets up the hash table.
*
* Input:
- * t Structure to to hold table.
+ * t Structure to to hold the table.
* numBuckets How many buckets to create for starters. This
* number is rounded up to a power of two. If
* <= 0, a reasonable default is chosen. The
* table will grow in size later as needed.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * Memory is allocated for the initial bucket area.
- *
- *---------------------------------------------------------
*/
-
void
Hash_InitTable(Hash_Table *t, int numBuckets)
{
@@ -146,118 +141,85 @@ Hash_InitTable(Hash_Table *t, int numBuckets)
continue;
}
t->numEntries = 0;
- t->size = i;
- t->mask = i - 1;
- t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i);
+ t->maxchain = 0;
+ t->bucketsSize = i;
+ t->bucketsMask = i - 1;
+ t->buckets = hp = bmake_malloc(sizeof(*hp) * i);
while (--i >= 0)
*hp++ = NULL;
}
-/*
- *---------------------------------------------------------
- *
- * Hash_DeleteTable --
- *
- * This routine removes everything from a hash table
- * and frees up the memory space it occupied (except for
- * the space in the Hash_Table structure).
- *
- * Results:
- * None.
- *
- * Side Effects:
- * Lots of memory is freed up.
- *
- *---------------------------------------------------------
- */
-
+/* Removes everything from the hash table and frees up the memory space it
+ * occupied (except for the space in the Hash_Table structure). */
void
Hash_DeleteTable(Hash_Table *t)
{
struct Hash_Entry **hp, *h, *nexth = NULL;
int i;
- for (hp = t->bucketPtr, i = t->size; --i >= 0;) {
+ for (hp = t->buckets, i = t->bucketsSize; --i >= 0;) {
for (h = *hp++; h != NULL; h = nexth) {
nexth = h->next;
free(h);
}
}
- free(t->bucketPtr);
+ free(t->buckets);
/*
* Set up the hash table to cause memory faults on any future access
* attempts until re-initialization.
*/
- t->bucketPtr = NULL;
+ t->buckets = NULL;
}
-/*
- *---------------------------------------------------------
- *
- * Hash_FindEntry --
- *
- * Searches a hash table for an entry corresponding to key.
+/* Searches the hash table for an entry corresponding to the key.
*
* Input:
* t Hash table to search.
* key A hash key.
*
* Results:
- * The return value is a pointer to the entry for key,
- * if key was present in the table. If key was not
- * present, NULL is returned.
- *
- * Side Effects:
- * None.
- *
- *---------------------------------------------------------
+ * Returns a pointer to the entry for key, or NULL if the table contains
+ * no entry for the key.
*/
-
Hash_Entry *
Hash_FindEntry(Hash_Table *t, const char *key)
{
Hash_Entry *e;
unsigned h;
const char *p;
+ int chainlen;
- if (t == NULL || t->bucketPtr == NULL) {
+ if (t == NULL || t->buckets == NULL) {
return NULL;
}
- for (h = 0, p = key; *p;)
- h = (h << 5) - h + *p++;
+ HASH(h, key, p);
p = key;
- for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next)
+ chainlen = 0;
+#ifdef DEBUG_HASH_LOOKUP
+ if (DEBUG(HASH))
+ fprintf(debug_file, "%s: %p h=%x key=%s\n", __func__,
+ t, h, key);
+#endif
+ for (e = t->buckets[h & t->bucketsMask]; e != NULL; e = e->next) {
+ chainlen++;
if (e->namehash == h && strcmp(e->name, p) == 0)
- return e;
- return NULL;
+ break;
+ }
+ if (chainlen > t->maxchain)
+ t->maxchain = chainlen;
+ return e;
}
-/*
- *---------------------------------------------------------
- *
- * Hash_CreateEntry --
- *
- * Searches a hash table for an entry corresponding to
- * key. If no entry is found, then one is created.
+/* Searches the hash table for an entry corresponding to the key.
+ * If no entry is found, then one is created.
*
* Input:
* t Hash table to search.
* key A hash key.
- * newPtr Filled in with TRUE if new entry created,
+ * newPtr Filled with TRUE if new entry created,
* FALSE otherwise.
- *
- * Results:
- * The return value is a pointer to the entry. If *newPtr
- * isn't NULL, then *newPtr is filled in with TRUE if a
- * new entry was created, and FALSE if an entry already existed
- * with the given key.
- *
- * Side Effects:
- * Memory may be allocated, and the hash buckets may be modified.
- *---------------------------------------------------------
*/
-
Hash_Entry *
Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr)
{
@@ -265,33 +227,44 @@ Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr)
unsigned h;
const char *p;
int keylen;
+ int chainlen;
struct Hash_Entry **hp;
/*
* Hash the key. As a side effect, save the length (strlen) of the
* key in case we need to create the entry.
*/
- for (h = 0, p = key; *p;)
- h = (h << 5) - h + *p++;
+ HASH(h, key, p);
keylen = p - key;
p = key;
- for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) {
+ chainlen = 0;
+#ifdef DEBUG_HASH_LOOKUP
+ if (DEBUG(HASH))
+ fprintf(debug_file, "%s: %p h=%x key=%s\n", __func__,
+ t, h, key);
+#endif
+ for (e = t->buckets[h & t->bucketsMask]; e != NULL; e = e->next) {
+ chainlen++;
if (e->namehash == h && strcmp(e->name, p) == 0) {
if (newPtr != NULL)
*newPtr = FALSE;
- return e;
+ break;
}
}
+ if (chainlen > t->maxchain)
+ t->maxchain = chainlen;
+ if (e)
+ return e;
/*
* The desired entry isn't there. Before allocating a new entry,
* expand the table if necessary (and this changes the resulting
* bucket chain).
*/
- if (t->numEntries >= rebuildLimit * t->size)
+ if (t->numEntries >= rebuildLimit * t->bucketsSize)
RebuildTable(t);
e = bmake_malloc(sizeof(*e) + keylen);
- hp = &t->bucketPtr[h & t->mask];
+ hp = &t->buckets[h & t->bucketsMask];
e->next = *hp;
*hp = e;
Hash_SetValue(e, NULL);
@@ -304,23 +277,7 @@ Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr)
return e;
}
-/*
- *---------------------------------------------------------
- *
- * Hash_DeleteEntry --
- *
- * Delete the given hash table entry and free memory associated with
- * it.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * Hash chain that entry lives in is modified and memory is freed.
- *
- *---------------------------------------------------------
- */
-
+/* Delete the given hash table entry and free memory associated with it. */
void
Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e)
{
@@ -328,7 +285,7 @@ Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e)
if (e == NULL)
return;
- for (hp = &t->bucketPtr[e->namehash & t->mask];
+ for (hp = &t->buckets[e->namehash & t->bucketsMask];
(p = *hp) != NULL; hp = &p->next) {
if (p == e) {
*hp = p->next;
@@ -341,12 +298,7 @@ Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e)
abort();
}
-/*
- *---------------------------------------------------------
- *
- * Hash_EnumFirst --
- * This procedure sets things up for a complete search
- * of all entries recorded in the hash table.
+/* Sets things up for enumerating all entries in the hash table.
*
* Input:
* t Table to be searched.
@@ -355,57 +307,34 @@ Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e)
* Results:
* The return value is the address of the first entry in
* the hash table, or NULL if the table is empty.
- *
- * Side Effects:
- * The information in searchPtr is initialized so that successive
- * calls to Hash_Next will return successive HashEntry's
- * from the table.
- *
- *---------------------------------------------------------
*/
-
Hash_Entry *
Hash_EnumFirst(Hash_Table *t, Hash_Search *searchPtr)
{
- searchPtr->tablePtr = t;
- searchPtr->nextIndex = 0;
- searchPtr->hashEntryPtr = NULL;
+ searchPtr->table = t;
+ searchPtr->nextBucket = 0;
+ searchPtr->entry = NULL;
return Hash_EnumNext(searchPtr);
}
-/*
- *---------------------------------------------------------
- *
- * Hash_EnumNext --
- * This procedure returns successive entries in the hash table.
+/* Returns the next entry in the hash table, or NULL if the end of the table
+ * is reached.
*
* Input:
* searchPtr Area used to keep state about search.
- *
- * Results:
- * The return value is a pointer to the next HashEntry
- * in the table, or NULL when the end of the table is
- * reached.
- *
- * Side Effects:
- * The information in searchPtr is modified to advance to the
- * next entry.
- *
- *---------------------------------------------------------
*/
-
Hash_Entry *
Hash_EnumNext(Hash_Search *searchPtr)
{
Hash_Entry *e;
- Hash_Table *t = searchPtr->tablePtr;
+ Hash_Table *t = searchPtr->table;
/*
- * The hashEntryPtr field points to the most recently returned
- * entry, or is nil if we are starting up. If not nil, we have
+ * The entry field points to the most recently returned
+ * entry, or is NULL if we are starting up. If not NULL, we have
* to start at the next one in the chain.
*/
- e = searchPtr->hashEntryPtr;
+ e = searchPtr->entry;
if (e != NULL)
e = e->next;
/*
@@ -413,59 +342,49 @@ Hash_EnumNext(Hash_Search *searchPtr)
* find the next nonempty chain.
*/
while (e == NULL) {
- if (searchPtr->nextIndex >= t->size)
+ if (searchPtr->nextBucket >= t->bucketsSize)
return NULL;
- e = t->bucketPtr[searchPtr->nextIndex++];
+ e = t->buckets[searchPtr->nextBucket++];
}
- searchPtr->hashEntryPtr = e;
+ searchPtr->entry = e;
return e;
}
-/*
- *---------------------------------------------------------
- *
- * RebuildTable --
- * This local routine makes a new hash table that
- * is larger than the old one.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * The entire hash table is moved, so any bucket numbers
- * from the old table are invalid.
- *
- *---------------------------------------------------------
- */
-
+/* Makes a new hash table that is larger than the old one. The entire hash
+ * table is moved, so any bucket numbers from the old table become invalid. */
static void
RebuildTable(Hash_Table *t)
{
Hash_Entry *e, *next = NULL, **hp, **xp;
int i, mask;
- Hash_Entry **oldhp;
+ Hash_Entry **oldhp;
int oldsize;
- oldhp = t->bucketPtr;
- oldsize = i = t->size;
+ oldhp = t->buckets;
+ oldsize = i = t->bucketsSize;
i <<= 1;
- t->size = i;
- t->mask = mask = i - 1;
- t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i);
+ t->bucketsSize = i;
+ t->bucketsMask = mask = i - 1;
+ t->buckets = hp = bmake_malloc(sizeof(*hp) * i);
while (--i >= 0)
*hp++ = NULL;
for (hp = oldhp, i = oldsize; --i >= 0;) {
for (e = *hp++; e != NULL; e = next) {
next = e->next;
- xp = &t->bucketPtr[e->namehash & mask];
+ xp = &t->buckets[e->namehash & mask];
e->next = *xp;
*xp = e;
}
}
free(oldhp);
+ if (DEBUG(HASH))
+ fprintf(debug_file, "%s: %p size=%d entries=%d maxchain=%d\n",
+ __func__, t, t->bucketsSize, t->numEntries, t->maxchain);
+ t->maxchain = 0;
}
-void Hash_ForEach(Hash_Table *t, void (*action)(void *, void *), void *data)
+void
+Hash_ForEach(Hash_Table *t, void (*action)(void *, void *), void *data)
{
Hash_Search search;
Hash_Entry *e;
@@ -475,3 +394,11 @@ void Hash_ForEach(Hash_Table *t, void (*action)(void *, void *), void *data)
e = Hash_EnumNext(&search))
action(Hash_GetValue(e), data);
}
+
+void
+Hash_DebugStats(Hash_Table *t, const char *name)
+{
+ if (DEBUG(HASH))
+ fprintf(debug_file, "Hash_Table %s: size=%d numEntries=%d maxchain=%d\n",
+ name, t->bucketsSize, t->numEntries, t->maxchain);
+}
diff --git a/hash.h b/hash.h
index 2e4ea6a43560..d98a8144ed85 100644
--- a/hash.h
+++ b/hash.h
@@ -1,4 +1,4 @@
-/* $NetBSD: hash.h,v 1.13 2020/07/03 17:03:09 rillig Exp $ */
+/* $NetBSD: hash.h,v 1.21 2020/09/01 21:11:31 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -72,71 +72,51 @@
* from: @(#)hash.h 8.1 (Berkeley) 6/6/93
*/
-/* hash.h --
- *
- * This file contains definitions used by the hash module,
- * which maintains hash tables.
- */
-
-#ifndef _HASH_H
-#define _HASH_H
+/* Hash tables with strings as keys and arbitrary pointers as values. */
-/*
- * The following defines one entry in the hash table.
- */
+#ifndef MAKE_HASH_H
+#define MAKE_HASH_H
+/* A single key-value entry in the hash table. */
typedef struct Hash_Entry {
- struct Hash_Entry *next; /* Used to link together all the
- * entries associated with the same
- * bucket. */
- void *clientPtr; /* Arbitrary pointer */
- unsigned namehash; /* hash value of key */
- char name[1]; /* key string */
+ struct Hash_Entry *next; /* Used to link together all the entries
+ * associated with the same bucket. */
+ void *value;
+ unsigned namehash; /* hash value of key */
+ char name[1]; /* key string, variable length */
} Hash_Entry;
+/* The hash table containing the entries. */
typedef struct Hash_Table {
- struct Hash_Entry **bucketPtr;/* Pointers to Hash_Entry, one
- * for each bucket in the table. */
- int size; /* Actual size of array. */
+ Hash_Entry **buckets; /* Pointers to Hash_Entry, one
+ * for each bucket in the table. */
+ int bucketsSize;
int numEntries; /* Number of entries in the table. */
- int mask; /* Used to select bits for hashing. */
+ int bucketsMask; /* Used to select the bucket for a hash. */
+ int maxchain; /* max length of chain detected */
} Hash_Table;
/*
* The following structure is used by the searching routines
* to record where we are in the search.
*/
-
typedef struct Hash_Search {
- Hash_Table *tablePtr; /* Table being searched. */
- int nextIndex; /* Next bucket to check (after current). */
- Hash_Entry *hashEntryPtr; /* Next entry to check in current bucket. */
+ Hash_Table *table; /* Table being searched. */
+ int nextBucket; /* Next bucket to check (after current). */
+ Hash_Entry *entry; /* Next entry to check in current bucket. */
} Hash_Search;
-/*
- * Macros.
- */
-
-/*
- * void * Hash_GetValue(h)
- * Hash_Entry *h;
- */
-
-#define Hash_GetValue(h) ((h)->clientPtr)
-
-/*
- * Hash_SetValue(h, val);
- * Hash_Entry *h;
- * char *val;
- */
-
-#define Hash_SetValue(h, val) ((h)->clientPtr = (val))
-
-/*
- * Hash_Size(n) returns the number of words in an object of n bytes
- */
+static inline void * MAKE_ATTR_UNUSED
+Hash_GetValue(Hash_Entry *h)
+{
+ return h->value;
+}
-#define Hash_Size(n) (((n) + sizeof (int) - 1) / sizeof (int))
+static inline void MAKE_ATTR_UNUSED
+Hash_SetValue(Hash_Entry *h, void *datum)
+{
+ h->value = datum;
+}
void Hash_InitTable(Hash_Table *, int);
void Hash_DeleteTable(Hash_Table *);
@@ -146,5 +126,6 @@ void Hash_DeleteEntry(Hash_Table *, Hash_Entry *);
Hash_Entry *Hash_EnumFirst(Hash_Table *, Hash_Search *);
Hash_Entry *Hash_EnumNext(Hash_Search *);
void Hash_ForEach(Hash_Table *, void (*)(void *, void *), void *);
+void Hash_DebugStats(Hash_Table *, const char *);
-#endif /* _HASH_H */
+#endif /* MAKE_HASH_H */
diff --git a/job.c b/job.c
index b6a0ab334a6f..08fbc147f901 100644
--- a/job.c
+++ b/job.c
@@ -1,4 +1,4 @@
-/* $NetBSD: job.c,v 1.201 2020/07/03 08:13:23 rillig Exp $ */
+/* $NetBSD: job.c,v 1.227 2020/08/30 19:56:02 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: job.c,v 1.201 2020/07/03 08:13:23 rillig Exp $";
+static char rcsid[] = "$NetBSD: job.c,v 1.227 2020/08/30 19:56:02 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: job.c,v 1.201 2020/07/03 08:13:23 rillig Exp $");
+__RCSID("$NetBSD: job.c,v 1.227 2020/08/30 19:56:02 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -112,7 +112,7 @@ __RCSID("$NetBSD: job.c,v 1.201 2020/07/03 08:13:23 rillig Exp $");
*
* Job_ParseShell Given the line following a .SHELL target, parse
* the line as a shell specification. Returns
- * FAILURE if the spec was incorrect.
+ * FALSE if the spec was incorrect.
*
* Job_Finish Perform any final processing which needs doing.
* This includes the execution of any commands
@@ -142,7 +142,6 @@ __RCSID("$NetBSD: job.c,v 1.201 2020/07/03 08:13:23 rillig Exp $");
#include <sys/time.h>
#include "wait.h"
-#include <assert.h>
#include <errno.h>
#if !defined(USE_SELECT) && defined(HAVE_POLL_H)
#include <poll.h>
@@ -155,15 +154,12 @@ __RCSID("$NetBSD: job.c,v 1.201 2020/07/03 08:13:23 rillig Exp $");
#endif
#endif
#include <signal.h>
-#include <stdio.h>
-#include <string.h>
#include <utime.h>
#if defined(HAVE_SYS_SOCKET_H)
# include <sys/socket.h>
#endif
#include "make.h"
-#include "hash.h"
#include "dir.h"
#include "job.h"
#include "pathnames.h"
@@ -184,7 +180,6 @@ static int aborting = 0; /* why is the make aborting? */
* this tracks the number of tokens currently "out" to build jobs.
*/
int jobTokensRunning = 0;
-int not_parallel = 0; /* set if .NOT_PARALLEL */
/*
* XXX: Avoid SunOS bug... FILENO() is fp->_file, and file
@@ -311,9 +306,9 @@ static Shell *commandShell = &shells[DEFSHELL_INDEX]; /* this is the shell to
* Job_ParseShell function */
const char *shellPath = NULL, /* full pathname of
* executable image */
- *shellName = NULL; /* last component of shell */
+ *shellName = NULL; /* last component of shell */
char *shellErrFlag = NULL;
-static const char *shellArgv = NULL; /* Custom shell args */
+static char *shellArgv = NULL; /* Custom shell args */
STATIC Job *job_table; /* The structures that describe them */
@@ -370,11 +365,6 @@ static void JobSigLock(sigset_t *);
static void JobSigUnlock(sigset_t *);
static void JobSigReset(void);
-#if !defined(MALLOC_OPTIONS)
-# define MALLOC_OPTIONS "A"
-#endif
-const char *malloc_options= MALLOC_OPTIONS;
-
static unsigned
nfds_per_job(void)
{
@@ -723,15 +713,14 @@ JobPrintCommand(void *cmdp, void *jobp)
char *escCmd = NULL; /* Command with quotes/backticks escaped */
char *cmd = (char *)cmdp;
Job *job = (Job *)jobp;
- int i, j;
noSpecials = NoExecute(job->node);
if (strcmp(cmd, "...") == 0) {
job->node->type |= OP_SAVE_CMDS;
if ((job->flags & JOB_IGNDOTS) == 0) {
- job->tailCmds = Lst_Succ(Lst_Member(job->node->commands,
- cmd));
+ LstNode dotsNode = Lst_FindDatum(job->node->commands, cmd);
+ job->tailCmds = dotsNode != NULL ? LstNode_Next(dotsNode) : NULL;
return 1;
}
return 0;
@@ -745,7 +734,7 @@ JobPrintCommand(void *cmdp, void *jobp)
numCommands += 1;
- cmdStart = cmd = Var_Subst(NULL, cmd, job->node, VARF_WANTRES);
+ cmdStart = cmd = Var_Subst(cmd, job->node, VARE_WANTRES);
cmdTemplate = "%s\n";
@@ -785,15 +774,17 @@ JobPrintCommand(void *cmdp, void *jobp)
*/
if (!commandShell->hasErrCtl) {
+ int i, j;
+
/* Worst that could happen is every char needs escaping. */
escCmd = bmake_malloc((strlen(cmd) * 2) + 1);
- for (i = 0, j= 0; cmd[i] != '\0'; i++, j++) {
- if (cmd[i] == '$' || cmd[i] == '`' || cmd[i] == '\\' ||
- cmd[i] == '"')
- escCmd[j++] = '\\';
- escCmd[j] = cmd[i];
+ for (i = 0, j = 0; cmd[i] != '\0'; i++, j++) {
+ if (cmd[i] == '$' || cmd[i] == '`' || cmd[i] == '\\' ||
+ cmd[i] == '"')
+ escCmd[j++] = '\\';
+ escCmd[j] = cmd[i];
}
- escCmd[j] = 0;
+ escCmd[j] = '\0';
}
if (shutUp) {
@@ -926,15 +917,15 @@ JobPrintCommand(void *cmdp, void *jobp)
* Always returns 0
*
* Side Effects:
- * The command is tacked onto the end of postCommands's commands list.
+ * The command is tacked onto the end of postCommands' commands list.
*
*-----------------------------------------------------------------------
*/
static int
JobSaveCommand(void *cmd, void *gn)
{
- cmd = Var_Subst(NULL, (char *)cmd, (GNode *)gn, VARF_WANTRES);
- (void)Lst_AtEnd(postCommands->commands, cmd);
+ cmd = Var_Subst((char *)cmd, (GNode *)gn, VARE_WANTRES);
+ Lst_Append(postCommands->commands, cmd);
return 0;
}
@@ -1124,7 +1115,7 @@ JobFinish (Job *job, WAIT_T status)
if (job->tailCmds != NULL) {
Lst_ForEachFrom(job->node->commands, job->tailCmds,
JobSaveCommand,
- job->node);
+ job->node);
}
job->node->made = MADE;
if (!(job->flags & JOB_SPECIAL))
@@ -1275,7 +1266,7 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
*/
Make_HandleUse(DEFAULT, gn);
Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn);
- free(p1);
+ bmake_free(p1);
} else if (Dir_MTime(gn, 0) == 0 && (gn->type & OP_SPECIAL) == 0) {
/*
* The node wasn't the target of an operator we have no .DEFAULT
@@ -1302,7 +1293,7 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
(void)fprintf(stdout, "%s%s %s (continuing)\n", progname,
msg, gn->name);
(void)fflush(stdout);
- return FALSE;
+ return FALSE;
} else {
(*abortProc)("%s%s %s. Stop", progname, msg, gn->name);
return FALSE;
@@ -1345,7 +1336,7 @@ JobExec(Job *job, char **argv)
for (i = 0; argv[i] != NULL; i++) {
(void)fprintf(debug_file, "%s ", argv[i]);
}
- (void)fprintf(debug_file, "\n");
+ (void)fprintf(debug_file, "\n");
}
/*
@@ -1719,7 +1710,7 @@ JobStart(GNode *gn, int flags)
* up the graph.
*/
job->cmdFILE = stdout;
- Job_Touch(gn, job->flags&JOB_SILENT);
+ Job_Touch(gn, job->flags&JOB_SILENT);
noExec = TRUE;
}
/* Just in case it isn't already... */
@@ -1748,8 +1739,8 @@ JobStart(GNode *gn, int flags)
if (cmdsOK && aborting == 0) {
if (job->tailCmds != NULL) {
Lst_ForEachFrom(job->node->commands, job->tailCmds,
- JobSaveCommand,
- job->node);
+ JobSaveCommand,
+ job->node);
}
job->node->made = MADE;
Make_Update(job->node);
@@ -1990,8 +1981,8 @@ JobRun(GNode *targ)
* and .INTERRUPT job in the parallel job module. This has
* the nice side effect that it avoids a lot of other problems.
*/
- Lst lst = Lst_Init(FALSE);
- Lst_AtEnd(lst, targ);
+ Lst lst = Lst_Init();
+ Lst_Append(lst, targ);
(void)Make_Run(lst);
Lst_Destroy(lst, NULL);
JobStart(targ, JOB_SPECIAL);
@@ -2218,8 +2209,9 @@ Shell_Init(void)
shellName++;
} else
#endif
- shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
+ shellPath = str_concat3(_PATH_DEFSHELLDIR, "/", shellName);
}
+ Var_Set_with_flags(".SHELL", shellPath, VAR_CMD, VAR_SET_READONLY);
if (commandShell->exit == NULL) {
commandShell->exit = "";
}
@@ -2253,38 +2245,23 @@ Shell_Init(void)
const char *
Shell_GetNewline(void)
{
-
return commandShell->newline;
}
void
Job_SetPrefix(void)
{
-
if (targPrefix) {
free(targPrefix);
} else if (!Var_Exists(MAKE_JOB_PREFIX, VAR_GLOBAL)) {
Var_Set(MAKE_JOB_PREFIX, "---", VAR_GLOBAL);
}
- targPrefix = Var_Subst(NULL, "${" MAKE_JOB_PREFIX "}",
- VAR_GLOBAL, VARF_WANTRES);
+ targPrefix = Var_Subst("${" MAKE_JOB_PREFIX "}",
+ VAR_GLOBAL, VARE_WANTRES);
}
-/*-
- *-----------------------------------------------------------------------
- * Job_Init --
- * Initialize the process module
- *
- * Input:
- *
- * Results:
- * none
- *
- * Side Effects:
- * lists and counters are initialized
- *-----------------------------------------------------------------------
- */
+/* Initialize the process module. */
void
Job_Init(void)
{
@@ -2390,19 +2367,7 @@ static void JobSigReset(void)
(void)bmake_signal(SIGCHLD, SIG_DFL);
}
-/*-
- *-----------------------------------------------------------------------
- * JobMatchShell --
- * Find a shell in 'shells' given its name.
- *
- * Results:
- * A pointer to the Shell structure.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
+/* Find a shell in 'shells' given its name, or return NULL. */
static Shell *
JobMatchShell(const char *name)
{
@@ -2425,7 +2390,7 @@ JobMatchShell(const char *name)
* line The shell spec
*
* Results:
- * FAILURE if the specification was incorrect.
+ * FALSE if the specification was incorrect.
*
* Side Effects:
* commandShell points to a Shell structure (either predefined or
@@ -2462,12 +2427,13 @@ JobMatchShell(const char *name)
*
*-----------------------------------------------------------------------
*/
-ReturnStatus
+Boolean
Job_ParseShell(char *line)
{
+ Words wordsList;
char **words;
char **argv;
- int argc;
+ size_t argc;
char *path;
Shell newShell;
Boolean fullSpec = FALSE;
@@ -2477,17 +2443,20 @@ Job_ParseShell(char *line)
line++;
}
- free(UNCONST(shellArgv));
+ free(shellArgv);
memset(&newShell, 0, sizeof(newShell));
/*
* Parse the specification by keyword
*/
- words = brk_string(line, &argc, TRUE, &path);
+ wordsList = Str_Words(line, TRUE);
+ words = wordsList.words;
+ argc = wordsList.len;
+ path = wordsList.freeIt;
if (words == NULL) {
Error("Unterminated quoted string [%s]", line);
- return FAILURE;
+ return FALSE;
}
shellArgv = path;
@@ -2526,7 +2495,7 @@ Job_ParseShell(char *line)
Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"",
*argv);
free(words);
- return FAILURE;
+ return FALSE;
}
fullSpec = TRUE;
}
@@ -2542,13 +2511,13 @@ Job_ParseShell(char *line)
if (newShell.name == NULL) {
Parse_Error(PARSE_FATAL, "Neither path nor name specified");
free(words);
- return FAILURE;
+ return FALSE;
} else {
if ((sh = JobMatchShell(newShell.name)) == NULL) {
Parse_Error(PARSE_WARNING, "%s: No matching shell",
newShell.name);
free(words);
- return FAILURE;
+ return FALSE;
}
commandShell = sh;
shellName = newShell.name;
@@ -2584,7 +2553,7 @@ Job_ParseShell(char *line)
Parse_Error(PARSE_WARNING, "%s: No matching shell",
shellName);
free(words);
- return FAILURE;
+ return FALSE;
}
commandShell = sh;
} else {
@@ -2613,7 +2582,7 @@ Job_ParseShell(char *line)
* shell specification.
*/
free(words);
- return SUCCESS;
+ return TRUE;
}
/*-
@@ -2790,7 +2759,6 @@ Job_AbortAll(void)
continue;
}
-
/*-
*-----------------------------------------------------------------------
* JobRestartJobs --
@@ -3125,7 +3093,7 @@ emul_poll(struct pollfd *fd, int nfd, int timeout)
usecs = timeout * 1000;
tv.tv_sec = usecs / 1000000;
tv.tv_usec = usecs % 1000000;
- tvp = &tv;
+ tvp = &tv;
}
nselect = select(maxfd + 1, &rfds, &wfds, 0, tvp);
diff --git a/job.h b/job.h
index 603c09e861f1..45fc1b7f8df4 100644
--- a/job.h
+++ b/job.h
@@ -1,4 +1,4 @@
-/* $NetBSD: job.h,v 1.43 2020/07/03 08:13:23 rillig Exp $ */
+/* $NetBSD: job.h,v 1.47 2020/08/29 12:20:17 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -77,8 +77,8 @@
* job.h --
* Definitions pertaining to the running of jobs in parallel mode.
*/
-#ifndef _JOB_H_
-#define _JOB_H_
+#ifndef MAKE_JOB_H
+#define MAKE_JOB_H
#define TMPPAT "makeXXXXXX" /* relative to tmpdir */
@@ -110,7 +110,6 @@ emul_poll(struct pollfd *fd, int nfd, int timeout);
*/
#define POLL_MSEC 5000
-
/*-
* Job Table definitions.
*
@@ -164,7 +163,7 @@ typedef struct Job {
* commands */
#define JOB_TRACED 0x400 /* we've sent 'set -x' */
- int jobPipe[2]; /* Pipe for readind output from job */
+ int jobPipe[2]; /* Pipe for reading output from job */
struct pollfd *inPollfd; /* pollfd associated with inPipe */
char outBuf[JOB_BUFSIZE + 1];
/* Buffer for storing the output of the
@@ -179,7 +178,6 @@ typedef struct Job {
#define inPipe jobPipe[0]
#define outPipe jobPipe[1]
-
/*-
* Shell Specifications:
* Each shell type has associated with it the following information:
@@ -252,23 +250,20 @@ void Shell_Init(void);
const char *Shell_GetNewline(void);
void Job_Touch(GNode *, Boolean);
Boolean Job_CheckCommands(GNode *, void (*abortProc )(const char *, ...));
-#define CATCH_BLOCK 1
void Job_CatchChildren(void);
void Job_CatchOutput(void);
void Job_Make(GNode *);
void Job_Init(void);
-Boolean Job_Full(void);
Boolean Job_Empty(void);
-ReturnStatus Job_ParseShell(char *);
+Boolean Job_ParseShell(char *);
int Job_Finish(void);
void Job_End(void);
void Job_Wait(void);
void Job_AbortAll(void);
-void JobFlagForMigration(int);
void Job_TokenReturn(void);
Boolean Job_TokenWithdraw(void);
void Job_ServerStart(int, int, int);
void Job_SetPrefix(void);
Boolean Job_RunTarget(const char *, const char *);
-#endif /* _JOB_H_ */
+#endif /* MAKE_JOB_H */
diff --git a/lst.c b/lst.c
new file mode 100644
index 000000000000..26b2457cc013
--- /dev/null
+++ b/lst.c
@@ -0,0 +1,641 @@
+/* $NetBSD: lst.c,v 1.60 2020/08/31 05:56:02 rillig Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+
+#include "make.h"
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lst.c,v 1.60 2020/08/31 05:56:02 rillig Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: lst.c,v 1.60 2020/08/31 05:56:02 rillig Exp $");
+#endif /* not lint */
+#endif
+
+struct ListNode {
+ struct ListNode *prev; /* previous element in list */
+ struct ListNode *next; /* next in list */
+ uint8_t useCount; /* Count of functions using the node.
+ * node may not be deleted until count
+ * goes to 0 */
+ Boolean deleted; /* List node should be removed when done */
+ union {
+ void *datum; /* datum associated with this element */
+ const GNode *gnode; /* alias, just for debugging */
+ const char *str; /* alias, just for debugging */
+ };
+};
+
+typedef enum {
+ Head, Middle, Tail, Unknown
+} Where;
+
+struct List {
+ LstNode first; /* first node in list */
+ LstNode last; /* last node in list */
+
+ /* fields for sequential access */
+ Boolean isOpen; /* true if list has been Lst_Open'ed */
+ Where lastAccess; /* Where in the list the last access was */
+ LstNode curr; /* current node, if open. NULL if
+ * *just* opened */
+ LstNode prev; /* Previous node, if open. Used by Lst_Remove */
+};
+
+/* Allocate and initialize a list node.
+ *
+ * The fields 'prev' and 'next' must be initialized by the caller.
+ */
+static LstNode
+LstNodeNew(void *datum)
+{
+ LstNode node = bmake_malloc(sizeof *node);
+ node->useCount = 0;
+ node->deleted = FALSE;
+ node->datum = datum;
+ return node;
+}
+
+static Boolean
+LstIsEmpty(Lst list)
+{
+ return list->first == NULL;
+}
+
+/* Create and initialize a new, empty list. */
+Lst
+Lst_Init(void)
+{
+ Lst list = bmake_malloc(sizeof *list);
+
+ list->first = NULL;
+ list->last = NULL;
+ list->isOpen = FALSE;
+ list->lastAccess = Unknown;
+
+ return list;
+}
+
+/* Duplicate an entire list, usually by copying the datum pointers.
+ * If copyProc is given, that function is used to create the new datum from the
+ * old datum, usually by creating a copy of it. */
+Lst
+Lst_Copy(Lst list, LstCopyProc copyProc)
+{
+ Lst newList;
+ LstNode node;
+
+ assert(list != NULL);
+
+ newList = Lst_Init();
+
+ for (node = list->first; node != NULL; node = node->next) {
+ void *datum = copyProc != NULL ? copyProc(node->datum) : node->datum;
+ Lst_Append(newList, datum);
+ }
+
+ return newList;
+}
+
+/* Free a list and all its nodes. The list data itself are not freed though. */
+void
+Lst_Free(Lst list)
+{
+ LstNode node;
+ LstNode next;
+
+ assert(list != NULL);
+
+ for (node = list->first; node != NULL; node = next) {
+ next = node->next;
+ free(node);
+ }
+
+ free(list);
+}
+
+/* Destroy a list and free all its resources. The freeProc is called with the
+ * datum from each node in turn before the node is freed. */
+void
+Lst_Destroy(Lst list, LstFreeProc freeProc)
+{
+ LstNode node;
+ LstNode next;
+
+ assert(list != NULL);
+ assert(freeProc != NULL);
+
+ for (node = list->first; node != NULL; node = next) {
+ next = node->next;
+ freeProc(node->datum);
+ free(node);
+ }
+
+ free(list);
+}
+
+/*
+ * Functions to modify a list
+ */
+
+/* Insert a new node with the given piece of data before the given node in the
+ * given list. */
+void
+Lst_InsertBefore(Lst list, LstNode node, void *datum)
+{
+ LstNode newNode;
+
+ assert(list != NULL);
+ assert(!LstIsEmpty(list));
+ assert(node != NULL);
+ assert(datum != NULL);
+
+ newNode = LstNodeNew(datum);
+ newNode->prev = node->prev;
+ newNode->next = node;
+
+ if (node->prev != NULL) {
+ node->prev->next = newNode;
+ }
+ node->prev = newNode;
+
+ if (node == list->first) {
+ list->first = newNode;
+ }
+}
+
+/* Add a piece of data at the start of the given list. */
+void
+Lst_Prepend(Lst list, void *datum)
+{
+ LstNode node;
+
+ assert(list != NULL);
+ assert(datum != NULL);
+
+ node = LstNodeNew(datum);
+ node->prev = NULL;
+ node->next = list->first;
+
+ if (list->first == NULL) {
+ list->first = node;
+ list->last = node;
+ } else {
+ list->first->prev = node;
+ list->first = node;
+ }
+}
+
+/* Add a piece of data at the end of the given list. */
+void
+Lst_Append(Lst list, void *datum)
+{
+ LstNode node;
+
+ assert(list != NULL);
+ assert(datum != NULL);
+
+ node = LstNodeNew(datum);
+ node->prev = list->last;
+ node->next = NULL;
+
+ if (list->last == NULL) {
+ list->first = node;
+ list->last = node;
+ } else {
+ list->last->next = node;
+ list->last = node;
+ }
+}
+
+/* Remove the given node from the given list.
+ * The datum stored in the node must be freed by the caller, if necessary. */
+void
+Lst_Remove(Lst list, LstNode node)
+{
+ assert(list != NULL);
+ assert(node != NULL);
+
+ /*
+ * unlink it from the list
+ */
+ if (node->next != NULL) {
+ node->next->prev = node->prev;
+ }
+ if (node->prev != NULL) {
+ node->prev->next = node->next;
+ }
+
+ /*
+ * if either the first or last of the list point to this node,
+ * adjust them accordingly
+ */
+ if (list->first == node) {
+ list->first = node->next;
+ }
+ if (list->last == node) {
+ list->last = node->prev;
+ }
+
+ /*
+ * Sequential access stuff. If the node we're removing is the current
+ * node in the list, reset the current node to the previous one. If the
+ * previous one was non-existent (prev == NULL), we set the
+ * end to be Unknown, since it is.
+ */
+ if (list->isOpen && list->curr == node) {
+ list->curr = list->prev;
+ if (list->curr == NULL) {
+ list->lastAccess = Unknown;
+ }
+ }
+
+ /*
+ * note that the datum is unmolested. The caller must free it as
+ * necessary and as expected.
+ */
+ if (node->useCount == 0) {
+ free(node);
+ } else {
+ node->deleted = TRUE;
+ }
+}
+
+/* Replace the datum in the given node with the new datum. */
+void
+LstNode_Set(LstNode node, void *datum)
+{
+ assert(node != NULL);
+ assert(datum != NULL);
+
+ node->datum = datum;
+}
+
+/* Replace the datum in the given node to NULL. */
+void
+LstNode_SetNull(LstNode node)
+{
+ assert(node != NULL);
+
+ node->datum = NULL;
+}
+
+
+/*
+ * Node-specific functions
+ */
+
+/* Return the first node from the given list, or NULL if the list is empty. */
+LstNode
+Lst_First(Lst list)
+{
+ assert(list != NULL);
+
+ return list->first;
+}
+
+/* Return the last node from the given list, or NULL if the list is empty. */
+LstNode
+Lst_Last(Lst list)
+{
+ assert(list != NULL);
+
+ return list->last;
+}
+
+/* Return the successor to the given node on its list, or NULL. */
+LstNode
+LstNode_Next(LstNode node)
+{
+ assert(node != NULL);
+
+ return node->next;
+}
+
+/* Return the predecessor to the given node on its list, or NULL. */
+LstNode
+LstNode_Prev(LstNode node)
+{
+ assert(node != NULL);
+ return node->prev;
+}
+
+/* Return the datum stored in the given node. */
+void *
+LstNode_Datum(LstNode node)
+{
+ assert(node != NULL);
+ return node->datum;
+}
+
+
+/*
+ * Functions for entire lists
+ */
+
+/* Return TRUE if the given list is empty. */
+Boolean
+Lst_IsEmpty(Lst list)
+{
+ assert(list != NULL);
+
+ return LstIsEmpty(list);
+}
+
+/* Return the first node from the list for which the match function returns
+ * TRUE, or NULL if none of the nodes matched. */
+LstNode
+Lst_Find(Lst list, LstFindProc match, const void *matchArgs)
+{
+ return Lst_FindFrom(list, Lst_First(list), match, matchArgs);
+}
+
+/* Return the first node from the list, starting at the given node, for which
+ * the match function returns TRUE, or NULL if none of the nodes matches.
+ *
+ * The start node may be NULL, in which case nothing is found. This allows
+ * for passing Lst_First or LstNode_Next as the start node. */
+LstNode
+Lst_FindFrom(Lst list, LstNode node, LstFindProc match, const void *matchArgs)
+{
+ LstNode tln;
+
+ assert(list != NULL);
+ assert(match != NULL);
+
+ for (tln = node; tln != NULL; tln = tln->next) {
+ if (match(tln->datum, matchArgs))
+ return tln;
+ }
+
+ return NULL;
+}
+
+/* Return the first node that contains the given datum, or NULL. */
+LstNode
+Lst_FindDatum(Lst list, const void *datum)
+{
+ LstNode node;
+
+ assert(list != NULL);
+ assert(datum != NULL);
+
+ for (node = list->first; node != NULL; node = node->next) {
+ if (node->datum == datum) {
+ return node;
+ }
+ }
+
+ return NULL;
+}
+
+/* Apply the given function to each element of the given list. The function
+ * should return 0 if traversal should continue and non-zero if it should
+ * abort. */
+int
+Lst_ForEach(Lst list, LstActionProc proc, void *procData)
+{
+ if (LstIsEmpty(list))
+ return 0; /* XXX: Document what this value means. */
+ return Lst_ForEachFrom(list, Lst_First(list), proc, procData);
+}
+
+/* Apply the given function to each element of the given list, starting from
+ * the given node. The function should return 0 if traversal should continue,
+ * and non-zero if it should abort. */
+int
+Lst_ForEachFrom(Lst list, LstNode node,
+ LstActionProc proc, void *procData)
+{
+ LstNode tln = node;
+ LstNode next;
+ Boolean done;
+ int result;
+
+ assert(list != NULL);
+ assert(node != NULL);
+ assert(proc != NULL);
+
+ do {
+ /*
+ * Take care of having the current element deleted out from under
+ * us.
+ */
+
+ next = tln->next;
+
+ /*
+ * We're done with the traversal if
+ * - the next node to examine doesn't exist and
+ * - nothing's been added after the current node (check this
+ * after proc() has been called).
+ */
+ done = next == NULL;
+
+ tln->useCount++;
+ result = (*proc)(tln->datum, procData);
+ tln->useCount--;
+
+ /*
+ * Now check whether a node has been added.
+ * Note: this doesn't work if this node was deleted before
+ * the new node was added.
+ */
+ if (next != tln->next) {
+ next = tln->next;
+ done = 0;
+ }
+
+ if (tln->deleted) {
+ free((char *)tln);
+ }
+ tln = next;
+ } while (!result && !LstIsEmpty(list) && !done);
+
+ return result;
+}
+
+/* Move all nodes from list2 to the end of list1.
+ * List2 is destroyed and freed. */
+void
+Lst_MoveAll(Lst list1, Lst list2)
+{
+ assert(list1 != NULL);
+ assert(list2 != NULL);
+
+ if (list2->first != NULL) {
+ list2->first->prev = list1->last;
+ if (list1->last != NULL) {
+ list1->last->next = list2->first;
+ } else {
+ list1->first = list2->first;
+ }
+ list1->last = list2->last;
+ }
+ free(list2);
+}
+
+/* Copy the element data from src to the start of dst. */
+void
+Lst_PrependAll(Lst dst, Lst src)
+{
+ LstNode node;
+ for (node = src->last; node != NULL; node = node->prev)
+ Lst_Prepend(dst, node->datum);
+}
+
+/* Copy the element data from src to the end of dst. */
+void
+Lst_AppendAll(Lst dst, Lst src)
+{
+ LstNode node;
+ for (node = src->first; node != NULL; node = node->next)
+ Lst_Append(dst, node->datum);
+}
+
+/*
+ * these functions are for dealing with a list as a table, of sorts.
+ * An idea of the "current element" is kept and used by all the functions
+ * between Lst_Open() and Lst_Close().
+ *
+ * The sequential functions access the list in a slightly different way.
+ * CurPtr points to their idea of the current node in the list and they
+ * access the list based on it.
+ */
+
+/* Open a list for sequential access. A list can still be searched, etc.,
+ * without confusing these functions. */
+void
+Lst_Open(Lst list)
+{
+ assert(list != NULL);
+ assert(!list->isOpen);
+
+ list->isOpen = TRUE;
+ list->lastAccess = LstIsEmpty(list) ? Head : Unknown;
+ list->curr = NULL;
+}
+
+/* Return the next node for the given list, or NULL if the end has been
+ * reached. */
+LstNode
+Lst_Next(Lst list)
+{
+ LstNode node;
+
+ assert(list != NULL);
+ assert(list->isOpen);
+
+ list->prev = list->curr;
+
+ if (list->curr == NULL) {
+ if (list->lastAccess == Unknown) {
+ /*
+ * If we're just starting out, lastAccess will be Unknown.
+ * Then we want to start this thing off in the right
+ * direction -- at the start with lastAccess being Middle.
+ */
+ list->curr = node = list->first;
+ list->lastAccess = Middle;
+ } else {
+ node = NULL;
+ list->lastAccess = Tail;
+ }
+ } else {
+ node = list->curr->next;
+ list->curr = node;
+
+ if (node == list->first || node == NULL) {
+ /*
+ * If back at the front, then we've hit the end...
+ */
+ list->lastAccess = Tail;
+ } else {
+ /*
+ * Reset to Middle if gone past first.
+ */
+ list->lastAccess = Middle;
+ }
+ }
+
+ return node;
+}
+
+/* Close a list which was opened for sequential access. */
+void
+Lst_Close(Lst list)
+{
+ assert(list != NULL);
+ assert(list->isOpen);
+
+ list->isOpen = FALSE;
+ list->lastAccess = Unknown;
+}
+
+
+/*
+ * for using the list as a queue
+ */
+
+/* Add the datum to the tail of the given list. */
+void
+Lst_Enqueue(Lst list, void *datum)
+{
+ Lst_Append(list, datum);
+}
+
+/* Remove and return the datum at the head of the given list. */
+void *
+Lst_Dequeue(Lst list)
+{
+ void *datum;
+
+ assert(list != NULL);
+ assert(!LstIsEmpty(list));
+
+ datum = list->first->datum;
+ Lst_Remove(list, list->first);
+ assert(datum != NULL);
+ return datum;
+}
diff --git a/lst.h b/lst.h
index e207bc808bf9..d9aa9feb3b65 100644
--- a/lst.h
+++ b/lst.h
@@ -1,4 +1,4 @@
-/* $NetBSD: lst.h,v 1.20 2014/09/07 20:55:34 joerg Exp $ */
+/* $NetBSD: lst.h,v 1.60 2020/09/02 23:33:13 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -73,117 +73,107 @@
* from: @(#)lst.h 8.1 (Berkeley) 6/6/93
*/
-/*-
- * lst.h --
- * Header for using the list library
- */
-#ifndef _LST_H_
-#define _LST_H_
-
-#include <sys/param.h>
-#include <stdlib.h>
+/* Doubly-linked lists of arbitrary pointers. */
-#include "sprite.h"
+#ifndef MAKE_LST_H
+#define MAKE_LST_H
-/*
- * basic typedef. This is what the Lst_ functions handle
- */
+#include <sys/param.h>
+#include <stdlib.h>
+/* A doubly-linked list of pointers. */
typedef struct List *Lst;
+/* A single node in the doubly-linked list. */
typedef struct ListNode *LstNode;
-typedef void *DuplicateProc(void *);
-typedef void FreeProc(void *);
+/* Copy a node, usually by allocating a copy of the given object.
+ * For reference-counted objects, the original object may need to be
+ * modified, therefore the parameter is not const. */
+typedef void *LstCopyProc(void *);
+/* Free the datum of a node, called before freeing the node itself. */
+typedef void LstFreeProc(void *);
+/* Return TRUE if the datum matches the args, for Lst_Find. */
+typedef Boolean LstFindProc(const void *datum, const void *args);
+/* An action for Lst_ForEach. */
+typedef int LstActionProc(void *datum, void *args);
-#define LST_CONCNEW 0 /* create new LstNode's when using Lst_Concat */
-#define LST_CONCLINK 1 /* relink LstNode's when using Lst_Concat */
+/* Create or destroy a list */
-/*
- * Creation/destruction functions
- */
-/* Create a new list */
-Lst Lst_Init(Boolean);
-/* Duplicate an existing list */
-Lst Lst_Duplicate(Lst, DuplicateProc *);
-/* Destroy an old one */
-void Lst_Destroy(Lst, FreeProc *);
-/* True if list is empty */
-Boolean Lst_IsEmpty(Lst);
+/* Create a new list. */
+Lst Lst_Init(void);
+/* Duplicate an existing list. */
+Lst Lst_Copy(Lst, LstCopyProc);
+/* Free the list, leaving the node data unmodified. */
+void Lst_Free(Lst);
+/* Free the list, freeing the node data using the given function. */
+void Lst_Destroy(Lst, LstFreeProc);
-/*
- * Functions to modify a list
- */
-/* Insert an element before another */
-ReturnStatus Lst_InsertBefore(Lst, LstNode, void *);
-/* Insert an element after another */
-ReturnStatus Lst_InsertAfter(Lst, LstNode, void *);
-/* Place an element at the front of a lst. */
-ReturnStatus Lst_AtFront(Lst, void *);
-/* Place an element at the end of a lst. */
-ReturnStatus Lst_AtEnd(Lst, void *);
-/* Remove an element */
-ReturnStatus Lst_Remove(Lst, LstNode);
-/* Replace a node with a new value */
-ReturnStatus Lst_Replace(LstNode, void *);
-/* Concatenate two lists */
-ReturnStatus Lst_Concat(Lst, Lst, int);
+/* Get information about a list */
-/*
- * Node-specific functions
- */
-/* Return first element in list */
-LstNode Lst_First(Lst);
-/* Return last element in list */
-LstNode Lst_Last(Lst);
-/* Return successor to given element */
-LstNode Lst_Succ(LstNode);
-/* Return predecessor to given element */
-LstNode Lst_Prev(LstNode);
-/* Get datum from LstNode */
-void *Lst_Datum(LstNode);
+Boolean Lst_IsEmpty(Lst);
+/* Return the first node of the list, or NULL. */
+LstNode Lst_First(Lst);
+/* Return the last node of the list, or NULL. */
+LstNode Lst_Last(Lst);
+/* Find the first node for which the function returns TRUE, or NULL. */
+LstNode Lst_Find(Lst, LstFindProc, const void *);
+/* Find the first node for which the function returns TRUE, or NULL.
+ * The search starts at the given node, towards the end of the list. */
+LstNode Lst_FindFrom(Lst, LstNode, LstFindProc, const void *);
+/* Find the first node that contains the given datum, or NULL. */
+LstNode Lst_FindDatum(Lst, const void *);
-/*
- * Functions for entire lists
- */
-/* Find an element in a list */
-LstNode Lst_Find(Lst, const void *, int (*)(const void *, const void *));
-/* Find an element starting from somewhere */
-LstNode Lst_FindFrom(Lst, LstNode, const void *,
- int (*cProc)(const void *, const void *));
-/*
- * See if the given datum is on the list. Returns the LstNode containing
- * the datum
- */
-LstNode Lst_Member(Lst, void *);
-/* Apply a function to all elements of a lst */
-int Lst_ForEach(Lst, int (*)(void *, void *), void *);
-/*
- * Apply a function to all elements of a lst starting from a certain point.
- * If the list is circular, the application will wrap around to the
- * beginning of the list again.
- */
-int Lst_ForEachFrom(Lst, LstNode, int (*)(void *, void *),
- void *);
-/*
- * these functions are for dealing with a list as a table, of sorts.
- * An idea of the "current element" is kept and used by all the functions
- * between Lst_Open() and Lst_Close().
- */
-/* Open the list */
-ReturnStatus Lst_Open(Lst);
-/* Next element please */
-LstNode Lst_Next(Lst);
-/* Done yet? */
-Boolean Lst_IsAtEnd(Lst);
-/* Finish table access */
-void Lst_Close(Lst);
+/* Modify a list */
-/*
- * for using the list as a queue
- */
-/* Place an element at tail of queue */
-ReturnStatus Lst_EnQueue(Lst, void *);
-/* Remove an element from head of queue */
-void *Lst_DeQueue(Lst);
+/* Insert a datum before the given node. */
+void Lst_InsertBefore(Lst, LstNode, void *);
+/* Place a datum at the front of the list. */
+void Lst_Prepend(Lst, void *);
+/* Place a datum at the end of the list. */
+void Lst_Append(Lst, void *);
+/* Remove the node from the list. */
+void Lst_Remove(Lst, LstNode);
+void Lst_PrependAll(Lst, Lst);
+void Lst_AppendAll(Lst, Lst);
+void Lst_MoveAll(Lst, Lst);
+
+/* Node-specific functions */
+
+/* Return the successor of the node, or NULL. */
+LstNode LstNode_Next(LstNode);
+/* Return the predecessor of the node, or NULL. */
+LstNode LstNode_Prev(LstNode);
+/* Return the datum of the node. Usually not NULL. */
+void *LstNode_Datum(LstNode);
+/* Replace the value of the node. */
+void LstNode_Set(LstNode, void *);
+/* Set the value of the node to NULL. Having NULL in a list is unusual. */
+void LstNode_SetNull(LstNode);
+
+/* Iterating over a list, using a callback function */
+
+/* Apply a function to each datum of the list, until the callback function
+ * returns non-zero. */
+int Lst_ForEach(Lst, LstActionProc, void *);
+/* Apply a function to each datum of the list, starting at the node,
+ * until the callback function returns non-zero. */
+int Lst_ForEachFrom(Lst, LstNode, LstActionProc, void *);
+
+/* Iterating over a list while keeping track of the current node and possible
+ * concurrent modifications */
+
+/* Start iterating the list. */
+void Lst_Open(Lst);
+/* Return the next node, or NULL. */
+LstNode Lst_Next(Lst);
+/* Finish iterating the list. */
+void Lst_Close(Lst);
+
+/* Using the list as a queue */
+
+/* Add a datum at the tail of the queue. */
+void Lst_Enqueue(Lst, void *);
+/* Remove the head node of the queue and return its datum. */
+void *Lst_Dequeue(Lst);
-#endif /* _LST_H_ */
+#endif /* MAKE_LST_H */
diff --git a/lst.lib/Makefile b/lst.lib/Makefile
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/lst.lib/Makefile
+++ /dev/null
diff --git a/lst.lib/lstAppend.c b/lst.lib/lstAppend.c
deleted file mode 100644
index 97e60d959d7d..000000000000
--- a/lst.lib/lstAppend.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* $NetBSD: lstAppend.c,v 1.15 2020/07/03 08:37:56 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstAppend.c,v 1.15 2020/07/03 08:37:56 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstAppend.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstAppend.c,v 1.15 2020/07/03 08:37:56 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstAppend.c --
- * Add a new node with a new datum after an existing node
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_InsertAfter --
- * Create a new node and add it to the given list after the given node.
- *
- * Input:
- * l affected list
- * ln node after which to append the datum
- * d said datum
- *
- * Results:
- * SUCCESS if all went well.
- *
- * Side Effects:
- * A new ListNode is created and linked in to the List. The lastPtr
- * field of the List will be altered if ln is the last node in the
- * list. lastPtr and firstPtr will alter if the list was empty and
- * ln was NULL.
- *
- *-----------------------------------------------------------------------
- */
-ReturnStatus
-Lst_InsertAfter(Lst l, LstNode ln, void *d)
-{
- List list;
- ListNode lNode;
- ListNode nLNode;
-
- if (LstValid (l) && (ln == NULL && LstIsEmpty (l))) {
- goto ok;
- }
-
- if (!LstValid (l) || LstIsEmpty (l) || ! LstNodeValid (ln, l)) {
- return FAILURE;
- }
- ok:
-
- list = l;
- lNode = ln;
-
- PAlloc (nLNode, ListNode);
- nLNode->datum = d;
- nLNode->useCount = nLNode->flags = 0;
-
- if (lNode == NULL) {
- if (list->isCirc) {
- nLNode->nextPtr = nLNode->prevPtr = nLNode;
- } else {
- nLNode->nextPtr = nLNode->prevPtr = NULL;
- }
- list->firstPtr = list->lastPtr = nLNode;
- } else {
- nLNode->prevPtr = lNode;
- nLNode->nextPtr = lNode->nextPtr;
-
- lNode->nextPtr = nLNode;
- if (nLNode->nextPtr != NULL) {
- nLNode->nextPtr->prevPtr = nLNode;
- }
-
- if (lNode == list->lastPtr) {
- list->lastPtr = nLNode;
- }
- }
-
- return SUCCESS;
-}
diff --git a/lst.lib/lstAtEnd.c b/lst.lib/lstAtEnd.c
deleted file mode 100644
index 4eadfdb0e7f3..000000000000
--- a/lst.lib/lstAtEnd.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* $NetBSD: lstAtEnd.c,v 1.14 2020/07/03 08:37:56 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstAtEnd.c,v 1.14 2020/07/03 08:37:56 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstAtEnd.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstAtEnd.c,v 1.14 2020/07/03 08:37:56 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstAtEnd.c --
- * Add a node at the end of the list
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_AtEnd --
- * Add a node to the end of the given list
- *
- * Input:
- * l List to which to add the datum
- * d Datum to add
- *
- * Results:
- * SUCCESS if life is good.
- *
- * Side Effects:
- * A new ListNode is created and added to the list.
- *
- *-----------------------------------------------------------------------
- */
-ReturnStatus
-Lst_AtEnd(Lst l, void *d)
-{
- LstNode end;
-
- end = Lst_Last(l);
- return Lst_InsertAfter(l, end, d);
-}
diff --git a/lst.lib/lstAtFront.c b/lst.lib/lstAtFront.c
deleted file mode 100644
index 724713c092ed..000000000000
--- a/lst.lib/lstAtFront.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* $NetBSD: lstAtFront.c,v 1.14 2020/07/03 08:37:56 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstAtFront.c,v 1.14 2020/07/03 08:37:56 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstAtFront.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstAtFront.c,v 1.14 2020/07/03 08:37:56 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstAtFront.c --
- * Add a node at the front of the list
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_AtFront --
- * Place a piece of data at the front of a list
- *
- * Results:
- * SUCCESS or FAILURE
- *
- * Side Effects:
- * A new ListNode is created and stuck at the front of the list.
- * hence, firstPtr (and possible lastPtr) in the list are altered.
- *
- *-----------------------------------------------------------------------
- */
-ReturnStatus
-Lst_AtFront(Lst l, void *d)
-{
- LstNode front;
-
- front = Lst_First(l);
- return Lst_InsertBefore(l, front, d);
-}
diff --git a/lst.lib/lstClose.c b/lst.lib/lstClose.c
deleted file mode 100644
index a1a3e9da80de..000000000000
--- a/lst.lib/lstClose.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* $NetBSD: lstClose.c,v 1.12 2020/07/03 08:37:56 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstClose.c,v 1.12 2020/07/03 08:37:56 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstClose.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstClose.c,v 1.12 2020/07/03 08:37:56 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstClose.c --
- * Close a list for sequential access.
- * The sequential functions access the list in a slightly different way.
- * CurPtr points to their idea of the current node in the list and they
- * access the list based on it. Because the list is circular, Lst_Next
- * and Lst_Prev will go around the list forever. Lst_IsAtEnd must be
- * used to determine when to stop.
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Close --
- * Close a list which was opened for sequential access.
- *
- * Input:
- * l The list to close
- *
- * Results:
- * None.
- *
- * Side Effects:
- * The list is closed.
- *
- *-----------------------------------------------------------------------
- */
-void
-Lst_Close(Lst l)
-{
- List list = l;
-
- if (LstValid(l) == TRUE) {
- list->isOpen = FALSE;
- list->atEnd = Unknown;
- }
-}
diff --git a/lst.lib/lstConcat.c b/lst.lib/lstConcat.c
deleted file mode 100644
index 2f667c5b0119..000000000000
--- a/lst.lib/lstConcat.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* $NetBSD: lstConcat.c,v 1.17 2020/07/03 08:37:56 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstConcat.c,v 1.17 2020/07/03 08:37:56 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstConcat.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstConcat.c,v 1.17 2020/07/03 08:37:56 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * listConcat.c --
- * Function to concatentate two lists.
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Concat --
- * Concatenate two lists. New elements are created to hold the data
- * elements, if specified, but the elements themselves are not copied.
- * If the elements should be duplicated to avoid confusion with another
- * list, the Lst_Duplicate function should be called first.
- * If LST_CONCLINK is specified, the second list is destroyed since
- * its pointers have been corrupted and the list is no longer useable.
- *
- * Input:
- * l1 The list to which l2 is to be appended
- * l2 The list to append to l1
- * flags LST_CONCNEW if LstNode's should be duplicated
- * LST_CONCLINK if should just be relinked
- *
- * Results:
- * SUCCESS if all went well. FAILURE otherwise.
- *
- * Side Effects:
- * New elements are created and appended the first list.
- *-----------------------------------------------------------------------
- */
-ReturnStatus
-Lst_Concat(Lst l1, Lst l2, int flags)
-{
- ListNode ln; /* original LstNode */
- ListNode nln; /* new LstNode */
- ListNode last; /* the last element in the list. Keeps
- * bookkeeping until the end */
- List list1 = l1;
- List list2 = l2;
-
- if (!LstValid (l1) || !LstValid (l2)) {
- return FAILURE;
- }
-
- if (flags == LST_CONCLINK) {
- if (list2->firstPtr != NULL) {
- /*
- * We set the nextPtr of the
- * last element of list two to be NIL to make the loop easier and
- * so we don't need an extra case should the first list turn
- * out to be non-circular -- the final element will already point
- * to NIL space and the first element will be untouched if it
- * existed before and will also point to NIL space if it didn't.
- */
- list2->lastPtr->nextPtr = NULL;
- /*
- * So long as the second list isn't empty, we just link the
- * first element of the second list to the last element of the
- * first list. If the first list isn't empty, we then link the
- * last element of the list to the first element of the second list
- * The last element of the second list, if it exists, then becomes
- * the last element of the first list.
- */
- list2->firstPtr->prevPtr = list1->lastPtr;
- if (list1->lastPtr != NULL) {
- list1->lastPtr->nextPtr = list2->firstPtr;
- } else {
- list1->firstPtr = list2->firstPtr;
- }
- list1->lastPtr = list2->lastPtr;
- }
- if (list1->isCirc && list1->firstPtr != NULL) {
- /*
- * If the first list is supposed to be circular and it is (now)
- * non-empty, we must make sure it's circular by linking the
- * first element to the last and vice versa
- */
- list1->firstPtr->prevPtr = list1->lastPtr;
- list1->lastPtr->nextPtr = list1->firstPtr;
- }
- free(l2);
- } else if (list2->firstPtr != NULL) {
- /*
- * We set the nextPtr of the last element of list 2 to be nil to make
- * the loop less difficult. The loop simply goes through the entire
- * second list creating new LstNodes and filling in the nextPtr, and
- * prevPtr to fit into l1 and its datum field from the
- * datum field of the corresponding element in l2. The 'last' node
- * follows the last of the new nodes along until the entire l2 has
- * been appended. Only then does the bookkeeping catch up with the
- * changes. During the first iteration of the loop, if 'last' is nil,
- * the first list must have been empty so the newly-created node is
- * made the first node of the list.
- */
- list2->lastPtr->nextPtr = NULL;
- for (last = list1->lastPtr, ln = list2->firstPtr;
- ln != NULL;
- ln = ln->nextPtr)
- {
- PAlloc (nln, ListNode);
- nln->datum = ln->datum;
- if (last != NULL) {
- last->nextPtr = nln;
- } else {
- list1->firstPtr = nln;
- }
- nln->prevPtr = last;
- nln->flags = nln->useCount = 0;
- last = nln;
- }
-
- /*
- * Finish bookkeeping. The last new element becomes the last element
- * of list one.
- */
- list1->lastPtr = last;
-
- /*
- * The circularity of both list one and list two must be corrected
- * for -- list one because of the new nodes added to it; list two
- * because of the alteration of list2->lastPtr's nextPtr to ease the
- * above for loop.
- */
- if (list1->isCirc) {
- list1->lastPtr->nextPtr = list1->firstPtr;
- list1->firstPtr->prevPtr = list1->lastPtr;
- } else {
- last->nextPtr = NULL;
- }
-
- if (list2->isCirc) {
- list2->lastPtr->nextPtr = list2->firstPtr;
- }
- }
-
- return SUCCESS;
-}
diff --git a/lst.lib/lstDatum.c b/lst.lib/lstDatum.c
deleted file mode 100644
index c8ccb558f3dc..000000000000
--- a/lst.lib/lstDatum.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* $NetBSD: lstDatum.c,v 1.14 2020/07/03 08:37:56 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstDatum.c,v 1.14 2020/07/03 08:37:56 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstDatum.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstDatum.c,v 1.14 2020/07/03 08:37:56 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstDatum.c --
- * Return the datum associated with a list node.
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Datum --
- * Return the datum stored in the given node.
- *
- * Results:
- * The datum or NULL if the node is invalid.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-void *
-Lst_Datum(LstNode ln)
-{
- if (ln != NULL) {
- return ln->datum;
- } else {
- return NULL;
- }
-}
diff --git a/lst.lib/lstDeQueue.c b/lst.lib/lstDeQueue.c
deleted file mode 100644
index 0f1452e4ac7e..000000000000
--- a/lst.lib/lstDeQueue.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* $NetBSD: lstDeQueue.c,v 1.15 2020/07/03 08:37:56 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstDeQueue.c,v 1.15 2020/07/03 08:37:56 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstDeQueue.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstDeQueue.c,v 1.15 2020/07/03 08:37:56 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstDeQueue.c --
- * Remove the node and return its datum from the head of the list
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_DeQueue --
- * Remove and return the datum at the head of the given list.
- *
- * Results:
- * The datum in the node at the head or NULL if the list
- * is empty.
- *
- * Side Effects:
- * The head node is removed from the list.
- *
- *-----------------------------------------------------------------------
- */
-void *
-Lst_DeQueue(Lst l)
-{
- void *rd;
- ListNode tln;
-
- tln = Lst_First(l);
- if (tln == NULL) {
- return NULL;
- }
-
- rd = tln->datum;
- if (Lst_Remove(l, tln) == FAILURE) {
- return NULL;
- } else {
- return rd;
- }
-}
diff --git a/lst.lib/lstDestroy.c b/lst.lib/lstDestroy.c
deleted file mode 100644
index 92c5b2b2050c..000000000000
--- a/lst.lib/lstDestroy.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/* $NetBSD: lstDestroy.c,v 1.16 2008/12/13 15:19:29 dsl Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstDestroy.c,v 1.16 2008/12/13 15:19:29 dsl Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstDestroy.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstDestroy.c,v 1.16 2008/12/13 15:19:29 dsl Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstDestroy.c --
- * Nuke a list and all its resources
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Destroy --
- * Destroy a list and free all its resources. If the freeProc is
- * given, it is called with the datum from each node in turn before
- * the node is freed.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * The given list is freed in its entirety.
- *
- *-----------------------------------------------------------------------
- */
-void
-Lst_Destroy(Lst list, FreeProc *freeProc)
-{
- ListNode ln;
- ListNode tln = NULL;
-
- if (list == NULL)
- return;
-
- /* To ease scanning */
- if (list->lastPtr != NULL)
- list->lastPtr->nextPtr = NULL;
- else {
- free(list);
- return;
- }
-
- if (freeProc) {
- for (ln = list->firstPtr; ln != NULL; ln = tln) {
- tln = ln->nextPtr;
- freeProc(ln->datum);
- free(ln);
- }
- } else {
- for (ln = list->firstPtr; ln != NULL; ln = tln) {
- tln = ln->nextPtr;
- free(ln);
- }
- }
-
- free(list);
-}
diff --git a/lst.lib/lstDupl.c b/lst.lib/lstDupl.c
deleted file mode 100644
index 6318ee4e462a..000000000000
--- a/lst.lib/lstDupl.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* $NetBSD: lstDupl.c,v 1.17 2020/07/03 08:37:56 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstDupl.c,v 1.17 2020/07/03 08:37:56 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstDupl.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstDupl.c,v 1.17 2020/07/03 08:37:56 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * listDupl.c --
- * Duplicate a list. This includes duplicating the individual
- * elements.
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Duplicate --
- * Duplicate an entire list. If a function to copy a void *is
- * given, the individual client elements will be duplicated as well.
- *
- * Input:
- * l the list to duplicate
- * copyProc A function to duplicate each void *
- *
- * Results:
- * The new Lst structure or NULL if failure.
- *
- * Side Effects:
- * A new list is created.
- *-----------------------------------------------------------------------
- */
-Lst
-Lst_Duplicate(Lst l, DuplicateProc *copyProc)
-{
- Lst nl;
- ListNode ln;
- List list = l;
-
- if (!LstValid (l)) {
- return NULL;
- }
-
- nl = Lst_Init(list->isCirc);
- if (nl == NULL) {
- return NULL;
- }
-
- ln = list->firstPtr;
- while (ln != NULL) {
- if (copyProc != NULL) {
- if (Lst_AtEnd(nl, copyProc(ln->datum)) == FAILURE) {
- return NULL;
- }
- } else if (Lst_AtEnd(nl, ln->datum) == FAILURE) {
- return NULL;
- }
-
- if (list->isCirc && ln == list->lastPtr) {
- ln = NULL;
- } else {
- ln = ln->nextPtr;
- }
- }
-
- return nl;
-}
diff --git a/lst.lib/lstEnQueue.c b/lst.lib/lstEnQueue.c
deleted file mode 100644
index c6941a8eb9d3..000000000000
--- a/lst.lib/lstEnQueue.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $NetBSD: lstEnQueue.c,v 1.14 2020/07/03 08:37:56 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstEnQueue.c,v 1.14 2020/07/03 08:37:56 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstEnQueue.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstEnQueue.c,v 1.14 2020/07/03 08:37:56 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstEnQueue.c--
- * Treat the list as a queue and place a datum at its end
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_EnQueue --
- * Add the datum to the tail of the given list.
- *
- * Results:
- * SUCCESS or FAILURE as returned by Lst_InsertAfter.
- *
- * Side Effects:
- * the lastPtr field is altered all the time and the firstPtr field
- * will be altered if the list used to be empty.
- *
- *-----------------------------------------------------------------------
- */
-ReturnStatus
-Lst_EnQueue(Lst l, void *d)
-{
- if (LstValid (l) == FALSE) {
- return FAILURE;
- }
-
- return Lst_InsertAfter(l, Lst_Last(l), d);
-}
diff --git a/lst.lib/lstFind.c b/lst.lib/lstFind.c
deleted file mode 100644
index a1d27d3ad686..000000000000
--- a/lst.lib/lstFind.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* $NetBSD: lstFind.c,v 1.16 2020/07/03 08:37:56 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstFind.c,v 1.16 2020/07/03 08:37:56 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstFind.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstFind.c,v 1.16 2020/07/03 08:37:56 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstFind.c --
- * Find a node on a list.
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Find --
- * Find a node on the given list using the given comparison function
- * and the given datum.
- *
- * Results:
- * The found node or NULL if none matches.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-LstNode
-Lst_Find(Lst l, const void *d, int (*cProc)(const void *, const void *))
-{
- return Lst_FindFrom(l, Lst_First(l), d, cProc);
-}
diff --git a/lst.lib/lstFindFrom.c b/lst.lib/lstFindFrom.c
deleted file mode 100644
index 676c07392039..000000000000
--- a/lst.lib/lstFindFrom.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* $NetBSD: lstFindFrom.c,v 1.16 2020/07/03 08:37:56 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstFindFrom.c,v 1.16 2020/07/03 08:37:56 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstFindFrom.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstFindFrom.c,v 1.16 2020/07/03 08:37:56 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstFindFrom.c --
- * Find a node on a list from a given starting point. Used by Lst_Find.
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_FindFrom --
- * Search for a node starting and ending with the given one on the
- * given list using the passed datum and comparison function to
- * determine when it has been found.
- *
- * Results:
- * The found node or NULL
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-LstNode
-Lst_FindFrom(Lst l, LstNode ln, const void *d,
- int (*cProc)(const void *, const void *))
-{
- ListNode tln;
-
- if (!LstValid (l) || LstIsEmpty (l) || !LstNodeValid (ln, l)) {
- return NULL;
- }
-
- tln = ln;
-
- do {
- if ((*cProc)(tln->datum, d) == 0)
- return tln;
- tln = tln->nextPtr;
- } while (tln != ln && tln != NULL);
-
- return NULL;
-}
diff --git a/lst.lib/lstFirst.c b/lst.lib/lstFirst.c
deleted file mode 100644
index a79db57120dd..000000000000
--- a/lst.lib/lstFirst.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* $NetBSD: lstFirst.c,v 1.13 2020/07/03 08:37:56 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstFirst.c,v 1.13 2020/07/03 08:37:56 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstFirst.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstFirst.c,v 1.13 2020/07/03 08:37:56 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstFirst.c --
- * Return the first node of a list
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_First --
- * Return the first node on the given list.
- *
- * Results:
- * The first node or NULL if the list is empty.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-LstNode
-Lst_First(Lst l)
-{
- if (!LstValid (l) || LstIsEmpty (l)) {
- return NULL;
- } else {
- return l->firstPtr;
- }
-}
diff --git a/lst.lib/lstForEach.c b/lst.lib/lstForEach.c
deleted file mode 100644
index dc2fdd8bfc57..000000000000
--- a/lst.lib/lstForEach.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* $NetBSD: lstForEach.c,v 1.14 2020/07/03 08:37:57 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstForEach.c,v 1.14 2020/07/03 08:37:57 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstForEach.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstForEach.c,v 1.14 2020/07/03 08:37:57 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstForeach.c --
- * Perform a given function on all elements of a list.
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_ForEach --
- * Apply the given function to each element of the given list. The
- * function should return 0 if Lst_ForEach should continue and non-
- * zero if it should abort.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * Only those created by the passed-in function.
- *
- *-----------------------------------------------------------------------
- */
-/*VARARGS2*/
-int
-Lst_ForEach(Lst l, int (*proc)(void *, void *), void *d)
-{
- return Lst_ForEachFrom(l, Lst_First(l), proc, d);
-}
diff --git a/lst.lib/lstForEachFrom.c b/lst.lib/lstForEachFrom.c
deleted file mode 100644
index a08ddf35935b..000000000000
--- a/lst.lib/lstForEachFrom.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/* $NetBSD: lstForEachFrom.c,v 1.18 2020/07/03 08:37:57 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstForEachFrom.c,v 1.18 2020/07/03 08:37:57 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstForEachFrom.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstForEachFrom.c,v 1.18 2020/07/03 08:37:57 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * lstForEachFrom.c --
- * Perform a given function on all elements of a list starting from
- * a given point.
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_ForEachFrom --
- * Apply the given function to each element of the given list. The
- * function should return 0 if traversal should continue and non-
- * zero if it should abort.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * Only those created by the passed-in function.
- *
- *-----------------------------------------------------------------------
- */
-/*VARARGS2*/
-int
-Lst_ForEachFrom(Lst l, LstNode ln, int (*proc)(void *, void *),
- void *d)
-{
- ListNode tln = ln;
- List list = l;
- ListNode next;
- Boolean done;
- int result;
-
- if (!LstValid (list) || LstIsEmpty (list)) {
- return 0;
- }
-
- do {
- /*
- * Take care of having the current element deleted out from under
- * us.
- */
-
- next = tln->nextPtr;
-
- /*
- * We're done with the traversal if
- * - the next node to examine is the first in the queue or
- * doesn't exist and
- * - nothing's been added after the current node (check this
- * after proc() has been called).
- */
- done = (next == NULL || next == list->firstPtr);
-
- (void) tln->useCount++;
- result = (*proc) (tln->datum, d);
- (void) tln->useCount--;
-
- /*
- * Now check whether a node has been added.
- * Note: this doesn't work if this node was deleted before
- * the new node was added.
- */
- if (next != tln->nextPtr) {
- next = tln->nextPtr;
- done = 0;
- }
-
- if (tln->flags & LN_DELETED) {
- free((char *)tln);
- }
- tln = next;
- } while (!result && !LstIsEmpty(list) && !done);
-
- return result;
-}
diff --git a/lst.lib/lstInit.c b/lst.lib/lstInit.c
deleted file mode 100644
index 3255da7e59a1..000000000000
--- a/lst.lib/lstInit.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* $NetBSD: lstInit.c,v 1.13 2020/07/03 08:37:57 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstInit.c,v 1.13 2020/07/03 08:37:57 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstInit.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstInit.c,v 1.13 2020/07/03 08:37:57 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * init.c --
- * Initialize a new linked list.
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Init --
- * Create and initialize a new list.
- *
- * Input:
- * circ TRUE if the list should be made circular
- *
- * Results:
- * The created list.
- *
- * Side Effects:
- * A list is created, what else?
- *
- *-----------------------------------------------------------------------
- */
-Lst
-Lst_Init(Boolean circ)
-{
- List nList;
-
- PAlloc (nList, List);
-
- nList->firstPtr = NULL;
- nList->lastPtr = NULL;
- nList->isOpen = FALSE;
- nList->isCirc = circ;
- nList->atEnd = Unknown;
-
- return nList;
-}
diff --git a/lst.lib/lstInsert.c b/lst.lib/lstInsert.c
deleted file mode 100644
index 845b8899e03b..000000000000
--- a/lst.lib/lstInsert.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* $NetBSD: lstInsert.c,v 1.15 2020/07/03 08:37:57 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstInsert.c,v 1.15 2020/07/03 08:37:57 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstInsert.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstInsert.c,v 1.15 2020/07/03 08:37:57 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstInsert.c --
- * Insert a new datum before an old one
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_InsertBefore --
- * Insert a new node with the given piece of data before the given
- * node in the given list.
- *
- * Input:
- * l list to manipulate
- * ln node before which to insert d
- * d datum to be inserted
- *
- * Results:
- * SUCCESS or FAILURE.
- *
- * Side Effects:
- * the firstPtr field will be changed if ln is the first node in the
- * list.
- *
- *-----------------------------------------------------------------------
- */
-ReturnStatus
-Lst_InsertBefore(Lst l, LstNode ln, void *d)
-{
- ListNode nLNode; /* new lnode for d */
- ListNode lNode = ln;
- List list = l;
-
-
- /*
- * check validity of arguments
- */
- if (LstValid (l) && (LstIsEmpty (l) && ln == NULL))
- goto ok;
-
- if (!LstValid (l) || LstIsEmpty (l) || !LstNodeValid (ln, l)) {
- return FAILURE;
- }
-
- ok:
- PAlloc (nLNode, ListNode);
-
- nLNode->datum = d;
- nLNode->useCount = nLNode->flags = 0;
-
- if (ln == NULL) {
- if (list->isCirc) {
- nLNode->prevPtr = nLNode->nextPtr = nLNode;
- } else {
- nLNode->prevPtr = nLNode->nextPtr = NULL;
- }
- list->firstPtr = list->lastPtr = nLNode;
- } else {
- nLNode->prevPtr = lNode->prevPtr;
- nLNode->nextPtr = lNode;
-
- if (nLNode->prevPtr != NULL) {
- nLNode->prevPtr->nextPtr = nLNode;
- }
- lNode->prevPtr = nLNode;
-
- if (lNode == list->firstPtr) {
- list->firstPtr = nLNode;
- }
- }
-
- return SUCCESS;
-}
diff --git a/lst.lib/lstInt.h b/lst.lib/lstInt.h
deleted file mode 100644
index ac53dcb67d77..000000000000
--- a/lst.lib/lstInt.h
+++ /dev/null
@@ -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_ */
diff --git a/lst.lib/lstIsAtEnd.c b/lst.lib/lstIsAtEnd.c
deleted file mode 100644
index c5add4d9867f..000000000000
--- a/lst.lib/lstIsAtEnd.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* $NetBSD: lstIsAtEnd.c,v 1.14 2020/07/03 08:37:57 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstIsAtEnd.c,v 1.14 2020/07/03 08:37:57 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstIsAtEnd.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstIsAtEnd.c,v 1.14 2020/07/03 08:37:57 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstIsAtEnd.c --
- * Tell if the current node is at the end of the list.
- * The sequential functions access the list in a slightly different way.
- * CurPtr points to their idea of the current node in the list and they
- * access the list based on it. Because the list is circular, Lst_Next
- * and Lst_Prev will go around the list forever. Lst_IsAtEnd must be
- * used to determine when to stop.
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_IsAtEnd --
- * Return true if have reached the end of the given list.
- *
- * Results:
- * TRUE if at the end of the list (this includes the list not being
- * open or being invalid) or FALSE if not. We return TRUE if the list
- * is invalid or unopend so as to cause the caller to exit its loop
- * asap, the assumption being that the loop is of the form
- * while (!Lst_IsAtEnd (l)) {
- * ...
- * }
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-Boolean
-Lst_IsAtEnd(Lst l)
-{
- List list = l;
-
- return !LstValid (l) || !list->isOpen ||
- list->atEnd == Head || list->atEnd == Tail;
-}
diff --git a/lst.lib/lstIsEmpty.c b/lst.lib/lstIsEmpty.c
deleted file mode 100644
index ccf4525a3506..000000000000
--- a/lst.lib/lstIsEmpty.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* $NetBSD: lstIsEmpty.c,v 1.12 2020/07/03 08:37:57 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstIsEmpty.c,v 1.12 2020/07/03 08:37:57 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstIsEmpty.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstIsEmpty.c,v 1.12 2020/07/03 08:37:57 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstIsEmpty.c --
- * A single function to decide if a list is empty
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_IsEmpty --
- * Return TRUE if the given list is empty.
- *
- * Results:
- * TRUE if the list is empty, FALSE otherwise.
- *
- * Side Effects:
- * None.
- *
- * A list is considered empty if its firstPtr == NULL (or if
- * the list itself is NULL).
- *-----------------------------------------------------------------------
- */
-Boolean
-Lst_IsEmpty(Lst l)
-{
- return !LstValid(l) || LstIsEmpty(l);
-}
diff --git a/lst.lib/lstLast.c b/lst.lib/lstLast.c
deleted file mode 100644
index 1d65bf19473e..000000000000
--- a/lst.lib/lstLast.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* $NetBSD: lstLast.c,v 1.13 2020/07/03 08:37:57 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstLast.c,v 1.13 2020/07/03 08:37:57 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstLast.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstLast.c,v 1.13 2020/07/03 08:37:57 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstLast.c --
- * Return the last element of a list
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Last --
- * Return the last node on the list l.
- *
- * Results:
- * The requested node or NULL if the list is empty.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-LstNode
-Lst_Last(Lst l)
-{
- if (!LstValid(l) || LstIsEmpty (l)) {
- return NULL;
- } else {
- return l->lastPtr;
- }
-}
diff --git a/lst.lib/lstMember.c b/lst.lib/lstMember.c
deleted file mode 100644
index e9046aca1436..000000000000
--- a/lst.lib/lstMember.c
+++ /dev/null
@@ -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;
-}
diff --git a/lst.lib/lstNext.c b/lst.lib/lstNext.c
deleted file mode 100644
index 9c180d2cfad1..000000000000
--- a/lst.lib/lstNext.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* $NetBSD: lstNext.c,v 1.13 2020/07/03 08:37:57 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstNext.c,v 1.13 2020/07/03 08:37:57 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstNext.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstNext.c,v 1.13 2020/07/03 08:37:57 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstNext.c --
- * Return the next node for a list.
- * The sequential functions access the list in a slightly different way.
- * CurPtr points to their idea of the current node in the list and they
- * access the list based on it. Because the list is circular, Lst_Next
- * and Lst_Prev will go around the list forever. Lst_IsAtEnd must be
- * used to determine when to stop.
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Next --
- * Return the next node for the given list.
- *
- * Results:
- * The next node or NULL if the list has yet to be opened. Also
- * if the list is non-circular and the end has been reached, NULL
- * is returned.
- *
- * Side Effects:
- * the curPtr field is updated.
- *
- *-----------------------------------------------------------------------
- */
-LstNode
-Lst_Next(Lst l)
-{
- ListNode tln;
- List list = l;
-
- if ((LstValid (l) == FALSE) ||
- (list->isOpen == FALSE)) {
- return NULL;
- }
-
- list->prevPtr = list->curPtr;
-
- if (list->curPtr == NULL) {
- if (list->atEnd == Unknown) {
- /*
- * If we're just starting out, atEnd will be Unknown.
- * Then we want to start this thing off in the right
- * direction -- at the start with atEnd being Middle.
- */
- list->curPtr = tln = list->firstPtr;
- list->atEnd = Middle;
- } else {
- tln = NULL;
- list->atEnd = Tail;
- }
- } else {
- tln = list->curPtr->nextPtr;
- list->curPtr = tln;
-
- if (tln == list->firstPtr || tln == NULL) {
- /*
- * If back at the front, then we've hit the end...
- */
- list->atEnd = Tail;
- } else {
- /*
- * Reset to Middle if gone past first.
- */
- list->atEnd = Middle;
- }
- }
-
- return tln;
-}
diff --git a/lst.lib/lstOpen.c b/lst.lib/lstOpen.c
deleted file mode 100644
index 919dd6d5000c..000000000000
--- a/lst.lib/lstOpen.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* $NetBSD: lstOpen.c,v 1.13 2020/07/03 08:37:57 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstOpen.c,v 1.13 2020/07/03 08:37:57 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstOpen.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstOpen.c,v 1.13 2020/07/03 08:37:57 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstOpen.c --
- * Open a list for sequential access. The sequential functions access the
- * list in a slightly different way. CurPtr points to their idea of the
- * current node in the list and they access the list based on it.
- * If the list is circular, Lst_Next and Lst_Prev will go around
- * the list forever. Lst_IsAtEnd must be used to determine when to stop.
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Open --
- * Open a list for sequential access. A list can still be searched,
- * etc., without confusing these functions.
- *
- * Results:
- * SUCCESS or FAILURE.
- *
- * Side Effects:
- * isOpen is set TRUE and curPtr is set to NULL so the
- * other sequential functions no it was just opened and can choose
- * the first element accessed based on this.
- *
- *-----------------------------------------------------------------------
- */
-ReturnStatus
-Lst_Open(Lst l)
-{
- if (LstValid (l) == FALSE) {
- return FAILURE;
- }
- (l)->isOpen = TRUE;
- (l)->atEnd = LstIsEmpty (l) ? Head : Unknown;
- (l)->curPtr = NULL;
-
- return SUCCESS;
-}
diff --git a/lst.lib/lstPrev.c b/lst.lib/lstPrev.c
deleted file mode 100644
index b6c548d9a523..000000000000
--- a/lst.lib/lstPrev.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* $NetBSD: lstPrev.c,v 1.4 2020/07/03 08:37:57 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstPrev.c,v 1.4 2020/07/03 08:37:57 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstPrev.c,v 1.4 2020/07/03 08:37:57 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstPrev.c --
- * return the predecessor to a given node
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Prev --
- * Return the predecessor to the given node on its list.
- *
- * Results:
- * The predecessor of the node, if it exists (note that on a circular
- * list, if the node is the only one in the list, it is its own
- * predecessor).
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-LstNode
-Lst_Prev(LstNode ln)
-{
- if (ln == NULL) {
- return NULL;
- } else {
- return ln->prevPtr;
- }
-}
diff --git a/lst.lib/lstRemove.c b/lst.lib/lstRemove.c
deleted file mode 100644
index 59245499bdc4..000000000000
--- a/lst.lib/lstRemove.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* $NetBSD: lstRemove.c,v 1.17 2020/07/03 08:37:57 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstRemove.c,v 1.17 2020/07/03 08:37:57 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstRemove.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstRemove.c,v 1.17 2020/07/03 08:37:57 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstRemove.c --
- * Remove an element from a list
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Remove --
- * Remove the given node from the given list.
- *
- * Results:
- * SUCCESS or FAILURE.
- *
- * Side Effects:
- * The list's firstPtr will be set to NULL if ln is the last
- * node on the list. firsPtr and lastPtr will be altered if ln is
- * either the first or last node, respectively, on the list.
- *
- *-----------------------------------------------------------------------
- */
-ReturnStatus
-Lst_Remove(Lst l, LstNode ln)
-{
- List list = l;
- ListNode lNode = ln;
-
- if (!LstValid (l) || !LstNodeValid (ln, l)) {
- return FAILURE;
- }
-
- /*
- * unlink it from the list
- */
- if (lNode->nextPtr != NULL) {
- lNode->nextPtr->prevPtr = lNode->prevPtr;
- }
- if (lNode->prevPtr != NULL) {
- lNode->prevPtr->nextPtr = lNode->nextPtr;
- }
-
- /*
- * if either the firstPtr or lastPtr of the list point to this node,
- * adjust them accordingly
- */
- if (list->firstPtr == lNode) {
- list->firstPtr = lNode->nextPtr;
- }
- if (list->lastPtr == lNode) {
- list->lastPtr = lNode->prevPtr;
- }
-
- /*
- * Sequential access stuff. If the node we're removing is the current
- * node in the list, reset the current node to the previous one. If the
- * previous one was non-existent (prevPtr == NULL), we set the
- * end to be Unknown, since it is.
- */
- if (list->isOpen && (list->curPtr == lNode)) {
- list->curPtr = list->prevPtr;
- if (list->curPtr == NULL) {
- list->atEnd = Unknown;
- }
- }
-
- /*
- * the only way firstPtr can still point to ln is if ln is the last
- * node on the list (the list is circular, so lNode->nextptr == lNode in
- * this case). The list is, therefore, empty and is marked as such
- */
- if (list->firstPtr == lNode) {
- list->firstPtr = NULL;
- }
-
- /*
- * note that the datum is unmolested. The caller must free it as
- * necessary and as expected.
- */
- if (lNode->useCount == 0) {
- free(ln);
- } else {
- lNode->flags |= LN_DELETED;
- }
-
- return SUCCESS;
-}
diff --git a/lst.lib/lstReplace.c b/lst.lib/lstReplace.c
deleted file mode 100644
index f30cb00855e3..000000000000
--- a/lst.lib/lstReplace.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $NetBSD: lstReplace.c,v 1.14 2020/07/03 08:37:57 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstReplace.c,v 1.14 2020/07/03 08:37:57 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstReplace.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstReplace.c,v 1.14 2020/07/03 08:37:57 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstReplace.c --
- * Replace the datum in a node with a new datum
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Replace --
- * Replace the datum in the given node with the new datum
- *
- * Results:
- * SUCCESS or FAILURE.
- *
- * Side Effects:
- * The datum field fo the node is altered.
- *
- *-----------------------------------------------------------------------
- */
-ReturnStatus
-Lst_Replace(LstNode ln, void *d)
-{
- if (ln == NULL) {
- return FAILURE;
- } else {
- (ln)->datum = d;
- return SUCCESS;
- }
-}
diff --git a/lst.lib/lstSucc.c b/lst.lib/lstSucc.c
deleted file mode 100644
index b3f73bb15fd2..000000000000
--- a/lst.lib/lstSucc.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* $NetBSD: lstSucc.c,v 1.14 2020/07/03 08:37:57 rillig Exp $ */
-
-/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstSucc.c,v 1.14 2020/07/03 08:37:57 rillig Exp $";
-#else
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: lstSucc.c,v 1.14 2020/07/03 08:37:57 rillig Exp $");
-#endif
-#endif /* not lint */
-#endif
-
-/*-
- * LstSucc.c --
- * return the successor to a given node
- */
-
-#include "lstInt.h"
-
-/*-
- *-----------------------------------------------------------------------
- * Lst_Succ --
- * Return the successor to the given node on its list.
- *
- * Results:
- * The successor of the node, if it exists (note that on a circular
- * list, if the node is the only one in the list, it is its own
- * successor).
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-LstNode
-Lst_Succ(LstNode ln)
-{
- if (ln == NULL) {
- return NULL;
- } else {
- return ln->nextPtr;
- }
-}
diff --git a/main.c b/main.c
index 25141625e55c..f27320c57451 100644
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $ */
+/* $NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
@@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $");
+__RCSID("$NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -124,13 +124,13 @@ __RCSID("$NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $");
#include <sys/utsname.h>
#include "wait.h"
+#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
-#include <ctype.h>
#include "make.h"
#include "hash.h"
@@ -162,7 +162,8 @@ static Lst makefiles; /* ordered list of makefiles to read */
static int printVars; /* -[vV] argument */
#define COMPAT_VARS 1
#define EXPAND_VARS 2
-static Lst variables; /* list of variables to print */
+static Lst variables; /* list of variables to print
+ * (for -v and -V) */
int maxJobs; /* -j argument */
static int maxJobTokens; /* -j argument */
Boolean compatMake; /* -B argument */
@@ -180,14 +181,13 @@ Boolean beSilent; /* -s flag */
Boolean oldVars; /* variable substitution style */
Boolean checkEnvFirst; /* -e flag */
Boolean parseWarnFatal; /* -W flag */
-Boolean jobServer; /* -J flag */
static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */
Boolean varNoExportEnv; /* -X flag */
Boolean doing_depend; /* Set while reading .depend */
static Boolean jobsRunning; /* TRUE if the jobs might be running */
static const char * tracefile;
static void MainParseArgs(int, char **);
-static int ReadMakefile(const void *, const void *);
+static int ReadMakefile(const char *);
static void usage(void) MAKE_ATTR_DEAD;
static void purge_cached_realpaths(void);
@@ -257,7 +257,7 @@ parse_debug_options(const char *argvalue)
for (modules = argvalue; *modules; ++modules) {
switch (*modules) {
case 'A':
- debug = ~0;
+ debug = ~(0|DEBUG_LINT);
break;
case 'a':
debug |= DEBUG_ARCH;
@@ -291,9 +291,15 @@ parse_debug_options(const char *argvalue)
++modules;
}
break;
+ case 'h':
+ debug |= DEBUG_HASH;
+ break;
case 'j':
debug |= DEBUG_JOB;
break;
+ case 'L':
+ debug |= DEBUG_LINT;
+ break;
case 'l':
debug |= DEBUG_LOUD;
break;
@@ -375,7 +381,7 @@ debug_setbuf:
/*
* does path contain any relative components
*/
-static int
+static Boolean
is_relpath(const char *path)
{
const char *cp;
@@ -383,10 +389,7 @@ is_relpath(const char *path)
if (path[0] != '/')
return TRUE;
cp = path;
- do {
- cp = strstr(cp, "/.");
- if (!cp)
- break;
+ while ((cp = strstr(cp, "/.")) != NULL) {
cp += 2;
if (cp[0] == '/' || cp[0] == '\0')
return TRUE;
@@ -394,7 +397,7 @@ is_relpath(const char *path)
if (cp[1] == '/' || cp[1] == '\0')
return TRUE;
}
- } while (cp);
+ }
return FALSE;
}
@@ -416,7 +419,7 @@ static void
MainParseArgs(int argc, char **argv)
{
char *p;
- int c = '?';
+ char c = '?';
int arginc;
char *argvalue;
const char *getopt_def;
@@ -531,7 +534,6 @@ rearg:
} else {
Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
- jobServer = TRUE;
}
break;
case 'N':
@@ -553,7 +555,7 @@ rearg:
case 'v':
if (argvalue == NULL) goto noarg;
printVars = c == 'v' ? EXPAND_VARS : COMPAT_VARS;
- (void)Lst_AtEnd(variables, argvalue);
+ Lst_Append(variables, argvalue);
Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
break;
@@ -581,7 +583,7 @@ rearg:
break;
case 'f':
if (argvalue == NULL) goto noarg;
- (void)Lst_AtEnd(makefiles, argvalue);
+ Lst_Append(makefiles, argvalue);
break;
case 'i':
ignoreErrors = TRUE;
@@ -674,7 +676,7 @@ rearg:
Punt("illegal (null) argument.");
if (*argv[1] == '-' && !dashDash)
goto rearg;
- (void)Lst_AtEnd(create, bmake_strdup(argv[1]));
+ Lst_Append(create, bmake_strdup(argv[1]));
}
return;
@@ -705,12 +707,10 @@ noarg:
void
Main_ParseArgLine(const char *line)
{
- char **argv; /* Manufactured argument vector */
- int argc; /* Number of arguments in argv */
- char *args; /* Space used by the args */
- char *buf, *p1;
- char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
- size_t len;
+ Words words;
+ char *p1;
+ const char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
+ char *buf;
if (line == NULL)
return;
@@ -733,21 +733,19 @@ Main_ParseArgLine(const char *line)
return;
}
#endif
- buf = bmake_malloc(len = strlen(line) + strlen(argv0) + 2);
- (void)snprintf(buf, len, "%s %s", argv0, line);
+ buf = str_concat3(argv0, " ", line);
free(p1);
- argv = brk_string(buf, &argc, TRUE, &args);
- if (argv == NULL) {
+ words = Str_Words(buf, TRUE);
+ if (words.words == NULL) {
Error("Unterminated quoted string [%s]", buf);
free(buf);
return;
}
free(buf);
- MainParseArgs(argc, argv);
+ MainParseArgs((int)words.len, words.words);
- free(args);
- free(argv);
+ Words_Free(words);
}
Boolean
@@ -775,7 +773,7 @@ Main_SetObjdir(const char *fmt, ...)
(void)fprintf(stderr, "make warning: %s: %s.\n",
path, strerror(errno));
} else {
- strncpy(objdir, path, MAXPATHLEN);
+ snprintf(objdir, sizeof objdir, "%s", path);
Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
setenv("PWD", objdir, 1);
Dir_InitDot();
@@ -792,37 +790,44 @@ Main_SetObjdir(const char *fmt, ...)
static Boolean
Main_SetVarObjdir(const char *var, const char *suffix)
{
- char *p, *path, *xpath;
+ char *path_freeIt;
+ const char *path = Var_Value(var, VAR_CMD, &path_freeIt);
+ const char *xpath;
+ char *xpath_freeIt;
- if ((path = Var_Value(var, VAR_CMD, &p)) == NULL ||
- *path == '\0')
+ if (path == NULL || path[0] == '\0') {
+ bmake_free(path_freeIt);
return FALSE;
+ }
/* expand variable substitutions */
+ xpath = path;
+ xpath_freeIt = NULL;
if (strchr(path, '$') != 0)
- xpath = Var_Subst(NULL, path, VAR_GLOBAL, VARF_WANTRES);
- else
- xpath = path;
+ xpath = xpath_freeIt = Var_Subst(path, VAR_GLOBAL,
+ VARE_WANTRES);
(void)Main_SetObjdir("%s%s", xpath, suffix);
- if (xpath != path)
- free(xpath);
- free(p);
+ bmake_free(xpath_freeIt);
+ bmake_free(path_freeIt);
return TRUE;
}
-/*-
- * ReadAllMakefiles --
- * wrapper around ReadMakefile() to read all.
- *
- * Results:
- * TRUE if ok, FALSE on error
- */
-static int
-ReadAllMakefiles(const void *p, const void *q)
+/* Read and parse the makefile.
+ * Return TRUE if reading the makefile succeeded, for Lst_Find. */
+static Boolean
+ReadMakefileSucceeded(const void *fname, const void *unused)
+{
+ return ReadMakefile(fname) == 0;
+}
+
+/* Read and parse the makefile.
+ * Return TRUE if reading the makefile failed, for Lst_Find. */
+static Boolean
+ReadMakefileFailed(const void *fname, const void *unused)
{
- return ReadMakefile(p, q) == 0;
+ return ReadMakefile(fname) != 0;
}
int
@@ -835,7 +840,7 @@ str2Lst_Append(Lst lp, char *str, const char *sep)
sep = " \t";
for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) {
- (void)Lst_AtEnd(lp, cp);
+ Lst_Append(lp, cp);
n++;
}
return n;
@@ -863,13 +868,13 @@ siginfo(int signo MAKE_ATTR_UNUSED)
void
MakeMode(const char *mode)
{
- char *mp = NULL;
+ char *mode_freeIt = NULL;
- if (!mode)
- mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}",
- VAR_GLOBAL, VARF_WANTRES);
+ if (mode == NULL)
+ mode = mode_freeIt = Var_Subst("${" MAKE_MODE ":tl}",
+ VAR_GLOBAL, VARE_WANTRES);
- if (mode && *mode) {
+ if (mode[0] != '\0') {
if (strstr(mode, "compat")) {
compatMake = TRUE;
forceJobs = FALSE;
@@ -880,7 +885,7 @@ MakeMode(const char *mode)
#endif
}
- free(mp);
+ free(mode_freeIt);
}
static void
@@ -896,15 +901,13 @@ doPrintVars(void)
else
expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE);
- for (ln = Lst_First(variables); ln != NULL;
- ln = Lst_Succ(ln)) {
- char *var = (char *)Lst_Datum(ln);
- char *value;
+ for (ln = Lst_First(variables); ln != NULL; ln = LstNode_Next(ln)) {
+ char *var = LstNode_Datum(ln);
+ const char *value;
char *p1;
if (strchr(var, '$')) {
- value = p1 = Var_Subst(NULL, var, VAR_GLOBAL,
- VARF_WANTRES);
+ value = p1 = Var_Subst(var, VAR_GLOBAL, VARE_WANTRES);
} else if (expandVars) {
char tmp[128];
int len = snprintf(tmp, sizeof(tmp), "${%s}", var);
@@ -912,13 +915,12 @@ doPrintVars(void)
if (len >= (int)sizeof(tmp))
Fatal("%s: variable name too big: %s",
progname, var);
- value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL,
- VARF_WANTRES);
+ value = p1 = Var_Subst(tmp, VAR_GLOBAL, VARE_WANTRES);
} else {
value = Var_Value(var, VAR_GLOBAL, &p1);
}
printf("%s\n", value ? value : "");
- free(p1);
+ bmake_free(p1);
}
}
@@ -962,7 +964,7 @@ runTargets(void)
Compat_Run(targs);
outOfDate = FALSE;
}
- Lst_Destroy(targs, NULL);
+ Lst_Free(targs);
return outOfDate;
}
@@ -1079,7 +1081,7 @@ main(int argc, char **argv)
#else
#ifndef MACHINE_ARCH
#ifdef MAKE_MACHINE_ARCH
- machine_arch = MAKE_MACHINE_ARCH;
+ machine_arch = MAKE_MACHINE_ARCH;
#else
machine_arch = "unknown";
#endif
@@ -1113,11 +1115,11 @@ main(int argc, char **argv)
VAR_GLOBAL);
Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL);
- create = Lst_Init(FALSE);
- makefiles = Lst_Init(FALSE);
+ create = Lst_Init();
+ makefiles = Lst_Init();
printVars = 0;
debugVflag = FALSE;
- variables = Lst_Init(FALSE);
+ variables = Lst_Init();
beSilent = FALSE; /* Print commands as executed */
ignoreErrors = FALSE; /* Pay attention to non-zero returns */
noExecute = FALSE; /* Execute all commands */
@@ -1199,7 +1201,7 @@ main(int argc, char **argv)
#ifdef USE_META
meta_init();
#endif
- Dir_Init(NULL); /* Dir_* safe to call from MainParseArgs */
+ Dir_Init();
/*
* First snag any flags out of the MAKE environment variable.
@@ -1265,8 +1267,8 @@ main(int argc, char **argv)
(void)strncpy(curdir, pwd, MAXPATHLEN);
}
}
- free(ptmp1);
- free(ptmp2);
+ bmake_free(ptmp1);
+ bmake_free(ptmp2);
}
#endif
Var_Set(".CURDIR", curdir, VAR_GLOBAL);
@@ -1280,7 +1282,7 @@ main(int argc, char **argv)
* and * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none
* of these paths exist, just use .CURDIR.
*/
- Dir_Init(curdir);
+ Dir_InitDir(curdir);
(void)Main_SetObjdir("%s", curdir);
if (!Main_SetVarObjdir("MAKEOBJDIRPREFIX", curdir) &&
@@ -1312,10 +1314,8 @@ main(int argc, char **argv)
if (!Lst_IsEmpty(create)) {
LstNode ln;
- for (ln = Lst_First(create); ln != NULL;
- ln = Lst_Succ(ln)) {
- char *name = (char *)Lst_Datum(ln);
-
+ for (ln = Lst_First(create); ln != NULL; ln = LstNode_Next(ln)) {
+ char *name = LstNode_Datum(ln);
Var_Append(".TARGETS", name, VAR_GLOBAL);
}
} else
@@ -1327,7 +1327,8 @@ main(int argc, char **argv)
* add the directories from the DEFSYSPATH (more than one may be given
* as dir1:...:dirn) to the system include path.
*/
- if (syspath == NULL || *syspath == '\0')
+ /* XXX: mismatch: the -m option sets sysIncPath, not syspath */
+ if (syspath == NULL || syspath[0] == '\0')
syspath = defsyspath;
else
syspath = bmake_strdup(syspath);
@@ -1353,48 +1354,46 @@ main(int argc, char **argv)
/*
* Read in the built-in rules first, followed by the specified
- * makefile, if it was (makefile != NULL), or the default
- * makefile and Makefile, in that order, if it wasn't.
+ * makefiles, or the default makefile and Makefile, in that order,
+ * if no makefiles were given on the command line.
*/
if (!noBuiltins) {
LstNode ln;
- sysMkPath = Lst_Init(FALSE);
+ sysMkPath = Lst_Init();
Dir_Expand(_PATH_DEFSYSMK,
Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath,
sysMkPath);
if (Lst_IsEmpty(sysMkPath))
Fatal("%s: no system rules (%s).", progname,
_PATH_DEFSYSMK);
- ln = Lst_Find(sysMkPath, NULL, ReadMakefile);
+ ln = Lst_Find(sysMkPath, ReadMakefileSucceeded, NULL);
if (ln == NULL)
Fatal("%s: cannot open %s.", progname,
- (char *)Lst_Datum(ln));
+ (char *)LstNode_Datum(Lst_First(sysMkPath)));
}
if (!Lst_IsEmpty(makefiles)) {
LstNode ln;
- ln = Lst_Find(makefiles, NULL, ReadAllMakefiles);
+ ln = Lst_Find(makefiles, ReadMakefileFailed, NULL);
if (ln != NULL)
Fatal("%s: cannot open %s.", progname,
- (char *)Lst_Datum(ln));
+ (char *)LstNode_Datum(ln));
} else {
- p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}",
- VAR_CMD, VARF_WANTRES);
- if (p1) {
+ p1 = Var_Subst("${" MAKEFILE_PREFERENCE "}",
+ VAR_CMD, VARE_WANTRES);
(void)str2Lst_Append(makefiles, p1, NULL);
- (void)Lst_Find(makefiles, NULL, ReadMakefile);
+ (void)Lst_Find(makefiles, ReadMakefileSucceeded, NULL);
free(p1);
- }
}
/* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
if (!noBuiltins || !printVars) {
- makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}",
- VAR_CMD, VARF_WANTRES);
+ makeDependfile = Var_Subst("${.MAKE.DEPENDFILE:T}",
+ VAR_CMD, VARE_WANTRES);
doing_depend = TRUE;
- (void)ReadMakefile(makeDependfile, NULL);
+ (void)ReadMakefile(makeDependfile);
doing_depend = FALSE;
}
@@ -1404,14 +1403,14 @@ main(int argc, char **argv)
MakeMode(NULL);
Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
- free(p1);
+ bmake_free(p1);
if (!forceJobs && !compatMake &&
Var_Exists(".MAKE.JOBS", VAR_GLOBAL)) {
char *value;
int n;
- value = Var_Subst(NULL, "${.MAKE.JOBS}", VAR_GLOBAL, VARF_WANTRES);
+ value = Var_Subst("${.MAKE.JOBS}", VAR_GLOBAL, VARE_WANTRES);
n = strtol(value, NULL, 0);
if (n < 1) {
(void)fprintf(stderr, "%s: illegal value for .MAKE.JOBS -- must be positive integer!\n",
@@ -1439,8 +1438,9 @@ main(int argc, char **argv)
if (!compatMake)
Job_ServerStart(maxJobTokens, jp_0, jp_1);
if (DEBUG(JOB))
- fprintf(debug_file, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
- jp_0, jp_1, maxJobs, maxJobTokens, compatMake);
+ fprintf(debug_file,
+ "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
+ jp_0, jp_1, maxJobs, maxJobTokens, compatMake ? 1 : 0);
if (!printVars)
Main_ExportMAKEFLAGS(TRUE); /* initial export */
@@ -1461,7 +1461,7 @@ main(int argc, char **argv)
*/
static char VPATH[] = "${VPATH}";
- vpath = Var_Subst(NULL, VPATH, VAR_CMD, VARF_WANTRES);
+ vpath = Var_Subst(VPATH, VAR_CMD, VARE_WANTRES);
path = vpath;
do {
/* skip to end of directory */
@@ -1502,9 +1502,9 @@ main(int argc, char **argv)
}
#ifdef CLEANUP
- Lst_Destroy(variables, NULL);
- Lst_Destroy(makefiles, NULL);
- Lst_Destroy(create, (FreeProc *)free);
+ Lst_Free(variables);
+ Lst_Free(makefiles);
+ Lst_Destroy(create, free);
#endif
/* print the graph now it's been processed if the user requested it */
@@ -1522,7 +1522,7 @@ main(int argc, char **argv)
meta_finish();
#endif
Suff_End();
- Targ_End();
+ Targ_End();
Arch_End();
Var_End();
Parse_End();
@@ -1533,23 +1533,16 @@ main(int argc, char **argv)
return outOfDate ? 1 : 0;
}
-/*-
- * ReadMakefile --
- * Open and parse the given makefile.
+/* Open and parse the given makefile, with all its side effects.
*
* Results:
* 0 if ok. -1 if couldn't open file.
- *
- * Side Effects:
- * lots
*/
static int
-ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
+ReadMakefile(const char *fname)
{
- const char *fname = p; /* makefile to read */
int fd;
- size_t len = MAXPATHLEN;
- char *name, *path = bmake_malloc(len);
+ char *name, *path = NULL;
if (!strcmp(fname, "-")) {
Parse_File(NULL /*stdin*/, -1);
@@ -1557,22 +1550,16 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
} else {
/* if we've chdir'd, rebuild the path name */
if (strcmp(curdir, objdir) && *fname != '/') {
- size_t plen = strlen(curdir) + strlen(fname) + 2;
- if (len < plen)
- path = bmake_realloc(path, len = 2 * plen);
-
- (void)snprintf(path, len, "%s/%s", curdir, fname);
+ path = str_concat3(curdir, "/", fname);
fd = open(path, O_RDONLY);
if (fd != -1) {
fname = path;
goto found;
}
+ free(path);
/* If curdir failed, try objdir (ala .depend) */
- plen = strlen(objdir) + strlen(fname) + 2;
- if (len < plen)
- path = bmake_realloc(path, len = 2 * plen);
- (void)snprintf(path, len, "%s/%s", objdir, fname);
+ path = str_concat3(objdir, "/", fname);
fd = open(path, O_RDONLY);
if (fd != -1) {
fname = path;
@@ -1613,31 +1600,32 @@ found:
/*-
* Cmd_Exec --
* Execute the command in cmd, and return the output of that command
- * in a string.
+ * in a string. In the output, newlines are replaced with spaces.
*
* Results:
- * A string containing the output of the command, or the empty string
- * If errnum is not NULL, it contains the reason for the command failure
+ * A string containing the output of the command, or the empty string.
+ * *errfmt returns a format string describing the command failure,
+ * if any, using a single %s conversion specification.
*
* Side Effects:
* The string must be freed by the caller.
*/
char *
-Cmd_Exec(const char *cmd, const char **errnum)
+Cmd_Exec(const char *cmd, const char **errfmt)
{
const char *args[4]; /* Args for invoking the shell */
int fds[2]; /* Pipe streams */
int cpid; /* Child PID */
int pid; /* PID from wait() */
- char *res; /* result */
WAIT_T status; /* command exit status */
Buffer buf; /* buffer to store the result */
+ ssize_t bytes_read;
+ char *res; /* result */
+ size_t res_len;
char *cp;
- int cc; /* bytes read, or -1 */
int savederr; /* saved errno */
-
- *errnum = NULL;
+ *errfmt = NULL;
if (!shellName)
Shell_Init();
@@ -1653,7 +1641,7 @@ Cmd_Exec(const char *cmd, const char **errnum)
* Open a pipe for fetching its output
*/
if (pipe(fds) == -1) {
- *errnum = "Couldn't create pipe for \"%s\"";
+ *errfmt = "Couldn't create pipe for \"%s\"";
goto bad;
}
@@ -1682,7 +1670,7 @@ Cmd_Exec(const char *cmd, const char **errnum)
/*NOTREACHED*/
case -1:
- *errnum = "Couldn't exec \"%s\"";
+ *errfmt = "Couldn't exec \"%s\"";
goto bad;
default:
@@ -1696,12 +1684,12 @@ Cmd_Exec(const char *cmd, const char **errnum)
do {
char result[BUFSIZ];
- cc = read(fds[0], result, sizeof(result));
- if (cc > 0)
- Buf_AddBytes(&buf, cc, result);
+ bytes_read = read(fds[0], result, sizeof(result));
+ if (bytes_read > 0)
+ Buf_AddBytes(&buf, result, (size_t)bytes_read);
}
- while (cc > 0 || (cc == -1 && errno == EINTR));
- if (cc == -1)
+ while (bytes_read > 0 || (bytes_read == -1 && errno == EINTR));
+ if (bytes_read == -1)
savederr = errno;
/*
@@ -1716,43 +1704,28 @@ Cmd_Exec(const char *cmd, const char **errnum)
JobReapChild(pid, status, FALSE);
continue;
}
- cc = Buf_Size(&buf);
+ res_len = Buf_Size(&buf);
res = Buf_Destroy(&buf, FALSE);
if (savederr != 0)
- *errnum = "Couldn't read shell's output for \"%s\"";
+ *errfmt = "Couldn't read shell's output for \"%s\"";
if (WIFSIGNALED(status))
- *errnum = "\"%s\" exited on a signal";
+ *errfmt = "\"%s\" exited on a signal";
else if (WEXITSTATUS(status) != 0)
- *errnum = "\"%s\" returned non-zero status";
-
- /*
- * Null-terminate the result, convert newlines to spaces and
- * install it in the variable.
- */
- res[cc] = '\0';
- cp = &res[cc];
+ *errfmt = "\"%s\" returned non-zero status";
- if (cc > 0 && *--cp == '\n') {
- /*
- * A final newline is just stripped
- */
- *cp-- = '\0';
- }
- while (cp >= res) {
- if (*cp == '\n') {
+ /* Convert newlines to spaces. A final newline is just stripped */
+ if (res_len > 0 && res[res_len - 1] == '\n')
+ res[res_len - 1] = '\0';
+ for (cp = res; *cp != '\0'; cp++)
+ if (*cp == '\n')
*cp = ' ';
- }
- cp--;
- }
break;
}
return res;
bad:
- res = bmake_malloc(1);
- *res = '\0';
- return res;
+ return bmake_strdup("");
}
/*-
@@ -1888,7 +1861,7 @@ DieHorribly(void)
*/
void
Finish(int errors)
- /* number of errors encountered in Make_Make */
+ /* number of errors encountered in Make_Make */
{
if (dieQuietly(NULL, -1))
exit(2);
@@ -1956,13 +1929,13 @@ usage(void)
{
char *p;
if ((p = strchr(progname, '[')) != NULL)
- *p = '\0';
+ *p = '\0';
(void)fprintf(stderr,
-"usage: %s [-BeikNnqrstWwX] \n\
- [-C directory] [-D variable] [-d flags] [-f makefile]\n\
- [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\
- [-V variable] [-v variable] [variable=value] [target ...]\n",
+"usage: %s [-BeikNnqrstWwX] \n"
+" [-C directory] [-D variable] [-d flags] [-f makefile]\n"
+" [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n"
+" [-V variable] [-v variable] [variable=value] [target ...]\n",
progname);
exit(2);
}
@@ -2010,7 +1983,8 @@ char *
cached_realpath(const char *pathname, char *resolved)
{
GNode *cache;
- char *rp, *cp;
+ const char *rp;
+ char *cp;
if (!pathname || !pathname[0])
return NULL;
@@ -2024,7 +1998,7 @@ cached_realpath(const char *pathname, char *resolved)
Var_Set(pathname, rp, cache);
} /* else should we negative-cache? */
- free(cp);
+ bmake_free(cp);
return rp ? resolved : NULL;
}
@@ -2070,9 +2044,14 @@ void
PrintOnError(GNode *gn, const char *s)
{
static GNode *en = NULL;
- char tmp[64];
+ const char *expr;
char *cp;
+ if (DEBUG(HASH)) {
+ Targ_Stats();
+ Var_Stats();
+ }
+
/* we generally want to keep quiet if a sub-make died */
if (dieQuietly(gn, -1))
return;
@@ -2092,14 +2071,10 @@ PrintOnError(GNode *gn, const char *s)
Var_Delete(".ERROR_CMD", VAR_GLOBAL);
Lst_ForEach(gn->commands, addErrorCMD, gn);
}
- strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
- sizeof(tmp) - 1);
- cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
- if (cp) {
- if (*cp)
- printf("%s", cp);
- free(cp);
- }
+ expr = "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}";
+ cp = Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES);
+ printf("%s", cp);
+ free(cp);
fflush(stdout);
/*
@@ -2115,18 +2090,17 @@ PrintOnError(GNode *gn, const char *s)
void
Main_ExportMAKEFLAGS(Boolean first)
{
- static int once = 1;
- char tmp[64];
+ static Boolean once = TRUE;
+ const char *expr;
char *s;
if (once != first)
return;
- once = 0;
+ once = FALSE;
- strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}",
- sizeof(tmp));
- s = Var_Subst(NULL, tmp, VAR_CMD, VARF_WANTRES);
- if (s && *s) {
+ expr = "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}";
+ s = Var_Subst(expr, VAR_CMD, VARE_WANTRES);
+ if (s[0] != '\0') {
#ifdef POSIX
setenv("MAKEFLAGS", s, 1);
#else
@@ -2147,8 +2121,8 @@ getTmpdir(void)
* Honor $TMPDIR but only if it is valid.
* Ensure it ends with /.
*/
- tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL,
- VARF_WANTRES);
+ tmpdir = Var_Subst("${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL,
+ VARE_WANTRES);
if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
free(tmpdir);
tmpdir = bmake_strdup(_PATH_TMP);
@@ -2235,18 +2209,12 @@ s2Boolean(const char *s, Boolean bf)
* is FALSE, otherwise TRUE.
*/
Boolean
-getBoolean(const char *name, Boolean bf)
+getBoolean(const char *name, Boolean fallback)
{
- char tmp[64];
- char *cp;
-
- if (snprintf(tmp, sizeof(tmp), "${%s:U:tl}", name) < (int)(sizeof(tmp))) {
- cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
-
- if (cp) {
- bf = s2Boolean(cp, bf);
- free(cp);
- }
- }
- return bf;
+ char *expr = str_concat3("${", name, ":U:tl}");
+ char *value = Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES);
+ Boolean res = s2Boolean(value, fallback);
+ free(value);
+ free(expr);
+ return res;
}
diff --git a/make-conf.h b/make-conf.h
index a85b86d3efb5..5b13e295ae0c 100644
--- a/make-conf.h
+++ b/make-conf.h
@@ -1,4 +1,4 @@
-/* $NetBSD: config.h,v 1.21 2012/03/31 00:12:24 christos Exp $ */
+/* $NetBSD: config.h,v 1.22 2020/09/01 17:40:34 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -100,7 +100,10 @@
* LIBSUFF
* Is the suffix used to denote libraries and is used by the Suff module
* to find the search path on which to seek any -l<xx> targets.
- *
+ */
+#define LIBSUFF ".a"
+
+/*
* RECHECK
* If defined, Make_Update will check a target for its current
* modification time after it has been re-made, setting it to the
@@ -108,10 +111,9 @@
* Unfortunately, under NFS the modification time often doesn't
* get updated in time, so a target will appear to not have been
* re-made, causing later targets to appear up-to-date. On systems
- * that don't have this problem, you should defined this. Under
+ * that don't have this problem, you should define this. Under
* NFS you probably should not, unless you aren't exporting jobs.
*/
-#define LIBSUFF ".a"
#define RECHECK
/*
diff --git a/make.1 b/make.1
index ae7e7033c077..9d83abe31d6c 100644
--- a/make.1
+++ b/make.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: make.1,v 1.282 2020/06/06 20:28:42 wiz Exp $
+.\" $NetBSD: make.1,v 1.289 2020/08/28 17:15:04 rillig Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
-.Dd June 5, 2020
+.Dd August 28, 2020
.Dt MAKE 1
.Os
.Sh NAME
@@ -166,8 +166,15 @@ Print the input graph after making everything, or before exiting
on error.
.It Ar "g3"
Print the input graph before exiting on error.
+.It Ar h
+Print debugging information about hash table operations.
.It Ar j
Print debugging information about running multiple shells.
+.It Ar L
+Turn on lint checks.
+This will throw errors for variable assignments that do not parse
+correctly, at the time of assignment so the file and line number
+are available.
.It Ar l
Print commands in Makefiles regardless of whether or not they are prefixed by
.Ql @
@@ -311,7 +318,8 @@ as an argument).
.It Fl n
Display the commands that would have been executed, but do not
actually execute them unless the target depends on the .MAKE special
-source (see below).
+source (see below) or the command is prefixed with
+.Ql Ic + .
.It Fl N
Display the commands which would have been executed, but do not
actually execute any of them; useful for debugging top-level makefiles
@@ -412,37 +420,44 @@ or more sources.
This creates a relationship where the targets
.Dq depend
on the sources
-and are usually created from them.
-The exact relationship between the target and the source is determined
-by the operator that separates them.
-The three operators are as follows:
+and are customarily created from them.
+A target is considered out-of-date if it does not exist, or if its
+modification time is less than that of any of its sources.
+An out-of-date target will be re-created, but not until all sources
+have been examined and themselves re-created as needed.
+Three operators may be used:
.Bl -tag -width flag
.It Ic \&:
-A target is considered out-of-date if its modification time is less than
-those of any of its sources.
-Sources for a target accumulate over dependency lines when this operator
-is used.
-The target is removed if
+Many dependency lines may name this target but only one may have
+attached shell commands.
+All sources named in all dependency lines are considered together,
+and if needed the attached shell commands are run to create or
+re-create the target.
+If
.Nm
-is interrupted.
+is interrupted, the target is removed.
.It Ic \&!
-Targets are always re-created, but not until all sources have been
-examined and re-created as necessary.
-Sources for a target accumulate over dependency lines when this operator
-is used.
-The target is removed if
-.Nm
-is interrupted.
+The same, but the target is always re-created whether or not it is out
+of date.
.It Ic \&::
-If no sources are specified, the target is always re-created.
-Otherwise, a target is considered out-of-date if any of its sources has
-been modified more recently than the target.
-Sources for a target do not accumulate over dependency lines when this
-operator is used.
-The target will not be removed if
+Any dependency line may have attached shell commands, but each one
+is handled independently: its sources are considered and the attached
+shell commands are run if the target is out of date with respect to
+(only) those sources.
+Thus, different groups of the attached shell commands may be run
+depending on the circumstances.
+Furthermore, unlike
+.Ic \&:,
+for dependency lines with no sources, the attached shell
+commands are always run.
+Also unlike
+.Ic \&:,
+the target will not be removed if
.Nm
is interrupted.
.El
+All dependency lines mentioning a particular target must use the same
+operator.
.Pp
Targets and sources may contain the shell wildcard values
.Ql \&? ,
@@ -608,7 +623,7 @@ This shorter form is not recommended.
.Pp
If the variable name contains a dollar, then the name itself is expanded first.
This allows almost arbitrary variable names, however names containing dollar,
-braces, parenthesis, or whitespace are really best avoided!
+braces, parentheses, or whitespace are really best avoided!
.Pp
If the result of expanding a variable contains a dollar sign
.Pq Ql \&$
@@ -1126,6 +1141,9 @@ is set to the value of
for all programs which
.Nm
executes.
+.It Ev .SHELL
+The pathname of the shell used to run target scripts.
+It is read-only.
.It Ev .TARGETS
The list of targets explicitly specified on the command line, if any.
.It Ev VPATH
@@ -1171,7 +1189,7 @@ Replaces each word in the variable with its suffix.
.It Cm \&:H
Replaces each word in the variable with everything but the last component.
.It Cm \&:M Ns Ar pattern
-Select only those words that match
+Selects only those words that match
.Ar pattern .
The standard shell wildcard characters
.Pf ( Ql * ,
@@ -1195,11 +1213,11 @@ This is identical to
but selects all words which do not match
.Ar pattern .
.It Cm \&:O
-Order every word in variable alphabetically.
+Orders every word in variable alphabetically.
.It Cm \&:Or
-Order every word in variable in reverse alphabetical order.
+Orders every word in variable in reverse alphabetical order.
.It Cm \&:Ox
-Randomize words in variable.
+Shuffles the words in variable.
The results will be different each time you are referring to the
modified variable; use the assignment with expansion
.Pq Ql Cm \&:=
@@ -1249,7 +1267,7 @@ If a
.Va utc
value is not provided or is 0, the current time is used.
.It Cm \&:hash
-Compute a 32-bit hash of the value and encode it as hex digits.
+Computes a 32-bit hash of the value and encode it as hex digits.
.It Cm \&:localtime[=utc]
The value is a format string for
.Xr strftime 3 ,
@@ -1259,7 +1277,7 @@ If a
.Va utc
value is not provided or is 0, the current time is used.
.It Cm \&:tA
-Attempt to convert variable to an absolute path using
+Attempts to convert variable to an absolute path using
.Xr realpath 3 ,
if that fails, the value is unchanged.
.It Cm \&:tl
@@ -1271,7 +1289,7 @@ This modifier sets the separator to the character
If
.Ar c
is omitted, then no separator is used.
-The common escapes (including octal numeric codes), work as expected.
+The common escapes (including octal numeric codes) work as expected.
.It Cm \&:tu
Converts variable to upper-case letters.
.It Cm \&:tW
@@ -1287,21 +1305,21 @@ See also
.Sm off
.It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW
.Sm on
-Modify the first occurrence of
+Modifies the first occurrence of
.Ar old_string
-in the variable's value, replacing it with
+in each word of the variable's value, replacing it with
.Ar new_string .
If a
.Ql g
-is appended to the last slash of the pattern, all occurrences
+is appended to the last delimiter of the pattern, all occurrences
in each word are replaced.
If a
.Ql 1
-is appended to the last slash of the pattern, only the first word
+is appended to the last delimiter of the pattern, only the first occurrence
is affected.
If a
.Ql W
-is appended to the last slash of the pattern,
+is appended to the last delimiter of the pattern,
then the value is treated as a single word
(possibly containing embedded white space).
If
@@ -1370,13 +1388,6 @@ as occur in the word or words it is found in; the
.Ql W
modifier causes the value to be treated as a single word
(possibly containing embedded white space).
-Note that
-.Ql 1
-and
-.Ql g
-are orthogonal; the former specifies whether multiple words are
-potentially affected, the latter whether multiple substitutions can
-potentially occur within each affected word.
.Pp
As for the
.Cm \&:S
@@ -1387,9 +1398,9 @@ and
are subjected to variable expansion before being parsed as
regular expressions.
.It Cm \&:T
-Replaces each word in the variable with its last component.
+Replaces each word in the variable with its last path component.
.It Cm \&:u
-Remove adjacent duplicate words (like
+Removes adjacent duplicate words (like
.Xr uniq 1 ) .
.Sm off
.It Cm \&:\&? Ar true_string Cm \&: Ar false_string
@@ -1405,7 +1416,7 @@ usually contain variable expansions.
A common error is trying to use expressions like
.Dl ${NUMBERS:M42:?match:no}
which actually tests defined(NUMBERS),
-to determine is any words match "42" you need to use something like:
+to determine if any words match "42" you need to use something like:
.Dl ${"${NUMBERS:M42}" != \&"\&":?match:no} .
.It Ar :old_string=new_string
This is the
@@ -1449,7 +1460,7 @@ in either the
or
.Ar old_string ,
only the first instance is treated specially (as the pattern character);
-all subsequent instances are treated as regular characters
+all subsequent instances are treated as regular characters.
.Pp
Variable expansion occurs in the normal fashion inside both
.Ar old_string
@@ -1466,11 +1477,10 @@ This is the loop expansion mechanism from the OSF Development
Environment (ODE) make.
Unlike
.Cm \&.for
-loops expansion occurs at the time of
-reference.
-Assign
+loops, expansion occurs at the time of reference.
+Assigns
.Ar temp
-to each word in the variable and evaluate
+to each word in the variable and evaluates
.Ar string .
The ODE convention is that
.Ar temp
@@ -1481,7 +1491,7 @@ For example.
However a single character variable is often more readable:
.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
.It Cm \&:_[=var]
-Save the current variable value in
+Saves the current variable value in
.Ql $_
or the named
.Va var
@@ -1502,7 +1512,7 @@ is used to save the result of the
modifier which is later referenced using the index values from
.Ql :range .
.It Cm \&:U Ns Ar newval
-If the variable is undefined
+If the variable is undefined,
.Ar newval
is the value.
If the variable is defined, the existing value is returned.
@@ -1512,7 +1522,7 @@ It is handy for setting per-target CFLAGS for instance:
If a value is only required if the variable is undefined, use:
.Dl ${VAR:D:Unewval}
.It Cm \&:D Ns Ar newval
-If the variable is defined
+If the variable is defined,
.Ar newval
is the value.
.It Cm \&:L
@@ -1641,7 +1651,7 @@ Returns the number of words in the value.
.El \" :[range]
.El
.Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS
-Makefile inclusion, conditional structures and for loops reminiscent
+Makefile inclusion, conditional structures and for loops reminiscent
of the C programming language are provided in
.Nm .
All such structures are identified by a line beginning with a single
@@ -1687,7 +1697,7 @@ The possible conditionals are as follows:
The message is printed along with the name of the makefile and line number,
then
.Nm
-will exit.
+will exit immediately.
.It Ic .export Ar variable ...
Export the specified global variable.
If no variable list is provided, all globals are exported
@@ -1876,7 +1886,7 @@ operator is not an integral value, then
string comparison is performed between the expanded
variables.
If no relational operator is given, it is assumed that the expanded
-variable is being compared against 0 or an empty string in the case
+variable is being compared against 0, or an empty string in the case
of a string comparison.
.Pp
When
@@ -1917,7 +1927,7 @@ The syntax of a for loop is:
.Pp
.Bl -tag -compact -width Ds
.It Ic \&.for Ar variable Oo Ar variable ... Oc Ic in Ar expression
-.It Aq make-rules
+.It Aq make-lines
.It Ic \&.endfor
.El
.Pp
@@ -1929,7 +1939,7 @@ On each iteration of the loop, one word is taken and assigned to each
in order, and these
.Ic variables
are substituted into the
-.Ic make-rules
+.Ic make-lines
inside the body of the for loop.
The number of words must come out even; that is, if there are three
iteration variables, the number of words provided must be a multiple
diff --git a/make.c b/make.c
index 9472a045c26a..da2b8adf6efd 100644
--- a/make.c
+++ b/make.c
@@ -1,4 +1,4 @@
-/* $NetBSD: make.c,v 1.99 2020/07/03 08:13:23 rillig Exp $ */
+/* $NetBSD: make.c,v 1.133 2020/08/30 14:11:42 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: make.c,v 1.99 2020/07/03 08:13:23 rillig Exp $";
+static char rcsid[] = "$NetBSD: make.c,v 1.133 2020/08/30 14:11:42 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: make.c,v 1.99 2020/07/03 08:13:23 rillig Exp $");
+__RCSID("$NetBSD: make.c,v 1.133 2020/08/30 14:11:42 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -116,7 +116,7 @@ __RCSID("$NetBSD: make.c,v 1.99 2020/07/03 08:13:23 rillig Exp $");
*/
#include "make.h"
-#include "hash.h"
+#include "enum.h"
#include "dir.h"
#include "job.h"
@@ -151,6 +151,43 @@ make_abort(GNode *gn, int line)
abort();
}
+ENUM_VALUE_RTTI_8(GNodeMade,
+ UNMADE, DEFERRED, REQUESTED, BEINGMADE,
+ MADE, UPTODATE, ERROR, ABORTED);
+
+ENUM_FLAGS_RTTI_31(GNodeType,
+ OP_DEPENDS, OP_FORCE, OP_DOUBLEDEP,
+ /* OP_OPMASK is omitted since it combines other flags */
+ OP_OPTIONAL, OP_USE, OP_EXEC, OP_IGNORE,
+ OP_PRECIOUS, OP_SILENT, OP_MAKE, OP_JOIN,
+ OP_MADE, OP_SPECIAL, OP_USEBEFORE, OP_INVISIBLE,
+ OP_NOTMAIN, OP_PHONY, OP_NOPATH, OP_WAIT,
+ OP_NOMETA, OP_META, OP_NOMETA_CMP, OP_SUBMAKE,
+ OP_TRANSFORM, OP_MEMBER, OP_LIB, OP_ARCHV,
+ OP_HAS_COMMANDS, OP_SAVE_CMDS, OP_DEPS_FOUND, OP_MARK);
+
+ENUM_FLAGS_RTTI_10(GNodeFlags,
+ REMAKE, CHILDMADE, FORCE, DONE_WAIT,
+ DONE_ORDER, FROM_DEPEND, DONE_ALLSRC, CYCLE,
+ DONECYCLE, INTERNAL);
+
+void
+GNode_FprintDetails(FILE *f, const char *prefix, const GNode *gn,
+ const char *suffix)
+{
+ char type_buf[GNodeType_ToStringSize];
+ char flags_buf[GNodeFlags_ToStringSize];
+
+ fprintf(f, "%smade %s, type %s, flags %s%s",
+ prefix,
+ Enum_ValueToString(gn->made, GNodeMade_ToStringSpecs),
+ Enum_FlagsToString(type_buf, sizeof type_buf,
+ gn->type, GNodeType_ToStringSpecs),
+ Enum_FlagsToString(flags_buf, sizeof flags_buf,
+ gn->flags, GNodeFlags_ToStringSpecs),
+ suffix);
+}
+
/*-
*-----------------------------------------------------------------------
* Make_TimeStamp --
@@ -189,7 +226,7 @@ MakeTimeStamp(void *pgn, void *cgn)
{
return Make_TimeStamp((GNode *)pgn, (GNode *)cgn);
}
-
+
/*-
*-----------------------------------------------------------------------
* Make_OODate --
@@ -350,7 +387,7 @@ Make_OODate(GNode *gn)
return oodate;
}
-
+
/*-
*-----------------------------------------------------------------------
* MakeAddChild --
@@ -378,11 +415,11 @@ MakeAddChild(void *gnp, void *lp)
if (DEBUG(MAKE))
fprintf(debug_file, "MakeAddChild: need to examine %s%s\n",
gn->name, gn->cohort_num);
- (void)Lst_EnQueue(l, gn);
+ Lst_Enqueue(l, gn);
}
return 0;
}
-
+
/*-
*-----------------------------------------------------------------------
* MakeFindChild --
@@ -412,31 +449,18 @@ MakeFindChild(void *gnp, void *pgnp)
return 0;
}
-
-/*-
- *-----------------------------------------------------------------------
- * Make_HandleUse --
- * Function called by Make_Run and SuffApplyTransform on the downward
- * pass to handle .USE and transformation nodes. It implements the
- * .USE and transformation functionality by copying the node's commands,
- * type flags and children to the parent node.
+
+/* Called by Make_Run and SuffApplyTransform on the downward pass to handle
+ * .USE and transformation nodes, by copying the child node's commands, type
+ * flags and children to the parent node.
*
- * A .USE node is much like an explicit transformation rule, except
- * its commands are always added to the target node, even if the
- * target already has commands.
+ * A .USE node is much like an explicit transformation rule, except its
+ * commands are always added to the target node, even if the target already
+ * has commands.
*
* Input:
* cgn The .USE node
* pgn The target of the .USE node
- *
- * Results:
- * none
- *
- * Side Effects:
- * Children and commands may be added to the parent and the parent's
- * type may be changed.
- *
- *-----------------------------------------------------------------------
*/
void
Make_HandleUse(GNode *cgn, GNode *pgn)
@@ -452,52 +476,42 @@ Make_HandleUse(GNode *cgn, GNode *pgn)
if ((cgn->type & (OP_USE|OP_USEBEFORE)) || Lst_IsEmpty(pgn->commands)) {
if (cgn->type & OP_USEBEFORE) {
- /*
- * .USEBEFORE --
- * prepend the child's commands to the parent.
- */
- Lst cmds = pgn->commands;
- pgn->commands = Lst_Duplicate(cgn->commands, NULL);
- (void)Lst_Concat(pgn->commands, cmds, LST_CONCNEW);
- Lst_Destroy(cmds, NULL);
+ /* .USEBEFORE */
+ Lst_PrependAll(pgn->commands, cgn->commands);
} else {
- /*
- * .USE or target has no commands --
- * append the child's commands to the parent.
- */
- (void)Lst_Concat(pgn->commands, cgn->commands, LST_CONCNEW);
+ /* .USE, or target has no commands */
+ Lst_AppendAll(pgn->commands, cgn->commands);
}
}
- if (Lst_Open(cgn->children) == SUCCESS) {
- while ((ln = Lst_Next(cgn->children)) != NULL) {
- GNode *tgn, *gn = (GNode *)Lst_Datum(ln);
+ Lst_Open(cgn->children);
+ while ((ln = Lst_Next(cgn->children)) != NULL) {
+ GNode *gn = LstNode_Datum(ln);
- /*
- * Expand variables in the .USE node's name
- * and save the unexpanded form.
- * We don't need to do this for commands.
- * They get expanded properly when we execute.
- */
- if (gn->uname == NULL) {
- gn->uname = gn->name;
- } else {
- free(gn->name);
- }
- gn->name = Var_Subst(NULL, gn->uname, pgn, VARF_WANTRES);
- if (gn->name && gn->uname && strcmp(gn->name, gn->uname) != 0) {
- /* See if we have a target for this node. */
- tgn = Targ_FindNode(gn->name, TARG_NOCREATE);
- if (tgn != NULL)
- gn = tgn;
- }
-
- (void)Lst_AtEnd(pgn->children, gn);
- (void)Lst_AtEnd(gn->parents, pgn);
- pgn->unmade += 1;
+ /*
+ * Expand variables in the .USE node's name
+ * and save the unexpanded form.
+ * We don't need to do this for commands.
+ * They get expanded properly when we execute.
+ */
+ if (gn->uname == NULL) {
+ gn->uname = gn->name;
+ } else {
+ free(gn->name);
}
- Lst_Close(cgn->children);
+ gn->name = Var_Subst(gn->uname, pgn, VARE_WANTRES);
+ if (gn->uname && strcmp(gn->name, gn->uname) != 0) {
+ /* See if we have a target for this node. */
+ GNode *tgn = Targ_FindNode(gn->name, TARG_NOCREATE);
+ if (tgn != NULL)
+ gn = tgn;
+ }
+
+ Lst_Append(pgn->children, gn);
+ Lst_Append(gn->parents, pgn);
+ pgn->unmade += 1;
}
+ Lst_Close(cgn->children);
pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_USEBEFORE|OP_TRANSFORM);
}
@@ -547,7 +561,7 @@ MakeHandleUse(void *cgnp, void *pgnp)
* children the parent has. This is used by Make_Run to decide
* whether to queue the parent or examine its children...
*/
- if ((ln = Lst_Member(pgn->children, cgn)) != NULL) {
+ if ((ln = Lst_FindDatum(pgn->children, cgn)) != NULL) {
Lst_Remove(pgn->children, ln);
pgn->unmade--;
}
@@ -680,8 +694,8 @@ void
Make_Update(GNode *cgn)
{
GNode *pgn; /* the parent node */
- char *cname; /* the child's name */
- LstNode ln; /* Element in parents and iParents lists */
+ const char *cname; /* the child's name */
+ LstNode ln; /* Element in parents and implicitParents lists */
time_t mtime = -1;
char *p1;
Lst parents;
@@ -691,7 +705,7 @@ Make_Update(GNode *cgn)
checked++;
cname = Var_Value(TARGET, cgn, &p1);
- free(p1);
+ bmake_free(p1);
if (DEBUG(MAKE))
fprintf(debug_file, "Make_Update: %s%s\n", cgn->name, cgn->cohort_num);
@@ -724,123 +738,123 @@ Make_Update(GNode *cgn)
Lst_ForEach(centurion->order_succ, MakeBuildParent, Lst_First(toBeMade));
/* Now mark all the parents as having one less unmade child */
- if (Lst_Open(parents) == SUCCESS) {
- while ((ln = Lst_Next(parents)) != NULL) {
- pgn = (GNode *)Lst_Datum(ln);
- if (DEBUG(MAKE))
- fprintf(debug_file, "inspect parent %s%s: flags %x, "
- "type %x, made %d, unmade %d ",
- pgn->name, pgn->cohort_num, pgn->flags,
- pgn->type, pgn->made, pgn->unmade-1);
-
- if (!(pgn->flags & REMAKE)) {
- /* This parent isn't needed */
- if (DEBUG(MAKE))
- fprintf(debug_file, "- not needed\n");
- continue;
- }
- if (mtime == 0 && !(cgn->type & OP_WAIT))
- pgn->flags |= FORCE;
+ Lst_Open(parents);
+ while ((ln = Lst_Next(parents)) != NULL) {
+ pgn = LstNode_Datum(ln);
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "inspect parent %s%s: flags %x, "
+ "type %x, made %d, unmade %d ",
+ pgn->name, pgn->cohort_num, pgn->flags,
+ pgn->type, pgn->made, pgn->unmade-1);
- /*
- * If the parent has the .MADE attribute, its timestamp got
- * updated to that of its newest child, and its unmake
- * child count got set to zero in Make_ExpandUse().
- * However other things might cause us to build one of its
- * children - and so we mustn't do any processing here when
- * the child build finishes.
- */
- if (pgn->type & OP_MADE) {
- if (DEBUG(MAKE))
- fprintf(debug_file, "- .MADE\n");
- continue;
- }
+ if (!(pgn->flags & REMAKE)) {
+ /* This parent isn't needed */
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "- not needed\n");
+ continue;
+ }
+ if (mtime == 0 && !(cgn->type & OP_WAIT))
+ pgn->flags |= FORCE;
- if ( ! (cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE))) {
- if (cgn->made == MADE)
- pgn->flags |= CHILDMADE;
- (void)Make_TimeStamp(pgn, cgn);
- }
+ /*
+ * If the parent has the .MADE attribute, its timestamp got
+ * updated to that of its newest child, and its unmake
+ * child count got set to zero in Make_ExpandUse().
+ * However other things might cause us to build one of its
+ * children - and so we mustn't do any processing here when
+ * the child build finishes.
+ */
+ if (pgn->type & OP_MADE) {
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "- .MADE\n");
+ continue;
+ }
- /*
- * A parent must wait for the completion of all instances
- * of a `::' dependency.
- */
- if (centurion->unmade_cohorts != 0 || centurion->made < MADE) {
- if (DEBUG(MAKE))
- fprintf(debug_file,
- "- centurion made %d, %d unmade cohorts\n",
- centurion->made, centurion->unmade_cohorts);
- continue;
- }
+ if ( ! (cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE))) {
+ if (cgn->made == MADE)
+ pgn->flags |= CHILDMADE;
+ (void)Make_TimeStamp(pgn, cgn);
+ }
- /* One more child of this parent is now made */
- pgn->unmade -= 1;
- if (pgn->unmade < 0) {
- if (DEBUG(MAKE)) {
- fprintf(debug_file, "Graph cycles through %s%s\n",
- pgn->name, pgn->cohort_num);
- Targ_PrintGraph(2);
- }
- Error("Graph cycles through %s%s", pgn->name, pgn->cohort_num);
- }
+ /*
+ * A parent must wait for the completion of all instances
+ * of a `::' dependency.
+ */
+ if (centurion->unmade_cohorts != 0 || centurion->made < MADE) {
+ if (DEBUG(MAKE))
+ fprintf(debug_file,
+ "- centurion made %d, %d unmade cohorts\n",
+ centurion->made, centurion->unmade_cohorts);
+ continue;
+ }
- /* We must always rescan the parents of .WAIT and .ORDER nodes. */
- if (pgn->unmade != 0 && !(centurion->type & OP_WAIT)
- && !(centurion->flags & DONE_ORDER)) {
- if (DEBUG(MAKE))
- fprintf(debug_file, "- unmade children\n");
- continue;
- }
- if (pgn->made != DEFERRED) {
- /*
- * Either this parent is on a different branch of the tree,
- * or it on the RHS of a .WAIT directive
- * or it is already on the toBeMade list.
- */
- if (DEBUG(MAKE))
- fprintf(debug_file, "- not deferred\n");
- continue;
- }
- if (pgn->order_pred
- && Lst_ForEach(pgn->order_pred, MakeCheckOrder, 0)) {
- /* A .ORDER rule stops us building this */
- continue;
- }
+ /* One more child of this parent is now made */
+ pgn->unmade -= 1;
+ if (pgn->unmade < 0) {
if (DEBUG(MAKE)) {
- static int two = 2;
- fprintf(debug_file, "- %s%s made, schedule %s%s (made %d)\n",
- cgn->name, cgn->cohort_num,
- pgn->name, pgn->cohort_num, pgn->made);
- Targ_PrintNode(pgn, &two);
+ fprintf(debug_file, "Graph cycles through %s%s\n",
+ pgn->name, pgn->cohort_num);
+ Targ_PrintGraph(2);
}
- /* Ok, we can schedule the parent again */
- pgn->made = REQUESTED;
- (void)Lst_EnQueue(toBeMade, pgn);
+ Error("Graph cycles through %s%s", pgn->name, pgn->cohort_num);
+ }
+
+ /* We must always rescan the parents of .WAIT and .ORDER nodes. */
+ if (pgn->unmade != 0 && !(centurion->type & OP_WAIT)
+ && !(centurion->flags & DONE_ORDER)) {
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "- unmade children\n");
+ continue;
+ }
+ if (pgn->made != DEFERRED) {
+ /*
+ * Either this parent is on a different branch of the tree,
+ * or it on the RHS of a .WAIT directive
+ * or it is already on the toBeMade list.
+ */
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "- not deferred\n");
+ continue;
}
- Lst_Close(parents);
+ assert(pgn->order_pred != NULL);
+ if (Lst_ForEach(pgn->order_pred, MakeCheckOrder, 0)) {
+ /* A .ORDER rule stops us building this */
+ continue;
+ }
+ if (DEBUG(MAKE)) {
+ static int two = 2;
+ fprintf(debug_file, "- %s%s made, schedule %s%s (made %d)\n",
+ cgn->name, cgn->cohort_num,
+ pgn->name, pgn->cohort_num, pgn->made);
+ Targ_PrintNode(pgn, &two);
+ }
+ /* Ok, we can schedule the parent again */
+ pgn->made = REQUESTED;
+ Lst_Enqueue(toBeMade, pgn);
}
+ Lst_Close(parents);
/*
* Set the .PREFIX and .IMPSRC variables for all the implied parents
* of this node.
*/
- if (Lst_Open(cgn->iParents) == SUCCESS) {
- char *cpref = Var_Value(PREFIX, cgn, &p1);
+ Lst_Open(cgn->implicitParents);
+ {
+ const char *cpref = Var_Value(PREFIX, cgn, &p1);
- while ((ln = Lst_Next(cgn->iParents)) != NULL) {
- pgn = (GNode *)Lst_Datum(ln);
+ while ((ln = Lst_Next(cgn->implicitParents)) != NULL) {
+ pgn = LstNode_Datum(ln);
if (pgn->flags & REMAKE) {
Var_Set(IMPSRC, cname, pgn);
if (cpref != NULL)
Var_Set(PREFIX, cpref, pgn);
}
}
- free(p1);
- Lst_Close(cgn->iParents);
+ bmake_free(p1);
+ Lst_Close(cgn->implicitParents);
}
}
-
+
/*-
*-----------------------------------------------------------------------
* MakeAddAllSrc --
@@ -890,7 +904,7 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
cgn->type |= OP_MARK;
if ((cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE|OP_INVISIBLE)) == 0) {
- char *child, *allsrc;
+ const char *child, *allsrc;
char *p1 = NULL, *p2 = NULL;
if (cgn->type & OP_ARCHV)
@@ -904,7 +918,7 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
}
if (allsrc != NULL)
Var_Append(ALLSRC, allsrc, pgn);
- free(p2);
+ bmake_free(p2);
if (pgn->type & OP_JOIN) {
if (cgn->made == MADE) {
Var_Append(OODATE, child, pgn);
@@ -930,11 +944,11 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
*/
Var_Append(OODATE, child, pgn);
}
- free(p1);
+ bmake_free(p1);
}
return 0;
}
-
+
/*-
*-----------------------------------------------------------------------
* Make_DoAllVar --
@@ -976,11 +990,11 @@ Make_DoAllVar(GNode *gn)
if (gn->type & OP_JOIN) {
char *p1;
Var_Set(TARGET, Var_Value(ALLSRC, gn, &p1), gn);
- free(p1);
+ bmake_free(p1);
}
gn->flags |= DONE_ALLSRC;
}
-
+
/*-
*-----------------------------------------------------------------------
* MakeStartJobs --
@@ -1023,7 +1037,8 @@ MakeBuildChild(void *v_cn, void *toBeMade_next)
return 0;
/* If this node is on the RHS of a .ORDER, check LHSs. */
- if (cn->order_pred && Lst_ForEach(cn->order_pred, MakeCheckOrder, 0)) {
+ assert(cn->order_pred);
+ if (Lst_ForEach(cn->order_pred, MakeCheckOrder, 0)) {
/* Can't build this (or anything else in this child list) yet */
cn->made = DEFERRED;
return 0; /* but keep looking */
@@ -1035,7 +1050,7 @@ MakeBuildChild(void *v_cn, void *toBeMade_next)
cn->made = REQUESTED;
if (toBeMade_next == NULL)
- Lst_AtEnd(toBeMade, cn);
+ Lst_Append(toBeMade, cn);
else
Lst_InsertBefore(toBeMade, toBeMade_next, cn);
@@ -1072,13 +1087,13 @@ MakeStartJobs(void)
GNode *gn;
int have_token = 0;
- while (!Lst_IsEmpty (toBeMade)) {
+ while (!Lst_IsEmpty(toBeMade)) {
/* Get token now to avoid cycling job-list when we only have 1 token */
if (!have_token && !Job_TokenWithdraw())
break;
have_token = 1;
- gn = (GNode *)Lst_DeQueue(toBeMade);
+ gn = Lst_Dequeue(toBeMade);
if (DEBUG(MAKE))
fprintf(debug_file, "Examining %s%s...\n",
gn->name, gn->cohort_num);
@@ -1147,7 +1162,7 @@ MakeStartJobs(void)
return FALSE;
}
-
+
/*-
*-----------------------------------------------------------------------
* MakePrintStatus --
@@ -1179,15 +1194,15 @@ MakePrintStatusOrder(void *ognp, void *gnp)
/* not waiting for this one */
return 0;
- printf(" `%s%s' has .ORDER dependency against %s%s "
- "(made %d, flags %x, type %x)\n",
- gn->name, gn->cohort_num,
- ogn->name, ogn->cohort_num, ogn->made, ogn->flags, ogn->type);
- if (DEBUG(MAKE) && debug_file != stdout)
- fprintf(debug_file, " `%s%s' has .ORDER dependency against %s%s "
- "(made %d, flags %x, type %x)\n",
- gn->name, gn->cohort_num,
- ogn->name, ogn->cohort_num, ogn->made, ogn->flags, ogn->type);
+ printf(" `%s%s' has .ORDER dependency against %s%s ",
+ gn->name, gn->cohort_num, ogn->name, ogn->cohort_num);
+ GNode_FprintDetails(stdout, "(", ogn, ")\n");
+
+ if (DEBUG(MAKE) && debug_file != stdout) {
+ fprintf(debug_file, " `%s%s' has .ORDER dependency against %s%s ",
+ gn->name, gn->cohort_num, ogn->name, ogn->cohort_num);
+ GNode_FprintDetails(debug_file, "(", ogn, ")\n");
+ }
return 0;
}
@@ -1214,12 +1229,13 @@ MakePrintStatus(void *gnp, void *v_errors)
case REQUESTED:
case BEINGMADE:
(*errors)++;
- printf("`%s%s' was not built (made %d, flags %x, type %x)!\n",
- gn->name, gn->cohort_num, gn->made, gn->flags, gn->type);
- if (DEBUG(MAKE) && debug_file != stdout)
- fprintf(debug_file,
- "`%s%s' was not built (made %d, flags %x, type %x)!\n",
- gn->name, gn->cohort_num, gn->made, gn->flags, gn->type);
+ printf("`%s%s' was not built", gn->name, gn->cohort_num);
+ GNode_FprintDetails(stdout, " (", gn, ")!\n");
+ if (DEBUG(MAKE) && debug_file != stdout) {
+ fprintf(debug_file, "`%s%s' was not built",
+ gn->name, gn->cohort_num);
+ GNode_FprintDetails(debug_file, " (", gn, ")!\n");
+ }
/* Most likely problem is actually caused by .ORDER */
Lst_ForEach(gn->order_pred, MakePrintStatusOrder, gn);
break;
@@ -1262,7 +1278,7 @@ MakePrintStatus(void *gnp, void *v_errors)
Lst_ForEach(gn->children, MakePrintStatus, errors);
return 0;
}
-
+
/*-
*-----------------------------------------------------------------------
@@ -1281,7 +1297,7 @@ Make_ExpandUse(Lst targs)
GNode *gn; /* a temporary pointer */
Lst examine; /* List of targets to examine */
- examine = Lst_Duplicate(targs, NULL);
+ examine = Lst_Copy(targs, NULL);
/*
* Make an initial downward pass over the graph, marking nodes to be made
@@ -1291,8 +1307,8 @@ Make_ExpandUse(Lst targs)
* be looked at in a minute, otherwise we add its children to our queue
* and go on about our business.
*/
- while (!Lst_IsEmpty (examine)) {
- gn = (GNode *)Lst_DeQueue(examine);
+ while (!Lst_IsEmpty(examine)) {
+ gn = Lst_Dequeue(examine);
if (gn->flags & REMAKE)
/* We've looked at this one already */
@@ -1302,13 +1318,8 @@ Make_ExpandUse(Lst targs)
fprintf(debug_file, "Make_ExpandUse: examine %s%s\n",
gn->name, gn->cohort_num);
- if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) {
- /* Append all the 'cohorts' to the list of things to examine */
- Lst new;
- new = Lst_Duplicate(gn->cohorts, NULL);
- Lst_Concat(new, examine, LST_CONCLINK);
- examine = new;
- }
+ if (gn->type & OP_DOUBLEDEP)
+ Lst_PrependAll(examine, gn->cohorts);
/*
* Apply any .USE rules before looking for implicit dependencies
@@ -1349,7 +1360,7 @@ Make_ExpandUse(Lst targs)
Lst_ForEach(gn->children, MakeAddChild, examine);
}
- Lst_Destroy(examine, NULL);
+ Lst_Free(examine);
}
/*-
@@ -1369,8 +1380,8 @@ link_parent(void *cnp, void *pnp)
GNode *cn = cnp;
GNode *pn = pnp;
- Lst_AtEnd(pn->children, cn);
- Lst_AtEnd(cn->parents, pn);
+ Lst_Append(pn->children, cn);
+ Lst_Append(cn->parents, pn);
pn->unmade++;
return 0;
}
@@ -1392,9 +1403,9 @@ add_wait_dep(void *v_cn, void *v_wn)
fprintf(debug_file, ".WAIT: add dependency %s%s -> %s\n",
cn->name, cn->cohort_num, wn->name);
- Lst_AtEnd(wn->children, cn);
+ Lst_Append(wn->children, cn);
wn->unmade++;
- Lst_AtEnd(cn->parents, wn);
+ Lst_Append(cn->parents, wn);
return 0;
}
@@ -1417,18 +1428,18 @@ Make_ProcessWait(Lst targs)
pgn->flags = REMAKE;
pgn->type = OP_PHONY | OP_DEPENDS;
/* Get it displayed in the diag dumps */
- Lst_AtFront(Targ_List(), pgn);
+ Lst_Prepend(Targ_List(), pgn);
Lst_ForEach(targs, link_parent, pgn);
/* Start building with the 'dummy' .MAIN' node */
MakeBuildChild(pgn, NULL);
- examine = Lst_Init(FALSE);
- Lst_AtEnd(examine, pgn);
+ examine = Lst_Init();
+ Lst_Append(examine, pgn);
- while (!Lst_IsEmpty (examine)) {
- pgn = Lst_DeQueue(examine);
+ while (!Lst_IsEmpty(examine)) {
+ pgn = Lst_Dequeue(examine);
/* We only want to process each child-list once */
if (pgn->flags & DONE_WAIT)
@@ -1437,30 +1448,25 @@ Make_ProcessWait(Lst targs)
if (DEBUG(MAKE))
fprintf(debug_file, "Make_ProcessWait: examine %s\n", pgn->name);
- if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (pgn->cohorts)) {
- /* Append all the 'cohorts' to the list of things to examine */
- Lst new;
- new = Lst_Duplicate(pgn->cohorts, NULL);
- Lst_Concat(new, examine, LST_CONCLINK);
- examine = new;
- }
+ if (pgn->type & OP_DOUBLEDEP)
+ Lst_PrependAll(examine, pgn->cohorts);
owln = Lst_First(pgn->children);
Lst_Open(pgn->children);
for (; (ln = Lst_Next(pgn->children)) != NULL; ) {
- cgn = Lst_Datum(ln);
+ cgn = LstNode_Datum(ln);
if (cgn->type & OP_WAIT) {
/* Make the .WAIT node depend on the previous children */
Lst_ForEachFrom(pgn->children, owln, add_wait_dep, cgn);
owln = ln;
} else {
- Lst_AtEnd(examine, cgn);
+ Lst_Append(examine, cgn);
}
}
Lst_Close(pgn->children);
}
- Lst_Destroy(examine, NULL);
+ Lst_Free(examine);
}
/*-
@@ -1493,7 +1499,7 @@ Make_Run(Lst targs)
int errors; /* Number of errors the Job module reports */
/* Start trying to make the current targets... */
- toBeMade = Lst_Init(FALSE);
+ toBeMade = Lst_Init();
Make_ExpandUse(targs);
Make_ProcessWait(targs);
diff --git a/make.h b/make.h
index eafa761ea36a..520a6602518f 100644
--- a/make.h
+++ b/make.h
@@ -1,4 +1,4 @@
-/* $NetBSD: make.h,v 1.109 2020/07/02 15:14:38 rillig Exp $ */
+/* $NetBSD: make.h,v 1.137 2020/09/02 23:42:58 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -77,8 +77,8 @@
* The global definitions for pmake
*/
-#ifndef _MAKE_H_
-#define _MAKE_H_
+#ifndef MAKE_MAKE_H
+#define MAKE_MAKE_H
#ifdef HAVE_CONFIG_H
# include "config.h"
@@ -86,7 +86,9 @@
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/stat.h>
+#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
@@ -132,8 +134,34 @@
#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) /* delete */
#endif
-#include "sprite.h"
+/*
+ * A boolean type is defined as an integer, not an enum, for historic reasons.
+ * The only allowed values are the constants TRUE and FALSE (1 and 0).
+ */
+
+#ifdef USE_DOUBLE_BOOLEAN
+/* During development, to find type mismatches in function declarations. */
+typedef double Boolean;
+#elif defined(USE_UCHAR_BOOLEAN)
+/* During development, to find code that depends on the exact value of TRUE or
+ * that stores other values in Boolean variables. */
+typedef unsigned char Boolean;
+#define TRUE ((unsigned char)0xFF)
+#define FALSE ((unsigned char)0x00)
+#elif defined(USE_ENUM_BOOLEAN)
+typedef enum { FALSE, TRUE} Boolean;
+#else
+typedef int Boolean;
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif /* TRUE */
+#ifndef FALSE
+#define FALSE 0
+#endif /* FALSE */
+
#include "lst.h"
+#include "enum.h"
#include "hash.h"
#include "make-conf.h"
#include "buf.h"
@@ -150,164 +178,191 @@
#define POSIX_SIGNALS
#endif
-/*-
- * The structure for an individual graph node. Each node has several
- * pieces of data associated with it.
- * 1) the name of the target it describes
- * 2) the location of the target file in the file system.
- * 3) the type of operator used to define its sources (qv. parse.c)
- * 4) whether it is involved in this invocation of make
- * 5) whether the target has been remade
- * 6) whether any of its children has been remade
- * 7) the number of its children that are, as yet, unmade
- * 8) its modification time
- * 9) the modification time of its youngest child (qv. make.c)
- * 10) a list of nodes for which this is a source (parents)
- * 11) a list of nodes on which this depends (children)
- * 12) a list of nodes that depend on this, as gleaned from the
- * transformation rules (iParents)
- * 13) a list of ancestor nodes, which includes parents, iParents,
- * and recursive parents of parents
- * 14) a list of nodes of the same name created by the :: operator
- * 15) a list of nodes that must be made (if they're made) before
- * this node can be, but that do not enter into the datedness of
- * this node.
- * 16) a list of nodes that must be made (if they're made) before
- * this node or any child of this node can be, but that do not
- * enter into the datedness of this node.
- * 17) a list of nodes that must be made (if they're made) after
- * this node is, but that do not depend on this node, in the
- * normal sense.
- * 18) a Lst of ``local'' variables that are specific to this target
- * and this target only (qv. var.c [$@ $< $?, etc.])
- * 19) a Lst of strings that are commands to be given to a shell
- * to create this target.
- */
+typedef enum {
+ UNMADE, /* Not examined yet */
+ DEFERRED, /* Examined once (building child) */
+ REQUESTED, /* on toBeMade list */
+ BEINGMADE, /* Target is already being made.
+ * Indicates a cycle in the graph. */
+ MADE, /* Was out-of-date and has been made */
+ UPTODATE, /* Was already up-to-date */
+ ERROR, /* An error occurred while it was being
+ * made (used only in compat mode) */
+ ABORTED /* The target was aborted due to an error
+ * making an inferior (compat). */
+} GNodeMade;
+
+/* The OP_ constants are used when parsing a dependency line as a way of
+ * communicating to other parts of the program the way in which a target
+ * should be made.
+ *
+ * These constants are bitwise-OR'ed together and placed in the 'type' field
+ * of each node. Any node that has a 'type' field which satisfies the OP_NOP
+ * function was never never on the left-hand side of an operator, though it
+ * may have been on the right-hand side... */
+typedef enum {
+ /* Execution of commands depends on children (:) */
+ OP_DEPENDS = 1 << 0,
+ /* Always execute commands (!) */
+ OP_FORCE = 1 << 1,
+ /* Execution of commands depends on children per line (::) */
+ OP_DOUBLEDEP = 1 << 2,
+
+ OP_OPMASK = OP_DEPENDS|OP_FORCE|OP_DOUBLEDEP,
+
+ /* Don't care if the target doesn't exist and can't be created */
+ OP_OPTIONAL = 1 << 3,
+ /* Use associated commands for parents */
+ OP_USE = 1 << 4,
+ /* Target is never out of date, but always execute commands anyway.
+ * Its time doesn't matter, so it has none...sort of */
+ OP_EXEC = 1 << 5,
+ /* Ignore errors when creating the node */
+ OP_IGNORE = 1 << 6,
+ /* Don't remove the target when interrupted */
+ OP_PRECIOUS = 1 << 7,
+ /* Don't echo commands when executed */
+ OP_SILENT = 1 << 8,
+ /* Target is a recursive make so its commands should always be executed
+ * when it is out of date, regardless of the state of the -n or -t flags */
+ OP_MAKE = 1 << 9,
+ /* Target is out-of-date only if any of its children was out-of-date */
+ OP_JOIN = 1 << 10,
+ /* Assume the children of the node have been already made */
+ OP_MADE = 1 << 11,
+ /* Special .BEGIN, .END, .INTERRUPT */
+ OP_SPECIAL = 1 << 12,
+ /* Like .USE, only prepend commands */
+ OP_USEBEFORE = 1 << 13,
+ /* The node is invisible to its parents. I.e. it doesn't show up in the
+ * parents' local variables. */
+ OP_INVISIBLE = 1 << 14,
+ /* The node is exempt from normal 'main target' processing in parse.c */
+ OP_NOTMAIN = 1 << 15,
+ /* Not a file target; run always */
+ OP_PHONY = 1 << 16,
+ /* Don't search for file in the path */
+ OP_NOPATH = 1 << 17,
+ /* .WAIT phony node */
+ OP_WAIT = 1 << 18,
+ /* .NOMETA do not create a .meta file */
+ OP_NOMETA = 1 << 19,
+ /* .META we _do_ want a .meta file */
+ OP_META = 1 << 20,
+ /* Do not compare commands in .meta file */
+ OP_NOMETA_CMP = 1 << 21,
+ /* Possibly a submake node */
+ OP_SUBMAKE = 1 << 22,
+
+ /* Attributes applied by PMake */
+
+ /* The node is a transformation rule */
+ OP_TRANSFORM = 1 << 31,
+ /* Target is a member of an archive */
+ OP_MEMBER = 1 << 30,
+ /* Target is a library */
+ OP_LIB = 1 << 29,
+ /* Target is an archive construct */
+ OP_ARCHV = 1 << 28,
+ /* Target has all the commands it should. Used when parsing to catch
+ * multiple commands for a target. */
+ OP_HAS_COMMANDS = 1 << 27,
+ /* Saving commands on .END (Compat) */
+ OP_SAVE_CMDS = 1 << 26,
+ /* Already processed by Suff_FindDeps */
+ OP_DEPS_FOUND = 1 << 25,
+ /* Node found while expanding .ALLSRC */
+ OP_MARK = 1 << 24
+} GNodeType;
+
+typedef enum {
+ REMAKE = 0x0001, /* this target needs to be (re)made */
+ CHILDMADE = 0x0002, /* children of this target were made */
+ FORCE = 0x0004, /* children don't exist, and we pretend made */
+ DONE_WAIT = 0x0008, /* Set by Make_ProcessWait() */
+ DONE_ORDER = 0x0010, /* Build requested by .ORDER processing */
+ FROM_DEPEND = 0x0020, /* Node created from .depend */
+ DONE_ALLSRC = 0x0040, /* We do it once only */
+ CYCLE = 0x1000, /* Used by MakePrintStatus */
+ DONECYCLE = 0x2000, /* Used by MakePrintStatus */
+ INTERNAL = 0x4000 /* Internal use only */
+} GNodeFlags;
+
+/* A graph node represents a target that can possibly be made, including its
+ * relation to other targets and a lot of other details. */
typedef struct GNode {
- char *name; /* The target's name */
- char *uname; /* The unexpanded name of a .USE node */
- char *path; /* The full pathname of the file */
- int type; /* Its type (see the OP flags, below) */
-
- int flags;
-#define REMAKE 0x1 /* this target needs to be (re)made */
-#define CHILDMADE 0x2 /* children of this target were made */
-#define FORCE 0x4 /* children don't exist, and we pretend made */
-#define DONE_WAIT 0x8 /* Set by Make_ProcessWait() */
-#define DONE_ORDER 0x10 /* Build requested by .ORDER processing */
-#define FROM_DEPEND 0x20 /* Node created from .depend */
-#define DONE_ALLSRC 0x40 /* We do it once only */
-#define CYCLE 0x1000 /* Used by MakePrintStatus */
-#define DONECYCLE 0x2000 /* Used by MakePrintStatus */
-#define INTERNAL 0x4000 /* Internal use only */
- enum enum_made {
- UNMADE, DEFERRED, REQUESTED, BEINGMADE,
- MADE, UPTODATE, ERROR, ABORTED
- } made; /* Set to reflect the state of processing
- * on this node:
- * UNMADE - Not examined yet
- * DEFERRED - Examined once (building child)
- * REQUESTED - on toBeMade list
- * BEINGMADE - Target is already being made.
- * Indicates a cycle in the graph.
- * MADE - Was out-of-date and has been made
- * UPTODATE - Was already up-to-date
- * ERROR - An error occurred while it was being
- * made (used only in compat mode)
- * ABORTED - The target was aborted due to
- * an error making an inferior (compat).
- */
- int unmade; /* The number of unmade children */
-
- time_t mtime; /* Its modification time */
- struct GNode *cmgn; /* The youngest child */
-
- Lst iParents; /* Links to parents for which this is an
- * implied source, if any */
- Lst cohorts; /* Other nodes for the :: operator */
- Lst parents; /* Nodes that depend on this one */
- Lst children; /* Nodes on which this one depends */
- Lst order_pred; /* .ORDER nodes we need made */
- Lst order_succ; /* .ORDER nodes who need us */
-
- char cohort_num[8]; /* #n for this cohort */
- int unmade_cohorts;/* # of unmade instances on the
- cohorts list */
- struct GNode *centurion; /* Pointer to the first instance of a ::
- node; only set when on a cohorts list */
- unsigned int checked; /* Last time we tried to makle this node */
-
- Hash_Table context; /* The local variables */
- Lst commands; /* Creation commands */
-
- struct _Suff *suffix; /* Suffix for the node (determined by
- * Suff_FindDeps and opaque to everyone
- * but the Suff module) */
- const char *fname; /* filename where the GNode got defined */
- int lineno; /* line number where the GNode got defined */
+ /* The target's name, such as "clean" or "make.c" */
+ char *name;
+ /* The unexpanded name of a .USE node */
+ char *uname;
+ /* The full pathname of the file belonging to the target.
+ * XXX: What about .PHONY targets? These don't have an associated path. */
+ char *path;
+
+ /* The type of operator used to define the sources (see the OP flags below).
+ * XXX: This looks like a wild mixture of type and flags. */
+ GNodeType type;
+ /* whether it is involved in this invocation of make */
+ GNodeFlags flags;
+
+ /* The state of processing on this node */
+ GNodeMade made;
+ int unmade; /* The number of unmade children */
+
+ time_t mtime; /* Its modification time */
+ struct GNode *cmgn; /* The youngest child */
+
+ /* The GNodes for which this node is an implied source. May be empty.
+ * For example, when there is an inference rule for .c.o, the node for
+ * file.c has the node for file.o in this list. */
+ Lst implicitParents;
+
+ /* Other nodes of the same name for the :: operator. */
+ Lst cohorts;
+
+ /* The nodes that depend on this one, or in other words, the nodes for
+ * which this is a source. */
+ Lst parents;
+ /* The nodes on which this one depends. */
+ Lst children;
+
+ /* .ORDER nodes we need made. The nodes that must be made (if they're
+ * made) before this node can be made, but that do not enter into the
+ * datedness of this node. */
+ Lst order_pred;
+ /* .ORDER nodes who need us. The nodes that must be made (if they're made
+ * at all) after this node is made, but that do not depend on this node,
+ * in the normal sense. */
+ Lst order_succ;
+
+ /* #n for this cohort */
+ char cohort_num[8];
+ /* The number of unmade instances on the cohorts list */
+ int unmade_cohorts;
+ /* Pointer to the first instance of a '::' node; only set when on a
+ * cohorts list */
+ struct GNode *centurion;
+
+ /* Last time (sequence number) we tried to make this node */
+ unsigned int checked;
+
+ /* The "local" variables that are specific to this target and this target
+ * only, such as $@, $<, $?. */
+ Hash_Table context;
+
+ /* The commands to be given to a shell to create this target. */
+ Lst commands;
+
+ /* Suffix for the node (determined by Suff_FindDeps and opaque to everyone
+ * but the Suff module) */
+ struct Suff *suffix;
+
+ /* filename where the GNode got defined */
+ const char *fname;
+ /* line number where the GNode got defined */
+ int lineno;
} GNode;
-/*
- * The OP_ constants are used when parsing a dependency line as a way of
- * communicating to other parts of the program the way in which a target
- * should be made. These constants are bitwise-OR'ed together and
- * placed in the 'type' field of each node. Any node that has
- * a 'type' field which satisfies the OP_NOP function was never never on
- * the lefthand side of an operator, though it may have been on the
- * righthand side...
- */
-#define OP_DEPENDS 0x00000001 /* Execution of commands depends on
- * kids (:) */
-#define OP_FORCE 0x00000002 /* Always execute commands (!) */
-#define OP_DOUBLEDEP 0x00000004 /* Execution of commands depends on kids
- * per line (::) */
-#define OP_OPMASK (OP_DEPENDS|OP_FORCE|OP_DOUBLEDEP)
-
-#define OP_OPTIONAL 0x00000008 /* Don't care if the target doesn't
- * exist and can't be created */
-#define OP_USE 0x00000010 /* Use associated commands for parents */
-#define OP_EXEC 0x00000020 /* Target is never out of date, but always
- * execute commands anyway. Its time
- * doesn't matter, so it has none...sort
- * of */
-#define OP_IGNORE 0x00000040 /* Ignore errors when creating the node */
-#define OP_PRECIOUS 0x00000080 /* Don't remove the target when
- * interrupted */
-#define OP_SILENT 0x00000100 /* Don't echo commands when executed */
-#define OP_MAKE 0x00000200 /* Target is a recursive make so its
- * commands should always be executed when
- * it is out of date, regardless of the
- * state of the -n or -t flags */
-#define OP_JOIN 0x00000400 /* Target is out-of-date only if any of its
- * children was out-of-date */
-#define OP_MADE 0x00000800 /* Assume the children of the node have
- * been already made */
-#define OP_SPECIAL 0x00001000 /* Special .BEGIN, .END, .INTERRUPT */
-#define OP_USEBEFORE 0x00002000 /* Like .USE, only prepend commands */
-#define OP_INVISIBLE 0x00004000 /* The node is invisible to its parents.
- * I.e. it doesn't show up in the parents's
- * local variables. */
-#define OP_NOTMAIN 0x00008000 /* The node is exempt from normal 'main
- * target' processing in parse.c */
-#define OP_PHONY 0x00010000 /* Not a file target; run always */
-#define OP_NOPATH 0x00020000 /* Don't search for file in the path */
-#define OP_WAIT 0x00040000 /* .WAIT phony node */
-#define OP_NOMETA 0x00080000 /* .NOMETA do not create a .meta file */
-#define OP_META 0x00100000 /* .META we _do_ want a .meta file */
-#define OP_NOMETA_CMP 0x00200000 /* Do not compare commands in .meta file */
-#define OP_SUBMAKE 0x00400000 /* Possibly a submake node */
-/* Attributes applied by PMake */
-#define OP_TRANSFORM 0x80000000 /* The node is a transformation rule */
-#define OP_MEMBER 0x40000000 /* Target is a member of an archive */
-#define OP_LIB 0x20000000 /* Target is a library */
-#define OP_ARCHV 0x10000000 /* Target is an archive construct */
-#define OP_HAS_COMMANDS 0x08000000 /* Target has all the commands it should.
- * Used when parsing to catch multiple
- * commands for a target */
-#define OP_SAVE_CMDS 0x04000000 /* Saving commands on .END (Compat) */
-#define OP_DEPS_FOUND 0x02000000 /* Already processed by Suff_FindDeps */
-#define OP_MARK 0x01000000 /* Node found while expanding .ALLSRC */
-
#define NoExecute(gn) ((gn->type & OP_MAKE) ? noRecursiveExecute : noExecute)
/*
* OP_NOP will return TRUE if the node with the given type was not the
@@ -330,18 +385,6 @@ typedef struct GNode {
#define TARG_N