summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pashev <igor.pashev@nexenta.com>2012-06-29 14:36:07 +0400
committerIgor Pashev <igor.pashev@nexenta.com>2012-06-29 14:36:07 +0400
commite0463df9c3d2ee6155221cc443c571d5da47098a (patch)
tree5c6b99e64c1b65d986e2722728c74f202a578be6
downloadsunmake-e0463df9c3d2ee6155221cc443c571d5da47098a.tar.gz
Initial import of DevPro make sourcesorig
Downloaded from http://dlc.sun.com/osol/devpro/downloads/current/ Licensed under CDDL http://www.opensource.org/licenses/CDDL-1.0
-rw-r--r--README110
-rw-r--r--ReleaseNotes51
-rw-r--r--usr/src/OPENSOLARIS.LICENSE242
-rwxr-xr-xusr/src/build127
-rwxr-xr-xusr/src/build_bin_img108
-rwxr-xr-xusr/src/build_src_img93
-rw-r--r--usr/src/make_src/Make/Makefile34
-rw-r--r--usr/src/make_src/Make/bin/Makefile32
-rw-r--r--usr/src/make_src/Make/bin/make/Common.mk46
-rw-r--r--usr/src/make_src/Make/bin/make/Makefile32
-rw-r--r--usr/src/make_src/Make/bin/make/common/ar.cc908
-rw-r--r--usr/src/make_src/Make/bin/make/common/default.mk.file231
-rw-r--r--usr/src/make_src/Make/bin/make/common/depvar.cc149
-rw-r--r--usr/src/make_src/Make/bin/make/common/dist.cc581
-rw-r--r--usr/src/make_src/Make/bin/make/common/dmake.cc29
-rw-r--r--usr/src/make_src/Make/bin/make/common/doname.cc3786
-rw-r--r--usr/src/make_src/Make/bin/make/common/dosys.cc174
-rw-r--r--usr/src/make_src/Make/bin/make/common/files.cc733
-rw-r--r--usr/src/make_src/Make/bin/make/common/globals.cc217
-rw-r--r--usr/src/make_src/Make/bin/make/common/implicit.cc1479
-rw-r--r--usr/src/make_src/Make/bin/make/common/macro.cc214
-rw-r--r--usr/src/make_src/Make/bin/make/common/main.cc3787
-rw-r--r--usr/src/make_src/Make/bin/make/common/make.cc29
-rw-r--r--usr/src/make_src/Make/bin/make/common/make.rules.file500
-rw-r--r--usr/src/make_src/Make/bin/make/common/misc.cc1007
-rw-r--r--usr/src/make_src/Make/bin/make/common/nse.cc610
-rw-r--r--usr/src/make_src/Make/bin/make/common/nse_printdep.cc517
-rw-r--r--usr/src/make_src/Make/bin/make/common/parallel.cc2477
-rw-r--r--usr/src/make_src/Make/bin/make/common/pmake.cc434
-rw-r--r--usr/src/make_src/Make/bin/make/common/read.cc2197
-rw-r--r--usr/src/make_src/Make/bin/make/common/read2.cc1938
-rw-r--r--usr/src/make_src/Make/bin/make/common/rep.cc529
-rw-r--r--usr/src/make_src/Make/bin/make/common/state.cc463
-rw-r--r--usr/src/make_src/Make/bin/make/common/svr4.make.rules.file242
-rw-r--r--usr/src/make_src/Make/bin/make/make.svr4/Makefile38
-rw-r--r--usr/src/make_src/Make/bin/make/make.xpg4/Makefile36
-rw-r--r--usr/src/make_src/Make/bin/make/smake/Makefile30
-rw-r--r--usr/src/make_src/Make/bin/make/smake/src/Makefile50
-rw-r--r--usr/src/make_src/Make/bin/make/smake/src/Variant.mk155
-rw-r--r--usr/src/make_src/Make/include/bsd/bsd.h58
-rw-r--r--usr/src/make_src/Make/include/mk/copyright.h27
-rw-r--r--usr/src/make_src/Make/include/mk/defs.h495
-rw-r--r--usr/src/make_src/Make/include/mksdmsi18n/mksdmsi18n.h44
-rw-r--r--usr/src/make_src/Make/include/mksh/defs.h1042
-rw-r--r--usr/src/make_src/Make/include/mksh/dosys.h50
-rw-r--r--usr/src/make_src/Make/include/mksh/globals.h35
-rw-r--r--usr/src/make_src/Make/include/mksh/i18n.h38
-rw-r--r--usr/src/make_src/Make/include/mksh/libmksh_init.h36
-rw-r--r--usr/src/make_src/Make/include/mksh/macro.h41
-rw-r--r--usr/src/make_src/Make/include/mksh/misc.h60
-rw-r--r--usr/src/make_src/Make/include/mksh/mksh.h49
-rw-r--r--usr/src/make_src/Make/include/mksh/read.h37
-rw-r--r--usr/src/make_src/Make/include/vroot/args.h70
-rw-r--r--usr/src/make_src/Make/include/vroot/report.h59
-rw-r--r--usr/src/make_src/Make/include/vroot/vroot.h67
-rw-r--r--usr/src/make_src/Make/lib/Lib.mk67
-rw-r--r--usr/src/make_src/Make/lib/Makefile39
-rw-r--r--usr/src/make_src/Make/lib/bsd/Makefile29
-rw-r--r--usr/src/make_src/Make/lib/bsd/src/Makefile49
-rw-r--r--usr/src/make_src/Make/lib/bsd/src/Variant.mk45
-rw-r--r--usr/src/make_src/Make/lib/bsd/src/bsd.cc182
-rw-r--r--usr/src/make_src/Make/lib/makestate/Makefile48
-rw-r--r--usr/src/make_src/Make/lib/makestate/src/Makefile50
-rw-r--r--usr/src/make_src/Make/lib/makestate/src/Variant.mk73
-rw-r--r--usr/src/make_src/Make/lib/makestate/src/ld_file.c192
-rw-r--r--usr/src/make_src/Make/lib/makestate/src/lock.c175
-rw-r--r--usr/src/make_src/Make/lib/mksdmsi18n/Makefile30
-rw-r--r--usr/src/make_src/Make/lib/mksdmsi18n/src/Makefile46
-rw-r--r--usr/src/make_src/Make/lib/mksdmsi18n/src/Variant.mk52
-rw-r--r--usr/src/make_src/Make/lib/mksdmsi18n/src/lib/Makefile54
-rw-r--r--usr/src/make_src/Make/lib/mksdmsi18n/src/lib/version.mk30
-rw-r--r--usr/src/make_src/Make/lib/mksdmsi18n/src/libmksdmsi18n_init.cc63
-rw-r--r--usr/src/make_src/Make/lib/mksh/Makefile29
-rw-r--r--usr/src/make_src/Make/lib/mksh/src/Makefile50
-rw-r--r--usr/src/make_src/Make/lib/mksh/src/Variant.mk58
-rw-r--r--usr/src/make_src/Make/lib/mksh/src/dosys.cc851
-rw-r--r--usr/src/make_src/Make/lib/mksh/src/globals.cc140
-rw-r--r--usr/src/make_src/Make/lib/mksh/src/i18n.cc100
-rw-r--r--usr/src/make_src/Make/lib/mksh/src/libmksh.msg81
-rw-r--r--usr/src/make_src/Make/lib/mksh/src/macro.cc1414
-rw-r--r--usr/src/make_src/Make/lib/mksh/src/misc.cc1178
-rw-r--r--usr/src/make_src/Make/lib/mksh/src/mksh.cc286
-rw-r--r--usr/src/make_src/Make/lib/mksh/src/read.cc174
-rw-r--r--usr/src/make_src/Make/lib/vroot/Makefile29
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/Makefile49
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/Variant.mk71
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/access.cc46
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/args.cc35
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/chdir.cc45
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/chmod.cc50
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/chown.cc51
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/chroot.cc48
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/creat.cc51
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/execve.cc54
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/libvroot.msg38
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/lock.cc196
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/lstat.cc50
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/mkdir.cc50
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/mount.cc53
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/open.cc53
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/readlink.cc50
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/report.cc396
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/rmdir.cc48
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/setenv.cc65
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/stat.cc50
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/statfs.cc49
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/truncate.cc49
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/unlink.cc48
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/unmount.cc48
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/utimes.cc50
-rw-r--r--usr/src/make_src/Make/lib/vroot/src/vroot.cc344
-rw-r--r--usr/src/make_src/Makefile38
-rw-r--r--usr/src/make_src/exe/options.sh105
-rw-r--r--usr/src/make_src/exe/sanity-check.sh60
-rw-r--r--usr/src/make_src/exe/variant.sh55
-rw-r--r--usr/src/make_src/include/Makefile30
-rw-r--r--usr/src/make_src/include/avo/avo_alloca.h49
-rw-r--r--usr/src/make_src/include/avo/intl.h77
-rw-r--r--usr/src/make_src/rules/computed-options.mk37
-rw-r--r--usr/src/make_src/rules/derived.mk66
-rw-r--r--usr/src/make_src/rules/dmake.mk33
-rw-r--r--usr/src/make_src/rules/i18n-install.mk73
-rw-r--r--usr/src/make_src/rules/import.mk28
-rw-r--r--usr/src/make_src/rules/install.mk240
-rw-r--r--usr/src/make_src/rules/intel-S2.mk60
-rw-r--r--usr/src/make_src/rules/l10n-install.mk70
-rw-r--r--usr/src/make_src/rules/lib.mk131
-rw-r--r--usr/src/make_src/rules/libraries.mk62
-rw-r--r--usr/src/make_src/rules/master.mk109
-rw-r--r--usr/src/make_src/rules/recurse.mk58
-rw-r--r--usr/src/make_src/rules/singleton.mk63
-rw-r--r--usr/src/make_src/rules/solaris.mk55
-rw-r--r--usr/src/make_src/rules/sparc-S2.mk61
-rw-r--r--usr/src/make_src/rules/variant.mk45
134 files changed, 35979 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..47f727a
--- /dev/null
+++ b/README
@@ -0,0 +1,110 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)README.usr 1.10 06/12/18
+#
+
+Enclosed in this directory tree is the source code for "make".
+
+Three different "build" options are supported.
+
+1. To build the executable itself:
+
+ Set up your environment variables, and then run "./build".
+
+ For example, in "sh", you could use this command:
+
+ cd usr/src; STUDIOBIN=/your/path/to/Sun/Studio/bin \
+ DESTDIR=/your/path/to/root/of/install/location \
+ ./build
+
+ The resulting files, listed below, will be installed under $DESTDIR.
+
+ The default values for these environment variables are:
+
+ STUDIOBIN=/opt/SUNWspro/bin
+ DESTDIR=../../destdir/root_`uname -p`
+
+ If you're happy with the default values, there is no need to specify any.
+
+ Also, the following derived variables can be set individually if so desired.
+ The default values are listed below for reference:
+
+ CC=$(STUDIOBIN)/cc
+ CCC=$(STUDIOBIN)/CC
+ MAKE=$(STUDIOBIN)/dmake -m serial
+
+ Note that only Sun Studio 10 or Sun Studio 11 compilers are supported.
+
+ List of created files:
+
+ $DESTDIR/usr/lib/libmakestate.so.1
+ $DESTDIR/usr/lib/amd64/libmakestate.so.1 OR $DESTDIR/usr/lib/sparcv9/libmakestate.so.1
+ $DESTDIR/usr/lib/svr4.make
+ $DESTDIR/usr/share/lib/make/svr4.make.rules
+ $DESTDIR/usr/share/lib/make/make.rules
+ $DESTDIR/usr/ccs/bin/make
+ $DESTDIR/usr/xpg4/bin/make
+
+2. To build a "binaries only" release image:
+
+ Set up your environment variables, and then run "./build_bin_img".
+
+ For example, in "sh", you could use this command:
+
+ cd usr/src; STUDIOBIN=/your/path/to/Sun/Studio/bin \
+ DESTDIR=/your/path/to/root/of/install/location \
+ BINIMGFILE=/your/path/to/binaries-only/imagefile \
+ ./build_bin_img
+
+ As in (1) above, the make executables are built under the control
+ of a handful of environment variables, and installed at $DESTDIR.
+
+ The files at $DESTDIR are then collected into a tarball, which is
+ is stored at $BINIMGFILE.bz2
+
+ The default value for BINIMGFILE is
+
+ devpro-make-open-bins-{date}.{arch}.tar
+
+ Where "date" is in the format "YYYYMMDD", and "arch" is either
+ "i386" or "sparc".
+
+3. To build a "source code" release image:
+
+ Set up your environment variable, and then run "./build_src_img".
+
+ For example, in "sh", you could use this command:
+
+ cd usr/src; SRCIMGFILE=/your/path/to/source-code/imagefile \
+ ./build_src_img
+
+ The entire source tree is collected into a tarball, which is
+ is stored at $SRCIMGFILE.bz2
+
+ The default value for SRCIMGFILE is:
+
+ SRCIMGFILE=../../imgdir/devpro-make-src-{date}.tar
+
+ Where "date" is in the format "YYYYMMDD".
+
diff --git a/ReleaseNotes b/ReleaseNotes
new file mode 100644
index 0000000..40be009
--- /dev/null
+++ b/ReleaseNotes
@@ -0,0 +1,51 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)ReleaseNotes 1.6 06/11/03
+#
+
+A tarball is supplied which contains the source code for "make."
+
+ % ls
+ devpro-make-src-20061002.tar.bz2
+
+To unpack this tarball:
+
+ % bunzip2 devpro-make-src-20061002.tar.bz2
+ % ls
+ devpro-make-src-20061002.tar
+ % tar xf devpro-make-src-20061002.tar
+ % ls -F
+ README
+ ReleaseNotes
+ devpro-make-src-20061002.tar
+ usr/
+ %
+
+The file "ReleaseNotes" is this document itself.
+
+The file "README" contains more information on building and installing
+this code.
+
+The code source tree, and scripts to manage it, are included under the
+"./usr/src/" directory.
diff --git a/usr/src/OPENSOLARIS.LICENSE b/usr/src/OPENSOLARIS.LICENSE
new file mode 100644
index 0000000..8ce4411
--- /dev/null
+++ b/usr/src/OPENSOLARIS.LICENSE
@@ -0,0 +1,242 @@
+ COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)
+ Version 1.0
+
+
+1. Definitions.
+
+ 1.1. “Contributor” means each individual or entity that creates or contributes to the creation of Modifications.
+
+ 1.2. “Contributor Version” means the combination of the Original Software, prior Modifications used by a Contributor
+ (if any), and the Modifications made by that particular Contributor.
+
+ 1.3. “Covered Software” means (a) the Original Software, or (b) Modifications, or (c) the combination
+ of files containing Original Software with files containing Modifications, in each case including portions thereof.
+
+ 1.4. “Executable” means the Covered Software in any form other than Source Code.
+
+ 1.5. “Initial Developer” means the individual or entity that first makes Original Software available under this License.
+
+ 1.6. “Larger Work” means a work which combines Covered Software or portions thereof with code not governed by the terms
+ of this License.
+
+ 1.7. “License” means this document.
+
+ 1.8. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the
+ initial grant or subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. “Modifications” means the Source Code and Executable form of any of the following:
+ A. Any file that results from an addition to, deletion from or modification of the contents of a file
+ containing Original Software or previous Modifications;
+ B. Any new file that contains any part of the Original Software or previous Modification; or
+ C. Any new file that is contributed or otherwise made available under the terms of this License.
+
+ 1.10. “Original Software” means the Source Code and Executable form of computer software code that is originally
+ released under this License.
+
+ 1.11. “Patent Claims” means any patent claim(s), now owned or hereafter acquired, including without limitation,
+ method, process, and apparatus claims, in any patent Licensable by grantor.
+
+ 1.12. “Source Code” means (a) the common form of computer software code in which modifications are made and
+ (b) associated documentation included in or with such code.
+
+ 1.13. “You” (or “Your”) means an individual or a legal entity exercising rights under, and complying with all of
+ the terms of, this License. For legal entities, “You” includes any entity which controls, is controlled by, or is
+ under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect,
+ to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more
+ than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity.
+
+2. License Grants.
+
+ 2.1. The Initial Developer Grant.
+ Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims,
+ the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer,
+ to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions
+ thereof), with or without Modifications, and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made,
+ use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof).
+
+ (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first
+ distributes or otherwise makes the Original Software available to a third party under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from
+ the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software,
+ or (ii) the combination of the Original Software with other software or devices.
+
+ 2.2. Contributor Grant.
+ Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims,
+ each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use,
+ reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor
+ (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or
+ as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor
+ either alone and/or in combination with its Contributor Version (or portions of such combination), to make,
+ use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor
+ (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor
+ Version (or portions of such combination).
+
+ (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes
+ or otherwise makes the Modifications available to a third party.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has
+ deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of
+ Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software
+ (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered
+ Software in the absence of Modifications made by that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Availability of Source Code.
+ Any Covered Software that You distribute or otherwise make available in Executable form must also be made available
+ in Source Code form and that Source Code form must be distributed only under the terms of this License. You must
+ include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or
+ otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they
+ can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used
+ for software exchange.
+
+ 3.2. Modifications.
+ The Modifications that You create or to which You contribute are governed by the terms of this License. You
+ represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to
+ grant the rights conveyed by this License.
+
+ 3.3. Required Notices.
+ You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification.
+ You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or
+ any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer.
+
+ 3.4. Application of Additional Terms.
+ You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the
+ applicable version of this License or the recipients’ rights hereunder. You may choose to offer, and to charge a
+ fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software.
+ However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor.
+ You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered
+ by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability
+ incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability
+ terms You offer.
+
+ 3.5. Distribution of Executable Versions.
+ You may distribute the Executable form of the Covered Software under the terms of this License or under the terms
+ of a license of Your choice, which may contain terms different from this License, provided that You are in compliance
+ with the terms of this License and that the license for the Executable form does not attempt to limit or alter
+ the recipient’s rights in the Source Code form from the rights set forth in this License. If You distribute the
+ Covered Software in Executable form under a different license, You must make it absolutely clear that any terms
+ which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby
+ agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer
+ or such Contributor as a result of any such terms You offer.
+
+ 3.6. Larger Works.
+ You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License
+ and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this
+ License are fulfilled for the Covered Software.
+
+4. Versions of the License.
+
+ 4.1. New Versions.
+ Sun Microsystems, Inc. is the initial license steward and may publish revised and/or new versions of this License
+ from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3,
+ no one other than the license steward has the right to modify this License.
+
+ 4.2. Effect of New Versions.
+ You may always continue to use, distribute or otherwise make the Covered Software available under the terms of
+ the version of the License under which You originally received the Covered Software. If the Initial Developer
+ includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under
+ any subsequent version of the License, You must distribute and make the Covered Software available under the terms
+ of the version of the License under which You originally received the Covered Software. Otherwise, You may also
+ choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version
+ of the License published by the license steward.
+
+ 4.3. Modified Versions.
+ When You are an Initial Developer and You want to create a new license for Your Original Software, You may create
+ and use a modified version of this License if You: (a) rename the license and remove any references to the name of
+ the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that
+ the license contains terms which differ from this License.
+
+5. DISCLAIMER OF WARRANTY.
+
+COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR
+IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A
+PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU.
+SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE.
+NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+6. TERMINATION.
+
+ 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms
+ herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their
+ nature, must remain in effect beyond the termination of this License shall survive.
+
+ 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer
+ or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as
+ “Participant”) alleging that the Participant Software (meaning the Contributor Version where the Participant
+ is a Contributor or the Original Software where the Participant is the Initial Developer) directly or
+ indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant,
+ the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1
+ and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically
+ at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with
+ respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement
+ with Participant.
+
+ 6.3. If You assert a patent infringement claim against Participant alleging that the Participant Software directly
+ or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the
+ initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant
+ under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license.
+
+ 6.4. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted
+ by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor)
+ shall survive termination.
+
+7. LIMITATION OF LIABILITY.
+
+UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE
+INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO
+ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR
+LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY
+SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
+INJURY RESULTING FROM SUCH PARTY’S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+8. U.S. GOVERNMENT END USERS.
+
+The Covered Software is a “commercial item,” as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of
+“commercial computer software” (as that term is defined at 48 C.F.R. § 252.227-7014(a)(1)) and “commercial computer software documentation”
+as such terms are used in 48 C.F.R. 12.212 Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of,
+and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License.
+
+9. MISCELLANEOUS.
+
+This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed
+by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any,
+provides otherwise), excluding such jurisdiction’s conflict-of-law provisions. Any litigation relating to this License shall be subject
+to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the
+losing party responsible for costs, including, without limitation, court costs and reasonable attorneys’ fees and expenses. The application of
+the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that
+the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for
+compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use,
+distribute or otherwise make available any Covered Software.
+
+10. RESPONSIBILITY FOR CLAIMS.
+
+As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of
+its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on
+an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability.
+
+--------
+
+NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION
+LICENSE (CDDL)
+
+The OpenSolaris code released under the CDDL shall be governed by the laws
+of the State of California (excluding conflict-of-law provisions). Any
+litigation relating to this License shall be subject to the jurisdiction of
+the Federal Courts of the Northern District of California and the state
+courts of the State of California, with venue lying in Santa Clara County,
+California.
+
diff --git a/usr/src/build b/usr/src/build
new file mode 100755
index 0000000..967f5af
--- /dev/null
+++ b/usr/src/build
@@ -0,0 +1,127 @@
+#!/bin/csh -f
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)build 1.15 06/12/18
+#
+
+
+# This script compiles the "make" sources to produce a "make"
+# executable.
+#
+# See also "./README" for a description of its use.
+#
+#
+# Optional environment variables:
+#
+# name typical use description
+#
+# STUDIOBIN $STUDIOBIN/cc installation of the Sun Studio compilers
+# CC $CC -c x.c preferred C compiler
+# CCC $CCC -c x.cc preferred C++ compiler
+# MAKE $MAKE {target} preferred "make" executable
+# DESTDIR $DESTDIR/usr/ccs root of installation tree
+
+# Legal arguments are "clean", "all", and "install". The default
+# is "install".
+
+set erruse = 0
+
+if ( $#argv == 0 ) then
+ set args = ( install )
+else if ( $#argv == 1 ) then
+ if ( ( $argv[1] == clean ) || ( $argv[1] == all ) || ( $argv[1] == install ) ) then
+ set args = ( $argv )
+ else
+ set erruse = 1
+ endif
+else
+ set erruse = 1
+endif
+
+if ( $erruse ) then
+ echo 'usage: build [ clean | all | install ]'
+ exit 0
+endif
+
+# Set up environment variables. User-supplied values are respected.
+# If the variable is not set by the user, a default is supplied.
+# If CC, CCC, or MAKE are not set, they are derived from STUDIOBIN
+
+if ( ! $?STUDIOBIN ) then
+ setenv STUDIOBIN /opt/SUNWspro/bin
+endif
+
+if ( ! $?CC ) then
+ setenv CC ${STUDIOBIN}/cc
+endif
+
+if ( ! $?CCC ) then
+ setenv CCC ${STUDIOBIN}/CC
+endif
+
+if ( ! $?MAKE ) then
+ setenv MAKE "${STUDIOBIN}/dmake -m serial"
+endif
+
+setenv CC64 $CC
+setenv CCC64 $CCC
+
+if ( ! $?DESTDIR ) then
+ setenv DESTDIR ../../destdir/root_`uname -p`
+endif
+
+# Ensure that $DESTDIR exists, and is absolute.
+
+if ( ! -d $DESTDIR ) then
+ mkdir -p $DESTDIR
+endif
+
+set p = `pwd`
+cd $DESTDIR
+setenv DESTDIR `pwd`
+cd $p
+
+cd ./make_src
+
+# Do the build itself, using .../make_src/Makefile.
+
+echo
+echo === starting build ===
+echo
+echo Using variables:
+echo
+echo ' 'CC = $CC
+echo ' 'CCC = $CCC
+echo ' 'DESTDIR = $DESTDIR
+echo ' 'MAKE = $MAKE
+echo ' 'STUDIOBIN = $STUDIOBIN
+echo
+$MAKE CC=${CC} CCC=${CCC} DESTDIR=${DESTDIR} MAKE=${MAKE} $args
+echo
+echo === build complete ===
+echo
+echo Binaries installed at $DESTDIR':'
+echo
+cd $DESTDIR
+find . -type f -print | sed 's/^/ /'
diff --git a/usr/src/build_bin_img b/usr/src/build_bin_img
new file mode 100755
index 0000000..d48f75b
--- /dev/null
+++ b/usr/src/build_bin_img
@@ -0,0 +1,108 @@
+#!/bin/csh -f
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)build_bin_img 1.18 06/12/18
+#
+
+
+# This script creates a "tarball" distribution image of the "make" executable.
+#
+# See also "./README" for a description of its use.
+#
+#
+# Optional environment variables:
+#
+# name typical use description
+#
+# DESTDIR $DESTDIR/usr/ccs root of installation tree
+# BINIMGFILE $BINIMGFILE''.bz2 bzipped tarball image
+
+
+if ( $#argv > 0 ) then
+ echo 'usage: build_bin_img'
+ exit 0
+endif
+
+# Set up environment variables. User-supplied values are respected.
+# If the variable is not set by the user, a default is supplied.
+
+if ( ! $?DESTDIR ) then
+ setenv DESTDIR ../../destdir/root_`uname -p`
+endif
+
+if ( ! $?BINIMGFILE ) then
+ setenv BINIMGFILE ../../imgdir/devpro-make-open-bins-`/usr/bin/date -u +'%'Y'%'m'%'d`.`uname -p`.tar
+endif
+
+# Compile the sources to produce the "make" binaries. See "./README"
+# for details.
+
+./build
+
+# Ensure that the path to $BINIMGFILE exists, and is absolute.
+
+set t = $BINIMGFILE
+
+if ( Z$BINIMGFILE =~ Z*/* ) then
+ set bifd = $t:h
+ set bifn = $t:t
+else
+ set bifd = .
+ set bifn = $t
+endif
+
+mkdir -p $bifd
+
+set p = `pwd`
+cd $bifd
+setenv BINIMGFILE `pwd`/$bifn
+cd $p
+
+# Ensure that $DESTDIR is absolute.
+
+set p = `pwd`
+cd $DESTDIR
+setenv DESTDIR `pwd`
+cd $p
+
+echo
+echo === starting build of binary image ===
+echo
+echo Using variables:
+echo
+echo ' 'DESTDIR = $DESTDIR
+echo ' 'BINIMGFILE = $BINIMGFILE
+
+# Create and compress the "tarball".
+
+rm -f $BINIMGFILE $BINIMGFILE''.bz2
+
+tar cf $BINIMGFILE -C $DESTDIR .
+
+bzip2 $BINIMGFILE
+
+echo
+echo === build of binary image complete ===
+echo
+ls -l $BINIMGFILE''*
diff --git a/usr/src/build_src_img b/usr/src/build_src_img
new file mode 100755
index 0000000..212d6f0
--- /dev/null
+++ b/usr/src/build_src_img
@@ -0,0 +1,93 @@
+#!/bin/csh -f
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)build_src_img 1.13 06/12/13
+#
+
+
+# This script creates a "tarball" distribution image of the "make" source code.
+#
+# See also "./README" for a description of its use
+#
+#
+# Optional environment variables:
+#
+# name typical use description
+#
+# SRCIMGFILE $SRCIMGFILE''.bz2 bzipped tarball image
+
+if ( $#argv > 0 ) then
+ echo 'usage: build_src_img'
+ exit 0
+endif
+
+# Set up environment variable. User-supplied value is respected.
+# If the variable is not set by the user, a default is supplied.
+
+if ( ! $?SRCIMGFILE ) then
+ setenv SRCIMGFILE ../../imgdir/devpro-make-src-`/usr/bin/date -u +'%'Y'%'m'%'d`.tar
+endif
+
+# Ensure that the path to $SRCIMGFILE exists, and is absolute.
+
+set t = $SRCIMGFILE
+
+if ( Z$t =~ Z*/* ) then
+ set sifd = $t:h
+ set sifn = $t:t
+else
+ set sifd = .
+ set sifn = $t
+endif
+
+if ( ! -d $sifd ) then
+ mkdir -p $sifd
+endif
+
+set p = `pwd`
+cd $sifd
+setenv SRCIMGFILE `pwd`/$sifn
+cd $p
+
+echo
+echo === starting build of source image ===
+echo
+echo Using variable:
+echo
+echo ' 'SRCIMGFILE = $SRCIMGFILE
+
+# Create and compress the "tarball".
+
+cd ../..
+
+rm -f $SRCIMGFILE $SRCIMGFILE''.bz2
+
+tar cf $SRCIMGFILE ./README ./ReleaseNotes ./usr/src
+
+bzip2 $SRCIMGFILE
+
+echo
+echo === build of source image complete ===
+echo
+ls -l $SRCIMGFILE''*
diff --git a/usr/src/make_src/Make/Makefile b/usr/src/make_src/Make/Makefile
new file mode 100644
index 0000000..886d661
--- /dev/null
+++ b/usr/src/make_src/Make/Makefile
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.21 06/12/12
+#
+
+TOP = ..
+
+SUBDIRS= lib \
+ bin \
+ localize \
+ man
+
+include ${TOP}/rules/recurse.mk
diff --git a/usr/src/make_src/Make/bin/Makefile b/usr/src/make_src/Make/bin/Makefile
new file mode 100644
index 0000000..a210f0e
--- /dev/null
+++ b/usr/src/make_src/Make/bin/Makefile
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.16 06/12/12
+#
+
+TOP = ../..
+
+# SUBDIRS = make maketool rxm rxs
+SUBDIRS = make rxm rxs
+
+include $(TOP)/rules/recurse.mk
diff --git a/usr/src/make_src/Make/bin/make/Common.mk b/usr/src/make_src/Make/bin/make/Common.mk
new file mode 100644
index 0000000..bf00849
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/Common.mk
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Common.mk 1.3 06/12/12
+#
+
+TOP = ../../../../..
+include $(TOP)/rules/master.mk
+
+PKG_TOP = $(TOP)/Make
+
+LIBBSD_DIR = $(PKG_TOP)/libbsd
+LIBBSD = $(LIBBSD_DIR)/$(VARIANT)/libbsd.a
+
+LIBMKSDMSI18N_DIR = $(PKG_TOP)/libmksdmsi18n
+LIBMKSDMSI18N = $(LIBMKSDMSI18N_DIR)/$(VARIANT)/libmksdmsi18n.a
+
+LIBMKSH_DIR = $(PKG_TOP)/libmksh
+LIBMKSH = $(LIBMKSH_DIR)/$(VARIANT)/libmksh.a
+
+LIBVROOT_DIR = $(PKG_TOP)/libvroot
+LIBVROOT = $(LIBVROOT_DIR)/$(VARIANT)/libvroot.a
+
+SRC = ../src
+include $(TOP)/rules/derived.mk
+
diff --git a/usr/src/make_src/Make/bin/make/Makefile b/usr/src/make_src/Make/bin/make/Makefile
new file mode 100644
index 0000000..58d212c
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/Makefile
@@ -0,0 +1,32 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1997 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.7 06/12/12
+#
+
+TOP = ../../..
+
+#SUBDIRS = dmake localize
+SUBDIRS = smake make.xpg4 make.svr4
+
+include $(TOP)/rules/recurse.mk
diff --git a/usr/src/make_src/Make/bin/make/common/ar.cc b/usr/src/make_src/Make/bin/make/common/ar.cc
new file mode 100644
index 0000000..dfd0362
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/ar.cc
@@ -0,0 +1,908 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)ar.cc 1.28 06/12/12
+ */
+
+#pragma ident "@(#)ar.cc 1.28 06/12/12"
+
+/*
+ * ar.c
+ *
+ * Deal with the lib.a(member.o) and lib.a((entry-point)) notations
+ *
+ * Look inside archives for notations a(b) and a((b))
+ * a(b) is file member b in archive a
+ * a((b)) is entry point b in object archive a
+ *
+ * For 6.0, create a make which can understand all archive
+ * formats. This is kind of tricky, and <ar.h> isnt any help.
+ */
+
+/*
+ * Included files
+ */
+#include <avo/avo_alloca.h> /* alloca() */
+#include <ar.h>
+#include <errno.h> /* errno */
+#include <fcntl.h> /* open() */
+#include <mk/defs.h>
+#include <mksh/misc.h> /* retmem_mb() */
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+struct ranlib {
+ union {
+ off_t ran_strx; /* string table index of */
+ char *ran_name; /* symbol defined by */
+ } ran_un;
+ off_t ran_off; /* library member at this offset */
+};
+#else
+#include <ranlib.h>
+#endif
+
+#if defined(linux)
+#include <ctype.h> /* isspace */
+#else
+#include <unistd.h> /* close() */
+#endif
+
+
+/*
+ * Defined macros
+ */
+#ifndef S5EMUL
+#undef BITSPERBYTE
+#define BITSPERBYTE 8
+#endif
+
+/*
+ * Defines for all the different archive formats. See next comment
+ * block for justification for not using <ar.h>s versions.
+ */
+#define AR_5_MAGIC "<ar>" /* 5.0 format magic string */
+#define AR_5_MAGIC_LENGTH 4 /* 5.0 format string length */
+
+#define AR_PORT_MAGIC "!<arch>\n" /* Port. (6.0) magic string */
+#define AR_PORT_MAGIC_LENGTH 8 /* Port. (6.0) string length */
+#define AR_PORT_END_MAGIC "`\n" /* Port. (6.0) end of header */
+#define AR_PORT_WORD 4 /* Port. (6.0) 'word' length */
+
+/*
+ * typedefs & structs
+ */
+/*
+ * These are the archive file headers for the formats. Note
+ * that it really doesnt matter if these structures are defined
+ * here. They are correct as of the respective archive format
+ * releases. If the archive format is changed, then since backwards
+ * compatability is the desired behavior, a new structure is added
+ * to the list.
+ */
+typedef struct { /* 5.0 ar header format: vax family; 3b family */
+ char ar_magic[AR_5_MAGIC_LENGTH]; /* AR_5_MAGIC*/
+ char ar_name[16]; /* Space terminated */
+ char ar_date[AR_PORT_WORD]; /* sgetl() accessed */
+ char ar_syms[AR_PORT_WORD]; /* sgetl() accessed */
+} Arh_5;
+
+typedef struct { /* 5.0 ar symbol format: vax family; 3b family */
+ char sym_name[8]; /* Space terminated */
+ char sym_ptr[AR_PORT_WORD]; /* sgetl() accessed */
+} Ars_5;
+
+typedef struct { /* 5.0 ar member format: vax family; 3b family */
+ char arf_name[16]; /* Space terminated */
+ char arf_date[AR_PORT_WORD]; /* sgetl() accessed */
+ char arf_uid[AR_PORT_WORD]; /* sgetl() accessed */
+ char arf_gid[AR_PORT_WORD]; /* sgetl() accessed */
+ char arf_mode[AR_PORT_WORD]; /* sgetl() accessed */
+ char arf_size[AR_PORT_WORD]; /* sgetl() accessed */
+} Arf_5;
+
+typedef struct { /* Portable (6.0) ar format: vax family; 3b family */
+ char ar_name[16]; /* Space terminated */
+ /* left-adjusted fields; decimal ascii; blank filled */
+ char ar_date[12];
+ char ar_uid[6];
+ char ar_gid[6];
+ char ar_mode[8]; /* octal ascii */
+ char ar_size[10];
+ /* special end-of-header string (AR_PORT_END_MAGIC) */
+ char ar_fmag[2];
+} Ar_port;
+
+enum ar_type {
+ AR_5,
+ AR_PORT
+};
+
+typedef unsigned int ar_port_word; // must be 4-bytes long
+
+typedef struct {
+ FILE *fd;
+ /* to distiguish ar format */
+ enum ar_type type;
+ /* where first ar member header is at */
+ long first_ar_mem;
+ /* where the symbol lookup starts */
+ long sym_begin;
+ /* the number of symbols available */
+ long num_symbols;
+ /* length of symbol directory file */
+ long sym_size;
+ Arh_5 arh_5;
+ Ars_5 ars_5;
+ Arf_5 arf_5;
+ Ar_port ar_port;
+} Ar;
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+extern timestruc_t& read_archive(register Name target);
+static Boolean open_archive(char *filename, register Ar *arp);
+static void close_archive(register Ar *arp);
+static Boolean read_archive_dir(register Ar *arp, Name library, char **long_names_table);
+static void translate_entry(register Ar *arp, Name target, register Property member, char **long_names_table);
+static long sgetl(char *);
+
+/*
+ * read_archive(target)
+ *
+ * Read the contents of an ar file.
+ *
+ * Return value:
+ * The time the member was created
+ *
+ * Parameters:
+ * target The member to find time for
+ *
+ * Global variables used:
+ * empty_name The Name ""
+ */
+
+int read_member_header (Ar_port *header, FILE *fd, char* filename);
+int process_long_names_member (register Ar *arp, char **long_names_table, char *filename);
+
+timestruc_t&
+read_archive(register Name target)
+{
+ register Property member;
+ wchar_t *slash;
+ String_rec true_member_name;
+ wchar_t buffer[STRING_BUFFER_LENGTH];
+ register Name true_member = NULL;
+ Ar ar;
+ char *long_names_table = NULL; /* Table of long
+ member names */
+
+ member = get_prop(target->prop, member_prop);
+ /*
+ * Check if the member has directory component.
+ * If so, remove the dir and see if we know the date.
+ */
+ if (member->body.member.member != NULL) {
+ Wstring member_string(member->body.member.member);
+ wchar_t * wcb = member_string.get_string();
+ if((slash = (wchar_t *) wsrchr(wcb, (int) slash_char)) != NULL) {
+ INIT_STRING_FROM_STACK(true_member_name, buffer);
+ append_string(member->body.member.library->string_mb,
+ &true_member_name,
+ FIND_LENGTH);
+ append_char((int) parenleft_char, &true_member_name);
+ append_string(slash + 1, &true_member_name, FIND_LENGTH);
+ append_char((int) parenright_char, &true_member_name);
+ true_member = GETNAME(true_member_name.buffer.start,
+ FIND_LENGTH);
+ if (true_member->stat.time != file_no_time) {
+ target->stat.time = true_member->stat.time;
+ return target->stat.time;
+ }
+ }
+ }
+ if (open_archive(member->body.member.library->string_mb, &ar) == failed) {
+ if (errno == ENOENT) {
+ target->stat.stat_errno = ENOENT;
+ close_archive(&ar);
+ if (member->body.member.member == NULL) {
+ member->body.member.member = empty_name;
+ }
+ return target->stat.time = file_doesnt_exist;
+ } else {
+ fatal(catgets(catd, 1, 1, "Can't access archive `%s': %s"),
+ member->body.member.library->string_mb,
+ errmsg(errno));
+ }
+ }
+ if (target->stat.time == file_no_time) {
+ if (read_archive_dir(&ar, member->body.member.library,
+ &long_names_table)
+ == failed){
+ fatal(catgets(catd, 1, 2, "Can't access archive `%s': %s"),
+ member->body.member.library->string_mb,
+ errmsg(errno));
+ }
+ }
+ if (member->body.member.entry != NULL) {
+ translate_entry(&ar, target, member,&long_names_table);
+ }
+ close_archive(&ar);
+ if (long_names_table) {
+ retmem_mb(long_names_table);
+ }
+ if (true_member != NULL) {
+ target->stat.time = true_member->stat.time;
+ }
+ if (target->stat.time == file_no_time) {
+ target->stat.time = file_doesnt_exist;
+ }
+ return target->stat.time;
+}
+
+/*
+ * open_archive(filename, arp)
+ *
+ * Return value:
+ * Indicates if open failed or not
+ *
+ * Parameters:
+ * filename The name of the archive we need to read
+ * arp Pointer to ar file description block
+ *
+ * Global variables used:
+ */
+static Boolean
+open_archive(char *filename, register Ar *arp)
+{
+ int fd;
+ char mag_5[AR_5_MAGIC_LENGTH];
+ char mag_port[AR_PORT_MAGIC_LENGTH];
+ char buffer[4];
+
+ arp->fd = NULL;
+ fd = open_vroot(filename, O_RDONLY, 0, NULL, VROOT_DEFAULT);
+ if ((fd < 0) || ((arp->fd = fdopen(fd, "r")) == NULL)) {
+ return failed;
+ }
+ (void) fcntl(fileno(arp->fd), F_SETFD, 1);
+
+#if !defined(SUN5_0) && !defined(linux) //XXX
+ /* Read enough of the archive to distinguish between the formats */
+ if (fread(mag_5, AR_5_MAGIC_LENGTH, 1, arp->fd) != 1) {
+ return failed;
+ }
+ if (IS_EQUALN(mag_5, AR_5_MAGIC, AR_5_MAGIC_LENGTH)) {
+ arp->type = AR_5;
+ /* Must read in header to set necessary info */
+ if (fseek(arp->fd, 0L, 0) != 0 ||
+ fread((char *) &arp->arh_5, sizeof (Arh_5), 1, arp->fd) !=
+ 1) {
+ return failed;
+ }
+ arp->sym_begin = ftell(arp->fd);
+ arp->num_symbols = sgetl(arp->arh_5.ar_syms);
+ arp->first_ar_mem = arp->sym_begin +
+ sizeof (Ars_5) * arp->num_symbols;
+ arp->sym_size = 0L;
+ return succeeded;
+ }
+ if (fseek(arp->fd, 0L, 0) != 0) {
+ return failed;
+ }
+#endif
+ if (fread(mag_port, AR_PORT_MAGIC_LENGTH, 1, arp->fd) != 1) {
+ return failed;
+ }
+ if (IS_EQUALN(mag_port, AR_PORT_MAGIC, AR_PORT_MAGIC_LENGTH)) {
+ arp->type = AR_PORT;
+ /*
+ * Read in first member header to find out if there is
+ * a symbol definition table.
+ */
+
+ int ret = read_member_header(&arp->ar_port, arp->fd, filename);
+ if (ret == failed) {
+ return failed;
+ } else if(ret == -1) {
+ /* There is no member header - empty archive */
+ arp->sym_size = arp->num_symbols = arp->sym_begin = 0L;
+ arp->first_ar_mem = ftell(arp->fd);
+ return succeeded;
+ }
+ /*
+ * The following values are the default if there is
+ * no symbol directory and long member names.
+ */
+ arp->sym_size = arp->num_symbols = arp->sym_begin = 0L;
+ arp->first_ar_mem = ftell(arp->fd) - (long) sizeof (Ar_port);
+
+ /*
+ * Do we have a symbol table? A symbol table is always
+ * the first member in an archive. In 4.1.x it has the
+ * name __.SYMDEF, in SVr4, it has the name "/ "
+ */
+/*
+#ifdef SUN5_0
+ MBSTOWCS(wcs_buffer, NOCATGETS("/ "));
+ if (IS_WEQUALN(arp->ar_port.ar_name, wcs_buffer, 16)) {
+#else
+ MBSTOWCS(wcs_buffer, NOCATGETS("__.SYMDEF "));
+ if (IS_WEQUALN(arp->ar_port.ar_name, wcs_buffer, 16)) {
+#endif
+ */
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ if (IS_EQUALN(arp->ar_port.ar_name,
+ NOCATGETS("/ "),
+ 16)) {
+#else
+ if (IS_EQUALN(arp->ar_port.ar_name,
+ NOCATGETS("__.SYMDEF "),
+ 16)) {
+#endif
+ if (sscanf(arp->ar_port.ar_size,
+ "%ld",
+ &arp->sym_size) != 1) {
+ return failed;
+ }
+ arp->sym_size += (arp->sym_size & 1); /* round up */
+ if (fread(buffer, sizeof buffer, 1, arp->fd) != 1) {
+ return failed;
+ }
+ arp->num_symbols = sgetl(buffer);
+ arp->sym_begin = ftell(arp->fd);
+ arp->first_ar_mem = arp->sym_begin +
+ arp->sym_size - sizeof buffer;
+ }
+ return succeeded;
+ }
+ fatal(catgets(catd, 1, 3, "`%s' is not an archive"), filename);
+ /* NOTREACHED */
+ return failed;
+}
+
+
+/*
+ * close_archive(arp)
+ *
+ * Parameters:
+ * arp Pointer to ar file description block
+ *
+ * Global variables used:
+ */
+static void
+close_archive(register Ar *arp)
+{
+ if (arp->fd != NULL) {
+ (void) fclose(arp->fd);
+ }
+}
+
+/*
+ * read_archive_dir(arp, library, long_names_table)
+ *
+ * Reads the directory of an archive and enters all
+ * the members into the make symboltable in lib(member) format
+ * with their dates.
+ *
+ * Parameters:
+ * arp Pointer to ar file description block
+ * library Name of lib to enter members for.
+ * Used to form "lib(member)" string.
+ * long_names_table table that contains list of members
+ * with names > 15 characters long
+ *
+ * Global variables used:
+ */
+static Boolean
+#if defined(SUN5_0) || defined(linux) //XXX
+read_archive_dir(register Ar *arp, Name library, char **long_names_table)
+#else
+read_archive_dir(register Ar *arp, Name library, char **)
+#endif
+{
+ wchar_t *name_string;
+ wchar_t *member_string;
+ register long len;
+ register wchar_t *p;
+ register char *q;
+ register Name name;
+ Property member;
+ long ptr;
+ long date;
+
+#if defined(SUN5_0) || defined(linux) //XXX
+ int offset;
+
+ /*
+ * If any of the members has a name > 15 chars,
+ * it will be found here.
+ */
+ if (process_long_names_member(arp, long_names_table, library->string_mb) == failed) {
+ return failed;
+ }
+#endif
+ name_string = ALLOC_WC((int) (library->hash.length +
+ (int) ar_member_name_len * 2));
+ (void) mbstowcs(name_string, library->string_mb, (int) library->hash.length);
+ member_string = name_string + library->hash.length;
+ *member_string++ = (int) parenleft_char;
+
+ if (fseek(arp->fd, arp->first_ar_mem, 0) != 0) {
+ goto read_error;
+ }
+ /* Read the directory using the appropriate format */
+ switch (arp->type) {
+ case AR_5:
+ for (;;) {
+ if (fread((char *) &arp->arf_5, sizeof arp->arf_5, 1, arp->fd)
+ != 1) {
+ if (feof(arp->fd)) {
+ return succeeded;
+ }
+ break;
+ }
+ len = sizeof arp->arf_5.arf_name;
+ for (p = member_string, q = arp->arf_5.arf_name;
+ (len > 0) && (*q != (int) nul_char) && !isspace(*q);
+ ) {
+ MBTOWC(p, q);
+ p++;
+ q++;
+ }
+ *p++ = (int) parenright_char;
+ *p = (int) nul_char;
+ name = GETNAME(name_string, FIND_LENGTH);
+ /*
+ * [tolik] Fix for dmake bug 1234018.
+ * If name->stat.time is already set, then it should not
+ * be changed. (D)make propogates time stamp for one
+ * member, and when it calls exists() for another member,
+ * the first one may be changed.
+ */
+ if(name->stat.time == file_no_time) {
+ name->stat.time.tv_sec = sgetl(arp->arf_5.arf_date);
+ name->stat.time.tv_nsec = LONG_MAX;
+ }
+ name->is_member = library->is_member;
+ member = maybe_append_prop(name, member_prop);
+ member->body.member.library = library;
+ *--p = (int) nul_char;
+ if (member->body.member.member == NULL) {
+ member->body.member.member =
+ GETNAME(member_string, FIND_LENGTH);
+ }
+ ptr = sgetl(arp->arf_5.arf_size);
+ ptr += (ptr & 1);
+ if (fseek(arp->fd, ptr, 1) != 0) {
+ goto read_error;
+ }
+ }
+ break;
+ case AR_PORT:
+ for (;;) {
+ if ((fread((char *) &arp->ar_port,
+ sizeof arp->ar_port,
+ 1,
+ arp->fd) != 1) ||
+ !IS_EQUALN(arp->ar_port.ar_fmag,
+ AR_PORT_END_MAGIC,
+ sizeof arp->ar_port.ar_fmag)) {
+ if (feof(arp->fd)) {
+ return succeeded;
+ }
+ fatal(
+ catgets(catd, 1, 28, "Read error in archive `%s': invalid archive file member header at 0x%x"),
+ library->string_mb,
+ ftell(arp->fd)
+ );
+ }
+#if defined(SUN5_0) || defined(linux) //XXX
+ /* If it's a long name, retrieve it from long name table */
+ if (arp->ar_port.ar_name[0] == '/') {
+ /*
+ * "len" is used for hashing the string.
+ * We're using "ar_member_name_len" instead of
+ * the actual name length since it's the longest
+ * string the "ar" command can handle at this
+ * point.
+ */
+ len = ar_member_name_len;
+ sscanf(arp->ar_port.ar_name + 1,
+ "%ld",
+ &offset);
+ q = *long_names_table + offset;
+ } else {
+ q = arp->ar_port.ar_name;
+ len = sizeof arp->ar_port.ar_name;
+ }
+#else
+ q = arp->ar_port.ar_name;
+ len = sizeof arp->ar_port.ar_name;
+#endif
+
+ for (p = member_string;
+ (len > 0) &&
+ (*q != (int) nul_char) &&
+ !isspace(*q) &&
+ (*q != (int) slash_char);
+ ) {
+ MBTOWC(p, q);
+ p++;
+ q++;
+ }
+ *p++ = (int) parenright_char;
+ *p = (int) nul_char;
+ name = GETNAME(name_string, FIND_LENGTH);
+ name->is_member = library->is_member;
+ member = maybe_append_prop(name, member_prop);
+ member->body.member.library = library;
+ *--p = (int) nul_char;
+ if (member->body.member.member == NULL) {
+ member->body.member.member =
+ GETNAME(member_string, FIND_LENGTH);
+ }
+ if (sscanf(arp->ar_port.ar_date, "%ld", &date) != 1) {
+ WCSTOMBS(mbs_buffer, name_string);
+ fatal(catgets(catd, 1, 4, "Bad date field for member `%s' in archive `%s'"),
+ mbs_buffer,
+ library->string_mb);
+ }
+ /*
+ * [tolik] Fix for dmake bug 1234018.
+ */
+ if(name->stat.time == file_no_time) {
+ name->stat.time.tv_sec = date;
+ name->stat.time.tv_nsec = LONG_MAX;
+ }
+ if (sscanf(arp->ar_port.ar_size, "%ld", &ptr) != 1) {
+ WCSTOMBS(mbs_buffer, name_string);
+ fatal(catgets(catd, 1, 5, "Bad size field for member `%s' in archive `%s'"),
+ mbs_buffer,
+ library->string_mb);
+ }
+ ptr += (ptr & 1);
+ if (fseek(arp->fd, ptr, 1) != 0) {
+ goto read_error;
+ }
+ }
+ break;
+ }
+
+ /* Only here if fread() [or IS_EQUALN()] failed and not at EOF */
+read_error:
+ fatal(catgets(catd, 1, 6, "Read error in archive `%s': %s"),
+ library->string_mb,
+ errmsg(errno));
+ /* NOTREACHED */
+}
+
+
+/*
+ * process_long_names_member(arp)
+ *
+ * If the archive contains members with names longer
+ * than 15 characters, then it has a special member
+ * with the name "// " that contains a table
+ * of null-terminated long names. This member
+ * is always the first member, after the symbol table
+ * if it exists.
+ *
+ * Parameters:
+ * arp Pointer to ar file description block
+ *
+ * Global variables used:
+ */
+int
+process_long_names_member(register Ar *arp, char **long_names_table, char *filename)
+{
+ Ar_port *ar_member_header;
+ int table_size;
+
+ if (fseek(arp->fd, arp->first_ar_mem, 0) != 0) {
+ return failed;
+ }
+ if ((ar_member_header =
+ (Ar_port *) alloca((int) sizeof(Ar_port))) == NULL){
+ perror(catgets(catd, 1, 7, "memory allocation failure"));
+ return failed;
+ }
+ int ret = read_member_header(ar_member_header, arp->fd, filename);
+ if (ret == failed) {
+ return failed;
+ } else if(ret == -1) {
+ /* There is no member header - empty archive */
+ return succeeded;
+ }
+ /* Do we have special member containing long names? */
+ if (IS_EQUALN(ar_member_header->ar_name,
+ NOCATGETS("// "),
+ 16)){
+ if (sscanf(ar_member_header->ar_size,
+ "%ld",
+ &table_size) != 1) {
+ return failed;
+ }
+ *long_names_table = (char *) malloc(table_size);
+ /* Read the list of long member names into the table */
+ if (fread(*long_names_table, table_size, 1, arp->fd) != 1) {
+ return failed;
+ }
+ arp->first_ar_mem = ftell(arp->fd);
+ }
+ return succeeded;
+}
+
+/*
+ * translate_entry(arp, target, member)
+ *
+ * Finds the member for one lib.a((entry))
+ *
+ * Parameters:
+ * arp Pointer to ar file description block
+ * target Target to find member name for
+ * member Property to fill in with info
+ *
+ * Global variables used:
+ */
+static void
+translate_entry(register Ar *arp, Name target, register Property member, char **long_names_table)
+{
+ register int len;
+ register int i;
+ wchar_t *member_string;
+ ar_port_word *offs;
+ int strtablen;
+ char *syms; /* string table */
+ char *csym; /* string table */
+ ar_port_word *offend; /* end of offsets table */
+ int date;
+ register wchar_t *ap;
+ register char *hp;
+ int maxs;
+ int offset;
+ char buffer[4];
+
+ if (arp->sym_begin == 0L || arp->num_symbols == 0L) {
+ fatal(catgets(catd, 1, 8, "Cannot find symbol `%s' in archive `%s'"),
+ member->body.member.entry->string_mb,
+ member->body.member.library->string_mb);
+ }
+
+ if (fseek(arp->fd, arp->sym_begin, 0) != 0) {
+ goto read_error;
+ }
+ member_string = ALLOC_WC((int) ((int) ar_member_name_len * 2));
+
+ switch (arp->type) {
+ case AR_5:
+ if ((len = member->body.member.entry->hash.length) > 8) {
+ len = 8;
+ }
+ for (i = 0; i < arp->num_symbols; i++) {
+ if (fread((char *) &arp->ars_5,
+ sizeof arp->ars_5,
+ 1,
+ arp->fd) != 1) {
+ goto read_error;
+ }
+ if (IS_EQUALN(arp->ars_5.sym_name,
+ member->body.member.entry->string_mb,
+ len)) {
+ if ((fseek(arp->fd,
+ sgetl(arp->ars_5.sym_ptr),
+ 0) != 0) ||
+ (fread((char *) &arp->arf_5,
+ sizeof arp->arf_5,
+ 1,
+ arp->fd) != 1)) {
+ goto read_error;
+ }
+ MBSTOWCS(wcs_buffer, arp->arf_5.arf_name);
+ (void) wsncpy(member_string,
+ wcs_buffer,
+ wslen(wcs_buffer));
+ member_string[sizeof(arp->arf_5.arf_name)] =
+ (int) nul_char;
+ member->body.member.member =
+ GETNAME(member_string, FIND_LENGTH);
+ target->stat.time.tv_sec = sgetl(arp->arf_5.arf_date);
+ target->stat.time.tv_nsec = LONG_MAX;
+ return;
+ }
+ }
+ break;
+ case AR_PORT:
+ offs = (ar_port_word *) alloca((int) (arp->num_symbols * AR_PORT_WORD));
+ if (fread((char *) offs,
+ AR_PORT_WORD,
+ (int) arp->num_symbols,
+ arp->fd) != arp->num_symbols) {
+ goto read_error;
+ }
+
+ for(i=0;i<arp->num_symbols;i++) {
+ *((int*)buffer)=offs[i];
+ offs[i]=(ar_port_word)sgetl(buffer);
+ }
+
+ strtablen=arp->sym_size-4-(int) (arp->num_symbols * AR_PORT_WORD);
+ syms = (char *) alloca(strtablen);
+ if (fread(syms,
+ sizeof (char),
+ strtablen,
+ arp->fd) != strtablen) {
+ goto read_error;
+ }
+ offend = &offs[arp->num_symbols];
+ while (offs < offend) {
+ maxs = strlen(member->body.member.entry->string_mb);
+ if(strlen(syms) > maxs)
+ maxs = strlen(syms);
+ if (IS_EQUALN(syms,
+ member->body.member.entry->string_mb,
+ maxs)) {
+ if (fseek(arp->fd,
+ (long) *offs,
+ 0) != 0) {
+ goto read_error;
+ }
+ if ((fread((char *) &arp->ar_port,
+ sizeof arp->ar_port,
+ 1,
+ arp->fd) != 1) ||
+ !IS_EQUALN(arp->ar_port.ar_fmag,
+ AR_PORT_END_MAGIC,
+ sizeof arp->ar_port.ar_fmag)) {
+ goto read_error;
+ }
+ if (sscanf(arp->ar_port.ar_date,
+ "%ld",
+ &date) != 1) {
+ fatal(catgets(catd, 1, 9, "Bad date field for member `%s' in archive `%s'"),
+ arp->ar_port.ar_name,
+ target->string_mb);
+ }
+#if defined(SUN5_0) || defined(linux) //XXX
+ /* If it's a long name, retrieve it from long name table */
+ if (arp->ar_port.ar_name[0] == '/') {
+ sscanf(arp->ar_port.ar_name + 1,
+ "%ld",
+ &offset);
+ len = ar_member_name_len;
+ hp = *long_names_table + offset;
+ } else {
+ len = sizeof arp->ar_port.ar_name;
+ hp = arp->ar_port.ar_name;
+ }
+#else
+ hp = arp->ar_port.ar_name;
+#endif
+ ap = member_string;
+ while (*hp &&
+ (*hp != (int) slash_char) &&
+ (ap < &member_string[len])) {
+ MBTOWC(ap, hp);
+ ap++;
+ hp++;
+ }
+ *ap = (int) nul_char;
+ member->body.member.member =
+ GETNAME(member_string, FIND_LENGTH);
+ target->stat.time.tv_sec = date;
+ target->stat.time.tv_nsec = LONG_MAX;
+ return;
+ }
+ offs++;
+ while(*syms!='\0') syms++;
+ syms++;
+ }
+ }
+ fatal(catgets(catd, 1, 10, "Cannot find symbol `%s' in archive `%s'"),
+ member->body.member.entry->string_mb,
+ member->body.member.library->string_mb);
+ /*NOTREACHED*/
+
+read_error:
+ if (ferror(arp->fd)) {
+ fatal(catgets(catd, 1, 11, "Read error in archive `%s': %s"),
+ member->body.member.library->string_mb,
+ errmsg(errno));
+ } else {
+ fatal(catgets(catd, 1, 12, "Read error in archive `%s': Premature EOF"),
+ member->body.member.library->string_mb);
+ }
+}
+
+/*
+ * sgetl(buffer)
+ *
+ * The intent here is to provide a means to make the value of
+ * bytes in an io-buffer correspond to the value of a long
+ * in the memory while doing the io a long at a time.
+ * Files written and read in this way are machine-independent.
+ *
+ * Return value:
+ * Long int read from buffer
+ * Parameters:
+ * buffer buffer we need to read long int from
+ *
+ * Global variables used:
+ */
+static long
+sgetl(register char *buffer)
+{
+ register long w = 0;
+ register int i = BITSPERBYTE * AR_PORT_WORD;
+
+ while ((i -= BITSPERBYTE) >= 0) {
+ w |= (long) ((unsigned char) *buffer++) << i;
+ }
+ return w;
+}
+
+
+/*
+ * read_member_header(header, fd, filename)
+ *
+ * reads the member header for the 4.1.x and SVr4 archives.
+ *
+ * Return value:
+ * fails if read error or member
+ * header is not the right format
+ * Parameters:
+ * header There's one before each archive member
+ * fd file descriptor for the archive file.
+ *
+ * Global variables used:
+ */
+int
+read_member_header(Ar_port *header, FILE *fd, char* filename)
+{
+ int num = fread((char *) header, sizeof (Ar_port), 1, fd);
+ if (num != 1 && feof(fd)) {
+ /* There is no member header - empty archive */
+ return -1;
+ }
+ if ((num != 1) ||
+ !IS_EQUALN(
+ AR_PORT_END_MAGIC,
+ header->ar_fmag,
+ sizeof (header->ar_fmag)
+ )
+ ) {
+ fatal(
+ catgets(catd, 1, 28, "Read error in archive `%s': invalid archive file member header at 0x%x"),
+ filename,
+ ftell(fd)
+ );
+ }
+ return succeeded;
+}
+
diff --git a/usr/src/make_src/Make/bin/make/common/default.mk.file b/usr/src/make_src/Make/bin/make/common/default.mk.file
new file mode 100644
index 0000000..6128d35
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/default.mk.file
@@ -0,0 +1,231 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)default.mk.file 1.4 06/12/12
+#
+
+SUFFIXES = .o .c .c~ .cc .cc~ .s .s~ .S .S~ .ln .f .f~ .F .F~ .l .l~ \
+ .mod .mod~ .sym .def .def~ .p .p~ .r .r~ .y .y~ .h .h~ .sh .sh~ \
+ .cps .cps~
+.SUFFIXES: $(SUFFIXES)
+
+# OUTPUT_OPTION should be defined to "-o $@" when
+# the default rules are used for non-local files.
+OUTPUT_OPTION=
+
+# C language section.
+CC=cc
+CFLAGS=
+CPPFLAGS=
+LINT=lint
+LINTFLAGS=
+COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -target $(TARGET_ARCH:-%=%) -c
+LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -target $(TARGET_ARCH:-%=%)
+LINT.c=$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)
+.c:
+ $(LINK.c) -o $@ $< $(LDLIBS)
+.c.ln:
+ $(LINT.c) $(OUTPUT_OPTION) -i $<
+.c.o:
+ $(COMPILE.c) $(OUTPUT_OPTION) $<
+.c.a:
+ $(COMPILE.c) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# C language section. yacc.
+YACC=yacc
+YFLAGS=
+YACC.y=$(YACC) $(YFLAGS)
+.y:
+ $(YACC.y) $<
+ $(LINK.c) -o $@ y.tab.c $(LDLIBS)
+ $(RM) y.tab.c
+.y.c:
+ $(YACC.y) $<
+ mv y.tab.c $@
+.y.ln:
+ $(YACC.y) $<
+ $(LINT.c) -o $@ -i y.tab.c
+ $(RM) y.tab.c
+.y.o:
+ $(YACC.y) $<
+ $(COMPILE.c) -o $@ y.tab.c
+ $(RM) y.tab.c
+
+# C language section. lex.
+LEX=lex
+LFLAGS=
+LEX.l=$(LEX) $(LFLAGS) -t
+.l:
+ $(RM) $*.c
+ $(LEX.l) $< > $*.c
+ $(LINK.c) -o $@ $*.c -ll $(LDLIBS)
+ $(RM) $*.c
+.l.c :
+ $(RM) $@
+ $(LEX.l) $< > $@
+.l.ln:
+ $(RM) $*.c
+ $(LEX.l) $< > $*.c
+ $(LINT.c) -o $@ -i $*.c
+ $(RM) $*.c
+.l.o:
+ $(RM) $*.c
+ $(LEX.l) $< > $*.c
+ $(COMPILE.c) -o $@ $*.c
+ $(RM) $*.c
+
+# C++ language section.
+CCC=CC
+CCFLAGS=
+COMPILE.cc=$(CCC) $(CCFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+LINK.cc=$(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+.cc:
+ $(LINK.cc) -o $@ $< $(LDLIBS)
+.cc.o:
+ $(COMPILE.cc) $(OUTPUT_OPTION) $<
+.cc.a:
+ $(COMPILE.cc) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# FORTRAN section.
+FC=f77
+FFLAGS=
+COMPILE.f=$(FC) $(FFLAGS) $(TARGET_ARCH) -c
+LINK.f=$(FC) $(FFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+COMPILE.F=$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+LINK.F=$(FC) $(FFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+.f:
+ $(LINK.f) -o $@ $< $(LDLIBS)
+.f.o:
+ $(COMPILE.f) $(OUTPUT_OPTION) $<
+.f.a:
+ $(COMPILE.f) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.F:
+ $(LINK.F) -o $@ $< $(LDLIBS)
+.F.o:
+ $(COMPILE.F) $(OUTPUT_OPTION) $<
+.F.a:
+ $(COMPILE.F) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# FORTRAN section. ratfor.
+RFLAGS=
+COMPILE.r=$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -c
+LINK.r=$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+.r:
+ $(LINK.r) -o $@ $< $(LDLIBS)
+.r.o:
+ $(COMPILE.r) $(OUTPUT_OPTION) $<
+.r.a:
+ $(COMPILE.r) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# Modula-2 section.
+M2C=m2c
+M2FLAGS=
+MODFLAGS=
+DEFFLAGS=
+COMPILE.def=$(M2C) $(M2FLAGS) $(DEFFLAGS) $(TARGET_ARCH)
+COMPILE.mod=$(M2C) $(M2FLAGS) $(MODFLAGS) $(TARGET_ARCH)
+.def.sym:
+ $(COMPILE.def) -o $@ $<
+.mod:
+ $(COMPILE.mod) -o $@ -e $@ $<
+.mod.o:
+ $(COMPILE.mod) -o $@ $<
+.mod.a:
+ $(COMPILE.mod) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# Pascal section.
+PC=pc
+PFLAGS=
+COMPILE.p=$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+LINK.p=$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+.p:
+ $(LINK.p) -o $@ $< $(LDLIBS)
+.p.o:
+ $(COMPILE.p) $(OUTPUT_OPTION) $<
+.p.a:
+ $(COMPILE.p) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# Assembly section.
+AS=as
+ASFLAGS=
+COMPILE.s=$(AS) $(ASFLAGS) $(TARGET_MACH)
+COMPILE.S=$(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+.s.o:
+ $(COMPILE.s) -o $@ $<
+.s.a:
+ $(COMPILE.s) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.S.o:
+ $(COMPILE.S) -o $@ $<
+.S.a:
+ $(COMPILE.S) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# Shell section.
+.sh:
+ $(RM) $@
+ cat $< > $@
+ chmod +x $@
+
+# NeWS section
+CPS=cps
+CPSFLAGS=
+.cps.h:
+ $(CPS) $(CPSFLAGS) $*.cps
+
+# Miscellaneous section.
+LD=ld
+LDFLAGS=
+LDLIBS=
+MAKE=make
+RM=rm -f
+AR=ar
+ARFLAGS=rv
+GET=/usr/sccs/get
+GFLAGS=
+
+markfile.o: markfile
+ echo "static char _sccsid[] = \"`grep @'(#)' markfile`\";" > markfile.c
+ cc -c markfile.c
+ $(RM) markfile.c
+
+SCCSFLAGS=
+SCCSGETFLAGS=-s
+.SCCS_GET:
+ sccs $(SCCSFLAGS) get $(SCCSGETFLAGS) $@ -G$@
diff --git a/usr/src/make_src/Make/bin/make/common/depvar.cc b/usr/src/make_src/Make/bin/make/common/depvar.cc
new file mode 100644
index 0000000..ee4be87
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/depvar.cc
@@ -0,0 +1,149 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1995 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)depvar.cc 1.14 06/12/12
+ */
+
+#pragma ident "@(#)depvar.cc 1.14 06/12/12"
+
+/*
+ * Included files
+ */
+#include <mk/defs.h>
+#include <mksh/misc.h> /* getmem() */
+
+/*
+ * This file deals with "Dependency Variables".
+ * The "-V var" command line option is used to indicate
+ * that var is a dependency variable. Used in conjunction with
+ * the -P option the user is asking if the named variables affect
+ * the dependencies of the given target.
+ */
+
+struct _Depvar {
+ Name name; /* Name of variable */
+ struct _Depvar *next; /* Linked list */
+ Boolean cmdline; /* Macro defined on the cmdline? */
+};
+
+typedef struct _Depvar *Depvar;
+
+static Depvar depvar_list;
+static Depvar *bpatch = &depvar_list;
+static Boolean variant_deps;
+
+/*
+ * Add a name to the list.
+ */
+
+void
+depvar_add_to_list(Name name, Boolean cmdline)
+{
+ Depvar dv;
+
+#ifdef SUNOS4_AND_AFTER
+ dv = ALLOC(Depvar);
+#else
+ dv = (Depvar) Malloc(sizeof(struct _Depvar));
+#endif
+ dv->name = name;
+ dv->next = NULL;
+ dv->cmdline = cmdline;
+ *bpatch = dv;
+ bpatch = &dv->next;
+}
+
+/*
+ * The macro `name' has been used in either the left-hand or
+ * right-hand side of a dependency. See if it is in the
+ * list. Two things are looked for. Names given as args
+ * to the -V list are checked so as to set the same/differ
+ * output for the -P option. Names given as macro=value
+ * command-line args are checked and, if found, an NSE
+ * warning is produced.
+ */
+void
+depvar_dep_macro_used(Name name)
+{
+ Depvar dv;
+
+ for (dv = depvar_list; dv != NULL; dv = dv->next) {
+ if (name == dv->name) {
+#ifdef NSE
+#ifdef SUNOS4_AND_AFTER
+ if (dv->cmdline) {
+#else
+ if (is_true(dv->cmdline)) {
+#endif
+ nse_dep_cmdmacro(dv->name->string);
+ }
+#endif
+ variant_deps = true;
+ break;
+ }
+ }
+}
+
+#ifdef NSE
+/*
+ * The macro `name' has been used in either the argument
+ * to a cd before a recursive make. See if it was
+ * defined on the command-line and, if so, complain.
+ */
+void
+depvar_rule_macro_used(Name name)
+{
+ Depvar dv;
+
+ for (dv = depvar_list; dv != NULL; dv = dv->next) {
+ if (name == dv->name) {
+#ifdef SUNOS4_AND_AFTER
+ if (dv->cmdline) {
+#else
+ if (is_true(dv->cmdline)) {
+#endif
+ nse_rule_cmdmacro(dv->name->string);
+ }
+ break;
+ }
+ }
+}
+#endif
+
+/*
+ * Print the results. If any of the Dependency Variables
+ * affected the dependencies then the dependencies potentially
+ * differ because of these variables.
+ */
+void
+depvar_print_results(void)
+{
+ if (variant_deps) {
+ printf(catgets(catd, 1, 234, "differ\n"));
+ } else {
+ printf(catgets(catd, 1, 235, "same\n"));
+ }
+}
+
diff --git a/usr/src/make_src/Make/bin/make/common/dist.cc b/usr/src/make_src/Make/bin/make/common/dist.cc
new file mode 100644
index 0000000..f825d43
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/dist.cc
@@ -0,0 +1,581 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)dist.cc 1.35 06/12/12
+ */
+
+#pragma ident "@(#)dist.cc 1.25 96/03/12"
+
+#ifdef DISTRIBUTED
+/*
+ * dist.cc
+ *
+ * Deal with the distributed processing
+ */
+
+#include <avo/err.h>
+#include <avo/find_dir.h>
+#include <avo/util.h>
+#include <dm/Avo_AcknowledgeMsg.h>
+#include <dm/Avo_DoJobMsg.h>
+#include <dm/Avo_JobResultMsg.h>
+#include <mk/defs.h>
+#include <mksh/misc.h> /* getmem() */
+#include <rw/pstream.h>
+#include <rw/queuecol.h>
+#include <rw/xdrstrea.h>
+#include <signal.h>
+#ifdef linux
+#include <sstream>
+using namespace std;
+#else
+#include <strstream.h>
+#endif
+#include <sys/stat.h> /* stat() */
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+
+/*
+ * Defined macros
+ */
+
+#define AVO_BLOCK_INTERUPTS sigfillset(&newset) ; \
+ sigprocmask(SIG_SETMASK, &newset, &oldset)
+
+#define AVO_UNBLOCK_INTERUPTS \
+ sigprocmask(SIG_SETMASK, &oldset, &newset)
+
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+int dmake_ifd;
+FILE* dmake_ifp;
+XDR xdrs_in;
+
+int dmake_ofd;
+FILE* dmake_ofp;
+XDR xdrs_out;
+
+// These instances are required for the RWfactory.
+static Avo_JobResultMsg dummyJobResultMsg;
+static Avo_AcknowledgeMsg dummyAcknowledgeMsg;
+static int firstAcknowledgeReceived = 0;
+
+int rxmPid = 0;
+
+/*
+ * File table of contents
+ */
+static void set_dmake_env_vars(void);
+
+/*
+ * void
+ * startup_rxm(void)
+ *
+ * When startup_rxm() is called, read_command_options() and
+ * read_files_and_state() have already been read, so DMake
+ * will now know what options to pass to rxm.
+ *
+ * rxm
+ * [ -k ] [ -n ]
+ * [ -c <dmake_rcfile> ]
+ * [ -g <dmake_group> ]
+ * [ -j <dmake_max_jobs> ]
+ * [ -m <dmake_mode> ]
+ * [ -o <dmake_odir> ]
+ * <read_fd> <write_fd>
+ *
+ * rxm will, among other things, read the rc file.
+ *
+ */
+void
+startup_rxm(void)
+{
+ Name dmake_name;
+ Name dmake_value;
+ Avo_err *find_run_dir_err;
+ int pipe1[2], pipe2[2];
+ Property prop;
+ char *run_dir;
+ char rxm_command[MAXPATHLEN];
+ int rxm_debug = 0;
+
+ int length;
+ char * env;
+
+ firstAcknowledgeReceived = 0;
+ /*
+ * Create two pipes, one for dmake->rxm, and one for rxm->dmake.
+ * pipe1 is dmake->rxm,
+ * pipe2 is rxm->dmake.
+ */
+ if ((pipe(pipe1) < 0) || (pipe(pipe2) < 0)) {
+ fatal(catgets(catd, 1, 245, "pipe() failed: %s"), errmsg(errno));
+ }
+
+ set_dmake_env_vars();
+
+ if ((rxmPid = fork()) < 0) { /* error */
+ fatal(catgets(catd, 1, 246, "fork() failed: %s"), errmsg(errno));
+ } else if (rxmPid > 0) { /* parent, dmake */
+ dmake_ofd = pipe1[1]; // write side of pipe
+ if (!(dmake_ofp = fdopen(dmake_ofd, "a"))) {
+ fatal(catgets(catd, 1, 247, "fdopen() failed: %s"), errmsg(errno));
+ }
+ xdrstdio_create(&xdrs_out, dmake_ofp, XDR_ENCODE);
+
+ dmake_ifd = pipe2[0]; // read side of pipe
+ if (!(dmake_ifp = fdopen(dmake_ifd, "r"))) {
+ fatal(catgets(catd, 1, 248, "fdopen() failed: %s"), errmsg(errno));
+ }
+ xdrstdio_create(&xdrs_in, dmake_ifp, XDR_DECODE);
+
+ close(pipe1[0]); // read side
+ close(pipe2[1]); // write side
+ } else { /* child, rxm */
+ close(pipe1[1]); // write side
+ close(pipe2[0]); // read side
+
+ /* Find the run directory of dmake, for rxm. */
+ find_run_dir_err = avo_find_run_dir(&run_dir);
+ if (find_run_dir_err) {
+ delete find_run_dir_err;
+ /* Use the path to find rxm. */
+ (void) sprintf(rxm_command, NOCATGETS("rxm"));
+ } else {
+ /* Use the run dir of dmake for rxm. */
+ (void) sprintf(rxm_command, NOCATGETS("%s/rxm"), run_dir);
+ }
+
+ if (continue_after_error) {
+ (void) strcat(rxm_command, NOCATGETS(" -k"));
+ }
+ if (do_not_exec_rule) {
+ (void) strcat(rxm_command, NOCATGETS(" -n"));
+ }
+ if (rxm_debug) {
+ (void) strcat(rxm_command, NOCATGETS(" -S"));
+ }
+ if (send_mtool_msgs) {
+ (void) sprintf(&rxm_command[strlen(rxm_command)],
+ NOCATGETS(" -O %d"),
+ mtool_msgs_fd);
+ }
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
+ dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+ ((dmake_value = prop->body.macro.value) != NULL)) {
+ (void) sprintf(&rxm_command[strlen(rxm_command)],
+ NOCATGETS(" -c %s"),
+ dmake_value->string_mb);
+ } else {
+ length = 2 + strlen(NOCATGETS("DMAKE_RCFILE"));
+ env = getmem(length);
+ (void) sprintf(env,
+ "%s=",
+ NOCATGETS("DMAKE_RCFILE"));
+ (void) putenv(env);
+ }
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_GROUP"));
+ dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+ ((dmake_value = prop->body.macro.value) != NULL)) {
+ (void) sprintf(&rxm_command[strlen(rxm_command)],
+ NOCATGETS(" -g %s"),
+ dmake_value->string_mb);
+ } else {
+ length = 2 + strlen(NOCATGETS("DMAKE_GROUP"));
+ env = getmem(length);
+ (void) sprintf(env,
+ "%s=",
+ NOCATGETS("DMAKE_GROUP"));
+ (void) putenv(env);
+ }
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MAX_JOBS"));
+ dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+ ((dmake_value = prop->body.macro.value) != NULL)) {
+ (void) sprintf(&rxm_command[strlen(rxm_command)],
+ NOCATGETS(" -j %s"),
+ dmake_value->string_mb);
+ } else {
+ length = 2 + strlen(NOCATGETS("DMAKE_MAX_JOBS"));
+ env = getmem(length);
+ (void) sprintf(env,
+ "%s=",
+ NOCATGETS("DMAKE_MAX_JOBS"));
+ (void) putenv(env);
+ }
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
+ dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+ ((dmake_value = prop->body.macro.value) != NULL)) {
+ (void) sprintf(&rxm_command[strlen(rxm_command)],
+ NOCATGETS(" -m %s"),
+ dmake_value->string_mb);
+ } else {
+ length = 2 + strlen(NOCATGETS("DMAKE_MODE"));
+ env = getmem(length);
+ (void) sprintf(env,
+ "%s=",
+ NOCATGETS("DMAKE_MODE"));
+ (void) putenv(env);
+ }
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_ODIR"));
+ dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+ ((dmake_value = prop->body.macro.value) != NULL)) {
+ (void) sprintf(&rxm_command[strlen(rxm_command)],
+ NOCATGETS(" -o %s"),
+ dmake_value->string_mb);
+ } else {
+ length = 2 + strlen(NOCATGETS("DMAKE_ODIR"));
+ env = getmem(length);
+ (void) sprintf(env,
+ "%s=",
+ NOCATGETS("DMAKE_ODIR"));
+ (void) putenv(env);
+ }
+
+ (void) sprintf(&rxm_command[strlen(rxm_command)],
+ NOCATGETS(" %d %d"),
+ pipe1[0], pipe2[1]);
+#ifdef linux
+ execl(NOCATGETS("/bin/sh"),
+#else
+ execl(NOCATGETS("/usr/bin/sh"),
+#endif
+ NOCATGETS("sh"),
+ NOCATGETS("-c"),
+ rxm_command,
+ (char *)NULL);
+ _exit(127);
+ }
+}
+
+/*
+ * static void
+ * set_dmake_env_vars()
+ *
+ * Sets the DMAKE_* environment variables for rxm and rxs.
+ * DMAKE_PWD
+ * DMAKE_NPWD
+ * DMAKE_UMASK
+ * DMAKE_SHELL
+ */
+static void
+set_dmake_env_vars()
+{
+ char *current_netpath;
+ char *current_path;
+ static char *env;
+ int length;
+ char netpath[MAXPATHLEN];
+ mode_t um;
+ char um_buf[MAXPATHLEN];
+ Name dmake_name;
+ Name dmake_value;
+ Property prop;
+
+#ifdef REDIRECT_ERR
+ /* Set __DMAKE_REDIRECT_STDERR */
+ length = 2 + strlen(NOCATGETS("__DMAKE_REDIRECT_STDERR")) + 1;
+ env = getmem(length);
+ (void) sprintf(env,
+ "%s=%s",
+ NOCATGETS("__DMAKE_REDIRECT_STDERR"),
+ out_err_same ? NOCATGETS("0") : NOCATGETS("1"));
+ (void) putenv(env);
+#endif
+
+ /* Set DMAKE_PWD to the current working directory */
+ current_path = get_current_path();
+ length = 2 + strlen(NOCATGETS("DMAKE_PWD")) + strlen(current_path);
+ env = getmem(length);
+ (void) sprintf(env,
+ "%s=%s",
+ NOCATGETS("DMAKE_PWD"),
+ current_path);
+ (void) putenv(env);
+
+ /* Set DMAKE_NPWD to machine:pathname */
+ if (avo_path_to_netpath(current_path, netpath)) {
+ current_netpath = netpath;
+ } else {
+ current_netpath = current_path;
+ }
+ length = 2 + strlen(NOCATGETS("DMAKE_NPWD")) + strlen(current_netpath);
+ env = getmem(length);
+ (void) sprintf(env,
+ "%s=%s",
+ NOCATGETS("DMAKE_NPWD"),
+ current_netpath);
+ (void) putenv(env);
+
+ /* Set DMAKE_UMASK to the value of umask */
+ um = umask(0);
+ umask(um);
+ (void) sprintf(um_buf, NOCATGETS("%ul"), um);
+ length = 2 + strlen(NOCATGETS("DMAKE_UMASK")) + strlen(um_buf);
+ env = getmem(length);
+ (void) sprintf(env,
+ "%s=%s",
+ NOCATGETS("DMAKE_UMASK"),
+ um_buf);
+ (void) putenv(env);
+
+ if (((prop = get_prop(shell_name->prop, macro_prop)) != NULL) &&
+ ((dmake_value = prop->body.macro.value) != NULL)) {
+ length = 2 + strlen(NOCATGETS("DMAKE_SHELL")) +
+ strlen(dmake_value->string_mb);
+ env = getmem(length);
+ (void) sprintf(env,
+ "%s=%s",
+ NOCATGETS("DMAKE_SHELL"),
+ dmake_value->string_mb);
+ (void) putenv(env);
+ }
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
+ dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+ ((dmake_value = prop->body.macro.value) != NULL)) {
+ length = 2 + strlen(NOCATGETS("DMAKE_OUTPUT_MODE")) +
+ strlen(dmake_value->string_mb);
+ env = getmem(length);
+ (void) sprintf(env,
+ "%s=%s",
+ NOCATGETS("DMAKE_OUTPUT_MODE"),
+ dmake_value->string_mb);
+ (void) putenv(env);
+ }
+}
+
+/*
+ * void
+ * distribute_rxm(Avo_DoJobMsg *dmake_job_msg)
+ *
+ * Write the DMake rule to be distributed down the pipe to rxm.
+ *
+ */
+void
+distribute_rxm(Avo_DoJobMsg *dmake_job_msg)
+{
+ /* Add all dynamic env vars to the dmake_job_msg. */
+ setvar_envvar(dmake_job_msg);
+
+ /*
+ * Copying dosys()...
+ * Stat .make.state to see if we'll need to reread it later
+ */
+ make_state->stat.time = file_no_time;
+ (void)exists(make_state);
+ make_state_before = make_state->stat.time;
+
+ // Wait for the first Acknowledge message from the rxm process
+ // before sending the first message.
+ if (!firstAcknowledgeReceived) {
+ firstAcknowledgeReceived++;
+ Avo_AcknowledgeMsg *msg = getAcknowledgeMsg();
+ if (msg) {
+ delete msg;
+ }
+ }
+
+ RWCollectable *doJobMsg = (RWCollectable *)dmake_job_msg;
+ sigset_t newset;
+ sigset_t oldset;
+
+ AVO_BLOCK_INTERUPTS;
+ int xdrResult = xdr(&xdrs_out, doJobMsg);
+
+ if (xdrResult) {
+ fflush(dmake_ofp);
+ AVO_UNBLOCK_INTERUPTS;
+ } else {
+ AVO_UNBLOCK_INTERUPTS;
+ fatal(catgets(catd, 1, 249, "Couldn't send the job request to rxm"));
+ }
+
+ delete dmake_job_msg;
+}
+
+// Queue for JobResult messages.
+static RWSlistCollectablesQueue jobResultQueue;
+
+// Queue for Acknowledge messages.
+static RWSlistCollectablesQueue acknowledgeQueue;
+
+// Read a message from the rxm process, and put it into a queue, by
+// message type. Return the message type.
+
+int
+getRxmMessage(void)
+{
+ RWCollectable *msg = (RWCollectable *)0;
+ int msgType = 0;
+// sigset_t newset;
+// sigset_t oldset;
+
+ // It seems unnecessarily to block interrupts here because
+ // any nonignored signal means exit for dmake in distributed mode.
+// AVO_BLOCK_INTERUPTS;
+ int xdrResult = xdr(&xdrs_in, msg);
+// AVO_UNBLOCK_INTERUPTS;
+
+ if (xdrResult) {
+ switch(msg->isA()) {
+ case __AVO_ACKNOWLEDGEMSG:
+ acknowledgeQueue.append(msg);
+ msgType = __AVO_ACKNOWLEDGEMSG;
+ break;
+ case __AVO_JOBRESULTMSG:
+ jobResultQueue.append(msg);
+ msgType = __AVO_JOBRESULTMSG;
+ break;
+ default:
+ warning(catgets(catd, 1, 291, "Unknown message on rxm input fd"));
+ msgType = 0;
+ break;
+ }
+ } else {
+ if (errno == EINTR) {
+ fputs(NOCATGETS("dmake: Internal error: xdr() has been interrupted by a signal.\n"), stderr);
+ }
+ fatal(catgets(catd, 1, 250, "Couldn't receive message from rxm"));
+ }
+
+ return msgType;
+}
+
+// Get a JobResult message from it's queue, and
+// if the queue is empty, call the getRxmMessage() function until
+// a JobResult message shows.
+
+Avo_JobResultMsg *
+getJobResultMsg(void)
+{
+ RWCollectable *msg = 0;
+
+ if (!(msg = jobResultQueue.get())) {
+ while (getRxmMessage() != __AVO_JOBRESULTMSG);
+ msg = jobResultQueue.get();
+ }
+
+ return (Avo_JobResultMsg *)msg;
+}
+
+// Get an Acknowledge message from it's queue, and
+// if the queue is empty, call the getRxmMessage() function until
+// a Acknowledge message shows.
+
+Avo_AcknowledgeMsg *
+getAcknowledgeMsg(void)
+{
+ RWCollectable *msg = 0;
+
+ if (!(msg = acknowledgeQueue.get())) {
+ while (getRxmMessage() != __AVO_ACKNOWLEDGEMSG);
+ msg = acknowledgeQueue.get();
+ }
+
+ return (Avo_AcknowledgeMsg *)msg;
+}
+
+
+/*
+ * Doname
+ * await_dist(Boolean waitflg)
+ *
+ * Waits for distributed children to exit and finishes their processing.
+ * Rxm will send a msg down the pipe when a child is done.
+ *
+ */
+Doname
+await_dist(Boolean waitflg)
+{
+ Avo_JobResultMsg *dmake_result_msg;
+ int job_msg_id;
+ Doname result = build_ok;
+ int result_msg_cmd_status;
+ int result_msg_job_status;
+ Running rp;
+
+ while (!(dmake_result_msg = getJobResultMsg()));
+ job_msg_id = dmake_result_msg->getId();
+ result_msg_cmd_status = dmake_result_msg->getCmdStatus();
+ result_msg_job_status = dmake_result_msg->getJobStatus();
+
+ if (waitflg) {
+ result = (result_msg_cmd_status == 0) ? build_ok : build_failed;
+
+#ifdef PRINT_EXIT_STATUS
+ if (result == build_ok) {
+ warning(NOCATGETS("I'm in await_dist(), waitflg is true, and result is build_ok."));
+ } else {
+ warning(NOCATGETS("I'm in await_dist(), waitflg is true, and result is build_failed."));
+ }
+#endif
+
+ } else {
+ for (rp = running_list;
+ (rp != NULL) && (job_msg_id != rp->job_msg_id);
+ rp = rp->next) {
+ }
+ if (rp == NULL) {
+ fatal(catgets(catd, 1, 251, "Internal error: returned child job_msg_id not in running_list"));
+ } else {
+ /* XXX - This may not be correct! */
+ if (result_msg_job_status == RETURNED) {
+ rp->state = build_ok;
+ } else {
+ rp->state = (result_msg_cmd_status == 0) ? build_ok : build_failed;
+ }
+ result = rp->state;
+
+#ifdef PRINT_EXIT_STATUS
+ if (result == build_ok) {
+ warning(NOCATGETS("I'm in await_dist(), waitflg is false, and result is build_ok."));
+ } else {
+ warning(NOCATGETS("I'm in await_dist(), waitflg is false, and result is build_failed."));
+ }
+#endif
+
+ }
+ parallel_process_cnt--;
+ }
+ delete dmake_result_msg;
+ return result;
+}
+
+#endif
+
+
diff --git a/usr/src/make_src/Make/bin/make/common/dmake.cc b/usr/src/make_src/Make/bin/make/common/dmake.cc
new file mode 100644
index 0000000..559a36d
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/dmake.cc
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)dmake.cc 1.2 06/12/12
+ */
+
+#pragma ident "@(#)dmake.cc 1.2 06/12/12"
diff --git a/usr/src/make_src/Make/bin/make/common/doname.cc b/usr/src/make_src/Make/bin/make/common/doname.cc
new file mode 100644
index 0000000..c06ba2f
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/doname.cc
@@ -0,0 +1,3786 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)doname.cc 1.115 06/12/12
+ */
+
+#pragma ident "@(#)doname.cc 1.115 06/12/12"
+
+/*
+ * doname.c
+ *
+ * Figure out which targets are out of date and rebuild them
+ */
+
+/*
+ * Included files
+ */
+#include <avo/avo_alloca.h> /* alloca() */
+#if defined(TEAMWARE_MAKE_CMN)
+#include <avo/util.h> /* avo_get_user(), avo_hostname() */
+#endif
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+# include <avo/strings.h> /* AVO_STRDUP() */
+# include <dm/Avo_MToolJobResultMsg.h>
+# include <dm/Avo_MToolJobStartMsg.h>
+# include <dm/Avo_MToolRsrcInfoMsg.h>
+# include <dm/Avo_macro_defs.h> /* AVO_BLOCK_INTERUPTS & AVO_UNBLOCK_INTERUPTS */
+# include <dmthread/Avo_ServerState.h>
+# include <rw/pstream.h>
+# include <rw/xdrstrea.h>
+#endif
+
+#include <fcntl.h>
+#include <mk/defs.h>
+#include <mksh/i18n.h> /* get_char_semantics_value() */
+#include <mksh/macro.h> /* getvar(), expand_value() */
+#include <mksh/misc.h> /* getmem() */
+#include <poll.h>
+
+#ifdef PARALLEL
+# include <rx/api.h>
+#endif
+
+#include <signal.h>
+
+#ifndef HP_UX
+# include <stropts.h>
+#endif
+
+#include <sys/errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/utsname.h> /* uname() */
+#include <sys/wait.h>
+#include <unistd.h> /* close() */
+
+/*
+ * Defined macros
+ */
+#ifndef PARALLEL
+# define LOCALHOST "localhost"
+#endif
+
+#define MAXRULES 100
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+#define SEND_MTOOL_MSG(cmds) \
+ if (send_mtool_msgs) { \
+ cmds \
+ }
+#else
+#define SEND_MTOOL_MSG(cmds)
+#endif
+
+// Sleep for .1 seconds between stat()'s
+const int STAT_RETRY_SLEEP_TIME = 100000;
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+static char hostName[MAXNAMELEN] = "";
+static char userName[MAXNAMELEN] = "";
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+ static FILE *mtool_msgs_fp;
+ static XDR xdrs;
+ static int sent_rsrc_info_msg = 0;
+#endif
+
+static int second_pass = 0;
+
+/*
+ * File table of contents
+ */
+extern Doname doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);
+extern Doname doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);
+static Boolean check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean doing_subtree, Chain *out_of_date_tail, Property old_locals, Boolean implicit, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals);
+void dynamic_dependencies(Name target);
+static Doname run_command(register Property line, Boolean print_machine);
+extern Doname execute_serial(Property line);
+extern Name vpath_translation(register Name cmd);
+extern void check_state(Name temp_file_name);
+static void read_dependency_file(register Name filename);
+static void check_read_state_file(void);
+static void do_assign(register Name line, register Name target);
+static void build_command_strings(Name target, register Property line);
+static Doname touch_command(register Property line, register Name target, Doname result);
+extern void update_target(Property line, Doname result);
+static Doname sccs_get(register Name target, register Property *command);
+extern void read_directory_of_file(register Name file);
+static void add_pattern_conditionals(register Name target);
+extern void set_locals(register Name target, register Property old_locals);
+extern void reset_locals(register Name target, register Property old_locals, register Property conditional, register int index);
+extern Boolean check_auto_dependencies(Name target, int auto_count, Name *automatics);
+static void delete_query_chain(Chain ch);
+
+// From read2.cc
+extern Name normalize_name(register wchar_t *name_string, register int length);
+
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+ static void append_job_result_msg(Avo_MToolJobResultMsg *job_result_msg);
+ static int pollResults(char *outFn, char *errFn, char *hostNm);
+ static void pollResultsAction(char *outFn, char *errFn);
+ static void rxmGetNextResultsBlock(int fd);
+ static int us_sleep(unsigned int nusecs);
+ extern "C" void Avo_PollResultsAction_Sigusr1Handler(int foo);
+#endif
+
+/*
+ * DONE.
+ *
+ * doname_check(target, do_get, implicit, automatic)
+ *
+ * Will call doname() and then inspect the return value
+ *
+ * Return value:
+ * Indication if the build failed or not
+ *
+ * Parameters:
+ * target The target to build
+ * do_get Passed thru to doname()
+ * implicit Passed thru to doname()
+ * automatic Are we building a hidden dependency?
+ *
+ * Global variables used:
+ * build_failed_seen Set if -k is on and error occurs
+ * continue_after_error Indicates that -k is on
+ * report_dependencies No error msg if -P is on
+ */
+Doname
+doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic)
+{
+ int first_time = 1;
+ (void) fflush(stdout);
+try_again:
+ switch (doname(target, do_get, implicit, automatic)) {
+ case build_ok:
+ second_pass = 0;
+ return build_ok;
+ case build_running:
+ second_pass = 0;
+ return build_running;
+ case build_failed:
+ if (!continue_after_error) {
+ fatal(catgets(catd, 1, 13, "Target `%s' not remade because of errors"),
+ target->string_mb);
+ }
+ build_failed_seen = true;
+ second_pass = 0;
+ return build_failed;
+ case build_dont_know:
+ /*
+ * If we can't figure out how to build an automatic
+ * (hidden) dependency, we just ignore it.
+ * We later declare the target to be out of date just in
+ * case something changed.
+ * Also, don't complain if just reporting the dependencies
+ * and not building anything.
+ */
+ if (automatic || (report_dependencies_level > 0)) {
+ second_pass = 0;
+ return build_dont_know;
+ }
+ if(first_time) {
+ first_time = 0;
+ second_pass = 1;
+ goto try_again;
+ }
+ second_pass = 0;
+ if (continue_after_error && !svr4) {
+ warning(catgets(catd, 1, 14, "Don't know how to make target `%s'"),
+ target->string_mb);
+ build_failed_seen = true;
+ return build_failed;
+ }
+ fatal(catgets(catd, 1, 15, "Don't know how to make target `%s'"), target->string_mb);
+ break;
+ }
+#ifdef lint
+ return build_failed;
+#endif
+}
+
+
+void
+enter_explicit_rule_from_dynamic_rule(Name target, Name source)
+{
+ Property line, source_line;
+ Dependency dependency;
+
+ source_line = get_prop(source->prop, line_prop);
+ line = maybe_append_prop(target, line_prop);
+ line->body.line.sccs_command = false;
+ line->body.line.target = target;
+ if (line->body.line.command_template == NULL) {
+ line->body.line.command_template = source_line->body.line.command_template;
+ for (dependency = source_line->body.line.dependencies;
+ dependency != NULL;
+ dependency = dependency->next) {
+ enter_dependency(line, dependency->name, false);
+ }
+ line->body.line.less = target;
+ }
+ line->body.line.percent = NULL;
+}
+
+
+
+Name
+find_dyntarget(Name target)
+{
+ Dyntarget p;
+ int i;
+ String_rec string;
+ wchar_t buffer[STRING_BUFFER_LENGTH];
+ wchar_t *pp, * bufend;
+ wchar_t tbuffer[MAXPATHLEN];
+ Wstring wcb(target);
+
+ for (p = dyntarget_list; p != NULL; p = p->next) {
+ INIT_STRING_FROM_STACK(string, buffer);
+ expand_value(p->name, &string, false);
+ i = 0;
+ pp = string.buffer.start;
+ bufend = pp + STRING_BUFFER_LENGTH;
+ while((*pp != nul_char) && (pp < bufend)) {
+ if(iswspace(*pp)) {
+ tbuffer[i] = nul_char;
+ if(i > 0) {
+ if (wcb.equal(tbuffer)) {
+ enter_explicit_rule_from_dynamic_rule(target, p->name);
+ return(target);
+ }
+ }
+ pp++;
+ i = 0;
+ continue;
+ }
+ tbuffer[i] = *pp;
+ i++;
+ pp++;
+ if(*pp == nul_char) {
+ tbuffer[i] = nul_char;
+ if(i > 0) {
+ if (wcb.equal(tbuffer)) {
+ enter_explicit_rule_from_dynamic_rule(target, p->name);
+ return(target);
+ }
+ }
+ break;
+ }
+ }
+ }
+ return(NULL);
+}
+
+/*
+ * DONE.
+ *
+ * doname(target, do_get, implicit)
+ *
+ * Chases all files the target depends on and builds any that
+ * are out of date. If the target is out of date it is then rebuilt.
+ *
+ * Return value:
+ * Indiates if build failed or nt
+ *
+ * Parameters:
+ * target Target to build
+ * do_get Run sccs get is nessecary
+ * implicit doname is trying to find an implicit rule
+ *
+ * Global variables used:
+ * assign_done True if command line assgnment has happened
+ * commands_done Preserved for the case that we need local value
+ * debug_level Should we trace make's actions?
+ * default_rule The rule for ".DEFAULT", used as last resort
+ * empty_name The Name "", used when looking for single sfx
+ * keep_state Indicates that .KEEP_STATE is on
+ * parallel True if building in parallel
+ * recursion_level Used for tracing
+ * report_dependencies make -P is on
+ */
+Doname
+doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic)
+{
+ Doname result = build_dont_know;
+ Chain out_of_date_list = NULL;
+#ifdef TEAMWARE_MAKE_CMN
+ Chain target_group;
+#endif
+ Property old_locals = NULL;
+ register Property line;
+ Property command = NULL;
+ register Dependency dependency;
+ Name less = NULL;
+ Name true_target = target;
+ Name *automatics = NULL;
+ register int auto_count;
+ Boolean rechecking_target = false;
+ Boolean saved_commands_done;
+ Boolean restart = false;
+ Boolean save_parallel = parallel;
+#ifdef NSE
+ Boolean save_readdep;
+#endif
+ Boolean doing_subtree = false;
+
+ Boolean recheck_conditionals = false;
+
+ if (target->state == build_running) {
+ return build_running;
+ }
+ line = get_prop(target->prop, line_prop);
+#ifdef TEAMWARE_MAKE_CMN
+ if (line != NULL) {
+ /*
+ * If this target is a member of target group and one of the
+ * other members of the group is running, mark this target
+ * as running.
+ */
+ for (target_group = line->body.line.target_group;
+ target_group != NULL;
+ target_group = target_group->next) {
+ if (is_running(target_group->name)) {
+ target->state = build_running;
+ add_pending(target,
+ recursion_level,
+ do_get,
+ implicit,
+ false);
+ return build_running;
+ }
+ }
+ }
+#ifdef NSE
+ nse_check_file_backquotes(target->string);
+#endif
+#endif
+ /*
+ * If the target is a constructed one for a "::" target,
+ * we need to consider that.
+ */
+ if (target->has_target_prop) {
+ true_target = get_prop(target->prop,
+ target_prop)->body.target.target;
+ if (true_target->colon_splits > 0) {
+ /* Make sure we have a valid time for :: targets */
+ Property time;
+
+ time = get_prop(true_target->prop, time_prop);
+ if (time != NULL) {
+ true_target->stat.time = time->body.time.time;
+ }
+ }
+ }
+ (void) exists(true_target);
+ /*
+ * If the target has been processed, we don't need to do it again,
+ * unless it depends on conditional macros or a delayed assignment,
+ * or it has been done when KEEP_STATE is on.
+ */
+ if (target->state == build_ok) {
+ if((!keep_state || (!target->depends_on_conditional && !assign_done))) {
+ return build_ok;
+ } else {
+ recheck_conditionals = true;
+ }
+ }
+ if (target->state == build_subtree) {
+ /* A dynamic macro subtree is being built */
+ target->state = build_dont_know;
+ doing_subtree = true;
+ if (!target->checking_subtree) {
+ /*
+ * This target has been started before and therefore
+ * not all dependencies have to be built.
+ */
+ restart = true;
+ }
+ } else if (target->state == build_pending) {
+ target->state = build_dont_know;
+ restart = true;
+/*
+#ifdef TEAMWARE_MAKE_CMN
+ } else if (parallel &&
+ keep_state &&
+ (target->conditional_cnt > 0)) {
+ if (!parallel_ok(target, false)) {
+ add_subtree(target, recursion_level, do_get, implicit);
+ target->state = build_running;
+ return build_running;
+ }
+#endif
+ */
+ }
+ /*
+ * If KEEP_STATE is on, we have to rebuild the target if the
+ * building of it caused new automatic dependencies to be reported.
+ * This is where we restart the build.
+ */
+ if (line != NULL) {
+ line->body.line.percent = NULL;
+ }
+recheck_target:
+ /* Init all local variables */
+ result = build_dont_know;
+ out_of_date_list = NULL;
+ command = NULL;
+ less = NULL;
+ auto_count = 0;
+ if (!restart && line != NULL) {
+ /*
+ * If this target has never been built before, mark all
+ * of the dependencies as never built.
+ */
+ for (dependency = line->body.line.dependencies;
+ dependency != NULL;
+ dependency = dependency->next) {
+ dependency->built = false;
+ }
+ }
+ /* Save the set of automatic depes defined for this target */
+ if (keep_state &&
+ (line != NULL) &&
+ (line->body.line.dependencies != NULL)) {
+ Name *p;
+
+ /*
+ * First run thru the dependency list to see how many
+ * autos there are.
+ */
+ for (dependency = line->body.line.dependencies;
+ dependency != NULL;
+ dependency = dependency->next) {
+ if (dependency->automatic && !dependency->stale) {
+ auto_count++;
+ }
+ }
+ /* Create vector to hold the current autos */
+ automatics =
+ (Name *) alloca((int) (auto_count * sizeof (Name)));
+ /* Copy them */
+ for (p = automatics, dependency = line->body.line.dependencies;
+ dependency != NULL;
+ dependency = dependency->next) {
+ if (dependency->automatic && !dependency->stale) {
+ *p++ = dependency->name;
+ }
+ }
+ }
+ if (debug_level > 1) {
+ (void) printf(NOCATGETS("%*sdoname(%s)\n"),
+ recursion_level,
+ "",
+ target->string_mb);
+ }
+ recursion_level++;
+ /* Avoid infinite loops */
+ if (target->state == build_in_progress) {
+ warning(catgets(catd, 1, 16, "Infinite loop: Target `%s' depends on itself"),
+ target->string_mb);
+ return build_ok;
+ }
+ target->state = build_in_progress;
+
+ /* Activate conditional macros for the target */
+ if (!target->added_pattern_conditionals) {
+ add_pattern_conditionals(target);
+ target->added_pattern_conditionals = true;
+ }
+ if (target->conditional_cnt > 0) {
+ old_locals = (Property) alloca(target->conditional_cnt *
+ sizeof (Property_rec));
+ set_locals(target, old_locals);
+ }
+
+/*
+ * after making the call to dynamic_dependecies unconditional we can handle
+ * target names that are same as file name. In this case $$@ in the
+ * dependencies did not mean anything. WIth this change it expands it
+ * as expected.
+ */
+ if (!target->has_depe_list_expanded)
+ {
+#ifdef NSE
+ save_readdep = reading_dependencies;
+ reading_dependencies= true;
+#endif
+ dynamic_dependencies(target);
+#ifdef NSE
+ reading_dependencies= save_readdep;
+#endif
+ }
+
+/*
+ * FIRST SECTION -- GO THROUGH DEPENDENCIES AND COLLECT EXPLICIT
+ * COMMANDS TO RUN
+ */
+ if ((line = get_prop(target->prop, line_prop)) != NULL) {
+ if (check_dependencies(&result,
+ line,
+ do_get,
+ target,
+ true_target,
+ doing_subtree,
+ &out_of_date_list,
+ old_locals,
+ implicit,
+ &command,
+ less,
+ rechecking_target,
+ recheck_conditionals)) {
+ return build_running;
+ }
+ if (line->body.line.query != NULL) {
+ delete_query_chain(line->body.line.query);
+ }
+ line->body.line.query = out_of_date_list;
+ }
+
+#ifdef PARALLEL
+ if (doing_subtree) {
+ parallel = false;
+ }
+#endif
+
+/*
+ * If the target is a :: type, do not try to find the rule for the target,
+ * all actions will be taken by separate branches.
+ * Else, we try to find an implicit rule using various methods,
+ * we quit as soon as one is found.
+ *
+ * [tolik, 12 Sep 2002] Do not try to find implicit rule for the target
+ * being rechecked - the target is being rechecked means that it already
+ * has explicit dependencies derived from an implicit rule found
+ * in previous step.
+ */
+ if (target->colon_splits == 0 && !rechecking_target) {
+ /* Look for percent matched rule */
+ if ((result == build_dont_know) &&
+ (command == NULL)) {
+ switch (find_percent_rule(
+ target,
+ &command,
+ recheck_conditionals)) {
+ case build_failed:
+ result = build_failed;
+ break;
+#ifdef TEAMWARE_MAKE_CMN
+ case build_running:
+ target->state = build_running;
+ add_pending(target,
+ --recursion_level,
+ do_get,
+ implicit,
+ false);
+ if (target->conditional_cnt > 0) {
+ reset_locals(target,
+ old_locals,
+ get_prop(target->prop,
+ conditional_prop),
+ 0);
+ }
+ return build_running;
+#endif
+ case build_ok:
+ result = build_ok;
+ break;
+ }
+ }
+ /* Look for double suffix rule */
+ if (result == build_dont_know) {
+ Property member;
+
+ if (target->is_member &&
+ ((member = get_prop(target->prop, member_prop)) !=
+ NULL)) {
+ switch (find_ar_suffix_rule(target,
+ member->body.
+ member.member,
+ &command,
+ recheck_conditionals)) {
+ case build_failed:
+ result = build_failed;
+ break;
+#ifdef TEAMWARE_MAKE_CMN
+ case build_running:
+ target->state = build_running;
+ add_pending(target,
+ --recursion_level,
+ do_get,
+ implicit,
+ false);
+ if (target->conditional_cnt > 0) {
+ reset_locals(target,
+ old_locals,
+ get_prop(target->prop,
+ conditional_prop),
+ 0);
+ }
+ return build_running;
+#endif
+ default:
+ /* ALWAYS bind $% for old style */
+ /* ar rules */
+ if (line == NULL) {
+ line =
+ maybe_append_prop(target,
+ line_prop);
+ }
+ line->body.line.percent =
+ member->body.member.member;
+ break;
+ }
+ } else {
+ switch (find_double_suffix_rule(target,
+ &command,
+ recheck_conditionals)) {
+ case build_failed:
+ result = build_failed;
+ break;
+#ifdef TEAMWARE_MAKE_CMN
+ case build_running:
+ target->state = build_running;
+ add_pending(target,
+ --recursion_level,
+ do_get,
+ implicit,
+ false);
+ if (target->conditional_cnt > 0) {
+ reset_locals(target,
+ old_locals,
+ get_prop(target->
+ prop,
+ conditional_prop),
+ 0);
+ }
+ return build_running;
+#endif
+ }
+ }
+ }
+ /* Look for single suffix rule */
+
+/* /tolik/
+ * I commented !implicit to fix bug 1247448: Suffix Rules failed when combine with Pattern Matching Rules.
+ * This caused problem with SVR4 tilde rules (infinite recursion). So I made some changes in "implicit.cc"
+ */
+/* /tolik, 06.21.96/
+ * Regression! See BugId 1255360
+ * If more than one percent rules are defined for the same target then
+ * the behaviour of 'make' with my previous fix may be different from one
+ * of the 'old make'.
+ * The global variable second_pass (maybe it should be an argument to doname())
+ * is intended to avoid this regression. It is set in doname_check().
+ * First, 'make' will work as it worked before. Only when it is
+ * going to say "don't know how to make target" it sets second_pass to true and
+ * run 'doname' again but now trying to use Single Suffix Rules.
+ */
+ if ((result == build_dont_know) && !automatic && (!implicit || second_pass) &&
+ ((line == NULL) ||
+ ((line->body.line.target != NULL) &&
+ !line->body.line.target->has_regular_dependency))) {
+ switch (find_suffix_rule(target,
+ target,
+ empty_name,
+ &command,
+ recheck_conditionals)) {
+ case build_failed:
+ result = build_failed;
+ break;
+#ifdef TEAMWARE_MAKE_CMN
+ case build_running:
+ target->state = build_running;
+ add_pending(target,
+ --recursion_level,
+ do_get,
+ implicit,
+ false);
+ if (target->conditional_cnt > 0) {
+ reset_locals(target,
+ old_locals,
+ get_prop(target->prop,
+ conditional_prop),
+ 0);
+ }
+ return build_running;
+#endif
+ }
+ }
+ /* Try to sccs get */
+ if ((command == NULL) &&
+ (result == build_dont_know) &&
+ do_get) {
+ result = sccs_get(target, &command);
+ }
+
+ /* Use .DEFAULT rule if it is defined. */
+ if ((command == NULL) &&
+ (result == build_dont_know) &&
+ (true_target->colons == no_colon) &&
+ default_rule &&
+ !implicit) {
+ /* Make sure we have a line prop */
+ line = maybe_append_prop(target, line_prop);
+ command = line;
+ Boolean out_of_date;
+ if (true_target->is_member) {
+ out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
+ line->body.line.dependency_time);
+ } else {
+ out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
+ line->body.line.dependency_time);
+ }
+ if (build_unconditional || out_of_date) {
+ line->body.line.is_out_of_date = true;
+ if (debug_level > 0) {
+ (void) printf(catgets(catd, 1, 17, "%*sBuilding %s using .DEFAULT because it is out of date\n"),
+ recursion_level,
+ "",
+ true_target->string_mb);
+ }
+ }
+ line->body.line.sccs_command = false;
+ line->body.line.command_template = default_rule;
+ line->body.line.target = true_target;
+ line->body.line.star = NULL;
+ line->body.line.less = true_target;
+ line->body.line.percent = NULL;
+ }
+ }
+
+ /* We say "target up to date" if no cmd were executed for the target */
+ if (!target->is_double_colon_parent) {
+ commands_done = false;
+ }
+
+ silent = silent_all;
+ ignore_errors = ignore_errors_all;
+ if (posix)
+ {
+ if (!silent)
+ {
+ silent = (Boolean) target->silent_mode;
+ }
+ if (!ignore_errors)
+ {
+ ignore_errors = (Boolean) target->ignore_error_mode;
+ }
+ }
+
+ int doname_dyntarget = 0;
+r_command:
+ /* Run commands if any. */
+ if ((command != NULL) &&
+ (command->body.line.command_template != NULL)) {
+ if (result != build_failed) {
+ result = run_command(command,
+ (Boolean) ((parallel || save_parallel) && !silent));
+#ifdef NSE
+ nse_check_no_deps_no_rule(target,
+ get_prop(target->prop, line_prop), command);
+#endif
+ }
+ switch (result) {
+#ifdef TEAMWARE_MAKE_CMN
+ case build_running:
+ add_running(target,
+ true_target,
+ command,
+ --recursion_level,
+ auto_count,
+ automatics,
+ do_get,
+ implicit);
+ target->state = build_running;
+ if ((line = get_prop(target->prop,
+ line_prop)) != NULL) {
+ if (line->body.line.query != NULL) {
+ delete_query_chain(line->body.line.query);
+ }
+ line->body.line.query = NULL;
+ }
+ if (target->conditional_cnt > 0) {
+ reset_locals(target,
+ old_locals,
+ get_prop(target->prop,
+ conditional_prop),
+ 0);
+ }
+ return build_running;
+ case build_serial:
+ add_serial(target,
+ --recursion_level,
+ do_get,
+ implicit);
+ target->state = build_running;
+ line = get_prop(target->prop, line_prop);
+ if (line != NULL) {
+ if (line->body.line.query != NULL) {
+ delete_query_chain(line->body.line.query);
+ }
+ line->body.line.query = NULL;
+ }
+ if (target->conditional_cnt > 0) {
+ reset_locals(target,
+ old_locals,
+ get_prop(target->prop,
+ conditional_prop),
+ 0);
+ }
+ return build_running;
+#endif
+ case build_ok:
+ /* If all went OK set a nice timestamp */
+ if (true_target->stat.time == file_doesnt_exist) {
+ true_target->stat.time = file_max_time;
+ }
+ break;
+ }
+ } else {
+ /*
+ * If no command was found for the target, and it doesn't
+ * exist, and it is mentioned as a target in the makefile,
+ * we say it is extremely new and that it is OK.
+ */
+ if (target->colons != no_colon) {
+ if (true_target->stat.time == file_doesnt_exist){
+ true_target->stat.time = file_max_time;
+ }
+ result = build_ok;
+ }
+ /*
+ * Trying dynamic targets.
+ */
+ if(!doname_dyntarget) {
+ doname_dyntarget = 1;
+ Name dtarg = find_dyntarget(target);
+ if(dtarg!=NULL) {
+ if (!target->has_depe_list_expanded) {
+ dynamic_dependencies(target);
+ }
+ if ((line = get_prop(target->prop, line_prop)) != NULL) {
+ if (check_dependencies(&result,
+ line,
+ do_get,
+ target,
+ true_target,
+ doing_subtree,
+ &out_of_date_list,
+ old_locals,
+ implicit,
+ &command,
+ less,
+ rechecking_target,
+ recheck_conditionals))
+ {
+ return build_running;
+ }
+ if (line->body.line.query != NULL) {
+ delete_query_chain(line->body.line.query);
+ }
+ line->body.line.query = out_of_date_list;
+ }
+ goto r_command;
+ }
+ }
+ /*
+ * If the file exists, it is OK that we couldnt figure
+ * out how to build it.
+ */
+ (void) exists(target);
+ if ((target->stat.time != file_doesnt_exist) &&
+ (result == build_dont_know)) {
+ result = build_ok;
+ }
+ }
+
+ /*
+ * Some of the following is duplicated in the function finish_doname.
+ * If anything is changed here, check to see if it needs to be
+ * changed there.
+ */
+ if ((line = get_prop(target->prop, line_prop)) != NULL) {
+ if (line->body.line.query != NULL) {
+ delete_query_chain(line->body.line.query);
+ }
+ line->body.line.query = NULL;
+ }
+ target->state = result;
+ parallel = save_parallel;
+ if (target->conditional_cnt > 0) {
+ reset_locals(target,
+ old_locals,
+ get_prop(target->prop, conditional_prop),
+ 0);
+ }
+ recursion_level--;
+ if (target->is_member) {
+ Property member;
+
+ /* Propagate the timestamp from the member file to the member*/
+ if ((target->stat.time != file_max_time) &&
+ ((member = get_prop(target->prop, member_prop)) != NULL) &&
+ (exists(member->body.member.member) > file_doesnt_exist)) {
+ target->stat.time =
+ member->body.member.member->stat.time;
+ }
+ }
+ /*
+ * Check if we found any new auto dependencies when we
+ * built the target.
+ */
+ if ((result == build_ok) && check_auto_dependencies(target,
+ auto_count,
+ automatics)) {
+ if (debug_level > 0) {
+ (void) printf(catgets(catd, 1, 18, "%*sTarget `%s' acquired new dependencies from build, rechecking all dependencies\n"),
+ recursion_level,
+ "",
+ true_target->string_mb);
+ }
+ rechecking_target = true;
+ saved_commands_done = commands_done;
+ goto recheck_target;
+ }
+
+ if (rechecking_target && !commands_done) {
+ commands_done = saved_commands_done;
+ }
+
+ return result;
+}
+
+/*
+ * DONE.
+ *
+ * check_dependencies(result, line, do_get,
+ * target, true_target, doing_subtree, out_of_date_tail,
+ * old_locals, implicit, command, less, rechecking_target)
+ *
+ * Return value:
+ * True returned if some dependencies left running
+ *
+ * Parameters:
+ * result Pointer to cell we update if build failed
+ * line We get the dependencies from here
+ * do_get Allow use of sccs get in recursive doname()
+ * target The target to chase dependencies for
+ * true_target The real one for :: and lib(member)
+ * doing_subtree True if building a conditional macro subtree
+ * out_of_date_tail Used to set the $? list
+ * old_locals Used for resetting the local macros
+ * implicit Called when scanning for implicit rules?
+ * command Place to stuff command
+ * less Set to $< value
+ *
+ * Global variables used:
+ * command_changed Set if we suspect .make.state needs rewrite
+ * debug_level Should we trace actions?
+ * force The Name " FORCE", compared against
+ * recursion_level Used for tracing
+ * rewrite_statefile Set if .make.state needs rewriting
+ * wait_name The Name ".WAIT", compared against
+ */
+static Boolean
+#ifdef TEAMWARE_MAKE_CMN
+check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean doing_subtree, Chain *out_of_date_tail, Property old_locals, Boolean implicit, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals)
+#else
+check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean, Chain *out_of_date_tail, Property, Boolean, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals)
+#endif
+{
+ Boolean dependencies_running;
+ register Dependency dependency;
+ Doname dep_result;
+ Boolean dependency_changed = false;
+
+ line->body.line.dependency_time = file_doesnt_exist;
+ if (line->body.line.query != NULL) {
+ delete_query_chain(line->body.line.query);
+ }
+ line->body.line.query = NULL;
+ line->body.line.is_out_of_date = false;
+ dependencies_running = false;
+ /*
+ * Run thru all the dependencies and call doname() recursively
+ * on each of them.
+ */
+ for (dependency = line->body.line.dependencies;
+ dependency != NULL;
+ dependency = dependency->next) {
+ Boolean this_dependency_changed = false;
+
+ if (!dependency->automatic &&
+ (rechecking_target || target->rechecking_target)) {
+ /*
+ * We only bother with the autos when rechecking
+ */
+ continue;
+ }
+
+ if (dependency->name == wait_name) {
+ /*
+ * The special target .WAIT means finish all of
+ * the prior dependencies before continuing.
+ */
+ if (dependencies_running) {
+ break;
+ }
+#ifdef DISTRIBUTED
+ } else if ((!parallel_ok(dependency->name, false)) &&
+ (dependencies_running)) {
+ /*
+ * If we can't execute the current dependency in
+ * parallel, hold off the dependency processing
+ * to preserve the order of the dependencies.
+ */
+ break;
+#endif
+ } else {
+ timestruc_t depe_time = file_doesnt_exist;
+
+
+ if (true_target->is_member) {
+ depe_time = exists(dependency->name);
+ }
+ if (dependency->built ||
+ (dependency->name->state == build_failed)) {
+ dep_result = (Doname) dependency->name->state;
+ } else {
+#ifdef NSE
+ nse_check_sccs(target->string,
+ dependency->name->string);
+ nse_check_derived_src(target,
+ dependency->name->string,
+ line->body.line.command_template);
+#endif
+ dep_result = doname_check(dependency->name,
+ do_get,
+ false,
+ (Boolean) dependency->automatic);
+ }
+ if (true_target->is_member || dependency->name->is_member) {
+ /* should compare only secs, cause lib members does not have nsec time resolution */
+ if (depe_time.tv_sec != dependency->name->stat.time.tv_sec) {
+ this_dependency_changed =
+ dependency_changed =
+ true;
+ }
+ } else {
+ if (depe_time != dependency->name->stat.time) {
+ this_dependency_changed =
+ dependency_changed =
+ true;
+ }
+ }
+ dependency->built = true;
+ switch (dep_result) {
+ case build_running:
+ dependencies_running = true;
+ continue;
+ case build_failed:
+ *result = build_failed;
+ break;
+ case build_dont_know:
+/*
+ * If make can't figure out how to make a dependency, maybe the dependency
+ * is out of date. In this case, we just declare the target out of date
+ * and go on. If we really need the dependency, the make'ing of the target
+ * will fail. This will only happen for automatic (hidden) dependencies.
+ */
+ if(!recheck_conditionals) {
+ line->body.line.is_out_of_date = true;
+ }
+ /*
+ * Make sure the dependency is not saved
+ * in the state file.
+ */
+ dependency->stale = true;
+ rewrite_statefile =
+ command_changed =
+ true;
+ if (debug_level > 0) {
+ (void) printf(catgets(catd, 1, 19, "Target %s rebuilt because dependency %s does not exist\n"),
+ true_target->string_mb,
+ dependency->name->string_mb);
+ }
+ break;
+ }
+ if (dependency->name->depends_on_conditional) {
+ target->depends_on_conditional = true;
+ }
+ if (dependency->name == force) {
+ target->stat.time =
+ dependency->name->stat.time;
+ }
+ /*
+ * Propagate new timestamp from "member" to
+ * "lib.a(member)".
+ */
+ (void) exists(dependency->name);
+
+ /* Collect the timestamp of the youngest dependency */
+ line->body.line.dependency_time =
+ MAX(dependency->name->stat.time,
+ line->body.line.dependency_time);
+
+ /* Correction: do not consider nanosecs for members */
+ if(true_target->is_member || dependency->name->is_member) {
+ line->body.line.dependency_time.tv_nsec = 0;
+ }
+
+ if (debug_level > 1) {
+ (void) printf(catgets(catd, 1, 20, "%*sDate(%s)=%s \n"),
+ recursion_level,
+ "",
+ dependency->name->string_mb,
+ time_to_string(dependency->name->
+ stat.time));
+ if (dependency->name->stat.time > line->body.line.dependency_time) {
+ (void) printf(catgets(catd, 1, 21, "%*sDate-dependencies(%s) set to %s\n"),
+ recursion_level,
+ "",
+ true_target->string_mb,
+ time_to_string(line->body.line.
+ dependency_time));
+ }
+ }
+
+ /* Build the $? list */
+ if (true_target->is_member) {
+ if (this_dependency_changed == true) {
+ true_target->stat.time = dependency->name->stat.time;
+ true_target->stat.time.tv_sec--;
+ } else {
+ /* Dina:
+ * The next statement is commented
+ * out as a fix for bug #1051032.
+ * if dependency hasn't changed
+ * then there's no need to invalidate
+ * true_target. This statemnt causes
+ * make to take much longer to process
+ * an already-built archive. Soren
+ * said it was a quick fix for some
+ * problem he doesn't remember.
+ true_target->stat.time = file_no_time;
+ */
+ (void) exists(true_target);
+ }
+ } else {
+ (void) exists(true_target);
+ }
+ Boolean out_of_date;
+ if (true_target->is_member || dependency->name->is_member) {
+ out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
+ dependency->name->stat.time);
+ } else {
+ out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
+ dependency->name->stat.time);
+ }
+ if ((build_unconditional || out_of_date) &&
+ (dependency->name != force) &&
+ (dependency->stale == false)) {
+ *out_of_date_tail = ALLOC(Chain);
+ if (dependency->name->is_member &&
+ (get_prop(dependency->name->prop,
+ member_prop) != NULL)) {
+ (*out_of_date_tail)->name =
+ get_prop(dependency->name->prop,
+ member_prop)->
+ body.member.member;
+ } else {
+ (*out_of_date_tail)->name =
+ dependency->name;
+ }
+ (*out_of_date_tail)->next = NULL;
+ out_of_date_tail = &(*out_of_date_tail)->next;
+ if (debug_level > 0) {
+ if (dependency->name->stat.time == file_max_time) {
+ (void) printf(catgets(catd, 1, 22, "%*sBuilding %s because %s does not exist\n"),
+ recursion_level,
+ "",
+ true_target->string_mb,
+ dependency->name->string_mb);
+ } else {
+ (void) printf(catgets(catd, 1, 23, "%*sBuilding %s because it is out of date relative to %s\n"),
+ recursion_level,
+ "",
+ true_target->string_mb,
+ dependency->name->string_mb);
+ }
+ }
+ }
+ if (dependency->name == force) {
+ force->stat.time =
+ file_max_time;
+ force->state = build_dont_know;
+ }
+ }
+ }
+#ifdef TEAMWARE_MAKE_CMN
+ if (dependencies_running) {
+ if (doing_subtree) {
+ if (target->conditional_cnt > 0) {
+ reset_locals(target,
+ old_locals,
+ get_prop(target->prop,
+ conditional_prop),
+ 0);
+ }
+ return true;
+ } else {
+ target->state = build_running;
+ add_pending(target,
+ --recursion_level,
+ do_get,
+ implicit,
+ false);
+ if (target->conditional_cnt > 0) {
+ reset_locals(target,
+ old_locals,
+ get_prop(target->prop,
+ conditional_prop),
+ 0);
+ }
+ return true;
+ }
+ }
+#endif
+ /*
+ * Collect the timestamp of the youngest double colon target
+ * dependency.
+ */
+ if (target->is_double_colon_parent) {
+ for (dependency = line->body.line.dependencies;
+ dependency != NULL;
+ dependency = dependency->next) {
+ Property tmp_line;
+
+ if ((tmp_line = get_prop(dependency->name->prop, line_prop)) != NULL) {
+ if(tmp_line->body.line.dependency_time != file_max_time) {
+ target->stat.time =
+ MAX(tmp_line->body.line.dependency_time,
+ target->stat.time);
+ }
+ }
+ }
+ }
+ if ((true_target->is_member) && (dependency_changed == true)) {
+ true_target->stat.time = file_no_time;
+ }
+ /*
+ * After scanning all the dependencies, we check the rule
+ * if we found one.
+ */
+ if (line->body.line.command_template != NULL) {
+ if (line->body.line.command_template_redefined) {
+ warning(catgets(catd, 1, 24, "Too many rules defined for target %s"),
+ target->string_mb);
+ }
+ *command = line;
+ /* Check if the target is out of date */
+ Boolean out_of_date;
+ if (true_target->is_member) {
+ out_of_date = (Boolean) OUT_OF_DATE_SEC(true_target->stat.time,
+ line->body.line.dependency_time);
+ } else {
+ out_of_date = (Boolean) OUT_OF_DATE(true_target->stat.time,
+ line->body.line.dependency_time);
+ }
+ if (build_unconditional || out_of_date){
+ if(!recheck_conditionals) {
+ line->body.line.is_out_of_date = true;
+ }
+ }
+ line->body.line.sccs_command = false;
+ line->body.line.target = true_target;
+ if(gnu_style) {
+
+ // set $< for explicit rule
+ if(line->body.line.dependencies != NULL) {
+ less = line->body.line.dependencies->name;
+ }
+
+ // set $* for explicit rule
+ Name target_body;
+ Name tt = true_target;
+ Property member;
+ register wchar_t *target_end;
+ register Dependency suffix;
+ register int suffix_length;
+ Wstring targ_string;
+ Wstring suf_string;
+
+ if (true_target->is_member &&
+ ((member = get_prop(target->prop, member_prop)) !=
+ NULL)) {
+ tt = member->body.member.member;
+ }
+ targ_string.init(tt);
+ target_end = targ_string.get_string() + tt->hash.length;
+ for (suffix = suffixes; suffix != NULL; suffix = suffix->next) {
+ suffix_length = suffix->name->hash.length;
+ suf_string.init(suffix->name);
+ if (tt->hash.length < suffix_length) {
+ continue;
+ } else if (!IS_WEQUALN(suf_string.get_string(),
+ (target_end - suffix_length),
+ suffix_length)) {
+ continue;
+ }
+ target_body = GETNAME(
+ targ_string.get_string(),
+ (int)(tt->hash.length - suffix_length)
+ );
+ line->body.line.star = target_body;
+ }
+
+ // set result = build_ok so that implicit rules are not used.
+ if(*result == build_dont_know) {
+ *result = build_ok;
+ }
+ }
+ if (less != NULL) {
+ line->body.line.less = less;
+ }
+ }
+
+ return false;
+}
+
+/*
+ * dynamic_dependencies(target)
+ *
+ * Checks if any dependency contains a macro ref
+ * If so, it replaces the dependency with the expanded version.
+ * Here, "$@" gets translated to target->string. That is
+ * the current name on the left of the colon in the
+ * makefile. Thus,
+ * xyz: s.$@.c
+ * translates into
+ * xyz: s.xyz.c
+ *
+ * Also, "$(@F)" translates to the same thing without a preceeding
+ * directory path (if one exists).
+ * Note, to enter "$@" on a dependency line in a makefile
+ * "$$@" must be typed. This is because make expands
+ * macros in dependency lists upon reading them.
+ * dynamic_dependencies() also expands file wildcards.
+ * If there are any Shell meta characters in the name,
+ * search the directory, and replace the dependency
+ * with the set of files the pattern matches
+ *
+ * Parameters:
+ * target Target to sanitize dependencies for
+ *
+ * Global variables used:
+ * c_at The Name "@", used to set macro value
+ * debug_level Should we trace actions?
+ * dot The Name ".", used to read directory
+ * recursion_level Used for tracing
+ */
+void
+dynamic_dependencies(Name target)
+{
+ wchar_t pattern[MAXPATHLEN];
+ register wchar_t *p;
+ Property line;
+ register Dependency dependency;
+ register Dependency *remove;
+ String_rec string;
+ wchar_t buffer[MAXPATHLEN];
+ register Boolean set_at = false;
+ register wchar_t *start;
+ Dependency new_depe;
+ register Boolean reuse_cell;
+ Dependency first_member;
+ Name directory;
+ Name lib;
+ Name member;
+ Property prop;
+ Name true_target = target;
+ wchar_t *library;
+
+ if ((line = get_prop(target->prop, line_prop)) == NULL) {
+ return;
+ }
+ /* If the target is constructed from a "::" target we consider that */
+ if (target->has_target_prop) {
+ true_target = get_prop(target->prop,
+ target_prop)->body.target.target;
+ }
+ /* Scan all dependencies and process the ones that contain "$" chars */
+ for (dependency = line->body.line.dependencies;
+ dependency != NULL;
+ dependency = dependency->next) {
+ if (!dependency->name->dollar) {
+ continue;
+ }
+ target->has_depe_list_expanded = true;
+
+ /* The make macro $@ is bound to the target name once per */
+ /* invocation of dynamic_dependencies() */
+ if (!set_at) {
+ (void) SETVAR(c_at, true_target, false);
+ set_at = true;
+ }
+ /* Expand this dependency string */
+ INIT_STRING_FROM_STACK(string, buffer);
+ expand_value(dependency->name, &string, false);
+ /* Scan the expanded string. It could contain whitespace */
+ /* which mean it expands to several dependencies */
+ start = string.buffer.start;
+ while (iswspace(*start)) {
+ start++;
+ }
+ /* Remove the cell (later) if the macro was empty */
+ if (start[0] == (int) nul_char) {
+ dependency->name = NULL;
+ }
+
+/* azv 10/26/95 to fix bug BID_1170218 */
+ if ((start[0] == (int) period_char) &&
+ (start[1] == (int) slash_char)) {
+ start += 2;
+ }
+/* azv */
+
+ first_member = NULL;
+ /* We use the original dependency cell for the first */
+ /* dependency from the expansion */
+ reuse_cell = true;
+ /* We also have to deal with dependencies that expand to */
+ /* lib.a(members) notation */
+ for (p = start; *p != (int) nul_char; p++) {
+ if ((*p == (int) parenleft_char)) {
+ lib = GETNAME(start, p - start);
+ lib->is_member = true;
+ first_member = dependency;
+ start = p + 1;
+ while (iswspace(*start)) {
+ start++;
+ }
+ break;
+ }
+ }
+ do {
+ /* First skip whitespace */
+ for (p = start; *p != (int) nul_char; p++) {
+ if ((*p == (int) nul_char) ||
+ iswspace(*p) ||
+ (*p == (int) parenright_char)) {
+ break;
+ }
+ }
+ /* Enter dependency from expansion */
+ if (p != start) {
+ /* Create new dependency cell if */
+ /* this is not the first dependency */
+ /* picked from the expansion */
+ if (!reuse_cell) {
+ new_depe = ALLOC(Dependency);
+ new_depe->next = dependency->next;
+ new_depe->automatic = false;
+ new_depe->stale = false;
+ new_depe->built = false;
+ dependency->next = new_depe;
+ dependency = new_depe;
+ }
+ reuse_cell = false;
+ /* Internalize the dependency name */
+ // tolik. Fix for bug 4110429: inconsistent expansion for macros that
+ // include "//" and "/./"
+ //dependency->name = GETNAME(start, p - start);
+ dependency->name = normalize_name(start, p - start);
+ if ((debug_level > 0) &&
+ (first_member == NULL)) {
+ (void) printf(catgets(catd, 1, 25, "%*sDynamic dependency `%s' for target `%s'\n"),
+ recursion_level,
+ "",
+ dependency->name->string_mb,
+ true_target->string_mb);
+ }
+ for (start = p; iswspace(*start); start++);
+ p = start;
+ }
+ } while ((*p != (int) nul_char) &&
+ (*p != (int) parenright_char));
+ /* If the expansion was of lib.a(members) format we now */
+ /* enter the proper member cells */
+ if (first_member != NULL) {
+ /* Scan the new dependencies and transform them from */
+ /* "foo" to "lib.a(foo)" */
+ for (; 1; first_member = first_member->next) {
+ /* Build "lib.a(foo)" name */
+ INIT_STRING_FROM_STACK(string, buffer);
+ APPEND_NAME(lib,
+ &string,
+ (int) lib->hash.length);
+ append_char((int) parenleft_char, &string);
+ APPEND_NAME(first_member->name,
+ &string,
+ FIND_LENGTH);
+ append_char((int) parenright_char, &string);
+ member = first_member->name;
+ /* Replace "foo" with "lib.a(foo)" */
+ first_member->name =
+ GETNAME(string.buffer.start, FIND_LENGTH);
+ if (string.free_after_use) {
+ retmem(string.buffer.start);
+ }
+ if (debug_level > 0) {
+ (void) printf(catgets(catd, 1, 26, "%*sDynamic dependency `%s' for target `%s'\n"),
+ recursion_level,
+ "",
+ first_member->name->
+ string_mb,
+ true_target->string_mb);
+ }
+ first_member->name->is_member = lib->is_member;
+ /* Add member property to member */
+ prop = maybe_append_prop(first_member->name,
+ member_prop);
+ prop->body.member.library = lib;
+ prop->body.member.entry = NULL;
+ prop->body.member.member = member;
+ if (first_member == dependency) {
+ break;
+ }
+ }
+ }
+ }
+ Wstring wcb;
+ /* Then scan all the dependencies again. This time we want to expand */
+ /* shell file wildcards */
+ for (remove = &line->body.line.dependencies, dependency = *remove;
+ dependency != NULL;
+ dependency = *remove) {
+ if (dependency->name == NULL) {
+ dependency = *remove = (*remove)->next;
+ continue;
+ }
+ /* If dependency name string contains shell wildcards */
+ /* replace the name with the expansion */
+ if (dependency->name->wildcard) {
+#ifdef NSE
+ nse_wildcard(target->string, dependency->name->string);
+#endif
+ wcb.init(dependency->name);
+ if ((start = (wchar_t *) wschr(wcb.get_string(),
+ (int) parenleft_char)) != NULL) {
+ /* lib(*) type pattern */
+ library = buffer;
+ (void) wsncpy(buffer,
+ wcb.get_string(),
+ start - wcb.get_string());
+ buffer[start-wcb.get_string()] =
+ (int) nul_char;
+ (void) wsncpy(pattern,
+ start + 1,
+(int) (dependency->name->hash.length-(start-wcb.get_string())-2));
+ pattern[dependency->name->hash.length -
+ (start-wcb.get_string()) - 2] =
+ (int) nul_char;
+ } else {
+ library = NULL;
+ (void) wsncpy(pattern,
+ wcb.get_string(),
+ (int) dependency->name->hash.length);
+ pattern[dependency->name->hash.length] =
+ (int) nul_char;
+ }
+ start = (wchar_t *) wsrchr(pattern, (int) slash_char);
+ if (start == NULL) {
+ directory = dot;
+ p = pattern;
+ } else {
+ directory = GETNAME(pattern, start-pattern);
+ p = start+1;
+ }
+ /* The expansion is handled by the read_dir() routine*/
+ if (read_dir(directory, p, line, library)) {
+ *remove = (*remove)->next;
+ } else {
+ remove = &dependency->next;
+ }
+ } else {
+ remove = &dependency->next;
+ }
+ }
+
+ /* Then unbind $@ */
+ (void) SETVAR(c_at, (Name) NULL, false);
+}
+
+/*
+ * DONE.
+ *
+ * run_command(line)
+ *
+ * Takes one Cmd_line and runs the commands from it.
+ *
+ * Return value:
+ * Indicates if the command failed or not
+ *
+ * Parameters:
+ * line The command line to run
+ *
+ * Global variables used:
+ * commands_done Set if we do run command
+ * current_line Set to the line we run a command from
+ * current_target Set to the target we run a command for
+ * file_number Used to form temp file name
+ * keep_state Indicates that .KEEP_STATE is on
+ * make_state The Name ".make.state", used to check timestamp
+ * parallel True if currently building in parallel
+ * parallel_process_cnt Count of parallel processes running
+ * quest Indicates that make -q is on
+ * rewrite_statefile Set if we do run a command
+ * sunpro_dependencies The Name "SUNPRO_DEPENDENCIES", set value
+ * temp_file_directory Used to form temp fie name
+ * temp_file_name Set to the name of the temp file
+ * touch Indicates that make -t is on
+ */
+static Doname
+run_command(register Property line, Boolean)
+{
+ register Doname result = build_ok;
+ register Boolean remember_only = false;
+ register Name target = line->body.line.target;
+ wchar_t *string;
+ char tmp_file_path[MAXPATHLEN];
+
+ if (!line->body.line.is_out_of_date && target->rechecking_target) {
+ target->rechecking_target = false;
+ return build_ok;
+ }
+
+ /*
+ * Build the command if we know the target is out of date,
+ * or if we want to check cmd consistency.
+ */
+ if (line->body.line.is_out_of_date || keep_state) {
+ /* Hack for handling conditional macros in DMake. */
+ if (!line->body.line.dont_rebuild_command_used) {
+ build_command_strings(target, line);
+ }
+ }
+ /* Never mind */
+ if (!line->body.line.is_out_of_date) {
+ return build_ok;
+ }
+ /* If quest, then exit(1) because the target is out of date */
+ if (quest) {
+ if (posix) {
+#ifdef TEAMWARE_MAKE_CMN
+ result = execute_parallel(line, true);
+#else
+ result = execute_serial(line);
+#endif
+ }
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ exit_status = 1;
+#endif
+ exit(1);
+ }
+ /* We actually had to do something this time */
+ rewrite_statefile = commands_done = true;
+ /*
+ * If this is an sccs command, we have to do some extra checking
+ * and possibly complain. If the file can't be gotten because it's
+ * checked out, we complain and behave as if the command was
+ * executed eventhough we ignored the command.
+ */
+ if (!touch &&
+ line->body.line.sccs_command &&
+ (target->stat.time != file_doesnt_exist) &&
+ ((target->stat.mode & 0222) != 0)) {
+ fatal(catgets(catd, 1, 27, "%s is writable so it cannot be sccs gotten"),
+ target->string_mb);
+ target->has_complained = remember_only = true;
+ }
+ /*
+ * If KEEP_STATE is on, we make sure we have the timestamp for
+ * .make.state. If .make.state changes during the command run,
+ * we reread .make.state after the command. We also setup the
+ * environment variable that asks utilities to report dependencies.
+ */
+ if (!touch &&
+ keep_state &&
+ !remember_only) {
+ (void) exists(make_state);
+ if((strlen(temp_file_directory) == 1) &&
+ (temp_file_directory[0] == '/')) {
+ tmp_file_path[0] = '\0';
+ } else {
+ strcpy(tmp_file_path, temp_file_directory);
+ }
+ sprintf(mbs_buffer,
+ NOCATGETS("%s/.make.dependency.%08x.%d.%d"),
+ tmp_file_path,
+ hostid,
+ getpid(),
+ file_number++);
+ MBSTOWCS(wcs_buffer, mbs_buffer);
+ Boolean fnd;
+ temp_file_name = getname_fn(wcs_buffer, FIND_LENGTH, false, &fnd);
+ temp_file_name->stat.is_file = true;
+ int len = 2*MAXPATHLEN + strlen(target->string_mb) + 2;
+ wchar_t *to = string = ALLOC_WC(len);
+ for (wchar_t *from = wcs_buffer; *from != (int) nul_char; ) {
+ if (*from == (int) space_char) {
+ *to++ = (int) backslash_char;
+ }
+ *to++ = *from++;
+ }
+ *to++ = (int) space_char;
+ MBSTOWCS(to, target->string_mb);
+ Name sprodep_name = getname_fn(string, FIND_LENGTH, false, &fnd);
+ (void) SETVAR(sunpro_dependencies,
+ sprodep_name,
+ false);
+ retmem(string);
+ } else {
+ temp_file_name = NULL;
+ }
+
+ /*
+ * In case we are interrupted, we need to know what was going on.
+ */
+ current_target = target;
+ /*
+ * We also need to be able to save an empty command instead of the
+ * interrupted one in .make.state.
+ */
+ current_line = line;
+ if (remember_only) {
+ /* Empty block!!! */
+ } else if (touch) {
+ result = touch_command(line, target, result);
+ if (posix) {
+#ifdef TEAMWARE_MAKE_CMN
+ result = execute_parallel(line, true);
+#else
+ result = execute_serial(line);
+#endif
+ }
+ } else {
+ /*
+ * If this is not a touch run, we need to execute the
+ * proper command(s) for the target.
+ */
+#ifdef TEAMWARE_MAKE_CMN
+ if (parallel) {
+ if (!parallel_ok(target, true)) {
+ /*
+ * We are building in parallel, but
+ * this target must be built in serial.
+ */
+ /*
+ * If nothing else is building,
+ * do this one, else wait.
+ */
+ if (parallel_process_cnt == 0) {
+#ifdef TEAMWARE_MAKE_CMN
+ result = execute_parallel(line, true, target->localhost);
+#else
+ result = execute_serial(line);
+#endif
+ } else {
+ current_target = NULL;
+ current_line = NULL;
+/*
+ line->body.line.command_used = NULL;
+ */
+ line->body.line.dont_rebuild_command_used = true;
+ return build_serial;
+ }
+ } else {
+ result = execute_parallel(line, false);
+ switch (result) {
+ case build_running:
+ return build_running;
+ case build_serial:
+ if (parallel_process_cnt == 0) {
+#ifdef TEAMWARE_MAKE_CMN
+ result = execute_parallel(line, true, target->localhost);
+#else
+ result = execute_serial(line);
+#endif
+ } else {
+ current_target = NULL;
+ current_line = NULL;
+ target->parallel = false;
+ line->body.line.command_used =
+ NULL;
+ return build_serial;
+ }
+ }
+ }
+ } else {
+#endif
+#ifdef TEAMWARE_MAKE_CMN
+ result = execute_parallel(line, true, target->localhost);
+#else
+ result = execute_serial(line);
+#endif
+#ifdef TEAMWARE_MAKE_CMN
+ }
+#endif
+ }
+ temp_file_name = NULL;
+ if (report_dependencies_level == 0){
+ update_target(line, result);
+ }
+ current_target = NULL;
+ current_line = NULL;
+ return result;
+}
+
+/*
+ * execute_serial(line)
+ *
+ * Runs thru the command line for the target and
+ * executes the rules one by one.
+ *
+ * Return value:
+ * The result of the command build
+ *
+ * Parameters:
+ * line The command to execute
+ *
+ * Static variables used:
+ *
+ * Global variables used:
+ * continue_after_error -k flag
+ * do_not_exec_rule -n flag
+ * report_dependencies -P flag
+ * silent Don't echo commands before executing
+ * temp_file_name Temp file for auto dependencies
+ * vpath_defined If true, translate path for command
+ */
+Doname
+execute_serial(Property line)
+{
+ int child_pid = 0;
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+ Avo_MToolJobResultMsg *job_result_msg;
+ RWCollectable *xdr_msg;
+#endif
+ Boolean printed_serial;
+ Doname result = build_ok;
+ Cmd_line rule, cmd_tail, command = NULL;
+ char mbstring[MAXPATHLEN];
+ int filed;
+ Name target = line->body.line.target;
+
+ SEND_MTOOL_MSG(
+ if (!sent_rsrc_info_msg) {
+ if (userName[0] == '\0') {
+ avo_get_user(userName, NULL);
+ }
+ if (hostName[0] == '\0') {
+ strcpy(hostName, avo_hostname());
+ }
+ send_rsrc_info_msg(1, hostName, userName);
+ sent_rsrc_info_msg = 1;
+ }
+ send_job_start_msg(line);
+ job_result_msg = new Avo_MToolJobResultMsg();
+ );
+
+ target->has_recursive_dependency = false;
+ // We have to create a copy of the rules chain for processing because
+ // the original one can be destroyed during .make.state file rereading.
+ for (rule = line->body.line.command_used;
+ rule != NULL;
+ rule = rule->next) {
+ if (command == NULL) {
+ command = cmd_tail = ALLOC(Cmd_line);
+ } else {
+ cmd_tail->next = ALLOC(Cmd_line);
+ cmd_tail = cmd_tail->next;
+ }
+ *cmd_tail = *rule;
+ }
+ if (command) {
+ cmd_tail->next = NULL;
+ }
+ for (rule = command; rule != NULL; rule = rule->next) {
+ if (posix && (touch || quest) && !rule->always_exec) {
+ continue;
+ }
+ if (vpath_defined) {
+ rule->command_line =
+ vpath_translation(rule->command_line);
+ }
+ /* Echo command line, maybe. */
+ if ((rule->command_line->hash.length > 0) &&
+ !silent &&
+ (!rule->silent || do_not_exec_rule) &&
+ (report_dependencies_level == 0)) {
+ (void) printf("%s\n", rule->command_line->string_mb);
+ SEND_MTOOL_MSG(
+ job_result_msg->appendOutput(AVO_STRDUP(rule->command_line->string_mb));
+ );
+ }
+ if (rule->command_line->hash.length > 0) {
+ SEND_MTOOL_MSG(
+ (void) sprintf(mbstring,
+ NOCATGETS("%s/make.stdout.%d.%d.XXXXXX"),
+ tmpdir,
+ getpid(),
+ file_number++);
+
+ int tmp_fd = mkstemp(mbstring);
+ if(tmp_fd) {
+ (void) close(tmp_fd);
+ }
+
+ stdout_file = strdup(mbstring);
+ stderr_file = NULL;
+ child_pid = pollResults(stdout_file,
+ (char *)NULL,
+ (char *)NULL);
+ );
+ /* Do assignment if command line prefixed with "=" */
+ if (rule->assign) {
+ result = build_ok;
+ do_assign(rule->command_line, target);
+ } else if (report_dependencies_level == 0) {
+ /* Execute command line. */
+#ifdef DISTRIBUTED
+ setvar_envvar((Avo_DoJobMsg *)NULL);
+#else
+ setvar_envvar();
+#endif
+ result = dosys(rule->command_line,
+ (Boolean) rule->ignore_error,
+ (Boolean) rule->make_refd,
+ /* ds 98.04.23 bug #4085164. make should always show error messages */
+ false,
+ /* BOOLEAN(rule->silent &&
+ rule->ignore_error), */
+ (Boolean) rule->always_exec,
+ target,
+ send_mtool_msgs);
+#ifdef NSE
+ nse_did_recursion= false;
+#endif
+ check_state(temp_file_name);
+#ifdef NSE
+ nse_check_cd(line);
+#endif
+ }
+ SEND_MTOOL_MSG(
+ append_job_result_msg(job_result_msg);
+ if (child_pid > 0) {
+ kill(child_pid, SIGUSR1);
+ while (!((waitpid(child_pid, 0, 0) == -1)
+ && (errno == ECHILD)));
+ }
+ child_pid = 0;
+ (void) unlink(stdout_file);
+ retmem_mb(stdout_file);
+ stdout_file = NULL;
+ );
+ } else {
+ result = build_ok;
+ }
+ if (result == build_failed) {
+ if (silent || rule->silent) {
+ (void) printf(catgets(catd, 1, 242, "The following command caused the error:\n%s\n"),
+ rule->command_line->string_mb);
+ SEND_MTOOL_MSG(
+ job_result_msg->appendOutput(AVO_STRDUP(catgets(catd, 1, 243, "The following command caused the error:")));
+ job_result_msg->appendOutput(AVO_STRDUP(rule->command_line->string_mb));
+ );
+ }
+ if (!rule->ignore_error && !ignore_errors) {
+ if (!continue_after_error) {
+ SEND_MTOOL_MSG(
+ job_result_msg->setResult(job_msg_id, (result == build_ok) ? 0 : 1, DONE);
+ xdr_msg = (RWCollectable*)
+ job_result_msg;
+ xdr(&xdrs, xdr_msg);
+ (void) fflush(mtool_msgs_fp);
+ delete job_result_msg;
+ );
+ fatal(catgets(catd, 1, 244, "Command failed for target `%s'"),
+ target->string_mb);
+ }
+ /*
+ * Make sure a failing command is not
+ * saved in .make.state.
+ */
+ line->body.line.command_used = NULL;
+ break;
+ } else {
+ result = build_ok;
+ }
+ }
+ }
+ for (rule = command; rule != NULL; rule = cmd_tail) {
+ cmd_tail = rule->next;
+ free(rule);
+ }
+ command = NULL;
+ SEND_MTOOL_MSG(
+ job_result_msg->setResult(job_msg_id, (result == build_ok) ? 0 : 1, DONE);
+ xdr_msg = (RWCollectable*) job_result_msg;
+ xdr(&xdrs, xdr_msg);
+ (void) fflush(mtool_msgs_fp);
+
+ delete job_result_msg;
+ );
+ if (temp_file_name != NULL) {
+ free_name(temp_file_name);
+ }
+ temp_file_name = NULL;
+
+ Property spro = get_prop(sunpro_dependencies->prop, macro_prop);
+ if(spro != NULL) {
+ Name val = spro->body.macro.value;
+ if(val != NULL) {
+ free_name(val);
+ spro->body.macro.value = NULL;
+ }
+ }
+ spro = get_prop(sunpro_dependencies->prop, env_mem_prop);
+ if(spro) {
+ char *val = spro->body.env_mem.value;
+ if(val != NULL) {
+ /*
+ * Do not return memory allocated for SUNPRO_DEPENDENCIES
+ * It will be returned in setvar_daemon() in macro.cc
+ */
+ // retmem_mb(val);
+ spro->body.env_mem.value = NULL;
+ }
+ }
+
+ return result;
+}
+
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+
+/*
+ * Create and send an Avo_MToolRsrcInfoMsg.
+ */
+void
+send_rsrc_info_msg(int max_jobs, char *hostname, char *username)
+{
+ static int first = 1;
+ Avo_MToolRsrcInfoMsg *msg;
+ RWSlistCollectables server_list;
+ Avo_ServerState *server_state;
+ RWCollectable *xdr_msg;
+
+ if (!first) {
+ return;
+ }
+ first = 0;
+
+ create_xdrs_ptr();
+
+ server_state = new Avo_ServerState(max_jobs, hostname, username);
+ server_list.append(server_state);
+ msg = new Avo_MToolRsrcInfoMsg(&server_list);
+
+ xdr_msg = (RWCollectable *)msg;
+ xdr(get_xdrs_ptr(), xdr_msg);
+ (void) fflush(get_mtool_msgs_fp());
+
+ delete server_state;
+ delete msg;
+}
+
+/*
+ * Create and send an Avo_MToolJobStartMsg.
+ */
+void
+send_job_start_msg(Property line)
+{
+ int cmd_options = 0;
+ Avo_MToolJobStartMsg *msg;
+ Cmd_line rule;
+ Name target = line->body.line.target;
+ RWCollectable *xdr_msg;
+
+ if (userName[0] == '\0') {
+ avo_get_user(userName, NULL);
+ }
+ if (hostName[0] == '\0') {
+ strcpy(hostName, avo_hostname());
+ }
+
+ msg = new Avo_MToolJobStartMsg();
+ msg->setJobId(++job_msg_id);
+ msg->setTarget(AVO_STRDUP(target->string_mb));
+ msg->setHost(AVO_STRDUP(hostName));
+ msg->setUser(AVO_STRDUP(userName));
+
+ for (rule = line->body.line.command_used;
+ rule != NULL;
+ rule = rule->next) {
+ if (posix && (touch || quest) && !rule->always_exec) {
+ continue;
+ }
+ if (vpath_defined) {
+ rule->command_line =
+ vpath_translation(rule->command_line);
+ }
+ cmd_options = 0;
+ if (rule->ignore_error || ignore_errors) {
+ cmd_options |= ignore_mask;
+ }
+ if (rule->silent || silent) {
+ cmd_options |= silent_mask;
+ }
+ if (rule->command_line->meta) {
+ cmd_options |= meta_mask;
+ }
+ if (!touch && (rule->command_line->hash.length > 0)) {
+ msg->appendCmd(new Avo_DmakeCommand(rule->command_line->string_mb, cmd_options));
+ }
+ }
+
+ xdr_msg = (RWCollectable*) msg;
+ xdr(&xdrs, xdr_msg);
+ (void) fflush(mtool_msgs_fp);
+
+/* tolik, 08/39/2002.
+ I commented out this code because it causes using unallocated memory.
+ delete msg;
+*/
+}
+
+/*
+ * Append the stdout/err to Avo_MToolJobResultMsg.
+ */
+static void
+append_job_result_msg(Avo_MToolJobResultMsg *job_result_msg)
+{
+ FILE *fp;
+ char line[MAXPATHLEN];
+ char stdout_file2[MAXPATHLEN];
+
+ if (stdout_file != NULL) {
+ fp = fopen(stdout_file, "r");
+ if (fp == NULL) {
+ /* Hmmm... what should we do here? */
+ warning(catgets(catd, 1, 326, "fopen() of stdout_file failed. Output may be lost"));
+ return;
+ }
+ while (fgets(line, MAXPATHLEN, fp) != NULL) {
+ if (line[strlen(line) - 1] == '\n') {
+ line[strlen(line) - 1] = '\0';
+ }
+ job_result_msg->appendOutput(AVO_STRDUP(line));
+ }
+ (void) fclose(fp);
+ us_sleep(STAT_RETRY_SLEEP_TIME);
+ } else {
+ /* Hmmm... stdout_file shouldn't be NULL */
+ warning(catgets(catd, 1, 327, "Internal stdout_file variable shouldn't be NULL. Output may be lost"));
+ }
+}
+#endif /* TEAMWARE_MAKE_CMN */
+
+/*
+ * vpath_translation(cmd)
+ *
+ * Translates one command line by
+ * checking each word. If the word has an alias it is translated.
+ *
+ * Return value:
+ * The translated command
+ *
+ * Parameters:
+ * cmd Command to translate
+ *
+ * Global variables used:
+ */
+Name
+vpath_translation(register Name cmd)
+{
+ wchar_t buffer[STRING_BUFFER_LENGTH];
+ String_rec new_cmd;
+ wchar_t *p;
+ wchar_t *start;
+
+ if (!vpath_defined || (cmd == NULL) || (cmd->hash.length == 0)) {
+ return cmd;
+ }
+ INIT_STRING_FROM_STACK(new_cmd, buffer);
+
+ Wstring wcb(cmd);
+ p = wcb.get_string();
+
+ while (*p != (int) nul_char) {
+ while (iswspace(*p) && (*p != (int) nul_char)) {
+ append_char(*p++, &new_cmd);
+ }
+ start = p;
+ while (!iswspace(*p) && (*p != (int) nul_char)) {
+ p++;
+ }
+ cmd = GETNAME(start, p - start);
+ if (cmd->has_vpath_alias_prop) {
+ cmd = get_prop(cmd->prop, vpath_alias_prop)->
+ body.vpath_alias.alias;
+ APPEND_NAME(cmd,
+ &new_cmd,
+ (int) cmd->hash.length);
+ } else {
+ append_string(start, &new_cmd, p - start);
+ }
+ }
+ cmd = GETNAME(new_cmd.buffer.start, FIND_LENGTH);
+ if (new_cmd.free_after_use) {
+ retmem(new_cmd.buffer.start);
+ }
+ return cmd;
+}
+
+/*
+ * check_state(temp_file_name)
+ *
+ * Reads and checks the state changed by the previously executed command.
+ *
+ * Parameters:
+ * temp_file_name The auto dependency temp file
+ *
+ * Global variables used:
+ */
+void
+check_state(Name temp_file_name)
+{
+ if (!keep_state) {
+ return;
+ }
+
+ /*
+ * Then read the temp file that now might
+ * contain dependency reports from utilities
+ */
+ read_dependency_file(temp_file_name);
+
+ /*
+ * And reread .make.state if it
+ * changed (the command ran recursive makes)
+ */
+ check_read_state_file();
+ if (temp_file_name != NULL) {
+ (void) unlink(temp_file_name->string_mb);
+ }
+}
+
+/*
+ * read_dependency_file(filename)
+ *
+ * Read the temp file used for reporting dependencies to make
+ *
+ * Parameters:
+ * filename The name of the file with the state info
+ *
+ * Global variables used:
+ * makefile_type The type of makefile being read
+ * read_trace_level Debug flag
+ * temp_file_number The always increasing number for unique files
+ * trace_reader Debug flag
+ */
+static void
+read_dependency_file(register Name filename)
+{
+ register Makefile_type save_makefile_type;
+
+ if (filename == NULL) {
+ return;
+ }
+ filename->stat.time = file_no_time;
+ if (exists(filename) > file_doesnt_exist) {
+ save_makefile_type = makefile_type;
+ makefile_type = reading_cpp_file;
+ if (read_trace_level > 1) {
+ trace_reader = true;
+ }
+ temp_file_number++;
+ (void) read_simple_file(filename,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false);
+ trace_reader = false;
+ makefile_type = save_makefile_type;
+ }
+}
+
+/*
+ * check_read_state_file()
+ *
+ * Check if .make.state has changed
+ * If it has we reread it
+ *
+ * Parameters:
+ *
+ * Global variables used:
+ * make_state Make state file name
+ * makefile_type Type of makefile being read
+ * read_trace_level Debug flag
+ * trace_reader Debug flag
+ */
+static void
+check_read_state_file(void)
+{
+ timestruc_t previous = make_state->stat.time;
+ register Makefile_type save_makefile_type;
+ register Property makefile;
+
+ make_state->stat.time = file_no_time;
+ if ((exists(make_state) == file_doesnt_exist) ||
+ (make_state->stat.time == previous)) {
+ return;
+ }
+ save_makefile_type = makefile_type;
+ makefile_type = rereading_statefile;
+ /* Make sure we clear the old cached contents of .make.state */
+ makefile = maybe_append_prop(make_state, makefile_prop);
+ if (makefile->body.makefile.contents != NULL) {
+ retmem(makefile->body.makefile.contents);
+ makefile->body.makefile.contents = NULL;
+ }
+ if (read_trace_level > 1) {
+ trace_reader = true;
+ }
+ temp_file_number++;
+ (void) read_simple_file(make_state,
+ false,
+ false,
+ false,
+ false,
+ false,
+ true);
+ trace_reader = false;
+ makefile_type = save_makefile_type;
+}
+
+/*
+ * do_assign(line, target)
+ *
+ * Handles runtime assignments for command lines prefixed with "=".
+ *
+ * Parameters:
+ * line The command that contains an assignment
+ * target The Name of the target, used for error reports
+ *
+ * Global variables used:
+ * assign_done Set to indicate doname needs to reprocess
+ */
+static void
+do_assign(register Name line, register Name target)
+{
+ Wstring wcb(line);
+ register wchar_t *string = wcb.get_string();
+ register wchar_t *equal;
+ register Name name;
+ register Boolean append = false;
+
+ /*
+ * If any runtime assignments are done, doname() must reprocess all
+ * targets in the future since the macro values used to build the
+ * command lines for the targets might have changed.
+ */
+ assign_done = true;
+ /* Skip white space. */
+ while (iswspace(*string)) {
+ string++;
+ }
+ equal = string;
+ /* Find "+=" or "=". */
+ while (!iswspace(*equal) &&
+ (*equal != (int) plus_char) &&
+ (*equal != (int) equal_char)) {
+ equal++;
+ }
+ /* Internalize macro name. */
+ name = GETNAME(string, equal - string);
+ /* Skip over "+=" "=". */
+ while (!((*equal == (int) nul_char) ||
+ (*equal == (int) equal_char) ||
+ (*equal == (int) plus_char))) {
+ equal++;
+ }
+ switch (*equal) {
+ case nul_char:
+ fatal(catgets(catd, 1, 31, "= expected in rule `%s' for target `%s'"),
+ line->string_mb,
+ target->string_mb);
+ case plus_char:
+ append = true;
+ equal++;
+ break;
+ }
+ equal++;
+ /* Skip over whitespace in front of value. */
+ while (iswspace(*equal)) {
+ equal++;
+ }
+ /* Enter new macro value. */
+ enter_equal(name,
+ GETNAME(equal, wcb.get_string() + line->hash.length - equal),
+ append);
+}
+
+/*
+ * build_command_strings(target, line)
+ *
+ * Builds the command string to used when
+ * building a target. If the string is different from the previous one
+ * is_out_of_date is set.
+ *
+ * Parameters:
+ * target Target to build commands for
+ * line Where to stuff result
+ *
+ * Global variables used:
+ * c_at The Name "@", used to set macro value
+ * command_changed Set if command is different from old
+ * debug_level Should we trace activities?
+ * do_not_exec_rule Always echo when running -n
+ * empty_name The Name "", used for empty rule
+ * funny Semantics of characters
+ * ignore_errors Used to init field for line
+ * is_conditional Set to false befor evaling macro, checked
+ * after expanding macros
+ * keep_state Indicates that .KEEP_STATE is on
+ * make_word_mentioned Set by macro eval, inits field for cmd
+ * query The Name "?", used to set macro value
+ * query_mentioned Set by macro eval, inits field for cmd
+ * recursion_level Used for tracing
+ * silent Used to init field for line
+ */
+static void
+build_command_strings(Name target, register Property line)
+{
+ String_rec command_line;
+ register Cmd_line command_template = line->body.line.command_template;
+ register Cmd_line *insert = &line->body.line.command_used;
+ register Cmd_line used = *insert;
+ wchar_t buffer[STRING_BUFFER_LENGTH];
+ wchar_t *start;
+ Name new_command_line;
+ register Boolean new_command_longer = false;
+ register Boolean ignore_all_command_dependency = true;
+ Property member;
+ static Name less_name;
+ static Name percent_name;
+ static Name star;
+ Name tmp_name;
+
+ if (less_name == NULL) {
+ MBSTOWCS(wcs_buffer, "<");
+ less_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, "%");
+ percent_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, "*");
+ star = GETNAME(wcs_buffer, FIND_LENGTH);
+ }
+
+ /* We have to check if a target depends on conditional macros */
+ /* Targets that do must be reprocessed by doname() each time around */
+ /* since the macro values used when building the target might have */
+ /* changed */
+ conditional_macro_used = false;
+ /* If we are building a lib.a(member) target $@ should be bound */
+ /* to lib.a */
+ if (target->is_member &&
+ ((member = get_prop(target->prop, member_prop)) != NULL)) {
+ target = member->body.member.library;
+ }
+ /* If we are building a "::" help target $@ should be bound to */
+ /* the real target name */
+ /* A lib.a(member) target is never :: */
+ if (target->has_target_prop) {
+ target = get_prop(target->prop, target_prop)->
+ body.target.target;
+ }
+ /* Bind the magic macros that make supplies */
+ tmp_name = target;
+ if(tmp_name != NULL) {
+ if (tmp_name->has_vpath_alias_prop) {
+ tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
+ body.vpath_alias.alias;
+ }
+ }
+ (void) SETVAR(c_at, tmp_name, false);
+
+ tmp_name = line->body.line.star;
+ if(tmp_name != NULL) {
+ if (tmp_name->has_vpath_alias_prop) {
+ tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
+ body.vpath_alias.alias;
+ }
+ }
+ (void) SETVAR(star, tmp_name, false);
+
+ tmp_name = line->body.line.less;
+ if(tmp_name != NULL) {
+ if (tmp_name->has_vpath_alias_prop) {
+ tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
+ body.vpath_alias.alias;
+ }
+ }
+ (void) SETVAR(less_name, tmp_name, false);
+
+ tmp_name = line->body.line.percent;
+ if(tmp_name != NULL) {
+ if (tmp_name->has_vpath_alias_prop) {
+ tmp_name = get_prop(tmp_name->prop, vpath_alias_prop)->
+ body.vpath_alias.alias;
+ }
+ }
+ (void) SETVAR(percent_name, tmp_name, false);
+
+ /* $? is seldom used and it is expensive to build */
+ /* so we store the list form and build the string on demand */
+ Chain query_list = NULL;
+ Chain *query_list_tail = &query_list;
+
+ for (Chain ch = line->body.line.query; ch != NULL; ch = ch->next) {
+ *query_list_tail = ALLOC(Chain);
+ (*query_list_tail)->name = ch->name;
+ if ((*query_list_tail)->name->has_vpath_alias_prop) {
+ (*query_list_tail)->name =
+ get_prop((*query_list_tail)->name->prop,
+ vpath_alias_prop)->body.vpath_alias.alias;
+ }
+ (*query_list_tail)->next = NULL;
+ query_list_tail = &(*query_list_tail)->next;
+ }
+ (void) setvar_daemon(query,
+ (Name) query_list,
+ false,
+ chain_daemon,
+ false,
+ debug_level);
+
+ /* build $^ */
+ Chain hat_list = NULL;
+ Chain *hat_list_tail = &hat_list;
+
+ for (Dependency dependency = line->body.line.dependencies;
+ dependency != NULL;
+ dependency = dependency->next) {
+ /* skip automatic dependencies */
+ if (!dependency->automatic) {
+ if ((dependency->name != force) &&
+ (dependency->stale == false)) {
+ *hat_list_tail = ALLOC(Chain);
+
+ if (dependency->name->is_member &&
+ (get_prop(dependency->name->prop, member_prop) != NULL)) {
+ (*hat_list_tail)->name =
+ get_prop(dependency->name->prop,
+ member_prop)->body.member.member;
+ } else {
+ (*hat_list_tail)->name = dependency->name;
+ }
+
+ if((*hat_list_tail)->name != NULL) {
+ if ((*hat_list_tail)->name->has_vpath_alias_prop) {
+ (*hat_list_tail)->name =
+ get_prop((*hat_list_tail)->name->prop,
+ vpath_alias_prop)->body.vpath_alias.alias;
+ }
+ }
+
+ (*hat_list_tail)->next = NULL;
+ hat_list_tail = &(*hat_list_tail)->next;
+ }
+ }
+ }
+ (void) setvar_daemon(hat,
+ (Name) hat_list,
+ false,
+ chain_daemon,
+ false,
+ debug_level);
+
+/* We have two command sequences we need to handle */
+/* The old one that we probably read from .make.state */
+/* and the new one we are building that will replace the old one */
+/* Even when KEEP_STATE is not on we build a new command sequence and store */
+/* it in the line prop. This command sequence is then executed by */
+/* run_command(). If KEEP_STATE is on it is also later written to */
+/* .make.state. The routine replaces the old command line by line with the */
+/* new one trying to reuse Cmd_lines */
+
+ /* If there is no old command_used we have to start creating */
+ /* Cmd_lines to keep the new cmd in */
+ if (used == NULL) {
+ new_command_longer = true;
+ *insert = used = ALLOC(Cmd_line);
+ used->next = NULL;
+ used->command_line = NULL;
+ insert = &used->next;
+ }
+ /* Run thru the template for the new command and build the expanded */
+ /* new command lines */
+ for (;
+ command_template != NULL;
+ command_template = command_template->next, insert = &used->next, used = *insert) {
+ /* If there is no old command_used Cmd_line we need to */
+ /* create one and say that cmd consistency failed */
+ if (used == NULL) {
+ new_command_longer = true;
+ *insert = used = ALLOC(Cmd_line);
+ used->next = NULL;
+ used->command_line = empty_name;
+ }
+ /* Prepare the Cmd_line for the processing */
+ /* The command line prefixes "@-=?" are stripped and that */
+ /* information is saved in the Cmd_line */
+ used->assign = false;
+ used->ignore_error = ignore_errors;
+ used->silent = silent;
+ used->always_exec = false;
+ /* Expand the macros in the command line */
+ INIT_STRING_FROM_STACK(command_line, buffer);
+ make_word_mentioned =
+ query_mentioned =
+ false;
+ expand_value(command_template->command_line, &command_line, true);
+ /* If the macro $(MAKE) is mentioned in the command */
+ /* "make -n" runs actually execute the command */
+ used->make_refd = make_word_mentioned;
+ used->ignore_command_dependency = query_mentioned;
+ /* Strip the prefixes */
+ start = command_line.buffer.start;
+ for (;
+ iswspace(*start) ||
+ (get_char_semantics_value(*start) & (int) command_prefix_sem);
+ start++) {
+ switch (*start) {
+ case question_char:
+ used->ignore_command_dependency = true;
+ break;
+ case exclam_char:
+ used->ignore_command_dependency = false;
+ break;
+ case equal_char:
+ used->assign = true;
+ break;
+ case hyphen_char:
+ used->ignore_error = true;
+ break;
+ case at_char:
+ if (!do_not_exec_rule) {
+ used->silent = true;
+ }
+ break;
+ case plus_char:
+ if(posix) {
+ used->always_exec = true;
+ }
+ break;
+ }
+ }
+ /* If all command lines of the template are prefixed with "?"*/
+ /* the VIRTUAL_ROOT is not used for cmd consistency checks */
+ if (!used->ignore_command_dependency) {
+ ignore_all_command_dependency = false;
+ }
+ /* Internalize the expanded and stripped command line */
+ new_command_line = GETNAME(start, FIND_LENGTH);
+ if ((used->command_line == NULL) &&
+ (line->body.line.sccs_command)) {
+ used->command_line = new_command_line;
+ new_command_longer = false;
+ }
+ /* Compare it with the old one for command consistency */
+ if (used->command_line != new_command_line) {
+ Name vpath_translated = vpath_translation(new_command_line);
+ if (keep_state &&
+ !used->ignore_command_dependency && (vpath_translated != used->command_line)) {
+ if (debug_level > 0) {
+ if (used->command_line != NULL
+ && *used->command_line->string_mb !=
+ '\0') {
+ (void) printf(catgets(catd, 1, 32, "%*sBuilding %s because new command \n\t%s\n%*sdifferent from old\n\t%s\n"),
+ recursion_level,
+ "",
+ target->string_mb,
+ vpath_translated->string_mb,
+ recursion_level,
+ "",
+ used->
+ command_line->
+ string_mb);
+ } else {
+ (void) printf(catgets(catd, 1, 33, "%*sBuilding %s because new command \n\t%s\n%*sdifferent from empty old command\n"),
+ recursion_level,
+ "",
+ target->string_mb,
+ vpath_translated->string_mb,
+ recursion_level,
+ "");
+ }
+ }
+ command_changed = true;
+ line->body.line.is_out_of_date = true;
+ }
+ used->command_line = new_command_line;
+ }
+ if (command_line.free_after_use) {
+ retmem(command_line.buffer.start);
+ }
+ }
+ /* Check if the old command is longer than the new for */
+ /* command consistency */
+ if (used != NULL) {
+ *insert = NULL;
+ if (keep_state &&
+ !ignore_all_command_dependency) {
+ if (debug_level > 0) {
+ (void) printf(catgets(catd, 1, 34, "%*sBuilding %s because new command shorter than old\n"),
+ recursion_level,
+ "",
+ target->string_mb);
+ }
+ command_changed = true;
+ line->body.line.is_out_of_date = true;
+ }
+ }
+ /* Check if the new command is longer than the old command for */
+ /* command consistency */
+ if (new_command_longer &&
+ !ignore_all_command_dependency &&
+ keep_state) {
+ if (debug_level > 0) {
+ (void) printf(catgets(catd, 1, 35, "%*sBuilding %s because new command longer than old\n"),
+ recursion_level,
+ "",
+ target->string_mb);
+ }
+ command_changed = true;
+ line->body.line.is_out_of_date = true;
+ }
+ /* Unbind the magic macros */
+ (void) SETVAR(c_at, (Name) NULL, false);
+ (void) SETVAR(star, (Name) NULL, false);
+ (void) SETVAR(less_name, (Name) NULL, false);
+ (void) SETVAR(percent_name, (Name) NULL, false);
+ (void) SETVAR(query, (Name) NULL, false);
+ if (query_list != NULL) {
+ delete_query_chain(query_list);
+ }
+ (void) SETVAR(hat, (Name) NULL, false);
+ if (hat_list != NULL) {
+ delete_query_chain(hat_list);
+ }
+
+ if (conditional_macro_used) {
+ target->conditional_macro_list = cond_macro_list;
+ cond_macro_list = NULL;
+ target->depends_on_conditional = true;
+ }
+}
+
+/*
+ * touch_command(line, target, result)
+ *
+ * If this is an "make -t" run we do this.
+ * We touch all targets in the target group ("foo + fie:") if any.
+ *
+ * Return value:
+ * Indicates if the command failed or not
+ *
+ * Parameters:
+ * line The command line to update
+ * target The target we are touching
+ * result Initial value for the result we return
+ *
+ * Global variables used:
+ * do_not_exec_rule Indicates that -n is on
+ * silent Do not echo commands
+ */
+static Doname
+touch_command(register Property line, register Name target, Doname result)
+{
+ Name name;
+ register Chain target_group;
+ String_rec touch_string;
+ wchar_t buffer[MAXPATHLEN];
+ Name touch_cmd;
+ Cmd_line rule;
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+ Avo_MToolJobResultMsg *job_result_msg;
+ RWCollectable *xdr_msg;
+ int child_pid = 0;
+ wchar_t string[MAXPATHLEN];
+ char mbstring[MAXPATHLEN];
+ int filed;
+#endif
+
+ SEND_MTOOL_MSG(
+ if (!sent_rsrc_info_msg) {
+ if (userName[0] == '\0') {
+ avo_get_user(userName, NULL);
+ }
+ if (hostName[0] == '\0') {
+ strcpy(hostName, avo_hostname());
+ }
+ send_rsrc_info_msg(1, hostName, userName);
+ sent_rsrc_info_msg = 1;
+ }
+ send_job_start_msg(line);
+ job_result_msg = new Avo_MToolJobResultMsg();
+ );
+ for (name = target, target_group = NULL; name != NULL;) {
+ if (!name->is_member) {
+ /*
+ * Build a touch command that can be passed
+ * to dosys(). If KEEP_STATE is on, "make -t"
+ * will save the proper command, not the
+ * "touch" in .make.state.
+ */
+ INIT_STRING_FROM_STACK(touch_string, buffer);
+ MBSTOWCS(wcs_buffer, NOCATGETS("touch "));
+ append_string(wcs_buffer, &touch_string, FIND_LENGTH);
+ touch_cmd = name;
+ if (name->has_vpath_alias_prop) {
+ touch_cmd = get_prop(name->prop,
+ vpath_alias_prop)->
+ body.vpath_alias.alias;
+ }
+ APPEND_NAME(touch_cmd,
+ &touch_string,
+ FIND_LENGTH);
+ touch_cmd = GETNAME(touch_string.buffer.start,
+ FIND_LENGTH);
+ if (touch_string.free_after_use) {
+ retmem(touch_string.buffer.start);
+ }
+ if (!silent ||
+ do_not_exec_rule &&
+ (target_group == NULL)) {
+ (void) printf("%s\n", touch_cmd->string_mb);
+ SEND_MTOOL_MSG(
+ job_result_msg->appendOutput(AVO_STRDUP(touch_cmd->string_mb));
+ );
+ }
+ /* Run the touch command, or simulate it */
+ if (!do_not_exec_rule) {
+
+ SEND_MTOOL_MSG(
+ (void) sprintf(mbstring,
+ NOCATGETS("%s/make.stdout.%d.%d.XXXXXX"),
+ tmpdir,
+ getpid(),
+ file_number++);
+
+ int tmp_fd = mkstemp(mbstring);
+ if(tmp_fd) {
+ (void) close(tmp_fd);
+ }
+
+ stdout_file = strdup(mbstring);
+ stderr_file = NULL;
+ child_pid = pollResults(stdout_file,
+ (char *)NULL,
+ (char *)NULL);
+ );
+
+ result = dosys(touch_cmd,
+ false,
+ false,
+ false,
+ false,
+ name,
+ send_mtool_msgs);
+
+ SEND_MTOOL_MSG(
+ append_job_result_msg(job_result_msg);
+ if (child_pid > 0) {
+ kill(child_pid, SIGUSR1);
+ while (!((waitpid(child_pid, 0, 0) == -1)
+ && (errno == ECHILD)));
+ }
+ child_pid = 0;
+ (void) unlink(stdout_file);
+ retmem_mb(stdout_file);
+ stdout_file = NULL;
+ );
+
+ } else {
+ result = build_ok;
+ }
+ } else {
+ result = build_ok;
+ }
+ if (target_group == NULL) {
+ target_group = line->body.line.target_group;
+ } else {
+ target_group = target_group->next;
+ }
+ if (target_group != NULL) {
+ name = target_group->name;
+ } else {
+ name = NULL;
+ }
+ }
+ SEND_MTOOL_MSG(
+ job_result_msg->setResult(job_msg_id, (result == build_ok) ? 0 : 1, DONE);
+ xdr_msg = (RWCollectable*) job_result_msg;
+ xdr(&xdrs, xdr_msg);
+ (void) fflush(mtool_msgs_fp);
+ delete job_result_msg;
+ );
+ return result;
+}
+
+/*
+ * update_target(line, result)
+ *
+ * updates the status of a target after executing its commands.
+ *
+ * Parameters:
+ * line The command line block to update
+ * result Indicates that build is OK so can update
+ *
+ * Global variables used:
+ * do_not_exec_rule Indicates that -n is on
+ * touch Fake the new timestamp if we are just touching
+ */
+void
+update_target(Property line, Doname result)
+{
+ Name target;
+ Chain target_group;
+ Property line2;
+ timestruc_t old_stat_time;
+ Property member;
+
+ /*
+ * [tolik] Additional fix for bug 1063790. It was fixed
+ * for serial make long ago, but DMake dumps core when
+ * target is a symlink and sccs file is newer then target.
+ * In this case, finish_children() calls update_target()
+ * with line==NULL.
+ */
+ if(line == NULL) {
+ /* XXX. Should we do anything here? */
+ return;
+ }
+
+ target = line->body.line.target;
+
+ if ((result == build_ok) && (line->body.line.command_used != NULL)) {
+ if (do_not_exec_rule ||
+ touch ||
+ (target->is_member &&
+ (line->body.line.command_template != NULL) &&
+ (line->body.line.command_template->command_line->string_mb[0] == 0) &&
+ (line->body.line.command_template->next == NULL))) {
+ /* If we are simulating execution we need to fake a */
+ /* new timestamp for the target we didnt build */
+ target->stat.time = file_max_time;
+ } else {
+ /*
+ * If we really built the target we read the new
+ * timestamp.
+ * Fix for bug #1110906: if .c file is newer than
+ * the corresponding .o file which is in an archive
+ * file, make will compile the .c file but it won't
+ * update the object in the .a file.
+ */
+ old_stat_time = target->stat.time;
+ target->stat.time = file_no_time;
+ (void) exists(target);
+ if ((target->is_member) &&
+ (target->stat.time == old_stat_time)) {
+ member = get_prop(target->prop, member_prop);
+ if (member != NULL) {
+ target->stat.time = member->body.member.library->stat.time;
+ target->stat.time.tv_sec++;
+ }
+ }
+ }
+ /* If the target is part of a group we need to propagate the */
+ /* result of the run to all members */
+ for (target_group = line->body.line.target_group;
+ target_group != NULL;
+ target_group = target_group->next) {
+ target_group->name->stat.time = target->stat.time;
+ line2 = maybe_append_prop(target_group->name,
+ line_prop);
+ line2->body.line.command_used =
+ line->body.line.command_used;
+ line2->body.line.target = target_group->name;
+ }
+ }
+ target->has_built = true;
+}
+
+/*
+ * sccs_get(target, command)
+ *
+ * Figures out if it possible to sccs get a file
+ * and builds the command to do it if it is.
+ *
+ * Return value:
+ * Indicates if sccs get failed or not
+ *
+ * Parameters:
+ * target Target to get
+ * command Where to deposit command to use
+ *
+ * Global variables used:
+ * debug_level Should we trace activities?
+ * recursion_level Used for tracing
+ * sccs_get_rule The rule to used for sccs getting
+ */
+static Doname
+sccs_get(register Name target, register Property *command)
+{
+ register int result;
+ char link[MAXPATHLEN];
+ String_rec string;
+ wchar_t name[MAXPATHLEN];
+ register wchar_t *p;
+ timestruc_t sccs_time;
+ register Property line;
+ int sym_link_depth = 0;
+
+ /* For sccs, we need to chase symlinks. */
+ while (target->stat.is_sym_link) {
+ if (sym_link_depth++ > 90) {
+ fatal(catgets(catd, 1, 95, "Can't read symbolic link `%s': Number of symbolic links encountered during path name traversal exceeds 90."),
+ target->string_mb);
+ }
+ /* Read the value of the link. */
+ result = readlink_vroot(target->string_mb,
+ link,
+ sizeof(link),
+ NULL,
+ VROOT_DEFAULT);
+ if (result == -1) {
+ fatal(catgets(catd, 1, 36, "Can't read symbolic link `%s': %s"),
+ target->string_mb, errmsg(errno));
+ }
+ link[result] = 0;
+ /* Use the value to build the proper filename. */
+ INIT_STRING_FROM_STACK(string, name);
+
+ Wstring wcb(target);
+ if ((link[0] != slash_char) &&
+ ((p = (wchar_t *) wsrchr(wcb.get_string(), slash_char)) != NULL)) {
+ append_string(wcb.get_string(), &string, p - wcb.get_string() + 1);
+ }
+ append_string(link, &string, result);
+ /* Replace the old name with the translated name. */
+ target = normalize_name(string.buffer.start, string.text.p - string.buffer.start);
+ (void) exists(target);
+ if (string.free_after_use) {
+ retmem(string.buffer.start);
+ }
+ }
+
+ /*
+ * read_dir() also reads the ?/SCCS dir and saves information
+ * about which files have SCSC/s. files.
+ */
+ if (target->stat.has_sccs == DONT_KNOW_SCCS) {
+ read_directory_of_file(target);
+ }
+ switch (target->stat.has_sccs) {
+ case DONT_KNOW_SCCS:
+ /* We dont know by now there is no SCCS/s.* */
+ target->stat.has_sccs = NO_SCCS;
+ case NO_SCCS:
+ /*
+ * If there is no SCCS/s.* but the plain file exists,
+ * we say things are OK.
+ */
+ if (target->stat.time > file_doesnt_exist) {
+ return build_ok;
+ }
+ /* If we cant find the plain file, we give up. */
+ return build_dont_know;
+ case HAS_SCCS:
+ /*
+ * Pay dirt. We now need to figure out if the plain file
+ * is out of date relative to the SCCS/s.* file.
+ */
+ sccs_time = exists(get_prop(target->prop,
+ sccs_prop)->body.sccs.file);
+ break;
+ }
+
+ if ((!target->has_complained &&
+ (sccs_time != file_doesnt_exist) &&
+ (sccs_get_rule != NULL))) {
+ /* only checking */
+ if (command == NULL) {
+ return build_ok;
+ }
+ /*
+ * We provide a command line for the target. The line is a
+ * "sccs get" command from default.mk.
+ */
+ line = maybe_append_prop(target, line_prop);
+ *command = line;
+ if (sccs_time > target->stat.time) {
+ /*
+ * And only if the plain file is out of date do we
+ * request execution of the command.
+ */
+ line->body.line.is_out_of_date = true;
+ if (debug_level > 0) {
+ (void) printf(catgets(catd, 1, 37, "%*sSccs getting %s because s. file is younger than source file\n"),
+ recursion_level,
+ "",
+ target->string_mb);
+ }
+ }
+ line->body.line.sccs_command = true;
+ line->body.line.command_template = sccs_get_rule;
+ if(!svr4 && (!allrules_read || posix)) {
+ if((target->prop) &&
+ (target->prop->body.sccs.file) &&
+ (target->prop->body.sccs.file->string_mb)) {
+ if((strlen(target->prop->body.sccs.file->string_mb) ==
+ strlen(target->string_mb) + 2) &&
+ (target->prop->body.sccs.file->string_mb[0] == 's') &&
+ (target->prop->body.sccs.file->string_mb[1] == '.')) {
+
+ line->body.line.command_template = get_posix_rule;
+ }
+ }
+ }
+ line->body.line.target = target;
+ /*
+ * Also make sure the rule is build with $* and $<
+ * bound properly.
+ */
+ line->body.line.star = NULL;
+ line->body.line.less = NULL;
+ line->body.line.percent = NULL;
+ return build_ok;
+ }
+ return build_dont_know;
+}
+
+/*
+ * read_directory_of_file(file)
+ *
+ * Reads the directory the specified file lives in.
+ *
+ * Parameters:
+ * file The file we need to read dir for
+ *
+ * Global variables used:
+ * dot The Name ".", used as the default dir
+ */
+void
+read_directory_of_file(register Name file)
+{
+
+ Wstring file_string(file);
+ wchar_t * wcb = file_string.get_string();
+ wchar_t usr_include_buf[MAXPATHLEN];
+ wchar_t usr_include_sys_buf[MAXPATHLEN];
+
+ register Name directory = dot;
+ register wchar_t *p = (wchar_t *) wsrchr(wcb,
+ (int) slash_char);
+ register int length = p - wcb;
+ static Name usr_include;
+ static Name usr_include_sys;
+
+ if (usr_include == NULL) {
+ MBSTOWCS(usr_include_buf, NOCATGETS("/usr/include"));
+ usr_include = GETNAME(usr_include_buf, FIND_LENGTH);
+ MBSTOWCS(usr_include_sys_buf, NOCATGETS("/usr/include/sys"));
+ usr_include_sys = GETNAME(usr_include_sys_buf, FIND_LENGTH);
+ }
+
+ /*
+ * If the filename contains a "/" we have to extract the path
+ * Else the path defaults to ".".
+ */
+ if (p != NULL) {
+ /*
+ * Check some popular directories first to possibly
+ * save time. Compare string length first to gain speed.
+ */
+ if ((usr_include->hash.length == length) &&
+ IS_WEQUALN(usr_include_buf,
+ wcb,
+ length)) {
+ directory = usr_include;
+ } else if ((usr_include_sys->hash.length == length) &&
+ IS_WEQUALN(usr_include_sys_buf,
+ wcb,
+ length)) {
+ directory = usr_include_sys;
+ } else {
+ directory = GETNAME(wcb, length);
+ }
+ }
+ (void) read_dir(directory,
+ (wchar_t *) NULL,
+ (Property) NULL,
+ (wchar_t *) NULL);
+}
+
+/*
+ * add_pattern_conditionals(target)
+ *
+ * Scan the list of conditionals defined for pattern targets and add any
+ * that match this target to its list of conditionals.
+ *
+ * Parameters:
+ * target The target we should add conditionals for
+ *
+ * Global variables used:
+ * conditionals The list of pattern conditionals
+ */
+static void
+add_pattern_conditionals(register Name target)
+{
+ register Property conditional;
+ Property new_prop;
+ Property *previous;
+ Name_rec dummy;
+ wchar_t *pattern;
+ wchar_t *percent;
+ int length;
+
+ Wstring wcb(target);
+ Wstring wcb1;
+
+ for (conditional = get_prop(conditionals->prop, conditional_prop);
+ conditional != NULL;
+ conditional = get_prop(conditional->next, conditional_prop)) {
+ wcb1.init(conditional->body.conditional.target);
+ pattern = wcb1.get_string();
+ if (pattern[1] != 0) {
+ percent = (wchar_t *) wschr(pattern, (int) percent_char);
+ if (!wcb.equaln(pattern, percent-pattern) ||
+ !IS_WEQUAL(wcb.get_string(wcb.length()-wslen(percent+1)), percent+1)) {
+ continue;
+ }
+ }
+ for (previous = &target->prop;
+ *previous != NULL;
+ previous = &(*previous)->next) {
+ if (((*previous)->type == conditional_prop) &&
+ ((*previous)->body.conditional.sequence >
+ conditional->body.conditional.sequence)) {
+ break;
+ }
+ }
+ if (*previous == NULL) {
+ new_prop = append_prop(target, conditional_prop);
+ } else {
+ dummy.prop = NULL;
+ new_prop = append_prop(&dummy, conditional_prop);
+ new_prop->next = *previous;
+ *previous = new_prop;
+ }
+ target->conditional_cnt++;
+ new_prop->body.conditional = conditional->body.conditional;
+ }
+}
+
+/*
+ * set_locals(target, old_locals)
+ *
+ * Sets any conditional macros for the target.
+ * Each target carries a possibly empty set of conditional properties.
+ *
+ * Parameters:
+ * target The target to set conditional macros for
+ * old_locals Space to store old values in
+ *
+ * Global variables used:
+ * debug_level Should we trace activity?
+ * is_conditional We need to preserve this value
+ * recursion_level Used for tracing
+ */
+void
+set_locals(register Name target, register Property old_locals)
+{
+ register Property conditional;
+ register int i;
+ register Boolean saved_conditional_macro_used;
+ Chain cond_name;
+ Chain cond_chain;
+
+#ifdef DISTRIBUTED
+ if (target->dont_activate_cond_values) {
+ return;
+ }
+#endif
+
+ saved_conditional_macro_used = conditional_macro_used;
+
+ /* Scan the list of conditional properties and apply each one */
+ for (conditional = get_prop(target->prop, conditional_prop), i = 0;
+ conditional != NULL;
+ conditional = get_prop(conditional->next, conditional_prop),
+ i++) {
+ /* Save the old value */
+ old_locals[i].body.macro =
+ maybe_append_prop(conditional->body.conditional.name,
+ macro_prop)->body.macro;
+ if (debug_level > 1) {
+ (void) printf(catgets(catd, 1, 38, "%*sActivating conditional value: "),
+ recursion_level,
+ "");
+ }
+ /* Set the conditional value. Macros are expanded when the */
+ /* macro is refd as usual */
+ if ((conditional->body.conditional.name != virtual_root) ||
+ (conditional->body.conditional.value != virtual_root)) {
+ (void) SETVAR(conditional->body.conditional.name,
+ conditional->body.conditional.value,
+ (Boolean) conditional->body.conditional.append);
+ }
+ cond_name = ALLOC(Chain);
+ cond_name->name = conditional->body.conditional.name;
+ }
+ /* Put this target on the front of the chain of conditional targets */
+ cond_chain = ALLOC(Chain);
+ cond_chain->name = target;
+ cond_chain->next = conditional_targets;
+ conditional_targets = cond_chain;
+ conditional_macro_used = saved_conditional_macro_used;
+}
+
+/*
+ * reset_locals(target, old_locals, conditional, index)
+ *
+ * Removes any conditional macros for the target.
+ *
+ * Parameters:
+ * target The target we are retoring values for
+ * old_locals The values to restore
+ * conditional The first conditional block for the target
+ * index into the old_locals vector
+ * Global variables used:
+ * debug_level Should we trace activities?
+ * recursion_level Used for tracing
+ */
+void
+reset_locals(register Name target, register Property old_locals, register Property conditional, register int index)
+{
+ register Property this_conditional;
+ Chain cond_chain;
+
+#ifdef DISTRIBUTED
+ if (target->dont_activate_cond_values) {
+ return;
+ }
+#endif
+
+ /* Scan the list of conditional properties and restore the old value */
+ /* to each one Reverse the order relative to when we assigned macros */
+ this_conditional = get_prop(conditional->next, conditional_prop);
+ if (this_conditional != NULL) {
+ reset_locals(target, old_locals, this_conditional, index+1);
+ } else {
+ /* Remove conditional target from chain */
+ if (conditional_targets == NULL ||
+ conditional_targets->name != target) {
+ warning(catgets(catd, 1, 39, "Internal error: reset target not at head of condtional_targets chain"));
+ } else {
+ cond_chain = conditional_targets->next;
+ retmem_mb((caddr_t) conditional_targets);
+ conditional_targets = cond_chain;
+ }
+ }
+ get_prop(conditional->body.conditional.name->prop,
+ macro_prop)->body.macro = old_locals[index].body.macro;
+ if (conditional->body.conditional.name == virtual_root) {
+ (void) SETVAR(virtual_root, getvar(virtual_root), false);
+ }
+ if (debug_level > 1) {
+ if (old_locals[index].body.macro.value != NULL) {
+ (void) printf(catgets(catd, 1, 40, "%*sdeactivating conditional value: %s= %s\n"),
+ recursion_level,
+ "",
+ conditional->body.conditional.name->
+ string_mb,
+ old_locals[index].body.macro.value->
+ string_mb);
+ } else {
+ (void) printf(catgets(catd, 1, 41, "%*sdeactivating conditional value: %s =\n"),
+ recursion_level,
+ "",
+ conditional->body.conditional.name->
+ string_mb);
+ }
+ }
+}
+
+/*
+ * check_auto_dependencies(target, auto_count, automatics)
+ *
+ * Returns true if the target now has a dependency
+ * it didn't previously have (saved on automatics).
+ *
+ * Return value:
+ * true if new dependency found
+ *
+ * Parameters:
+ * target Target we check
+ * auto_count Number of old automatic vars
+ * automatics Saved old automatics
+ *
+ * Global variables used:
+ * keep_state Indicates that .KEEP_STATE is on
+ */
+Boolean
+check_auto_dependencies(Name target, int auto_count, Name *automatics)
+{
+ Name *p;
+ int n;
+ Property line;
+ Dependency dependency;
+
+ if (keep_state) {
+ if ((line = get_prop(target->prop, line_prop)) == NULL) {
+ return false;
+ }
+ /* Go thru new list of automatic depes */
+ for (dependency = line->body.line.dependencies;
+ dependency != NULL;
+ dependency = dependency->next) {
+ /* And make sure that each one existed before we */
+ /* built the target */
+ if (dependency->automatic && !dependency->stale) {
+ for (n = auto_count, p = automatics;
+ n > 0;
+ n--) {
+ if (*p++ == dependency->name) {
+ /* If we can find it on the */
+ /* saved list of autos we */
+ /* are OK */
+ goto not_new;
+ }
+ }
+ /* But if we scan over the old list */
+ /* of auto. without finding it it is */
+ /* new and we must check it */
+ return true;
+ }
+ not_new:;
+ }
+ return false;
+ } else {
+ return false;
+ }
+}
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+void
+create_xdrs_ptr(void)
+{
+ static int xdrs_init = 0;
+
+ if (!xdrs_init) {
+ xdrs_init = 1;
+ mtool_msgs_fp = fdopen(mtool_msgs_fd, "a");
+ xdrstdio_create(&xdrs,
+ mtool_msgs_fp,
+ XDR_ENCODE);
+ }
+}
+
+XDR *
+get_xdrs_ptr(void)
+{
+ return &xdrs;
+}
+
+FILE *
+get_mtool_msgs_fp(void)
+{
+ return mtool_msgs_fp;
+}
+
+int
+get_job_msg_id(void)
+{
+ return job_msg_id;
+}
+
+// Continuously poll and show the results of remotely executing a job,
+// i.e., output the stdout and stderr files.
+
+static int
+pollResults(char *outFn, char *errFn, char *hostNm)
+{
+ int child;
+
+ child = fork();
+ switch (child) {
+ case -1:
+ break;
+ case 0:
+ enable_interrupt((void (*) (int))SIG_DFL);
+#ifdef linux
+ (void) signal(SIGUSR1, Avo_PollResultsAction_Sigusr1Handler);
+#else
+ (void) sigset(SIGUSR1, Avo_PollResultsAction_Sigusr1Handler);
+#endif
+ pollResultsAction(outFn, errFn);
+
+ exit(0);
+ break;
+ default:
+ break;
+ }
+ return child;
+}
+
+// This is the PollResultsAction SIGUSR1 handler.
+
+static bool_t pollResultsActionTimeToFinish = FALSE;
+
+extern "C" void
+Avo_PollResultsAction_Sigusr1Handler(int foo)
+{
+ pollResultsActionTimeToFinish = TRUE;
+}
+
+static void
+pollResultsAction(char *outFn, char *errFn)
+{
+ int fd;
+ time_t file_time = 0;
+ long file_time_nsec = 0;
+ struct stat statbuf;
+ int stat_rc;
+
+ // Keep stat'ing until file exists.
+ while (((stat_rc = stat(outFn, &statbuf)) != 0) &&
+ (errno == ENOENT) &&
+ !pollResultsActionTimeToFinish) {
+ us_sleep(STAT_RETRY_SLEEP_TIME);
+ }
+ // The previous stat() could be failed due to EINTR
+ // So one more try is needed
+ if (stat_rc != 0 && stat(outFn, &statbuf) != 0) {
+ // stat() failed
+ warning(NOCATGETS("Internal error: stat(\"%s\", ...) failed: %s\n"),
+ outFn, strerror(errno));
+ exit(1);
+ }
+
+ if ((fd = open(outFn, O_RDONLY)) < 0
+ && (errno != EINTR || (fd = open(outFn, O_RDONLY)) < 0)) {
+ // open() failed
+ warning(NOCATGETS("Internal error: open(\"%s\", O_RDONLY) failed: %s\n"),
+ outFn, strerror(errno));
+ exit(1);
+ }
+
+ while (!pollResultsActionTimeToFinish && stat(outFn, &statbuf) == 0) {
+#ifdef linux
+ if ((statbuf.st_mtime > file_time)
+ ) {
+ file_time = statbuf.st_mtime;
+ rxmGetNextResultsBlock(fd);
+ }
+#else
+ if ((statbuf.st_mtim.tv_sec > file_time) ||
+ ((statbuf.st_mtim.tv_sec == file_time) &&
+ (statbuf.st_mtim.tv_nsec > file_time_nsec))
+ ) {
+ file_time = statbuf.st_mtim.tv_sec;
+ file_time_nsec = statbuf.st_mtim.tv_nsec;
+ rxmGetNextResultsBlock(fd);
+ }
+#endif
+ us_sleep(STAT_RETRY_SLEEP_TIME);
+ }
+ // Check for the rest of output
+ rxmGetNextResultsBlock(fd);
+
+ (void) close(fd);
+}
+
+static void
+rxmGetNextResultsBlock(int fd)
+{
+ size_t to_read = 8 * 1024;
+ ssize_t bytes_read;
+ ssize_t bytes_written;
+ char results_buf[8 * 1024];
+ sigset_t newset;
+ sigset_t oldset;
+
+ // Read some more from the output/results file.
+ // Hopefully the kernel managed to prefetch the stuff.
+ bytes_read = read(fd, results_buf, to_read);
+ while (bytes_read > 0) {
+ AVO_BLOCK_INTERUPTS;
+ bytes_written = write(1, results_buf, bytes_read);
+ AVO_UNBLOCK_INTERUPTS;
+ if (bytes_written != bytes_read) {
+ // write() failed
+ warning(NOCATGETS("Internal error: write(1, ...) failed: %s\n"),
+ strerror(errno));
+ exit(1);
+ }
+ bytes_read = read(fd, results_buf, to_read);
+ }
+}
+
+// Generic, interruptable microsecond resolution sleep member function.
+
+static int
+us_sleep(unsigned int nusecs)
+{
+ struct pollfd dummy;
+ int timeout;
+
+ if ((timeout = nusecs/1000) <= 0) {
+ timeout = 1;
+ }
+ return poll(&dummy, 0, timeout);
+}
+#endif /* TEAMWARE_MAKE_CMN */
+
+// Recursively delete each of the Chain struct on the chain.
+
+static void
+delete_query_chain(Chain ch)
+{
+ if (ch == NULL) {
+ return;
+ } else {
+ delete_query_chain(ch->next);
+ retmem_mb((char *) ch);
+ }
+}
+
+Doname
+target_can_be_built(register Name target) {
+ Doname result = build_dont_know;
+ Name true_target = target;
+ Property line;
+
+ if (target == wait_name) {
+ return(build_ok);
+ }
+ /*
+ * If the target is a constructed one for a "::" target,
+ * we need to consider that.
+ */
+ if (target->has_target_prop) {
+ true_target = get_prop(target->prop,
+ target_prop)->body.target.target;
+ }
+
+ (void) exists(true_target);
+
+ if (true_target->state == build_running) {
+ return(build_running);
+ }
+ if (true_target->stat.time != file_doesnt_exist) {
+ result = build_ok;
+ }
+
+ /* get line property for the target */
+ line = get_prop(true_target->prop, line_prop);
+
+ /* first check for explicit rule */
+ if (line != NULL && line->body.line.command_template != NULL) {
+ result = build_ok;
+ }
+ /* try to find pattern rule */
+ if (result == build_dont_know) {
+ result = find_percent_rule(target, NULL, false);
+ }
+
+ /* try to find double suffix rule */
+ if (result == build_dont_know) {
+ if (target->is_member) {
+ Property member = get_prop(target->prop, member_prop);
+ if (member != NULL && member->body.member.member != NULL) {
+ result = find_ar_suffix_rule(target, member->body.member.member, NULL, false);
+ } else {
+ result = find_double_suffix_rule(target, NULL, false);
+ }
+ } else {
+ result = find_double_suffix_rule(target, NULL, false);
+ }
+ }
+
+ /* try to find suffix rule */
+ if ((result == build_dont_know) && second_pass) {
+ result = find_suffix_rule(target, target, empty_name, NULL, false);
+ }
+
+ /* check for sccs */
+ if (result == build_dont_know) {
+ result = sccs_get(target, NULL);
+ }
+
+ /* try to find dyn target */
+ if (result == build_dont_know) {
+ Name dtarg = find_dyntarget(target);
+ if (dtarg != NULL) {
+ result = target_can_be_built(dtarg);
+ }
+ }
+
+ /* check whether target was mentioned in makefile */
+ if (result == build_dont_know) {
+ if (target->colons != no_colon) {
+ result = build_ok;
+ }
+ }
+
+ /* result */
+ return result;
+}
diff --git a/usr/src/make_src/Make/bin/make/common/dosys.cc b/usr/src/make_src/Make/bin/make/common/dosys.cc
new file mode 100644
index 0000000..de9b043
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/dosys.cc
@@ -0,0 +1,174 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)dosys.cc 1.45 06/12/12
+ */
+
+#pragma ident "@(#)dosys.cc 1.45 06/12/12"
+
+/*
+ * dosys.cc
+ *
+ * Execute one commandline
+ */
+
+/*
+ * Included files
+ */
+#include <fcntl.h> /* open() */
+#include <mk/defs.h>
+#include <mksh/dosys.h> /* doshell(), doexec() */
+#include <mksh/misc.h> /* getmem() */
+#include <sys/stat.h> /* open() */
+#include <unistd.h> /* getpid() */
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+static int filter_file;
+static char *filter_file_name;
+
+/*
+ * File table of contents
+ */
+static void redirect_stderr(void);
+
+/*
+ * dosys(command, ignore_error, call_make, silent_error, target)
+ *
+ * Check if command string contains meta chars and dispatch to
+ * the proper routine for executing one command line.
+ *
+ * Return value:
+ * Indicates if the command execution failed
+ *
+ * Parameters:
+ * command The command to run
+ * ignore_error Should make abort when an error is seen?
+ * call_make Did command reference $(MAKE) ?
+ * silent_error Should error messages be suppressed for pmake?
+ * target Target we are building
+ *
+ * Global variables used:
+ * do_not_exec_rule Is -n on?
+ * working_on_targets We started processing real targets
+ */
+Doname
+dosys(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target, Boolean redirect_out_err)
+{
+ timestruc_t before;
+ register int length = command->hash.length;
+ Wstring wcb(command);
+ register wchar_t *p = wcb.get_string();
+ register wchar_t *q;
+ Doname result;
+
+ /* Strip spaces from head of command string */
+ while (iswspace(*p)) {
+ p++, length--;
+ }
+ if (*p == (int) nul_char) {
+ return build_failed;
+ }
+ /* If we are faking it we just return */
+ if (do_not_exec_rule &&
+ working_on_targets &&
+ !call_make &&
+ !always_exec) {
+ return build_ok;
+ }
+ /* no_action_was_taken is used to print special message */
+ no_action_was_taken = false;
+
+ /* Copy string to make it OK to write it. */
+ q = ALLOC_WC(length + 1);
+ (void) wscpy(q, p);
+ /* Write the state file iff this command uses make. */
+ if (call_make && command_changed) {
+ write_state_file(0, false);
+ }
+ make_state->stat.time = file_no_time;
+ (void)exists(make_state);
+ before = make_state->stat.time;
+ /*
+ * Run command directly if it contains no shell meta chars,
+ * else run it using the shell.
+ */
+ if (await(ignore_error,
+ silent_error,
+ target,
+ wcb.get_string(),
+ command->meta ?
+ doshell(q, ignore_error, redirect_out_err,
+ stdout_file, stderr_file, 0) :
+ doexec(q, ignore_error, redirect_out_err,
+ stdout_file, stderr_file,
+ vroot_path, 0),
+ send_mtool_msgs,
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+ get_xdrs_ptr(),
+ get_job_msg_id()
+#else
+ NULL,
+ -1
+#endif
+ )) {
+ result = build_ok;
+ } else {
+ result = build_failed;
+ }
+ retmem(q);
+
+ if ((report_dependencies_level == 0) &&
+ call_make) {
+ make_state->stat.time = file_no_time;
+ (void)exists(make_state);
+ if (before == make_state->stat.time) {
+ return result;
+ }
+ makefile_type = reading_statefile;
+ if (read_trace_level > 1) {
+ trace_reader = true;
+ }
+ temp_file_number++;
+ (void) read_simple_file(make_state,
+ false,
+ false,
+ false,
+ false,
+ false,
+ true);
+ trace_reader = false;
+ }
+ return result;
+}
diff --git a/usr/src/make_src/Make/bin/make/common/files.cc b/usr/src/make_src/Make/bin/make/common/files.cc
new file mode 100644
index 0000000..6ca6919
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/files.cc
@@ -0,0 +1,733 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)files.cc 1.37 06/12/12
+ */
+
+#pragma ident "@(#)files.cc 1.37 06/12/12"
+
+/*
+ * files.c
+ *
+ * Various file related routines:
+ * Figure out if file exists
+ * Wildcard resolution for directory reader
+ * Directory reader
+ */
+
+
+/*
+ * Included files
+ */
+#if defined(SUN5_0) || defined(HP_UX)
+#include <dirent.h> /* opendir() */
+#else
+#include <sys/dir.h> /* opendir() */
+#endif
+#include <errno.h> /* errno */
+#include <mk/defs.h>
+#include <mksh/macro.h> /* getvar() */
+#include <mksh/misc.h> /* get_prop(), append_prop() */
+#include <sys/stat.h> /* lstat() */
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+extern timestruc_t& exists(register Name target);
+extern void set_target_stat(register Name target, struct stat buf);
+static timestruc_t& vpath_exists(register Name target);
+static Name enter_file_name(wchar_t *name_string, wchar_t *library);
+static Boolean star_match(register char *string, register char *pattern);
+static Boolean amatch(register wchar_t *string, register wchar_t *pattern);
+
+/*
+ * exists(target)
+ *
+ * Figure out the timestamp for one target.
+ *
+ * Return value:
+ * The time the target was created
+ *
+ * Parameters:
+ * target The target to check
+ *
+ * Global variables used:
+ * debug_level Should we trace the stat call?
+ * recursion_level Used for tracing
+ * vpath_defined Was the variable VPATH defined in environment?
+ */
+timestruc_t&
+exists(register Name target)
+{
+ struct stat buf;
+ register int result;
+
+ /* We cache stat information. */
+ if (target->stat.time != file_no_time) {
+ return target->stat.time;
+ }
+
+ /*
+ * If the target is a member, we have to extract the time
+ * from the archive.
+ */
+ if (target->is_member &&
+ (get_prop(target->prop, member_prop) != NULL)) {
+ return read_archive(target);
+ }
+
+ if (debug_level > 1) {
+ (void) printf(NOCATGETS("%*sstat(%s)\n"),
+ recursion_level,
+ "",
+ target->string_mb);
+ }
+
+ result = lstat_vroot(target->string_mb, &buf, NULL, VROOT_DEFAULT);
+ if ((result != -1) && ((buf.st_mode & S_IFMT) == S_IFLNK)) {
+ /*
+ * If the file is a symbolic link, we remember that
+ * and then we get the status for the refd file.
+ */
+ target->stat.is_sym_link = true;
+ result = stat_vroot(target->string_mb, &buf, NULL, VROOT_DEFAULT);
+ } else {
+ target->stat.is_sym_link = false;
+ }
+
+ if (result < 0) {
+ target->stat.time = file_doesnt_exist;
+ target->stat.stat_errno = errno;
+ if ((errno == ENOENT) &&
+ vpath_defined &&
+/* azv, fixing bug 1262942, VPATH works with a leaf name
+ * but not a directory name.
+ */
+ (target->string_mb[0] != (int) slash_char) ) {
+/* BID_1214655 */
+/* azv */
+ vpath_exists(target);
+ // return vpath_exists(target);
+ }
+ } else {
+ /* Save all the information we need about the file */
+ target->stat.stat_errno = 0;
+ target->stat.is_file = true;
+ target->stat.mode = buf.st_mode & 0777;
+ target->stat.size = buf.st_size;
+ target->stat.is_dir =
+ BOOLEAN((buf.st_mode & S_IFMT) == S_IFDIR);
+ if (target->stat.is_dir) {
+ target->stat.time = file_is_dir;
+ } else {
+ /* target->stat.time = buf.st_mtime; */
+/* BID_1129806 */
+/* vis@nbsp.nsk.su */
+#if defined(linux)
+ timestruc_t ttime = { buf.st_mtime, 0 };
+ target->stat.time = MAX(ttime, file_min_time);
+#else
+ target->stat.time = MAX(buf.st_mtim, file_min_time);
+#endif
+ }
+ }
+ if ((target->colon_splits > 0) &&
+ (get_prop(target->prop, time_prop) == NULL)) {
+ append_prop(target, time_prop)->body.time.time =
+ target->stat.time;
+ }
+ return target->stat.time;
+}
+
+/*
+ * set_target_stat( target, buf)
+ *
+ * Called by exists() to set some stat fields in the Name structure
+ * to those read by the stat_vroot() call (from disk).
+ *
+ * Parameters:
+ * target The target whose stat field is set
+ * buf stat values (on disk) of the file
+ * represented by target.
+ */
+void
+set_target_stat(register Name target, struct stat buf)
+{
+ target->stat.stat_errno = 0;
+ target->stat.is_file = true;
+ target->stat.mode = buf.st_mode & 0777;
+ target->stat.size = buf.st_size;
+ target->stat.is_dir =
+ BOOLEAN((buf.st_mode & S_IFMT) == S_IFDIR);
+ if (target->stat.is_dir) {
+ target->stat.time = file_is_dir;
+ } else {
+ /* target->stat.time = buf.st_mtime; */
+/* BID_1129806 */
+/* vis@nbsp.nsk.su */
+#if defined(linux)
+ timestruc_t ttime = { buf.st_mtime, 0 };
+ target->stat.time = ttime;
+#else
+ target->stat.time = MAX(buf.st_mtim, file_min_time);
+#endif
+ }
+}
+
+
+/*
+ * vpath_exists(target)
+ *
+ * Called if exists() discovers that there is a VPATH defined.
+ * This function stats the VPATH translation of the target.
+ *
+ * Return value:
+ * The time the target was created
+ *
+ * Parameters:
+ * target The target to check
+ *
+ * Global variables used:
+ * vpath_name The Name "VPATH", used to get macro value
+ */
+static timestruc_t&
+vpath_exists(register Name target)
+{
+ wchar_t *vpath;
+ wchar_t file_name[MAXPATHLEN];
+ wchar_t *name_p;
+ Name alias;
+
+ /*
+ * To avoid recursive search through VPATH when exists(alias) is called
+ */
+ vpath_defined = false;
+
+ Wstring wcb(getvar(vpath_name));
+ Wstring wcb1(target);
+
+ vpath = wcb.get_string();
+
+ while (*vpath != (int) nul_char) {
+ name_p = file_name;
+ while ((*vpath != (int) colon_char) &&
+ (*vpath != (int) nul_char)) {
+ *name_p++ = *vpath++;
+ }
+ *name_p++ = (int) slash_char;
+ (void) wscpy(name_p, wcb1.get_string());
+ alias = GETNAME(file_name, FIND_LENGTH);
+ if (exists(alias) != file_doesnt_exist) {
+ target->stat.is_file = true;
+ target->stat.mode = alias->stat.mode;
+ target->stat.size = alias->stat.size;
+ target->stat.is_dir = alias->stat.is_dir;
+ target->stat.time = alias->stat.time;
+ maybe_append_prop(target, vpath_alias_prop)->
+ body.vpath_alias.alias = alias;
+ target->has_vpath_alias_prop = true;
+ vpath_defined = true;
+ return alias->stat.time;
+ }
+ while ((*vpath != (int) nul_char) &&
+ ((*vpath == (int) colon_char) || iswspace(*vpath))) {
+ vpath++;
+ }
+ }
+ /*
+ * Restore vpath_defined
+ */
+ vpath_defined = true;
+ return target->stat.time;
+}
+
+/*
+ * read_dir(dir, pattern, line, library)
+ *
+ * Used to enter the contents of directories into makes namespace.
+ * Presence of a file is important when scanning for implicit rules.
+ * read_dir() is also used to expand wildcards in dependency lists.
+ *
+ * Return value:
+ * Non-0 if we found files to match the pattern
+ *
+ * Parameters:
+ * dir Path to the directory to read
+ * pattern Pattern for that files should match or NULL
+ * line When we scan using a pattern we enter files
+ * we find as dependencies for this line
+ * library If we scan for "lib.a(<wildcard-member>)"
+ *
+ * Global variables used:
+ * debug_level Should we trace the dir reading?
+ * dot The Name ".", compared against
+ * sccs_dir_path The path to the SCCS dir (from PROJECTDIR)
+ * vpath_defined Was the variable VPATH defined in environment?
+ * vpath_name The Name "VPATH", use to get macro value
+ */
+int
+read_dir(Name dir, wchar_t *pattern, Property line, wchar_t *library)
+{
+ wchar_t file_name[MAXPATHLEN];
+ wchar_t *file_name_p = file_name;
+ Name file;
+ wchar_t plain_file_name[MAXPATHLEN];
+ wchar_t *plain_file_name_p;
+ Name plain_file;
+ wchar_t tmp_wcs_buffer[MAXPATHLEN];
+ DIR *dir_fd;
+ int m_local_dependency=0;
+#if defined(SUN5_0) || defined(HP_UX)
+#define d_fileno d_ino
+ register struct dirent *dp;
+#else
+ register struct direct *dp;
+#endif
+ wchar_t *vpath = NULL;
+ wchar_t *p;
+ int result = 0;
+
+ if(dir->hash.length >= MAXPATHLEN) {
+ return 0;
+ }
+
+ Wstring wcb(dir);
+ Wstring vps;
+
+ /* A directory is only read once unless we need to expand wildcards. */
+ if (pattern == NULL) {
+ if (dir->has_read_dir) {
+ return 0;
+ }
+ dir->has_read_dir = true;
+ }
+ /* Check if VPATH is active and setup list if it is. */
+ if (vpath_defined && (dir == dot)) {
+ vps.init(getvar(vpath_name));
+ vpath = vps.get_string();
+ }
+
+ /*
+ * Prepare the string where we build the full name of the
+ * files in the directory.
+ */
+ if ((dir->hash.length > 1) || (wcb.get_string()[0] != (int) period_char)) {
+ (void) wscpy(file_name, wcb.get_string());
+ MBSTOWCS(wcs_buffer, "/");
+ (void) wscat(file_name, wcs_buffer);
+ file_name_p = file_name + wslen(file_name);
+ }
+
+ /* Open the directory. */
+vpath_loop:
+ dir_fd = opendir(dir->string_mb);
+ if (dir_fd == NULL) {
+ return 0;
+ }
+
+ /* Read all the directory entries. */
+ while ((dp = readdir(dir_fd)) != NULL) {
+ /* We ignore "." and ".." */
+ if ((dp->d_fileno == 0) ||
+ ((dp->d_name[0] == (int) period_char) &&
+ ((dp->d_name[1] == 0) ||
+ ((dp->d_name[1] == (int) period_char) &&
+ (dp->d_name[2] == 0))))) {
+ continue;
+ }
+ /*
+ * Build the full name of the file using whatever
+ * path supplied to the function.
+ */
+ MBSTOWCS(tmp_wcs_buffer, dp->d_name);
+ (void) wscpy(file_name_p, tmp_wcs_buffer);
+ file = enter_file_name(file_name, library);
+ if ((pattern != NULL) && amatch(tmp_wcs_buffer, pattern)) {
+ /*
+ * If we are expanding a wildcard pattern, we
+ * enter the file as a dependency for the target.
+ */
+ if (debug_level > 0){
+ WCSTOMBS(mbs_buffer, pattern);
+ (void) printf(catgets(catd, 1, 231, "'%s: %s' due to %s expansion\n"),
+ line->body.line.target->string_mb,
+ file->string_mb,
+ mbs_buffer);
+ }
+ enter_dependency(line, file, false);
+ result++;
+ } else {
+ /*
+ * If the file has an SCCS/s. file,
+ * we will detect that later on.
+ */
+ file->stat.has_sccs = NO_SCCS;
+ /*
+ * If this is an s. file, we also enter it as if it
+ * existed in the plain directory.
+ */
+ if ((dp->d_name[0] == 's') &&
+ (dp->d_name[1] == (int) period_char)) {
+
+ MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
+ plain_file_name_p = plain_file_name;
+ (void) wscpy(plain_file_name_p, tmp_wcs_buffer);
+ plain_file = GETNAME(plain_file_name, FIND_LENGTH);
+ plain_file->stat.is_file = true;
+ plain_file->stat.has_sccs = HAS_SCCS;
+ /*
+ * Enter the s. file as a dependency for the
+ * plain file.
+ */
+ maybe_append_prop(plain_file, sccs_prop)->
+ body.sccs.file = file;
+ MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
+ if ((pattern != NULL) &&
+ amatch(tmp_wcs_buffer, pattern)) {
+ if (debug_level > 0) {
+ WCSTOMBS(mbs_buffer, pattern);
+ (void) printf(catgets(catd, 1, 232, "'%s: %s' due to %s expansion\n"),
+ line->body.line.target->
+ string_mb,
+ plain_file->string_mb,
+ mbs_buffer);
+ }
+ enter_dependency(line, plain_file, false);
+ result++;
+ }
+ }
+ }
+ }
+ (void) closedir(dir_fd);
+ if ((vpath != NULL) && (*vpath != (int) nul_char)) {
+ while ((*vpath != (int) nul_char) &&
+ (iswspace(*vpath) || (*vpath == (int) colon_char))) {
+ vpath++;
+ }
+ p = vpath;
+ while ((*vpath != (int) colon_char) &&
+ (*vpath != (int) nul_char)) {
+ vpath++;
+ }
+ if (vpath > p) {
+ dir = GETNAME(p, vpath - p);
+ goto vpath_loop;
+ }
+ }
+/*
+ * look into SCCS directory only if it's not svr4. For svr4 dont do that.
+ */
+
+/*
+ * Now read the SCCS directory.
+ * Files in the SCSC directory are considered to be part of the set of
+ * files in the plain directory. They are also entered in their own right.
+ * Prepare the string where we build the true name of the SCCS files.
+ */
+ (void) wsncpy(plain_file_name,
+ file_name,
+ file_name_p - file_name);
+ plain_file_name[file_name_p - file_name] = 0;
+ plain_file_name_p = plain_file_name + wslen(plain_file_name);
+
+ if(!svr4) {
+
+ if (sccs_dir_path != NULL) {
+ wchar_t tmp_wchar;
+ wchar_t path[MAXPATHLEN];
+ char mb_path[MAXPATHLEN];
+
+ if (file_name_p - file_name > 0) {
+ tmp_wchar = *file_name_p;
+ *file_name_p = 0;
+ WCSTOMBS(mbs_buffer, file_name);
+ (void) sprintf(mb_path, NOCATGETS("%s/%s/SCCS"),
+ sccs_dir_path,
+ mbs_buffer);
+ *file_name_p = tmp_wchar;
+ } else {
+ (void) sprintf(mb_path, NOCATGETS("%s/SCCS"), sccs_dir_path);
+ }
+ MBSTOWCS(path, mb_path);
+ (void) wscpy(file_name, path);
+ } else {
+ MBSTOWCS(wcs_buffer, NOCATGETS("SCCS"));
+ (void) wscpy(file_name_p, wcs_buffer);
+ }
+ } else {
+ MBSTOWCS(wcs_buffer, NOCATGETS("."));
+ (void) wscpy(file_name_p, wcs_buffer);
+ }
+ /* Internalize the constructed SCCS dir name. */
+ (void) exists(dir = GETNAME(file_name, FIND_LENGTH));
+ /* Just give up if the directory file doesnt exist. */
+ if (!dir->stat.is_file) {
+ return result;
+ }
+ /* Open the directory. */
+ dir_fd = opendir(dir->string_mb);
+ if (dir_fd == NULL) {
+ return result;
+ }
+ MBSTOWCS(wcs_buffer, "/");
+ (void) wscat(file_name, wcs_buffer);
+ file_name_p = file_name + wslen(file_name);
+
+ while ((dp = readdir(dir_fd)) != NULL) {
+ if ((dp->d_fileno == 0) ||
+ ((dp->d_name[0] == (int) period_char) &&
+ ((dp->d_name[1] == 0) ||
+ ((dp->d_name[1] == (int) period_char) &&
+ (dp->d_name[2] == 0))))) {
+ continue;
+ }
+ /* Construct and internalize the true name of the SCCS file. */
+ MBSTOWCS(wcs_buffer, dp->d_name);
+ (void) wscpy(file_name_p, wcs_buffer);
+ file = GETNAME(file_name, FIND_LENGTH);
+ file->stat.is_file = true;
+ file->stat.has_sccs = NO_SCCS;
+ /*
+ * If this is an s. file, we also enter it as if it
+ * existed in the plain directory.
+ */
+ if ((dp->d_name[0] == 's') &&
+ (dp->d_name[1] == (int) period_char)) {
+
+ MBSTOWCS(wcs_buffer, dp->d_name + 2);
+ (void) wscpy(plain_file_name_p, wcs_buffer);
+ plain_file = GETNAME(plain_file_name, FIND_LENGTH);
+ plain_file->stat.is_file = true;
+ plain_file->stat.has_sccs = HAS_SCCS;
+ /* if sccs dependency is already set,skip */
+ if(plain_file->prop) {
+ Property sprop = get_prop(plain_file->prop,sccs_prop);
+ if(sprop != NULL) {
+ if (sprop->body.sccs.file) {
+ goto try_pattern;
+ }
+ }
+ }
+
+ /*
+ * Enter the s. file as a dependency for the
+ * plain file.
+ */
+ maybe_append_prop(plain_file, sccs_prop)->
+ body.sccs.file = file;
+try_pattern:
+ MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
+ if ((pattern != NULL) &&
+ amatch(tmp_wcs_buffer, pattern)) {
+ if (debug_level > 0) {
+ WCSTOMBS(mbs_buffer, pattern);
+ (void) printf(catgets(catd, 1, 233, "'%s: %s' due to %s expansion\n"),
+ line->body.line.target->
+ string_mb,
+ plain_file->string_mb,
+ mbs_buffer);
+ }
+ enter_dependency(line, plain_file, false);
+ result++;
+ }
+ }
+ }
+ (void) closedir(dir_fd);
+
+ return result;
+}
+
+/*
+ * enter_file_name(name_string, library)
+ *
+ * Helper function for read_dir().
+ *
+ * Return value:
+ * The Name that was entered
+ *
+ * Parameters:
+ * name_string Name of the file we want to enter
+ * library The library it is a member of, if any
+ *
+ * Global variables used:
+ */
+static Name
+enter_file_name(wchar_t *name_string, wchar_t *library)
+{
+ wchar_t buffer[STRING_BUFFER_LENGTH];
+ String_rec lib_name;
+ Name name;
+ Property prop;
+
+ if (library == NULL) {
+ name = GETNAME(name_string, FIND_LENGTH);
+ name->stat.is_file = true;
+ return name;
+ }
+
+ INIT_STRING_FROM_STACK(lib_name, buffer);
+ append_string(library, &lib_name, FIND_LENGTH);
+ append_char((int) parenleft_char, &lib_name);
+ append_string(name_string, &lib_name, FIND_LENGTH);
+ append_char((int) parenright_char, &lib_name);
+
+ name = GETNAME(lib_name.buffer.start, FIND_LENGTH);
+ name->stat.is_file = true;
+ name->is_member = true;
+ prop = maybe_append_prop(name, member_prop);
+ prop->body.member.library = GETNAME(library, FIND_LENGTH);
+ prop->body.member.library->stat.is_file = true;
+ prop->body.member.entry = NULL;
+ prop->body.member.member = GETNAME(name_string, FIND_LENGTH);
+ prop->body.member.member->stat.is_file = true;
+ return name;
+}
+
+/*
+ * star_match(string, pattern)
+ *
+ * This is a regular shell type wildcard pattern matcher
+ * It is used when xpanding wildcards in dependency lists
+ *
+ * Return value:
+ * Indication if the string matched the pattern
+ *
+ * Parameters:
+ * string String to match
+ * pattern Pattern to match it against
+ *
+ * Global variables used:
+ */
+static Boolean
+star_match(register wchar_t *string, register wchar_t *pattern)
+{
+ register int pattern_ch;
+
+ switch (*pattern) {
+ case 0:
+ return succeeded;
+ case bracketleft_char:
+ case question_char:
+ case asterisk_char:
+ while (*string) {
+ if (amatch(string++, pattern)) {
+ return succeeded;
+ }
+ }
+ break;
+ default:
+ pattern_ch = (int) *pattern++;
+ while (*string) {
+ if ((*string++ == pattern_ch) &&
+ amatch(string, pattern)) {
+ return succeeded;
+ }
+ }
+ break;
+ }
+ return failed;
+}
+
+/*
+ * amatch(string, pattern)
+ *
+ * Helper function for shell pattern matching
+ *
+ * Return value:
+ * Indication if the string matched the pattern
+ *
+ * Parameters:
+ * string String to match
+ * pattern Pattern to match it against
+ *
+ * Global variables used:
+ */
+static Boolean
+amatch(register wchar_t *string, register wchar_t *pattern)
+{
+ register long lower_bound;
+ register long string_ch;
+ register long pattern_ch;
+ register int k;
+
+top:
+ for (; 1; pattern++, string++) {
+ lower_bound = 017777777777;
+ string_ch = *string;
+ switch (pattern_ch = *pattern) {
+ case bracketleft_char:
+ k = 0;
+ while ((pattern_ch = *++pattern) != 0) {
+ switch (pattern_ch) {
+ case bracketright_char:
+ if (!k) {
+ return failed;
+ }
+ string++;
+ pattern++;
+ goto top;
+ case hyphen_char:
+ k |= (lower_bound <= string_ch) &&
+ (string_ch <=
+ (pattern_ch = pattern[1]));
+ default:
+ if (string_ch ==
+ (lower_bound = pattern_ch)) {
+ k++;
+ }
+ }
+ }
+ return failed;
+ case asterisk_char:
+ return star_match(string, ++pattern);
+ case 0:
+ return BOOLEAN(!string_ch);
+ case question_char:
+ if (string_ch == 0) {
+ return failed;
+ }
+ break;
+ default:
+ if (pattern_ch != string_ch) {
+ return failed;
+ }
+ break;
+ }
+ }
+ /* NOTREACHED */
+}
+
diff --git a/usr/src/make_src/Make/bin/make/common/globals.cc b/usr/src/make_src/Make/bin/make/common/globals.cc
new file mode 100644
index 0000000..903a109
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/globals.cc
@@ -0,0 +1,217 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)globals.cc 1.42 06/12/12
+ */
+
+#pragma ident "@(#)globals.cc 1.42 06/12/12"
+
+/*
+ * globals.cc
+ *
+ * This declares all global variables
+ */
+
+/*
+ * Included files
+ */
+#include <nl_types.h>
+#include <mk/defs.h>
+#include <sys/stat.h>
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Global variables used by make only
+ */
+ FILE *dependency_report_file;
+
+/*
+ * Global variables used by make
+ */
+ Boolean allrules_read=false;
+ Name posix_name;
+ Name svr4_name;
+ Boolean sdot_target; /* used to identify s.m(/M)akefile */
+ Boolean all_parallel; /* TEAMWARE_MAKE_CMN */
+ Boolean assign_done;
+ int foo;
+ Boolean build_failed_seen;
+#ifdef DISTRIBUTED
+ Boolean building_serial;
+#endif
+ Name built_last_make_run;
+ Name c_at;
+#ifdef DISTRIBUTED
+ Boolean called_make = false;
+#endif
+ Boolean cleanup;
+ Boolean close_report;
+ Boolean command_changed;
+ Boolean commands_done;
+ Chain conditional_targets;
+ Name conditionals;
+ Boolean continue_after_error; /* `-k' */
+ Property current_line;
+ Name current_make_version;
+ Name current_target;
+ short debug_level;
+ Cmd_line default_rule;
+ Name default_rule_name;
+ Name default_target_to_build;
+ Name dmake_group;
+ Name dmake_max_jobs;
+ Name dmake_mode;
+ DMake_mode dmake_mode_type;
+ Name dmake_output_mode;
+ DMake_output_mode output_mode = txt1_mode;
+ Name dmake_odir;
+ Name dmake_rcfile;
+ Name done;
+ Name dot;
+ Name dot_keep_state;
+ Name dot_keep_state_file;
+ Name empty_name;
+#if defined(HP_UX) || defined(linux)
+ int exit_status;
+#endif
+ Boolean fatal_in_progress;
+ int file_number;
+#if 0
+ Boolean filter_stderr; /* `-X' */
+#endif
+ Name force;
+ Name ignore_name;
+ Boolean ignore_errors; /* `-i' */
+ Boolean ignore_errors_all; /* `-i' */
+ Name init;
+ int job_msg_id;
+ Boolean keep_state;
+ Name make_state;
+#ifdef TEAMWARE_MAKE_CMN
+ timestruc_t make_state_before;
+#endif
+ Dependency makefiles_used;
+ Name makeflags;
+// Boolean make_state_locked; // Moved to lib/mksh
+ Name make_version;
+ char mbs_buffer2[(MAXPATHLEN * MB_LEN_MAX)];
+ char *mbs_ptr;
+ char *mbs_ptr2;
+ int mtool_msgs_fd;
+ Boolean depinfo_already_read = false;
+#ifdef NSE
+ Name derived_src;
+ Boolean nse; /* NSE on */
+ Name nse_backquote_seen;
+ char nse_depinfo_lockfile[MAXPATHLEN];
+ Boolean nse_depinfo_locked;
+ Boolean nse_did_recursion;
+ Name nse_shell_var_used;
+ Boolean nse_watch_vars = false;
+ wchar_t current_makefile[MAXPATHLEN];
+#endif
+ Boolean no_action_was_taken = true; /* true if we've not **
+ ** run any command */
+
+ Boolean no_parallel = false; /* TEAMWARE_MAKE_CMN */
+#ifdef SGE_SUPPORT
+ Boolean grid = false; /* TEAMWARE_MAKE_CMN */
+#endif
+ Name no_parallel_name;
+ Name not_auto;
+ Boolean only_parallel; /* TEAMWARE_MAKE_CMN */
+ Boolean parallel; /* TEAMWARE_MAKE_CMN */
+ Name parallel_name;
+ Name localhost_name;
+ int parallel_process_cnt;
+ Percent percent_list;
+ Dyntarget dyntarget_list;
+ Name plus;
+ Name pmake_machinesfile;
+ Name precious;
+ Name primary_makefile;
+ Boolean quest; /* `-q' */
+ short read_trace_level;
+ Boolean reading_dependencies = false;
+ Name recursive_name;
+ int recursion_level;
+ short report_dependencies_level = 0; /* -P */
+ Boolean report_pwd;
+ Boolean rewrite_statefile;
+ Running running_list;
+ char *sccs_dir_path;
+ Name sccs_get_name;
+ Name sccs_get_posix_name;
+ Cmd_line sccs_get_rule;
+ Cmd_line sccs_get_org_rule;
+ Cmd_line sccs_get_posix_rule;
+ Name get_name;
+ Cmd_line get_rule;
+ Name get_posix_name;
+ Cmd_line get_posix_rule;
+ Boolean send_mtool_msgs; /* `-K' */
+ Boolean all_precious;
+ Boolean silent_all; /* `-s' */
+ Boolean report_cwd; /* `-w' */
+ Boolean silent; /* `-s' */
+ Name silent_name;
+ char *stderr_file = NULL;
+ char *stdout_file = NULL;
+#ifdef SGE_SUPPORT
+ char script_file[MAXPATHLEN] = "";
+#endif
+ Boolean stdout_stderr_same;
+ Dependency suffixes;
+ Name suffixes_name;
+ Name sunpro_dependencies;
+ Boolean target_variants;
+ char *tmpdir = NOCATGETS("/tmp");
+ char *temp_file_directory = NOCATGETS(".");
+ Name temp_file_name;
+ short temp_file_number;
+ time_t timing_start;
+ wchar_t *top_level_target;
+ Boolean touch; /* `-t' */
+ Boolean trace_reader; /* `-D' */
+ Boolean build_unconditional; /* `-u' */
+ pathpt vroot_path = VROOT_DEFAULT;
+ Name wait_name;
+ wchar_t wcs_buffer2[MAXPATHLEN];
+ wchar_t *wcs_ptr;
+ wchar_t *wcs_ptr2;
+ nl_catd catd;
+ long int hostid;
+
+/*
+ * File table of contents
+ */
+
diff --git a/usr/src/make_src/Make/bin/make/common/implicit.cc b/usr/src/make_src/Make/bin/make/common/implicit.cc
new file mode 100644
index 0000000..a9b2f1d
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/implicit.cc
@@ -0,0 +1,1479 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)implicit.cc 1.64 06/12/12
+ */
+
+#pragma ident "@(#)implicit.cc 1.64 06/12/12"
+
+/*
+ * implicit.c
+ *
+ * Handle suffix and percent rules
+ */
+
+/*
+ * Included files
+ */
+#include <mk/defs.h>
+#include <mksh/macro.h> /* expand_value() */
+#include <mksh/misc.h> /* retmem() */
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+static wchar_t WIDE_NULL[1] = {(wchar_t) nul_char};
+
+/*
+ * File table of contents
+ */
+extern Doname find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *command, Boolean rechecking);
+extern Doname find_ar_suffix_rule(register Name target, Name true_target, Property *command, Boolean rechecking);
+extern Doname find_double_suffix_rule(register Name target, Property *command, Boolean rechecking);
+extern void build_suffix_list(register Name target_suffix);
+extern Doname find_percent_rule(register Name target, Property *command, Boolean rechecking);
+static void create_target_group_and_dependencies_list(Name target, Percent pat_rule, String percent);
+static Boolean match_found_with_pattern(Name target, Percent pat_rule, String percent, wchar_t *percent_buf);
+static void construct_string_from_pattern(Percent pat_rule, String percent, String result);
+static Boolean dependency_exists(Name target, Property line);
+extern Property maybe_append_prop(Name, Property_id);
+extern void add_target_to_chain(Name target, Chain * query);
+
+/*
+ * find_suffix_rule(target, target_body, target_suffix, command, rechecking)
+ *
+ * Does the lookup for single and double suffix rules.
+ * It calls build_suffix_list() to build the list of possible suffixes
+ * for the given target.
+ * It then scans the list to find the first possible source file that
+ * exists. This is done by concatenating the body of the target name
+ * (target name less target suffix) and the source suffix and checking
+ * if the resulting file exists.
+ *
+ * Return value:
+ * Indicates if search failed or not
+ *
+ * Parameters:
+ * target The target we need a rule for
+ * target_body The target name without the suffix
+ * target_suffix The suffix of the target
+ * command Pointer to slot to deposit cmd in if found
+ * rechecking true if we are rechecking target which depends
+ * on conditional macro and keep_state is set
+ *
+ * Global variables used:
+ * debug_level Indicates how much tracing to do
+ * recursion_level Used for tracing
+ */
+
+extern int printf (const char *, ...);
+
+static Boolean actual_doname = false;
+
+/* /tolik/
+ * fix bug 1247448: Suffix Rules failed when combine with Pattern Matching Rules.
+ * When make attemps to apply % rule it didn't look for a single suffix rule because
+ * if "doname" is called from "find_percent_rule" argument "implicit" is set to true
+ * and find_suffix_rule was not called. I've commented the checking of "implicit"
+ * in "doname" and make got infinite recursion for SVR4 tilde rules.
+ * Usage of "we_are_in_tilde" is intended to avoid this recursion.
+ */
+
+static Boolean we_are_in_tilde = false;
+
+Doname
+find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *command, Boolean rechecking)
+{
+ static wchar_t static_string_buf_3M [ 3 * MAXPATHLEN ];
+ Name true_target = target;
+ wchar_t *sourcename = (wchar_t*)static_string_buf_3M;
+ register wchar_t *put_suffix;
+ register Property source_suffix;
+ register Name source;
+ Doname result;
+ register Property line;
+ extern Boolean tilde_rule;
+ Boolean name_found = true;
+ Boolean posix_tilde_attempt = true;
+ int src_len = MAXPATHLEN + strlen(target_body->string_mb);
+
+ /*
+ * To avoid infinite recursion
+ */
+ if(we_are_in_tilde) {
+ we_are_in_tilde = false;
+ return(build_dont_know);
+ }
+
+ /*
+ * If the target is a constructed one for a "::" target,
+ * we need to consider that.
+ */
+ if (target->has_target_prop) {
+ true_target = get_prop(target->prop,
+ target_prop)->body.target.target;
+ }
+ if (debug_level > 1) {
+ (void) printf(NOCATGETS("%*sfind_suffix_rule(%s,%s,%s)\n"),
+ recursion_level,
+ "",
+ true_target->string_mb,
+ target_body->string_mb,
+ target_suffix->string_mb);
+ }
+ if (command != NULL) {
+ if ((true_target->suffix_scan_done == true) && (*command == NULL)) {
+ return build_ok;
+ }
+ }
+ true_target->suffix_scan_done = true;
+ /*
+ * Enter all names from the directory where the target lives as
+ * files that makes sense.
+ * This will make finding the synthesized source possible.
+ */
+ read_directory_of_file(target_body);
+ /* Cache the suffixes for this target suffix if not done. */
+ if (!target_suffix->has_read_suffixes) {
+ build_suffix_list(target_suffix);
+ }
+ /* Preload the sourcename vector with the head of the target name. */
+ if (src_len >= sizeof(static_string_buf_3M)) {
+ sourcename = ALLOC_WC(src_len);
+ }
+ (void) mbstowcs(sourcename,
+ target_body->string_mb,
+ (int) target_body->hash.length);
+ put_suffix = sourcename + target_body->hash.length;
+ /* Scan the suffix list for the target if one exists. */
+ if (target_suffix->has_suffixes) {
+posix_attempts:
+ for (source_suffix = get_prop(target_suffix->prop,
+ suffix_prop);
+ source_suffix != NULL;
+ source_suffix = get_prop(source_suffix->next,
+ suffix_prop)) {
+ /* Build the synthesized source name. */
+ (void) mbstowcs(put_suffix,
+ source_suffix->body.
+ suffix.suffix->string_mb,
+ (int) source_suffix->body.
+ suffix.suffix->hash.length);
+ put_suffix[source_suffix->body.
+ suffix.suffix->hash.length] =
+ (int) nul_char;
+ if (debug_level > 1) {
+ WCSTOMBS(mbs_buffer, sourcename);
+ (void) printf(catgets(catd, 1, 218, "%*sTrying %s\n"),
+ recursion_level,
+ "",
+ mbs_buffer);
+ }
+ source = getname_fn(sourcename, FIND_LENGTH, false, &name_found);
+ /*
+ * If the source file is not registered as
+ * a file, this source suffix did not match.
+ */
+ if(vpath_defined && !posix && !svr4) {
+ (void) exists(source);
+ }
+ if (!source->stat.is_file) {
+ if(!(posix|svr4))
+ {
+ if(!name_found) {
+ free_name(source);
+ }
+ continue;
+ }
+
+ /* following code will ensure that the corresponding
+ ** tilde rules are executed when corresponding s. file
+ ** exists in the current directory. Though the current
+ ** target ends with a ~ character, there wont be any
+ ** any file in the current directory with that suffix
+ ** as it's fictitious. Even if it exists, it'll
+ ** execute all the rules for the ~ target.
+ */
+
+ if(source->string_mb[source->hash.length - 1] == '~' &&
+ ( svr4 || posix_tilde_attempt ) )
+ {
+ char *p, *np;
+ char *tmpbuf;
+
+ tmpbuf = getmem(source->hash.length + 8);
+ /* + 8 to add "s." or "SCCS/s." */
+ memset(tmpbuf,0,source->hash.length + 8);
+ source->string_mb[source->hash.length - 1] = '\0';
+ if(p = (char *) memchr((char *)source->string_mb,'/',source->hash.length))
+ {
+ while(1) {
+ if(np = (char *) memchr((char *)p+1,'/',source->hash.length - (p - source->string_mb))) {
+ p = np;
+ } else {break;}
+ }
+ /* copy everything including '/' */
+ strncpy(tmpbuf, source->string_mb, p - source->string_mb + 1);
+ strcat(tmpbuf, NOCATGETS("s."));
+ strcat(tmpbuf, p+1);
+ retmem((wchar_t *) source->string_mb);
+ source->string_mb = tmpbuf;
+
+ } else {
+ strcpy(tmpbuf, NOCATGETS("s."));
+ strcat(tmpbuf, source->string_mb);
+ retmem((wchar_t *) source->string_mb);
+ source->string_mb = tmpbuf;
+
+ }
+ source->hash.length = strlen(source->string_mb);
+ if(exists(source) == file_doesnt_exist)
+ continue;
+ tilde_rule = true;
+ we_are_in_tilde = true;
+ } else {
+ if(!name_found) {
+ free_name(source);
+ }
+ continue;
+ }
+ } else {
+ if(posix && posix_tilde_attempt) {
+ if(exists(source) == file_doesnt_exist) {
+ if(!name_found) {
+ free_name(source);
+ }
+ continue;
+ }
+ }
+ }
+
+ if (command != NULL) {
+ if(!name_found) {
+ store_name(source);
+ }
+ /*
+ * The source file is a file.
+ * Make sure it is up to date.
+ */
+ if (dependency_exists(source,
+ get_prop(target->prop,
+ line_prop))) {
+ result = (Doname) source->state;
+ } else {
+#ifdef NSE
+ nse_check_derived_src(target, source->string,
+ source_suffix->body.suffix.command_template);
+#endif
+#if 0 /* with_squiggle sends false, which is buggy. : djay */
+ result = doname(source,
+ (Boolean) source_suffix->body.
+ suffix.suffix->with_squiggle,
+ true);
+#else
+ result = doname(source,
+ true,
+ true);
+#endif
+ }
+ } else {
+ result = target_can_be_built(source);
+
+ if (result == build_ok) {
+ return result;
+ } else {
+ if(!name_found) {
+ free_name(source);
+ }
+ continue;
+ }
+ }
+
+ switch (result) {
+ case build_dont_know:
+ /*
+ * If we still can't build the source,
+ * this rule is not a match,
+ * try the next one.
+ */
+ if (source->stat.time == file_doesnt_exist) {
+ if(!name_found) {
+ free_name(source);
+ }
+ continue;
+ }
+ case build_running:
+ if(!name_found) {
+ store_name(source);
+ }
+ true_target->suffix_scan_done = false;
+ line = maybe_append_prop(target, line_prop);
+ enter_dependency(line, source, false);
+ line->body.line.target = true_target;
+ return build_running;
+ case build_ok:
+ if(!name_found) {
+ store_name(source);
+ }
+ break;
+ case build_failed:
+ if(!name_found) {
+ store_name(source);
+ }
+ if (sourcename != static_string_buf_3M) {
+ retmem(sourcename);
+ }
+ return build_failed;
+ }
+
+ if (debug_level > 1) {
+ WCSTOMBS(mbs_buffer, sourcename);
+ (void) printf(catgets(catd, 1, 219, "%*sFound %s\n"),
+ recursion_level,
+ "",
+ mbs_buffer);
+ }
+
+ if (source->depends_on_conditional) {
+ target->depends_on_conditional = true;
+ }
+/*
+ * Since it is possible that the same target is built several times during
+ * the make run, we have to patch the target with all information we found
+ * here. Thus, the target will have an explicit rule the next time around.
+ */
+ line = maybe_append_prop(target, line_prop);
+ if (*command == NULL) {
+ *command = line;
+ }
+ if ((source->stat.time > (*command)->body.line.dependency_time) &&
+ (debug_level > 1)) {
+ (void) printf(catgets(catd, 1, 220, "%*sDate(%s)=%s Date-dependencies(%s)=%s\n"),
+ recursion_level,
+ "",
+ source->string_mb,
+ time_to_string(source->
+ stat.time),
+ true_target->string_mb,
+ time_to_string((*command)->
+ body.line.
+ dependency_time));
+ }
+ /*
+ * Determine if this new dependency made the
+ * target out of date.
+ */
+ (*command)->body.line.dependency_time =
+ MAX((*command)->body.line.dependency_time,
+ source->stat.time);
+ Boolean out_of_date;
+ if (target->is_member) {
+ out_of_date = (Boolean) OUT_OF_DATE_SEC(target->stat.time,
+ (*command)->body.line.dependency_time);
+ } else {
+ out_of_date = (Boolean) OUT_OF_DATE(target->stat.time,
+ (*command)->body.line.dependency_time);
+ }
+ if (build_unconditional || out_of_date) {
+ if(!rechecking) {
+ line->body.line.is_out_of_date = true;
+ }
+ if (debug_level > 0) {
+ (void) printf(catgets(catd, 1, 221, "%*sBuilding %s using suffix rule for %s%s because it is out of date relative to %s\n"),
+ recursion_level,
+ "",
+ true_target->string_mb,
+ source_suffix->body.suffix.suffix->string_mb,
+ target_suffix->string_mb,
+ source->string_mb);
+ }
+ }
+ /*
+ * Add the implicit rule as the target's explicit
+ * rule if none actually given, and register
+ * dependency.
+ * The time checking above really should be
+ * conditional on actual use of implicit rule
+ * as well.
+ */
+ line->body.line.sccs_command = false;
+ if (line->body.line.command_template == NULL) {
+ line->body.line.command_template =
+ source_suffix->body.suffix.command_template;
+ }
+ enter_dependency(line, source, false);
+ line->body.line.target = true_target;
+ /*
+ * Also make sure the rule is built with
+ * $* and $< bound properly.
+ */
+ line->body.line.star = target_body;
+ if(svr4|posix) {
+ char * p;
+ char tstr[256];
+ extern Boolean dollarless_flag;
+ extern Name dollarless_value;
+
+ if(tilde_rule) {
+ MBSTOWCS(wcs_buffer, NOCATGETS(source->string_mb));
+ dollarless_value = GETNAME(wcs_buffer,FIND_LENGTH);
+ }
+ else {
+ dollarless_flag = false;
+ }
+ }
+ line->body.line.less = source;
+ line->body.line.percent = NULL;
+ add_target_to_chain(source, &(line->body.line.query));
+ if (sourcename != static_string_buf_3M) {
+ retmem(sourcename);
+ }
+ return build_ok;
+ }
+ if(posix && posix_tilde_attempt) {
+ posix_tilde_attempt = false;
+ goto posix_attempts;
+ }
+ if ((command != NULL) &&
+ ((*command) != NULL) &&
+ ((*command)->body.line.star == NULL)) {
+ (*command)->body.line.star = target_body;
+ }
+ }
+ if (sourcename != static_string_buf_3M) {
+ retmem(sourcename);
+ }
+ /* Return here in case no rule matched the target */
+ return build_dont_know;
+}
+
+/*
+ * find_ar_suffix_rule(target, true_target, command, rechecking)
+ *
+ * Scans the .SUFFIXES list and tries
+ * to find a suffix on it that matches the tail of the target member name.
+ * If it finds a matching suffix it calls find_suffix_rule() to find
+ * a rule for the target using the suffix ".a".
+ *
+ * Return value:
+ * Indicates if search failed or not
+ *
+ * Parameters:
+ * target The target we need a rule for
+ * true_target The proper name
+ * command Pointer to slot where we stuff cmd, if found
+ * rechecking true if we are rechecking target which depends
+ * on conditional macro and keep_state is set
+ *
+ * Global variables used:
+ * debug_level Indicates how much tracing to do
+ * dot_a The Name ".a", compared against
+ * recursion_level Used for tracing
+ * suffixes List of suffixes used for scan (from .SUFFIXES)
+ */
+Doname
+find_ar_suffix_rule(register Name target, Name true_target, Property *command, Boolean rechecking)
+{
+ wchar_t *target_end;
+ register Dependency suffix;
+ register int suffix_length;
+ Property line;
+ Name body;
+ static Name dot_a;
+
+ Wstring targ_string(true_target);
+ Wstring suf_string;
+
+ if (dot_a == NULL) {
+ MBSTOWCS(wcs_buffer, NOCATGETS(".a"));
+ dot_a = GETNAME(wcs_buffer, FIND_LENGTH);
+ }
+ target_end = targ_string.get_string() + true_target->hash.length;
+
+ /*
+ * We compare the tail of the target name with the suffixes
+ * from .SUFFIXES.
+ */
+ if (debug_level > 1) {
+ (void) printf(NOCATGETS("%*sfind_ar_suffix_rule(%s)\n"),
+ recursion_level,
+ "",
+ true_target->string_mb);
+ }
+ /*
+ * Scan the .SUFFIXES list to see if the target matches any of
+ * those suffixes.
+ */
+ for (suffix = suffixes; suffix != NULL; suffix = suffix->next) {
+ /* Compare one suffix. */
+ suffix_length = suffix->name->hash.length;
+ suf_string.init(suffix->name);
+ if (!IS_WEQUALN(suf_string.get_string(),
+ target_end - suffix_length,
+ suffix_length)) {
+ goto not_this_one;
+ }
+ /*
+ * The target tail matched a suffix from the .SUFFIXES list.
+ * Now check for a rule to match.
+ */
+ target->suffix_scan_done = false;
+ body = GETNAME(targ_string.get_string(),
+ (int)(true_target->hash.length -
+ suffix_length));
+ we_are_in_tilde = false;
+ switch (find_suffix_rule(target,
+ body,
+ dot_a,
+ command,
+ rechecking)) {
+ case build_ok:
+ line = get_prop(target->prop, line_prop);
+ line->body.line.star = body;
+ return build_ok;
+ case build_running:
+ return build_running;
+ }
+ /*
+ * If no rule was found, we try the next suffix to see
+ * if it matches the target tail, and so on.
+ * Go here if the suffix did not match the target tail.
+ */
+ not_this_one:;
+ }
+ return build_dont_know;
+}
+
+/*
+ * find_double_suffix_rule(target, command, rechecking)
+ *
+ * Scans the .SUFFIXES list and tries
+ * to find a suffix on it that matches the tail of the target name.
+ * If it finds a matching suffix it calls find_suffix_rule() to find
+ * a rule for the target.
+ *
+ * Return value:
+ * Indicates if scan failed or not
+ *
+ * Parameters:
+ * target Target we need a rule for
+ * command Pointer to slot where we stuff cmd, if found
+ * rechecking true if we are rechecking target which depends
+ * on conditional macro and keep_state is set
+ *
+ * Global variables used:
+ * debug_level Indicates how much tracing to do
+ * recursion_level Used for tracing
+ * suffixes List of suffixes used for scan (from .SUFFIXES)
+ */
+Doname
+find_double_suffix_rule(register Name target, Property *command, Boolean rechecking)
+{
+ Name true_target = target;
+ Name target_body;
+ register wchar_t *target_end;
+ register Dependency suffix;
+ register int suffix_length;
+ Boolean scanned_once = false;
+ Boolean name_found = true;
+
+ Wstring targ_string;
+ Wstring suf_string;
+
+ /*
+ * If the target is a constructed one for a "::" target,
+ * we need to consider that.
+ */
+ if (target->has_target_prop) {
+ true_target = get_prop(target->prop,
+ target_prop)->body.target.target;
+ }
+ targ_string.init(true_target);
+
+ /*
+ * We compare the tail of the target name with the
+ * suffixes from .SUFFIXES.
+ */
+ target_end = targ_string.get_string() + true_target->hash.length;
+ if (debug_level > 1) {
+ (void) printf(NOCATGETS("%*sfind_double_suffix_rule(%s)\n"),
+ recursion_level,
+ "",
+ true_target->string_mb);
+ }
+ /*
+ * Scan the .SUFFIXES list to see if the target matches
+ * any of those suffixes.
+ */
+ for (suffix = suffixes; suffix != NULL; suffix = suffix->next) {
+ target->suffix_scan_done = false;
+ true_target->suffix_scan_done = false;
+ /* Compare one suffix. */
+ suffix_length = suffix->name->hash.length;
+ suf_string.init(suffix->name);
+ /* Check the lengths, or else RTC will report rua. */
+ if (true_target->hash.length < suffix_length) {
+ goto not_this_one;
+ } else if (!IS_WEQUALN(suf_string.get_string(),
+ (target_end - suffix_length),
+ suffix_length)) {
+ goto not_this_one;
+ }
+ /*
+ * The target tail matched a suffix from the .SUFFIXES list.
+ * Now check for a rule to match.
+ */
+ we_are_in_tilde = false;
+ target_body = GETNAME(
+ targ_string.get_string(),
+ (int)(true_target->hash.length - suffix_length)
+ );
+ switch (find_suffix_rule(target,
+ target_body,
+ suffix->name,
+ command,
+ rechecking)) {
+ case build_ok:
+ return build_ok;
+ case build_running:
+ return build_running;
+ }
+ if (true_target->suffix_scan_done == true) {
+ scanned_once = true;
+ }
+ /*
+ * If no rule was found, we try the next suffix to see
+ * if it matches the target tail. And so on.
+ * Go here if the suffix did not match the target tail.
+ */
+ not_this_one:;
+ }
+ if (scanned_once)
+ true_target->suffix_scan_done = true;
+ return build_dont_know;
+}
+
+/*
+ * build_suffix_list(target_suffix)
+ *
+ * Scans the .SUFFIXES list and figures out
+ * which suffixes this target can be derived from.
+ * The target itself is not know here, we just know the suffix of the
+ * target. For each suffix on the list the target can be derived iff
+ * a rule exists for the name "<suffix-on-list><target-suffix>".
+ * A list of all possible building suffixes is built, with the rule for
+ * each, and tacked to the target suffix nameblock.
+ *
+ * Parameters:
+ * target_suffix The suffix we build a match list for
+ *
+ * Global variables used:
+ * debug_level Indicates how much tracing to do
+ * recursion_level Used for tracing
+ * suffixes List of suffixes used for scan (from .SUFFIXES)
+ * working_on_targets Indicates that this is a real target
+ */
+void
+build_suffix_list(register Name target_suffix)
+{
+ register Dependency source_suffix;
+ wchar_t rule_name[MAXPATHLEN];
+ register Property line;
+ register Property suffix;
+ Name rule;
+
+ /* If this is before default.mk has been read we just return to try */
+ /* again later */
+ if ((suffixes == NULL) || !working_on_targets) {
+ return;
+ }
+ if (debug_level > 1) {
+ (void) printf(NOCATGETS("%*sbuild_suffix_list(%s) "),
+ recursion_level,
+ "",
+ target_suffix->string_mb);
+ }
+ /* Mark the target suffix saying we cashed its list */
+ target_suffix->has_read_suffixes = true;
+ /* Scan the .SUFFIXES list */
+ for (source_suffix = suffixes;
+ source_suffix != NULL;
+ source_suffix = source_suffix->next) {
+ /*
+ * Build the name "<suffix-on-list><target-suffix>".
+ * (a popular one would be ".c.o").
+ */
+ (void) mbstowcs(rule_name,
+ source_suffix->name->string_mb,
+ (int) source_suffix->name->hash.length);
+ (void) mbstowcs(rule_name + source_suffix->name->hash.length,
+ target_suffix->string_mb,
+ (int) target_suffix->hash.length);
+ /*
+ * Check if that name has a rule. If not, it cannot match
+ * any implicit rule scan and is ignored.
+ * The GETNAME() call only checks for presence, it will not
+ * enter the name if it is not defined.
+ */
+ if (((rule = getname_fn(rule_name,
+ (int) (source_suffix->name->
+ hash.length +
+ target_suffix->hash.length),
+ true)) != NULL) &&
+ ((line = get_prop(rule->prop, line_prop)) != NULL)) {
+ if (debug_level > 1) {
+ (void) printf("%s ", rule->string_mb);
+ }
+ /*
+ * This makes it possible to quickly determine if
+ * it will pay to look for a suffix property.
+ */
+ target_suffix->has_suffixes = true;
+ /*
+ * Add the suffix property to the target suffix
+ * and save the rule with it.
+ * All information the implicit rule scanner need
+ * is saved in the suffix property.
+ */
+ suffix = append_prop(target_suffix, suffix_prop);
+ suffix->body.suffix.suffix = source_suffix->name;
+ suffix->body.suffix.command_template =
+ line->body.line.command_template;
+ }
+ }
+ if (debug_level > 1) {
+ (void) printf("\n");
+ }
+}
+
+/*
+ * find_percent_rule(target, command, rechecking)
+ *
+ * Tries to find a rule from the list of wildcard matched rules.
+ * It scans the list attempting to match the target.
+ * For each target match it checks if the corresponding source exists.
+ * If it does the match is returned.
+ * The percent_list is built at makefile read time.
+ * Each percent rule get one entry on the list.
+ *
+ * Return value:
+ * Indicates if the scan failed or not
+ *
+ * Parameters:
+ * target The target we need a rule for
+ * command Pointer to slot where we stuff cmd, if found
+ * rechecking true if we are rechecking target which depends
+ * on conditional macro and keep_state is set
+ *
+ * Global variables used:
+ * debug_level Indicates how much tracing to do
+ * percent_list List of all percent rules
+ * recursion_level Used for tracing
+ * empty_name
+ */
+Doname
+find_percent_rule(register Name target, Property *command, Boolean rechecking)
+{
+ register Percent pat_rule, pat_depe;
+ register Name depe_to_check;
+ register Dependency depe;
+ register Property line;
+ String_rec string;
+ wchar_t string_buf[STRING_BUFFER_LENGTH];
+ String_rec percent;
+ wchar_t percent_buf[STRING_BUFFER_LENGTH];
+ Name true_target = target;
+ Name less;
+ Boolean nonpattern_less;
+ Boolean dep_name_found = false;
+ Doname result = build_dont_know;
+ Percent rule_candidate = NULL;
+ Boolean rule_maybe_ok;
+ Boolean is_pattern;
+
+ /* If the target is constructed for a "::" target we consider that */
+ if (target->has_target_prop) {
+ true_target = get_prop(target->prop,
+ target_prop)->body.target.target;
+ }
+ if (target->has_long_member_name) {
+ true_target = get_prop(target->prop,
+ long_member_name_prop)->body.long_member_name.member_name;
+ }
+ if (debug_level > 1) {
+ (void) printf(catgets(catd, 1, 222, "%*sLooking for %% rule for %s\n"),
+ recursion_level,
+ "",
+ true_target->string_mb);
+ }
+ for (pat_rule = percent_list;
+ pat_rule != NULL;
+ pat_rule = pat_rule->next) {
+ /* Avoid infinite recursion when expanding patterns */
+ if (pat_rule->being_expanded == true) {
+ continue;
+ }
+
+ /* Mark this pat_rule as "maybe ok". If no % rule is found
+ make will use this rule. The following algorithm is used:
+ 1) make scans all pattern rules in order to find the rule
+ where ALL dependencies, including nonpattern ones, exist or
+ can be built (GNU behaviour). If such rule is found make
+ will apply it.
+ 2) During this check make also remembers the first pattern rule
+ where all PATTERN dependencies can be build (no matter what
+ happens with nonpattern dependencies).
+ 3) If no rule satisfying 1) is found, make will apply the rule
+ remembered in 2) if there is one.
+ */
+ rule_maybe_ok = true;
+
+ /* used to track first percent dependency */
+ less = NULL;
+ nonpattern_less = true;
+
+ /* check whether pattern matches.
+ if it matches, percent string will contain matched percent part of pattern */
+ if (!match_found_with_pattern(true_target, pat_rule, &percent, percent_buf)) {
+ continue;
+ }
+ if (pat_rule->dependencies != NULL) {
+ for (pat_depe = pat_rule->dependencies;
+ pat_depe != NULL;
+ pat_depe = pat_depe->next) {
+ /* checking result for dependency */
+ result = build_dont_know;
+
+ dep_name_found = true;
+ if (pat_depe->name->percent) {
+ is_pattern = true;
+ /* build dependency name */
+ INIT_STRING_FROM_STACK(string, string_buf);
+ construct_string_from_pattern(pat_depe, &percent, &string);
+ depe_to_check = getname_fn(string.buffer.start,
+ FIND_LENGTH,
+ false,
+ &dep_name_found
+ );
+
+ if ((less == NULL) || nonpattern_less) {
+ less = depe_to_check;
+ nonpattern_less = false;
+ }
+ } else {
+ /* nonpattern dependency */
+ is_pattern = false;
+ depe_to_check = pat_depe->name;
+ if(depe_to_check->dollar) {
+ INIT_STRING_FROM_STACK(string, string_buf);
+ expand_value(depe_to_check, &string, false);
+ depe_to_check = getname_fn(string.buffer.start,
+ FIND_LENGTH,
+ false,
+ &dep_name_found
+ );
+ }
+ if (less == NULL) {
+ less = depe_to_check;
+ }
+ }
+
+ if (depe_to_check == empty_name) {
+ result = build_ok;
+ } else {
+ if (debug_level > 1) {
+ (void) printf(catgets(catd, 1, 223, "%*sTrying %s\n"),
+ recursion_level,
+ "",
+ depe_to_check->string_mb);
+ }
+
+ pat_rule->being_expanded = true;
+
+ /* suppress message output */
+ int save_debug_level = debug_level;
+ debug_level = 0;
+
+ /* check whether dependency can be built */
+ if (dependency_exists(depe_to_check,
+ get_prop(target->prop,
+ line_prop)))
+ {
+ result = (Doname) depe_to_check->state;
+ } else {
+ if(actual_doname) {
+ result = doname(depe_to_check, true, true);
+ } else {
+ result = target_can_be_built(depe_to_check);
+ }
+ if(!dep_name_found) {
+ if(result != build_ok && result != build_running) {
+ free_name(depe_to_check);
+ } else {
+ store_name(depe_to_check);
+ }
+ }
+ }
+ if(result != build_ok && is_pattern) {
+ rule_maybe_ok = false;
+ }
+
+ /* restore debug_level */
+ debug_level = save_debug_level;
+ }
+
+ if (pat_depe->name->percent) {
+ if (string.free_after_use) {
+ retmem(string.buffer.start);
+ }
+ }
+ /* make can't figure out how to make this dependency */
+ if (result != build_ok && result != build_running) {
+ pat_rule->being_expanded = false;
+ break;
+ }
+ }
+ } else {
+ result = build_ok;
+ }
+
+ /* this pattern rule is the needed one since all dependencies could be built */
+ if (result == build_ok || result == build_running) {
+ break;
+ }
+
+ /* Make does not know how to build some of dependencies from this rule.
+ But if all "pattern" dependencies can be built, we remember this rule
+ as a candidate for the case if no other pattern rule found.
+ */
+ if(rule_maybe_ok && rule_candidate == NULL) {
+ rule_candidate = pat_rule;
+ }
+ }
+
+ /* if no pattern matching rule was found, use the remembered candidate
+ or return build_dont_know if there is no candidate.
+ */
+ if (result != build_ok && result != build_running) {
+ if(rule_candidate) {
+ pat_rule = rule_candidate;
+ } else {
+ return build_dont_know;
+ }
+ }
+
+ /* if we are performing only check whether dependency could be built with existing rules,
+ return success */
+ if (command == NULL) {
+ if(pat_rule != NULL) {
+ pat_rule->being_expanded = false;
+ }
+ return result;
+ }
+
+ if (debug_level > 1) {
+ (void) printf(catgets(catd, 1, 224, "%*sMatched %s:"),
+ recursion_level,
+ "",
+ target->string_mb);
+
+ for (pat_depe = pat_rule->dependencies;
+ pat_depe != NULL;
+ pat_depe = pat_depe->next) {
+ if (pat_depe->name->percent) {
+ INIT_STRING_FROM_STACK(string, string_buf);
+ construct_string_from_pattern(pat_depe, &percent, &string);
+ depe_to_check = GETNAME(string.buffer.start, FIND_LENGTH);
+ } else {
+ depe_to_check = pat_depe->name;
+ if(depe_to_check->dollar) {
+ INIT_STRING_FROM_STACK(string, string_buf);
+ expand_value(depe_to_check, &string, false);
+ depe_to_check = GETNAME(string.buffer.start, FIND_LENGTH);
+ }
+ }
+
+ if (depe_to_check != empty_name) {
+ (void) printf(" %s", depe_to_check->string_mb);
+ }
+ }
+
+ (void) printf(catgets(catd, 1, 225, " from: %s:"),
+ pat_rule->name->string_mb);
+
+ for (pat_depe = pat_rule->dependencies;
+ pat_depe != NULL;
+ pat_depe = pat_depe->next) {
+ (void) printf(" %s", pat_depe->name->string_mb);
+ }
+
+ (void) printf("\n");
+ }
+
+ if (true_target->colons == no_colon) {
+ true_target->colons = one_colon;
+ }
+
+ /* create deppendency list and target group from matched pattern rule */
+ create_target_group_and_dependencies_list(target, pat_rule, &percent);
+
+ /* save command */
+ line = get_prop(target->prop, line_prop);
+ *command = line;
+
+ /* free query chain if one exist */
+ while(line->body.line.query != NULL) {
+ Chain to_free = line->body.line.query;
+ line->body.line.query = line->body.line.query->next;
+ retmem_mb((char *) to_free);
+ }
+
+ if (line->body.line.dependencies != NULL) {
+ /* build all collected dependencies */
+ for (depe = line->body.line.dependencies;
+ depe != NULL;
+ depe = depe->next) {
+ actual_doname = true;
+ result = doname_check(depe->name, true, true, depe->automatic);
+
+ actual_doname = false;
+ if (result == build_failed) {
+ pat_rule->being_expanded = false;
+ return build_failed;
+ }
+ if (result == build_running) {
+ pat_rule->being_expanded = false;
+ return build_running;
+ }
+
+ if ((depe->name->stat.time > line->body.line.dependency_time) &&
+ (debug_level > 1)) {
+ (void) printf(catgets(catd, 1, 226, "%*sDate(%s)=%s Date-dependencies(%s)=%s\n"),
+ recursion_level,
+ "",
+ depe->name->string_mb,
+ time_to_string(depe->name->stat.time),
+ true_target->string_mb,
+ time_to_string(line->body.line.dependency_time));
+ }
+
+ line->body.line.dependency_time =
+ MAX(line->body.line.dependency_time, depe->name->stat.time);
+
+ /* determine whether this dependency made target out of date */
+ Boolean out_of_date;
+ if (target->is_member || depe->name->is_member) {
+ out_of_date = (Boolean) OUT_OF_DATE_SEC(target->stat.time, depe->name->stat.time);
+ } else {
+ out_of_date = (Boolean) OUT_OF_DATE(target->stat.time, depe->name->stat.time);
+ }
+ if (build_unconditional || out_of_date) {
+ if(!rechecking) {
+ line->body.line.is_out_of_date = true;
+ }
+ add_target_to_chain(depe->name, &(line->body.line.query));
+
+ if (debug_level > 0) {
+ (void) printf(catgets(catd, 1, 227, "%*sBuilding %s using pattern rule %s:"),
+ recursion_level,
+ "",
+ true_target->string_mb,
+ pat_rule->name->string_mb);
+
+ for (pat_depe = pat_rule->dependencies;
+ pat_depe != NULL;
+ pat_depe = pat_depe->next) {
+ (void) printf(" %s", pat_depe->name->string_mb);
+ }
+
+ (void) printf(catgets(catd, 1, 228, " because it is out of date relative to %s\n"),
+ depe->name->string_mb);
+ }
+ }
+ }
+ } else {
+ if ((true_target->stat.time <= file_doesnt_exist) ||
+ (true_target->stat.time < line->body.line.dependency_time)) {
+ if(!rechecking) {
+ line->body.line.is_out_of_date = true;
+ }
+ if (debug_level > 0) {
+ (void) printf(catgets(catd, 1, 229, "%*sBuilding %s using pattern rule %s: "),
+ recursion_level,
+ "",
+ true_target->string_mb,
+ pat_rule->name->string_mb,
+ (target->stat.time > file_doesnt_exist) ?
+ catgets(catd, 1, 230, "because it is out of date") :
+ catgets(catd, 1, 236, "because it does not exist"));
+ }
+ }
+ }
+
+ /* enter explicit rule from percent rule */
+ Name lmn_target = true_target;
+ if (true_target->has_long_member_name) {
+ lmn_target = get_prop(true_target->prop, long_member_name_prop)->body.long_member_name.member_name;
+ }
+ line->body.line.sccs_command = false;
+ line->body.line.target = true_target;
+ line->body.line.command_template = pat_rule->command_template;
+ line->body.line.star = GETNAME(percent.buffer.start, FIND_LENGTH);
+ line->body.line.less = less;
+
+ if (lmn_target->parenleft) {
+ Wstring lmn_string(lmn_target);
+
+ wchar_t *left = (wchar_t *) wschr(lmn_string.get_string(), (int) parenleft_char);
+ wchar_t *right = (wchar_t *) wschr(lmn_string.get_string(), (int) parenright_char);
+
+ if ((left == NULL) || (right == NULL)) {
+ line->body.line.percent = NULL;
+ } else {
+ line->body.line.percent = GETNAME(left + 1, right - left - 1);
+ }
+ } else {
+ line->body.line.percent = NULL;
+ }
+ pat_rule->being_expanded = false;
+
+#ifdef TEAMWARE_MAKE_CMN
+ /*
+ * This #ifdef fixes a dmake bug, but introduces bugid 1136156.
+ */
+ return result;
+#else
+ return build_ok;
+#endif
+}
+
+/*
+ * match_found_with_pattern
+ * ( target, pat_rule, percent, percent_buf)
+ *
+ * matches "target->string" with a % pattern.
+ * If pattern contains a MACRO definition, it's expanded first.
+ *
+ * Return value:
+ * true if a match was found
+ *
+ * Parameters:
+ * target The target we're trying to match
+ * pattern
+ * percent record that contains "percent_buf" below
+ * percent_buf This is where the patched % part of pattern is stored
+ *
+ */
+
+static Boolean
+match_found_with_pattern(Name target, Percent pat_rule, String percent, wchar_t *percent_buf) {
+ String_rec string;
+ wchar_t string_buf[STRING_BUFFER_LENGTH];
+
+ /* construct prefix string and check whether prefix matches */
+ Name prefix = pat_rule->patterns[0];
+ int prefix_length;
+
+ Wstring targ_string(target);
+ Wstring pref_string(prefix);
+ Wstring suf_string;
+
+ if (prefix->dollar) {
+ INIT_STRING_FROM_STACK(string, string_buf);
+ expand_value(prefix, &string, false);
+ prefix_length = string.text.p - string.buffer.start;
+ if ((string.buffer.start[0] == (int) period_char) &&
+ (string.buffer.start[1] == (int) slash_char)) {
+ string.buffer.start += 2;
+ prefix_length -= 2;
+ }
+ if (!targ_string.equaln(string.buffer.start, prefix_length)) {
+ return false;
+ }
+ } else {
+ prefix_length = prefix->hash.length;
+ if (!targ_string.equaln(&pref_string, prefix_length)) {
+ return false;
+ }
+ }
+
+ /* do the same with pattern suffix */
+ Name suffix = pat_rule->patterns[pat_rule->patterns_total - 1];
+ suf_string.init(suffix);
+
+ int suffix_length;
+ if (suffix->dollar) {
+ INIT_STRING_FROM_STACK(string, string_buf);
+ expand_value(suffix, &string, false);
+ suffix_length = string.text.p - string.buffer.start;
+ if(suffix_length > target->hash.length) {
+ return false;
+ }
+ if (!targ_string.equal(string.buffer.start, target->hash.length - suffix_length)) {
+ return false;
+ }
+ } else {
+ suffix_length = (int) suffix->hash.length;
+ if(suffix_length > target->hash.length) {
+ return false;
+ }
+ if (!targ_string.equal(&suf_string, target->hash.length - suffix_length)) {
+ return false;
+ }
+ }
+
+ Boolean match_found = false;
+ int percent_length = target->hash.length - prefix_length - suffix_length;
+
+ while (!match_found && (percent_length >= 0)) {
+ /* init result string */
+ INIT_STRING_FROM_STACK(string, string_buf);
+
+ /* init percent string */
+ percent->buffer.start = percent_buf;
+ percent->text.p = percent_buf;
+ percent->text.end = NULL;
+ percent->free_after_use = false;
+ percent->buffer.end = percent_buf + STRING_BUFFER_LENGTH;
+
+ /* construct percent and result strings */
+ targ_string.append_to_str(percent, prefix_length, percent_length);
+ construct_string_from_pattern(pat_rule, percent, &string);
+
+ /* check for match */
+ if (targ_string.equal(string.buffer.start, 0)) {
+ match_found = true;
+ } else {
+ percent_length--;
+ }
+ }
+
+ /* result */
+ return match_found;
+}
+
+
+/*
+ * create_target_group_and_dependencies_list
+ * (target, pat_rule, percent)
+ *
+ * constructs dependency list and a target group from pattern.
+ *
+ * If we have the lines
+ * %/%.a + %/%.b + C%/CC%.c: yyy %.d bb%/BB%.e
+ * commands
+ *
+ * and we have matched the pattern xx/xx.a with %/%.a, then we
+ * construct a target group that looks like this:
+ * xx/xx.a + xx/xx.b + Cxx/CCxx.c: dependencies
+ *
+ * and construct dependency list that looks like this:
+ * yyy xx.d bbxx/BBxx.e + already existed dependencies
+ *
+ * Return value:
+ * none
+ *
+ * Parameters:
+ * target The target we are building, in the previous
+ * example, this is xx/xx.a
+ * pat_rule the % pattern that matched "target", here %/%.a
+ * percent string containing matched % part. In the example=xx.
+ *
+ * Global variables used:
+ * empty_name
+ */
+
+static void
+create_target_group_and_dependencies_list(Name target, Percent pat_rule, String percent) {
+ String_rec string;
+ wchar_t string_buf[STRING_BUFFER_LENGTH];
+ Percent pat_depe;
+ Name depe;
+ Property line = maybe_append_prop(target, line_prop);
+ Chain new_target_group = NULL;
+ Chain *new_target_group_tail = &new_target_group;
+ Chain group_member;
+
+ /* create and append dependencies from rule */
+ for (pat_depe = pat_rule->dependencies; pat_depe != NULL; pat_depe = pat_depe->next) {
+ if (pat_depe->name->percent) {
+ INIT_STRING_FROM_STACK(string, string_buf);
+ construct_string_from_pattern(pat_depe, percent, &string);
+ depe = GETNAME(string.buffer.start, FIND_LENGTH);
+ if (depe != empty_name) {
+ enter_dependency(line, depe, false);
+ }
+ } else {
+ depe = pat_depe->name;
+ if(depe->dollar) {
+ INIT_STRING_FROM_STACK(string, string_buf);
+ expand_value(depe, &string, false);
+ depe = GETNAME(string.buffer.start, FIND_LENGTH);
+ }
+ enter_dependency(line, depe, false);
+ }
+ }
+
+ /* if matched pattern is a group member, create new target group */
+ for (group_member = pat_rule->target_group; group_member != NULL; group_member = group_member->next) {
+ Name new_target = group_member->name;
+ if (group_member->name->percent) {
+ INIT_STRING_FROM_STACK(string, string_buf);
+ construct_string_from_pattern(group_member->percent_member, percent, &string);
+ new_target = GETNAME(string.buffer.start, FIND_LENGTH);
+ if (new_target == empty_name) {
+ continue;
+ }
+ }
+
+ /* check for duplicates */
+ Chain tgm;
+ for (tgm = new_target_group; tgm != NULL; tgm = tgm->next) {
+ if (new_target == tgm->name) {
+ break;
+ }
+ }
+ if (tgm != NULL) {
+ continue;
+ }
+
+ /* insert it into the targets list */
+ (*new_target_group_tail) = ALLOC(Chain);
+ (*new_target_group_tail)->name = new_target;
+ (*new_target_group_tail)->next = NULL;
+ new_target_group_tail = &(*new_target_group_tail)->next;
+ }
+
+ /* now we gathered all dependencies and created target group */
+ line->body.line.target_group = new_target_group;
+
+ /* update properties for group members */
+ for (group_member = new_target_group; group_member != NULL; group_member = group_member->next) {
+ if (group_member->name != target) {
+ group_member->name->prop = target->prop;
+ group_member->name->conditional_cnt = target->conditional_cnt;
+ }
+ }
+}
+
+/*
+ * construct_string_from_pattern
+ * (pat_rule, percent, result)
+ *
+ * after pattern matched a target this routine is called to construct targets and dependencies
+ * strings from this matched pattern rule and a string (percent) with substitutes % sign in pattern.
+ *
+ * Return value:
+ * none
+ *
+ * Parameters:
+ * pat_rule matched pattern rule
+ * percent string containing matched % sign part.
+ * result holds the result of string construction.
+ *
+ */
+static void
+construct_string_from_pattern(Percent pat_rule, String percent, String result) {
+ for (int i = 0; i < pat_rule->patterns_total; i++) {
+ if (pat_rule->patterns[i]->dollar) {
+ expand_value(pat_rule->patterns[i],
+ result,
+ false);
+
+ } else {
+ append_string(pat_rule->patterns[i]->string_mb,
+ result,
+ pat_rule->patterns[i]->hash.length);
+ }
+
+ if (i < pat_rule->patterns_total - 1) {
+ append_string(percent->buffer.start,
+ result,
+ percent->text.p - percent->buffer.start);
+ }
+ }
+
+ if ((result->buffer.start[0] == (int) period_char) &&
+ (result->buffer.start[1] == (int) slash_char)) {
+ result->buffer.start += 2;
+ }
+}
+
+/*
+ * dependency_exists(target, line)
+ *
+ * Returns true if the target exists in the
+ * dependency list of the line.
+ *
+ * Return value:
+ * True if target is on dependency list
+ *
+ * Parameters:
+ * target Target we scan for
+ * line We get the dependency list from here
+ *
+ * Global variables used:
+ */
+static Boolean
+dependency_exists(Name target, Property line)
+{
+ Dependency dp;
+
+ if (line == NULL) {
+ return false;
+ }
+ for (dp = line->body.line.dependencies; dp != NULL; dp = dp->next) {
+ if (dp->name == target) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+add_target_to_chain(Name target, Chain * query)
+{
+ if (target->is_member && (get_prop(target->prop, member_prop) != NULL)) {
+ target = get_prop(target->prop, member_prop)->body.member.member;
+ }
+ Chain *query_tail;
+ for (query_tail = query; *query_tail != NULL; query_tail = &(*query_tail)->next) {
+ if ((*query_tail)->name == target) {
+ return;
+ }
+ }
+ *query_tail = ALLOC(Chain);
+ (*query_tail)->name = target;
+ (*query_tail)->next = NULL;
+}
+
diff --git a/usr/src/make_src/Make/bin/make/common/macro.cc b/usr/src/make_src/Make/bin/make/common/macro.cc
new file mode 100644
index 0000000..0f5bf82
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/macro.cc
@@ -0,0 +1,214 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)macro.cc 1.28 06/12/12
+ */
+
+#pragma ident "@(#)macro.cc 1.28 06/12/12"
+
+/*
+ * macro.cc
+ *
+ * Handle expansion of make macros
+ */
+
+/*
+ * Included files
+ */
+#ifdef DISTRIBUTED
+#include <avo/strings.h> /* AVO_STRDUP() */
+#include <dm/Avo_DoJobMsg.h>
+#endif
+#include <mk/defs.h>
+#include <mksh/macro.h> /* getvar(), expand_value() */
+#include <mksh/misc.h> /* getmem() */
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+
+void
+setvar_append(register Name name, register Name value)
+{
+ register Property macro_apx = get_prop(name->prop, macro_append_prop);
+ register Property macro = get_prop(name->prop, macro_prop);
+ int length;
+ String_rec destination;
+ wchar_t buffer[STRING_BUFFER_LENGTH];
+ register Chain chain;
+ Name val = NULL;
+
+ if(macro_apx == NULL) {
+ macro_apx = append_prop(name, macro_append_prop);
+ if(macro != NULL) {
+ macro_apx->body.macro_appendix.value = macro->body.macro.value;
+ }
+ }
+
+ val = macro_apx->body.macro_appendix.value_to_append;
+
+ INIT_STRING_FROM_STACK(destination, buffer);
+ buffer[0] = 0;
+ if (val != NULL) {
+ APPEND_NAME(val,
+ &destination,
+ (int) val->hash.length);
+ if (value != NULL) {
+ MBTOWC(wcs_buffer, " ");
+ append_char(wcs_buffer[0], &destination);
+ }
+ }
+ if (value != NULL) {
+ APPEND_NAME(value,
+ &destination,
+ (int) value->hash.length);
+ }
+ value = GETNAME(destination.buffer.start, FIND_LENGTH);
+ if (destination.free_after_use) {
+ retmem(destination.buffer.start);
+ }
+ macro_apx->body.macro_appendix.value_to_append = value;
+
+ SETVAR(name, empty_name, true);
+}
+
+/*
+ * setvar_envvar()
+ *
+ * This function scans the list of environment variables that have
+ * dynamic values and sets them.
+ *
+ * Parameters:
+ *
+ * Global variables used:
+ * envvar A list of environment vars with $ in value
+ */
+void
+#ifdef DISTRIBUTED
+setvar_envvar(Avo_DoJobMsg *dmake_job_msg)
+#else
+setvar_envvar(void)
+#endif
+{
+ wchar_t buffer[STRING_BUFFER_LENGTH];
+ int length;
+#ifdef DISTRIBUTED
+ Property macro;
+#endif
+ register char *mbs, *tmp_mbs_buffer = NULL;
+ register char *env, *tmp_mbs_buffer2 = NULL;
+ Envvar p;
+ String_rec value;
+
+ for (p = envvar; p != NULL; p = p->next) {
+ if (p->already_put
+#ifdef DISTRIBUTED
+ && !dmake_job_msg
+#endif
+ ) {
+ continue;
+ }
+ INIT_STRING_FROM_STACK(value, buffer);
+ expand_value(p->value, &value, false);
+ if ((length = wslen(value.buffer.start)) >= MAXPATHLEN) {
+ mbs = tmp_mbs_buffer = getmem((length + 1) * MB_LEN_MAX);
+ (void) wcstombs(mbs,
+ value.buffer.start,
+ (length + 1) * MB_LEN_MAX);
+ } else {
+ mbs = mbs_buffer;
+ WCSTOMBS(mbs, value.buffer.start);
+ }
+ length = 2 + strlen(p->name->string_mb) + strlen(mbs);
+ if (!p->already_put || length > (MAXPATHLEN * MB_LEN_MAX)) {
+ env = tmp_mbs_buffer2 = getmem(length);
+ } else {
+ env = mbs_buffer2;
+ }
+ (void) sprintf(env,
+ "%s=%s",
+ p->name->string_mb,
+ mbs);
+ if (!p->already_put) {
+ (void) putenv(env);
+ p->already_put = true;
+ if (p->env_string) {
+ retmem_mb(p->env_string);
+ }
+ p->env_string = env;
+ tmp_mbs_buffer2 = NULL; // We should not return this memory now
+ }
+#ifdef DISTRIBUTED
+ if (dmake_job_msg) {
+ dmake_job_msg->appendVar(env);
+ }
+#endif
+ if (tmp_mbs_buffer2) {
+ retmem_mb(tmp_mbs_buffer2);
+ tmp_mbs_buffer2 = NULL;
+ }
+ if (tmp_mbs_buffer) {
+ retmem_mb(tmp_mbs_buffer);
+ tmp_mbs_buffer = NULL;
+ }
+ }
+#ifdef DISTRIBUTED
+ /* Append SUNPRO_DEPENDENCIES to the dmake_job_msg. */
+ if (keep_state && dmake_job_msg) {
+ macro = get_prop(sunpro_dependencies->prop, macro_prop);
+ length = 2 +
+ strlen(sunpro_dependencies->string_mb) +
+ strlen(macro->body.macro.value->string_mb);
+ if (length > (MAXPATHLEN * MB_LEN_MAX)) {
+ env = tmp_mbs_buffer2 = getmem(length);
+ } else {
+ env = mbs_buffer2;
+ }
+ (void) sprintf(env,
+ "%s=%s",
+ sunpro_dependencies->string_mb,
+ macro->body.macro.value->string_mb);
+ dmake_job_msg->appendVar(env);
+ if (tmp_mbs_buffer2) {
+ retmem_mb(tmp_mbs_buffer2);
+ tmp_mbs_buffer2 = NULL;
+ }
+ }
+#endif
+}
+
+
diff --git a/usr/src/make_src/Make/bin/make/common/main.cc b/usr/src/make_src/Make/bin/make/common/main.cc
new file mode 100644
index 0000000..e594d59
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/main.cc
@@ -0,0 +1,3787 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)main.cc 1.158 06/12/12
+ */
+
+#pragma ident "@(#)main.cc 1.158 06/12/12"
+
+/*
+ * main.cc
+ *
+ * make program main routine plus some helper routines
+ */
+
+/*
+ * Included files
+ */
+#if defined(TEAMWARE_MAKE_CMN)
+# include <avo/intl.h>
+# include <avo/libcli.h> /* libcli_init() */
+# include <avo/cli_license.h> /* avo_cli_get_license() */
+# include <avo/find_dir.h> /* avo_find_run_dir() */
+# include <avo/version_string.h>
+# include <avo/util.h> /* avo_init() */
+#ifdef USE_DMS_CCR
+# include <avo/usage_tracking.h>
+#else
+# include <avo/cleanup.h>
+#endif
+#endif
+
+#if defined(TEAMWARE_MAKE_CMN)
+/* This is for dmake only (not for Solaris make).
+ * Include code to check updates (dmake patches)
+ */
+#ifdef _CHECK_UPDATE_H
+#include <libAU.h>
+#endif
+#endif
+
+#include <bsd/bsd.h> /* bsd_signal() */
+
+#ifdef DISTRIBUTED
+# include <dm/Avo_AcknowledgeMsg.h>
+# include <rw/xdrstrea.h>
+# include <dmrc/dmrc.h> /* dmakerc file processing */
+#endif
+
+#include <locale.h> /* setlocale() */
+#include <mk/copyright.h>
+#include <mk/defs.h>
+#include <mksdmsi18n/mksdmsi18n.h> /* libmksdmsi18n_init() */
+#include <mksh/macro.h> /* getvar() */
+#include <mksh/misc.h> /* getmem(), setup_char_semantics() */
+
+#if defined(TEAMWARE_MAKE_CMN)
+#ifdef USE_DMS_CCR
+# include <pubdmsi18n/pubdmsi18n.h> /* libpubdmsi18n_init() */
+#endif
+#endif
+
+#include <pwd.h> /* getpwnam() */
+#include <setjmp.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <sys/errno.h> /* ENOENT */
+#include <sys/stat.h> /* fstat() */
+#include <fcntl.h> /* open() */
+
+#ifdef SUN5_0
+# include <sys/systeminfo.h> /* sysinfo() */
+#endif
+
+#include <sys/types.h> /* stat() */
+#include <sys/wait.h> /* wait() */
+#include <unistd.h> /* execv(), unlink(), access() */
+#include <vroot/report.h> /* report_dependency(), get_report_file() */
+
+// From read2.cc
+extern Name normalize_name(register wchar_t *name_string, register int length);
+
+// From parallel.cc
+#if defined(TEAMWARE_MAKE_CMN)
+#define MAXJOBS_ADJUST_RFE4694000
+
+#ifdef MAXJOBS_ADJUST_RFE4694000
+extern void job_adjust_fini();
+#endif /* MAXJOBS_ADJUST_RFE4694000 */
+#endif /* TEAMWARE_MAKE_CMN */
+
+#if defined(linux)
+#include <ctype.h>
+#endif
+
+/*
+ * Defined macros
+ */
+#define LD_SUPPORT_ENV_VAR NOCATGETS("SGS_SUPPORT")
+#define LD_SUPPORT_MAKE_LIB NOCATGETS("libmakestate.so.1")
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+static char *argv_zero_string;
+static Boolean build_failed_ever_seen;
+static Boolean continue_after_error_ever_seen; /* `-k' */
+static Boolean dmake_group_specified; /* `-g' */
+static Boolean dmake_max_jobs_specified; /* `-j' */
+static Boolean dmake_mode_specified; /* `-m' */
+static Boolean dmake_add_mode_specified; /* `-x' */
+static Boolean dmake_output_mode_specified; /* `-x DMAKE_OUTPUT_MODE=' */
+static Boolean dmake_compat_mode_specified; /* `-x SUN_MAKE_COMPAT_MODE=' */
+static Boolean dmake_odir_specified; /* `-o' */
+static Boolean dmake_rcfile_specified; /* `-c' */
+static Boolean env_wins; /* `-e' */
+static Boolean ignore_default_mk; /* `-r' */
+static Boolean list_all_targets; /* `-T' */
+static int mf_argc;
+static char **mf_argv;
+static Dependency_rec not_auto_depen_struct;
+static Dependency not_auto_depen = &not_auto_depen_struct;
+static Boolean pmake_cap_r_specified; /* `-R' */
+static Boolean pmake_machinesfile_specified; /* `-M' */
+static Boolean stop_after_error_ever_seen; /* `-S' */
+static Boolean trace_status; /* `-p' */
+
+#ifdef DMAKE_STATISTICS
+static Boolean getname_stat = false;
+#endif
+
+#if defined(TEAMWARE_MAKE_CMN)
+ static time_t start_time;
+ static int g_argc;
+ static char **g_argv;
+#ifdef USE_DMS_CCR
+ static Avo_usage_tracking *usageTracking = NULL;
+#else
+ static Avo_cleanup *cleanup = NULL;
+#endif
+#endif
+
+/*
+ * File table of contents
+ */
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ extern "C" void cleanup_after_exit(void);
+#else
+ extern void cleanup_after_exit(int, ...);
+#endif
+
+#ifdef TEAMWARE_MAKE_CMN
+extern "C" {
+ extern void dmake_exit_callback(void);
+ extern void dmake_message_callback(char *);
+}
+#endif
+
+extern Name normalize_name(register wchar_t *name_string, register int length);
+
+extern int main(int, char * []);
+
+static void append_makeflags_string(Name, String);
+static void doalarm(int);
+static void enter_argv_values(int , char **, ASCII_Dyn_Array *);
+static void make_targets(int, char **, Boolean);
+static int parse_command_option(char);
+static void read_command_options(int, char **);
+static void read_environment(Boolean);
+static void read_files_and_state(int, char **);
+static Boolean read_makefile(Name, Boolean, Boolean, Boolean);
+static void report_recursion(Name);
+static void set_sgs_support(void);
+static void setup_for_projectdir(void);
+static void setup_makeflags_argv(void);
+static void report_dir_enter_leave(Boolean entering);
+
+extern void expand_value(Name, register String , Boolean);
+
+#ifdef DISTRIBUTED
+ extern int dmake_ofd;
+ extern FILE* dmake_ofp;
+ extern int rxmPid;
+ extern XDR xdrs_out;
+#endif
+#ifdef TEAMWARE_MAKE_CMN
+ extern char verstring[];
+#endif
+
+jmp_buf jmpbuffer;
+#if !defined(linux)
+nl_catd catd;
+#endif
+
+/*
+ * main(argc, argv)
+ *
+ * Parameters:
+ * argc You know what this is
+ * argv You know what this is
+ *
+ * Static variables used:
+ * list_all_targets make -T seen
+ * trace_status make -p seen
+ *
+ * Global variables used:
+ * debug_level Should we trace make actions?
+ * keep_state Set if .KEEP_STATE seen
+ * makeflags The Name "MAKEFLAGS", used to get macro
+ * remote_command_name Name of remote invocation cmd ("on")
+ * running_list List of parallel running processes
+ * stdout_stderr_same true if stdout and stderr are the same
+ * auto_dependencies The Name "SUNPRO_DEPENDENCIES"
+ * temp_file_directory Set to the dir where we create tmp file
+ * trace_reader Set to reflect tracing status
+ * working_on_targets Set when building user targets
+ */
+int
+main(int argc, char *argv[])
+{
+ /*
+ * cp is a -> to the value of the MAKEFLAGS env var,
+ * which has to be regular chars.
+ */
+ register char *cp;
+ char make_state_dir[MAXPATHLEN];
+ Boolean parallel_flag = false;
+ char *prognameptr;
+ char *slash_ptr;
+ mode_t um;
+ int i;
+#ifdef TEAMWARE_MAKE_CMN
+ struct itimerval value;
+ char def_dmakerc_path[MAXPATHLEN];
+ Name dmake_name, dmake_name2;
+ Name dmake_value, dmake_value2;
+ Property prop, prop2;
+ struct stat statbuf;
+ int statval;
+#endif
+
+#ifndef PARALLEL
+ struct stat out_stat, err_stat;
+#endif
+ hostid = gethostid();
+#ifdef TEAMWARE_MAKE_CMN
+ avo_get_user(NULL, NULL); // Initialize user name
+#endif
+ bsd_signals();
+
+ (void) setlocale(LC_ALL, "");
+
+#if defined (HP_UX) || defined(linux)
+ /* HP-UX users typically will not have NLSPATH set, and this binary
+ * requires that it be set. On HP-UX 9.0x, /usr/lib/nls/%L/%N.cat is
+ * the path to set it to.
+ */
+
+ if (getenv(NOCATGETS("NLSPATH")) == NULL) {
+ putenv(NOCATGETS("NLSPATH=/usr/lib/nls/%L/%N.cat"));
+ }
+#endif
+
+#ifdef DMAKE_STATISTICS
+ if (getenv(NOCATGETS("DMAKE_STATISTICS"))) {
+ getname_stat = true;
+ }
+#endif
+
+
+ /*
+ * avo_init() sets the umask to 0. Save it here and restore
+ * it after the avo_init() call.
+ */
+#if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL)
+ um = umask(0);
+ avo_init(argv[0]);
+ umask(um);
+
+#ifdef USE_DMS_CCR
+ usageTracking = new Avo_usage_tracking(NOCATGETS("dmake"), argc, argv);
+#else
+ cleanup = new Avo_cleanup(NOCATGETS("dmake"), argc, argv);
+#endif
+#endif
+
+#if defined(TEAMWARE_MAKE_CMN)
+ catd = catopen(AVO_DOMAIN_DMAKE, NL_CAT_LOCALE);
+ libcli_init();
+
+#ifdef _CHECK_UPDATE_H
+ /* This is for dmake only (not for Solaris make).
+ * Check (in background) if there is an update (dmake patch)
+ * and inform user
+ */
+ {
+ Avo_err *err;
+ char *dir;
+ err = avo_find_run_dir(&dir);
+ if (AVO_OK == err) {
+ AU_check_update_service(NOCATGETS("Dmake"), dir);
+ }
+ }
+#endif /* _CHECK_UPDATE_H */
+#endif
+
+// ---> fprintf(stderr, catgets(catd, 15, 666, "--- SUN make ---\n"));
+
+
+#if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL)
+/*
+ * I put libmksdmsi18n_init() under #ifdef because it requires avo_i18n_init()
+ * from avo_util library.
+ */
+ libmksdmsi18n_init();
+#ifdef USE_DMS_CCR
+ libpubdmsi18n_init();
+#endif
+#endif
+
+
+#ifndef TEAMWARE_MAKE_CMN
+ textdomain(NOCATGETS("SUNW_SPRO_MAKE"));
+#endif /* TEAMWARE_MAKE_CMN */
+
+#ifdef TEAMWARE_MAKE_CMN
+ g_argc = argc;
+ g_argv = (char **) malloc((g_argc + 1) * sizeof(char *));
+ for (i = 0; i < argc; i++) {
+ g_argv[i] = argv[i];
+ }
+ g_argv[i] = NULL;
+#endif /* TEAMWARE_MAKE_CMN */
+
+ /*
+ * Set argv_zero_string to some form of argv[0] for
+ * recursive MAKE builds.
+ */
+
+ if (*argv[0] == (int) slash_char) {
+ /* argv[0] starts with a slash */
+ argv_zero_string = strdup(argv[0]);
+ } else if (strchr(argv[0], (int) slash_char) == NULL) {
+ /* argv[0] contains no slashes */
+ argv_zero_string = strdup(argv[0]);
+ } else {
+ /*
+ * argv[0] contains at least one slash,
+ * but doesn't start with a slash
+ */
+ char *tmp_current_path;
+ char *tmp_string;
+
+ tmp_current_path = get_current_path();
+ tmp_string = getmem(strlen(tmp_current_path) + 1 +
+ strlen(argv[0]) + 1);
+ (void) sprintf(tmp_string,
+ "%s/%s",
+ tmp_current_path,
+ argv[0]);
+ argv_zero_string = strdup(tmp_string);
+ retmem_mb(tmp_string);
+ }
+
+ /*
+ * The following flags are reset if we don't have the
+ * (.nse_depinfo or .make.state) files locked and only set
+ * AFTER the file has been locked. This ensures that if the user
+ * interrupts the program while file_lock() is waiting to lock
+ * the file, the interrupt handler doesn't remove a lock
+ * that doesn't belong to us.
+ */
+ make_state_lockfile = NULL;
+ make_state_locked = false;
+
+#ifdef NSE
+ nse_depinfo_lockfile[0] = '\0';
+ nse_depinfo_locked = false;
+#endif
+
+ /*
+ * look for last slash char in the path to look at the binary
+ * name. This is to resolve the hard link and invoke make
+ * in svr4 mode.
+ */
+
+ /* Sun OS make standart */
+ svr4 = false;
+ posix = false;
+ if(!strcmp(argv_zero_string, NOCATGETS("/usr/xpg4/bin/make"))) {
+ svr4 = false;
+ posix = true;
+ } else {
+ prognameptr = strrchr(argv[0], '/');
+ if(prognameptr) {
+ prognameptr++;
+ } else {
+ prognameptr = argv[0];
+ }
+ if(!strcmp(prognameptr, NOCATGETS("svr4.make"))) {
+ svr4 = true;
+ posix = false;
+ }
+ }
+#if !defined(HP_UX) && !defined(linux)
+ if (getenv(USE_SVR4_MAKE) || getenv(NOCATGETS("USE_SVID"))){
+ svr4 = true;
+ posix = false;
+ }
+#endif
+
+ /*
+ * Find the dmake_compat_mode: posix, sun, svr4, or gnu_style, .
+ */
+ char * dmake_compat_mode_var = getenv(NOCATGETS("SUN_MAKE_COMPAT_MODE"));
+ if (dmake_compat_mode_var != NULL) {
+ if (0 == strcasecmp(dmake_compat_mode_var, NOCATGETS("GNU"))) {
+ gnu_style = true;
+ }
+ //svr4 = false;
+ //posix = false;
+ }
+
+ /*
+ * Temporary directory set up.
+ */
+ char * tmpdir_var = getenv(NOCATGETS("TMPDIR"));
+ if (tmpdir_var != NULL && *tmpdir_var == '/' && strlen(tmpdir_var) < MAXPATHLEN) {
+ strcpy(mbs_buffer, tmpdir_var);
+ for (tmpdir_var = mbs_buffer+strlen(mbs_buffer);
+ *(--tmpdir_var) == '/' && tmpdir_var > mbs_buffer;
+ *tmpdir_var = '\0');
+ if (strlen(mbs_buffer) + 32 < MAXPATHLEN) { /* 32 = strlen("/dmake.stdout.%d.%d.XXXXXX") */
+ sprintf(mbs_buffer2, NOCATGETS("%s/dmake.tst.%d.XXXXXX"),
+ mbs_buffer, getpid());
+ int fd = mkstemp(mbs_buffer2);
+ if (fd >= 0) {
+ close(fd);
+ unlink(mbs_buffer2);
+ tmpdir = strdup(mbs_buffer);
+ }
+ }
+ }
+
+#ifndef PARALLEL
+ /* find out if stdout and stderr point to the same place */
+ if (fstat(1, &out_stat) < 0) {
+ fatal(catgets(catd, 1, 165, "fstat of standard out failed: %s"), errmsg(errno));
+ }
+ if (fstat(2, &err_stat) < 0) {
+ fatal(catgets(catd, 1, 166, "fstat of standard error failed: %s"), errmsg(errno));
+ }
+ if ((out_stat.st_dev == err_stat.st_dev) &&
+ (out_stat.st_ino == err_stat.st_ino)) {
+ stdout_stderr_same = true;
+ } else {
+ stdout_stderr_same = false;
+ }
+#else
+ stdout_stderr_same = false;
+#endif
+ /* Make the vroot package scan the path using shell semantics */
+ set_path_style(0);
+
+ setup_char_semantics();
+
+ setup_for_projectdir();
+
+ /*
+ * If running with .KEEP_STATE, curdir will be set with
+ * the connected directory.
+ */
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ (void) atexit(cleanup_after_exit);
+#else
+ (void) on_exit(cleanup_after_exit, (char *) NULL);
+#endif
+
+ load_cached_names();
+
+/*
+ * Set command line flags
+ */
+ setup_makeflags_argv();
+ read_command_options(mf_argc, mf_argv);
+ read_command_options(argc, argv);
+ if (debug_level > 0) {
+ cp = getenv(makeflags->string_mb);
+ (void) printf(catgets(catd, 1, 167, "MAKEFLAGS value: %s\n"), cp == NULL ? "" : cp);
+ }
+
+ setup_interrupt(handle_interrupt);
+
+ read_files_and_state(argc, argv);
+
+#ifdef TEAMWARE_MAKE_CMN
+ /*
+ * Find the dmake_output_mode: TXT1, TXT2 or HTML1.
+ */
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
+ dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
+ prop2 = get_prop(dmake_name2->prop, macro_prop);
+ if (prop2 == NULL) {
+ /* DMAKE_OUTPUT_MODE not defined, default to TXT1 mode */
+ output_mode = txt1_mode;
+ } else {
+ dmake_value2 = prop2->body.macro.value;
+ if ((dmake_value2 == NULL) ||
+ (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("TXT1")))) {
+ output_mode = txt1_mode;
+ } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("TXT2"))) {
+ output_mode = txt2_mode;
+ } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("HTML1"))) {
+ output_mode = html1_mode;
+ } else {
+ warning(catgets(catd, 1, 352, "Unsupported value `%s' for DMAKE_OUTPUT_MODE after -x flag (ignored)"),
+ dmake_value2->string_mb);
+ }
+ }
+ /*
+ * Find the dmake_mode: distributed, parallel, or serial.
+ */
+ if ((!pmake_cap_r_specified) &&
+ (!pmake_machinesfile_specified)) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
+ dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
+ prop2 = get_prop(dmake_name2->prop, macro_prop);
+ if (prop2 == NULL) {
+ /* DMAKE_MODE not defined, default to distributed mode */
+ dmake_mode_type = distributed_mode;
+ no_parallel = false;
+ } else {
+ dmake_value2 = prop2->body.macro.value;
+ if ((dmake_value2 == NULL) ||
+ (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("distributed")))) {
+ dmake_mode_type = distributed_mode;
+ no_parallel = false;
+ } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("parallel"))) {
+ dmake_mode_type = parallel_mode;
+ no_parallel = false;
+#ifdef SGE_SUPPORT
+ grid = false;
+ } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("grid"))) {
+ dmake_mode_type = parallel_mode;
+ no_parallel = false;
+ grid = true;
+#endif
+ } else if (IS_EQUAL(dmake_value2->string_mb, NOCATGETS("serial"))) {
+ dmake_mode_type = serial_mode;
+ no_parallel = true;
+ } else {
+ fatal(catgets(catd, 1, 307, "Unknown dmake mode argument `%s' after -m flag"), dmake_value2->string_mb);
+ }
+ }
+
+ if ((!list_all_targets) &&
+ (report_dependencies_level == 0)) {
+ /*
+ * Check to see if either DMAKE_RCFILE or DMAKE_MODE is defined.
+ * They could be defined in the env, in the makefile, or on the
+ * command line.
+ * If neither is defined, and $(HOME)/.dmakerc does not exists,
+ * then print a message, and default to parallel mode.
+ */
+#ifdef DISTRIBUTED
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
+ dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
+ dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
+ if ((((prop = get_prop(dmake_name->prop, macro_prop)) == NULL) ||
+ ((dmake_value = prop->body.macro.value) == NULL)) &&
+ (((prop2 = get_prop(dmake_name2->prop, macro_prop)) == NULL) ||
+ ((dmake_value2 = prop2->body.macro.value) == NULL))) {
+ Boolean empty_dmakerc = true;
+ char *homedir = getenv(NOCATGETS("HOME"));
+ if ((homedir != NULL) && (strlen(homedir) < (sizeof(def_dmakerc_path) - 16))) {
+ sprintf(def_dmakerc_path, NOCATGETS("%s/.dmakerc"), homedir);
+ if ((((statval = stat(def_dmakerc_path, &statbuf)) != 0) && (errno == ENOENT)) ||
+ ((statval == 0) && (statbuf.st_size == 0))) {
+ } else {
+ Avo_dmakerc *rcfile = new Avo_dmakerc();
+ Avo_err *err = rcfile->read(def_dmakerc_path, NULL, TRUE);
+ if (err) {
+ fatal(err->str);
+ }
+ empty_dmakerc = rcfile->was_empty();
+ delete rcfile;
+ }
+ }
+ if (empty_dmakerc) {
+ if (getenv(NOCATGETS("DMAKE_DEF_PRINTED")) == NULL) {
+ putenv(NOCATGETS("DMAKE_DEF_PRINTED=TRUE"));
+ (void) fprintf(stdout, catgets(catd, 1, 302, "dmake: defaulting to parallel mode.\n"));
+ (void) fprintf(stdout, catgets(catd, 1, 303, "See the man page dmake(1) for more information on setting up the .dmakerc file.\n"));
+ }
+ dmake_mode_type = parallel_mode;
+ no_parallel = false;
+ }
+ }
+#else
+ if(dmake_mode_type == distributed_mode) {
+ (void) fprintf(stdout, NOCATGETS("dmake: Distributed mode not implemented.\n"));
+ (void) fprintf(stdout, NOCATGETS(" Defaulting to parallel mode.\n"));
+ dmake_mode_type = parallel_mode;
+ no_parallel = false;
+ }
+#endif /* DISTRIBUTED */
+ }
+ }
+#endif
+
+#ifdef TEAMWARE_MAKE_CMN
+ parallel_flag = true;
+ /* XXX - This is a major hack for DMake/Licensing. */
+ if (getenv(NOCATGETS("DMAKE_CHILD")) == NULL) {
+ if (!avo_cli_search_license(argv[0], dmake_exit_callback, TRUE, dmake_message_callback)) {
+ /*
+ * If the user can not get a TeamWare license,
+ * default to serial mode.
+ */
+ dmake_mode_type = serial_mode;
+ no_parallel = true;
+ } else {
+ putenv(NOCATGETS("DMAKE_CHILD=TRUE"));
+ }
+ start_time = time(NULL);
+ /*
+ * XXX - Hack to disable SIGALRM's from licensing library's
+ * setitimer().
+ */
+ value.it_interval.tv_sec = 0;
+ value.it_interval.tv_usec = 0;
+ value.it_value.tv_sec = 0;
+ value.it_value.tv_usec = 0;
+ (void) setitimer(ITIMER_REAL, &value, NULL);
+ }
+
+//
+// If dmake is running with -t option, set dmake_mode_type to serial.
+// This is done because doname() calls touch_command() that runs serially.
+// If we do not do that, maketool will have problems.
+//
+ if(touch) {
+ dmake_mode_type = serial_mode;
+ no_parallel = true;
+ }
+#else
+ parallel_flag = false;
+#endif
+
+#if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR)
+ /*
+ * Check whether stdout and stderr are physically same.
+ * This is in order to decide whether we need to redirect
+ * stderr separately from stdout.
+ * This check is performed only if __DMAKE_SEPARATE_STDERR
+ * is not set. This variable may be used in order to preserve
+ * the 'old' behaviour.
+ */
+ out_err_same = true;
+ char * dmake_sep_var = getenv(NOCATGETS("__DMAKE_SEPARATE_STDERR"));
+ if (dmake_sep_var == NULL || (0 != strcasecmp(dmake_sep_var, NOCATGETS("NO")))) {
+ struct stat stdout_stat;
+ struct stat stderr_stat;
+ if( (fstat(1, &stdout_stat) == 0)
+ && (fstat(2, &stderr_stat) == 0) )
+ {
+ if( (stdout_stat.st_dev != stderr_stat.st_dev)
+ || (stdout_stat.st_ino != stderr_stat.st_ino) )
+ {
+ out_err_same = false;
+ }
+ }
+ }
+#endif
+
+#ifdef DISTRIBUTED
+ /*
+ * At this point, DMake should startup an rxm with any and all
+ * DMake command line options. Rxm will, among other things,
+ * read the rc file.
+ */
+ if ((!list_all_targets) &&
+ (report_dependencies_level == 0) &&
+ (dmake_mode_type == distributed_mode)) {
+ startup_rxm();
+ }
+#endif
+
+/*
+ * Enable interrupt handler for alarms
+ */
+ (void) bsd_signal(SIGALRM, (SIG_PF)doalarm);
+
+/*
+ * Check if make should report
+ */
+ if (getenv(sunpro_dependencies->string_mb) != NULL) {
+ FILE *report_file;
+
+ report_dependency("");
+ report_file = get_report_file();
+ if ((report_file != NULL) && (report_file != (FILE*)-1)) {
+ (void) fprintf(report_file, "\n");
+ }
+ }
+
+/*
+ * Make sure SUNPRO_DEPENDENCIES is exported (or not) properly
+ * and NSE_DEP.
+ */
+ if (keep_state) {
+ maybe_append_prop(sunpro_dependencies, macro_prop)->
+ body.macro.exported = true;
+#ifdef NSE
+ (void) setenv(NOCATGETS("NSE_DEP"), get_current_path());
+#endif
+ } else {
+ maybe_append_prop(sunpro_dependencies, macro_prop)->
+ body.macro.exported = false;
+ }
+
+ working_on_targets = true;
+ if (trace_status) {
+ dump_make_state();
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ fclose(stdout);
+ fclose(stderr);
+ exit_status = 0;
+#endif
+ exit(0);
+ }
+ if (list_all_targets) {
+ dump_target_list();
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ fclose(stdout);
+ fclose(stderr);
+ exit_status = 0;
+#endif
+ exit(0);
+ }
+ trace_reader = false;
+
+ /*
+ * Set temp_file_directory to the directory the .make.state
+ * file is written to.
+ */
+ if ((slash_ptr = strrchr(make_state->string_mb, (int) slash_char)) == NULL) {
+ temp_file_directory = strdup(get_current_path());
+ } else {
+ *slash_ptr = (int) nul_char;
+ (void) strcpy(make_state_dir, make_state->string_mb);
+ *slash_ptr = (int) slash_char;
+ /* when there is only one slash and it's the first
+ ** character, make_state_dir should point to '/'.
+ */
+ if(make_state_dir[0] == '\0') {
+ make_state_dir[0] = '/';
+ make_state_dir[1] = '\0';
+ }
+ if (make_state_dir[0] == (int) slash_char) {
+ temp_file_directory = strdup(make_state_dir);
+ } else {
+ char tmp_current_path2[MAXPATHLEN];
+
+ (void) sprintf(tmp_current_path2,
+ "%s/%s",
+ get_current_path(),
+ make_state_dir);
+ temp_file_directory = strdup(tmp_current_path2);
+ }
+ }
+
+#ifdef DISTRIBUTED
+ building_serial = false;
+#endif
+
+ report_dir_enter_leave(true);
+
+ make_targets(argc, argv, parallel_flag);
+
+ report_dir_enter_leave(false);
+
+#ifdef NSE
+ exit(nse_exit_status());
+#else
+ if (build_failed_ever_seen) {
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ if (posix) {
+ exit_status = 1;
+ }
+#endif
+ exit(1);
+ }
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ exit_status = 0;
+#endif
+ exit(0);
+#endif
+ /* NOTREACHED */
+}
+
+/*
+ * cleanup_after_exit()
+ *
+ * Called from exit(), performs cleanup actions.
+ *
+ * Parameters:
+ * status The argument exit() was called with
+ * arg Address of an argument vector to
+ * cleanup_after_exit()
+ *
+ * Global variables used:
+ * command_changed Set if we think .make.state should be rewritten
+ * current_line Is set we set commands_changed
+ * do_not_exec_rule
+ * True if -n flag on
+ * done The Name ".DONE", rule we run
+ * keep_state Set if .KEEP_STATE seen
+ * parallel True if building in parallel
+ * quest If -q is on we do not run .DONE
+ * report_dependencies
+ * True if -P flag on
+ * running_list List of parallel running processes
+ * temp_file_name The temp file is removed, if any
+ * catd the message catalog file
+ * usage_tracking Should have been constructed in main()
+ * should destroyed just before exiting
+ */
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+extern "C" void
+cleanup_after_exit(void)
+#else
+void cleanup_after_exit(int status, ...)
+#endif
+{
+ Running rp;
+#ifdef NSE
+ char push_cmd[NSE_TFS_PUSH_LEN + 3 +
+ (MAXPATHLEN * MB_LEN_MAX) + 12];
+ char *active;
+#endif
+
+extern long getname_bytes_count;
+extern long getname_names_count;
+extern long getname_struct_count;
+extern long freename_bytes_count;
+extern long freename_names_count;
+extern long freename_struct_count;
+extern long other_alloc;
+
+extern long env_alloc_num;
+extern long env_alloc_bytes;
+
+
+#ifdef DMAKE_STATISTICS
+if(getname_stat) {
+ printf(NOCATGETS(">>> Getname statistics:\n"));
+ printf(NOCATGETS(" Allocated:\n"));
+ printf(NOCATGETS(" Names: %ld\n"), getname_names_count);
+ printf(NOCATGETS(" Strings: %ld Kb (%ld bytes)\n"), getname_bytes_count/1000, getname_bytes_count);
+ printf(NOCATGETS(" Structs: %ld Kb (%ld bytes)\n"), getname_struct_count/1000, getname_struct_count);
+ printf(NOCATGETS(" Total bytes: %ld Kb (%ld bytes)\n"), getname_struct_count/1000 + getname_bytes_count/1000, getname_struct_count + getname_bytes_count);
+
+ printf(NOCATGETS("\n Unallocated: %ld\n"), freename_names_count);
+ printf(NOCATGETS(" Names: %ld\n"), freename_names_count);
+ printf(NOCATGETS(" Strings: %ld Kb (%ld bytes)\n"), freename_bytes_count/1000, freename_bytes_count);
+ printf(NOCATGETS(" Structs: %ld Kb (%ld bytes)\n"), freename_struct_count/1000, freename_struct_count);
+ printf(NOCATGETS(" Total bytes: %ld Kb (%ld bytes)\n"), freename_struct_count/1000 + freename_bytes_count/1000, freename_struct_count + freename_bytes_count);
+
+ printf(NOCATGETS("\n Total used: %ld Kb (%ld bytes)\n"), (getname_struct_count/1000 + getname_bytes_count/1000) - (freename_struct_count/1000 + freename_bytes_count/1000), (getname_struct_count + getname_bytes_count) - (freename_struct_count + freename_bytes_count));
+
+ printf(NOCATGETS("\n>>> Other:\n"));
+ printf(
+ NOCATGETS(" Env (%ld): %ld Kb (%ld bytes)\n"),
+ env_alloc_num,
+ env_alloc_bytes/1000,
+ env_alloc_bytes
+ );
+
+}
+#endif
+
+/*
+#ifdef DISTRIBUTED
+ if (get_parent() == TRUE) {
+#endif
+ */
+
+ parallel = false;
+#ifdef SUN5_0
+ /* If we used the SVR4_MAKE, don't build .DONE or .FAILED */
+ if (!getenv(USE_SVR4_MAKE)){
+#endif
+ /* Build the target .DONE or .FAILED if we caught an error */
+ if (!quest && !list_all_targets) {
+ Name failed_name;
+
+ MBSTOWCS(wcs_buffer, NOCATGETS(".FAILED"));
+ failed_name = GETNAME(wcs_buffer, FIND_LENGTH);
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ if ((exit_status != 0) && (failed_name->prop != NULL)) {
+#else
+ if ((status != 0) && (failed_name->prop != NULL)) {
+#endif
+#ifdef TEAMWARE_MAKE_CMN
+ /*
+ * [tolik] switch DMake to serial mode
+ */
+ dmake_mode_type = serial_mode;
+ no_parallel = true;
+#endif
+ (void) doname(failed_name, false, true);
+ } else {
+ if (!trace_status) {
+#ifdef TEAMWARE_MAKE_CMN
+ /*
+ * Switch DMake to serial mode
+ */
+ dmake_mode_type = serial_mode;
+ no_parallel = true;
+#endif
+ (void) doname(done, false, true);
+ }
+ }
+ }
+#ifdef SUN5_0
+ }
+#endif
+ /*
+ * Remove the temp file utilities report dependencies thru if it
+ * is still around
+ */
+ if (temp_file_name != NULL) {
+ (void) unlink(temp_file_name->string_mb);
+ }
+ /*
+ * Do not save the current command in .make.state if make
+ * was interrupted.
+ */
+ if (current_line != NULL) {
+ command_changed = true;
+ current_line->body.line.command_used = NULL;
+ }
+ /*
+ * For each parallel build process running, remove the temp files
+ * and zap the command line so it won't be put in .make.state
+ */
+ for (rp = running_list; rp != NULL; rp = rp->next) {
+ if (rp->temp_file != NULL) {
+ (void) unlink(rp->temp_file->string_mb);
+ }
+ if (rp->stdout_file != NULL) {
+ (void) unlink(rp->stdout_file);
+ retmem_mb(rp->stdout_file);
+ rp->stdout_file = NULL;
+ }
+ if (rp->stderr_file != NULL) {
+ (void) unlink(rp->stderr_file);
+ retmem_mb(rp->stderr_file);
+ rp->stderr_file = NULL;
+ }
+ command_changed = true;
+/*
+ line = get_prop(rp->target->prop, line_prop);
+ if (line != NULL) {
+ line->body.line.command_used = NULL;
+ }
+ */
+ }
+ /* Remove the statefile lock file if the file has been locked */
+ if ((make_state_lockfile != NULL) && (make_state_locked)) {
+ (void) unlink(make_state_lockfile);
+ make_state_lockfile = NULL;
+ make_state_locked = false;
+ }
+ /* Write .make.state */
+ write_state_file(1, (Boolean) 1);
+
+#ifdef TEAMWARE_MAKE_CMN
+ // Deleting the usage tracking object sends the usage mail
+#ifdef USE_DMS_CCR
+ //usageTracking->setExitStatus(exit_status, NULL);
+ //delete usageTracking;
+#else
+ cleanup->set_exit_status(exit_status);
+ delete cleanup;
+#endif
+#endif
+
+#ifdef NSE
+ /* If running inside an activated environment, push the */
+ /* .nse_depinfo file (if written) */
+ active = getenv(NSE_VARIANT_ENV);
+ if (keep_state &&
+ (active != NULL) &&
+ !IS_EQUAL(active, NSE_RT_SOURCE_NAME) &&
+ !do_not_exec_rule &&
+ (report_dependencies_level == 0)) {
+ (void) sprintf(push_cmd,
+ "%s %s/%s",
+ NSE_TFS_PUSH,
+ get_current_path(),
+ NSE_DEPINFO);
+ (void) system(push_cmd);
+ }
+#endif
+
+/*
+#ifdef DISTRIBUTED
+ }
+#endif
+ */
+
+#if defined (TEAMWARE_MAKE_CMN) && defined (MAXJOBS_ADJUST_RFE4694000)
+ job_adjust_fini();
+#endif
+
+#ifdef TEAMWARE_MAKE_CMN
+ catclose(catd);
+#endif
+#ifdef DISTRIBUTED
+ if (rxmPid > 0) {
+ // Tell rxm to exit by sending it an Avo_AcknowledgeMsg
+ Avo_AcknowledgeMsg acknowledgeMsg;
+ RWCollectable *msg = (RWCollectable *)&acknowledgeMsg;
+
+ int xdrResult = xdr(&xdrs_out, msg);
+
+ if (xdrResult) {
+ fflush(dmake_ofp);
+ } else {
+/*
+ fatal(catgets(catd, 1, 266, "couldn't tell rxm to exit"));
+ */
+ kill(rxmPid, SIGTERM);
+ }
+
+ waitpid(rxmPid, NULL, 0);
+ rxmPid = 0;
+ }
+#endif
+}
+
+/*
+ * handle_interrupt()
+ *
+ * This is where C-C traps are caught.
+ *
+ * Parameters:
+ *
+ * Global variables used (except DMake 1.0):
+ * current_target Sometimes the current target is removed
+ * do_not_exec_rule But not if -n is on
+ * quest or -q
+ * running_list List of parallel running processes
+ * touch Current target is not removed if -t on
+ */
+void
+handle_interrupt(int)
+{
+ Property member;
+ Running rp;
+
+ (void) fflush(stdout);
+#ifdef DISTRIBUTED
+ if (rxmPid > 0) {
+ // Tell rxm to exit by sending it an Avo_AcknowledgeMsg
+ Avo_AcknowledgeMsg acknowledgeMsg;
+ RWCollectable *msg = (RWCollectable *)&acknowledgeMsg;
+
+ int xdrResult = xdr(&xdrs_out, msg);
+
+ if (xdrResult) {
+ fflush(dmake_ofp);
+ } else {
+ kill(rxmPid, SIGTERM);
+ rxmPid = 0;
+ }
+ }
+#endif
+ if (childPid > 0) {
+ kill(childPid, SIGTERM);
+ childPid = -1;
+ }
+ for (rp = running_list; rp != NULL; rp = rp->next) {
+ if (rp->state != build_running) {
+ continue;
+ }
+ if (rp->pid > 0) {
+ kill(rp->pid, SIGTERM);
+ rp->pid = -1;
+ }
+ }
+ if (getpid() == getpgrp()) {
+ bsd_signal(SIGTERM, SIG_IGN);
+ kill (-getpid(), SIGTERM);
+ }
+#ifdef TEAMWARE_MAKE_CMN
+ /* Clean up all parallel/distributed children already finished */
+ finish_children(false);
+#endif
+
+ /* Make sure the processes running under us terminate first */
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ while (wait((int *) NULL) != -1);
+#else
+ while (wait((union wait*) NULL) != -1);
+#endif
+ /* Delete the current targets unless they are precious */
+ if ((current_target != NULL) &&
+ current_target->is_member &&
+ ((member = get_prop(current_target->prop, member_prop)) != NULL)) {
+ current_target = member->body.member.library;
+ }
+ if (!do_not_exec_rule &&
+ !touch &&
+ !quest &&
+ (current_target != NULL) &&
+ !(current_target->stat.is_precious || all_precious)) {
+
+/* BID_1030811 */
+/* azv 16 Oct 95 */
+ current_target->stat.time = file_no_time;
+
+ if (exists(current_target) != file_doesnt_exist) {
+ (void) fprintf(stderr,
+ "\n*** %s ",
+ current_target->string_mb);
+ if (current_target->stat.is_dir) {
+ (void) fprintf(stderr,
+ catgets(catd, 1, 168, "not removed.\n"),
+ current_target->string_mb);
+ } else if (unlink(current_target->string_mb) == 0) {
+ (void) fprintf(stderr,
+ catgets(catd, 1, 169, "removed.\n"),
+ current_target->string_mb);
+ } else {
+ (void) fprintf(stderr,
+ catgets(catd, 1, 170, "could not be removed: %s.\n"),
+ current_target->string_mb,
+ errmsg(errno));
+ }
+ }
+ }
+ for (rp = running_list; rp != NULL; rp = rp->next) {
+ if (rp->state != build_running) {
+ continue;
+ }
+ if (rp->target->is_member &&
+ ((member = get_prop(rp->target->prop, member_prop)) !=
+ NULL)) {
+ rp->target = member->body.member.library;
+ }
+ if (!do_not_exec_rule &&
+ !touch &&
+ !quest &&
+ !(rp->target->stat.is_precious || all_precious)) {
+
+ rp->target->stat.time = file_no_time;
+ if (exists(rp->target) != file_doesnt_exist) {
+ (void) fprintf(stderr,
+ "\n*** %s ",
+ rp->target->string_mb);
+ if (rp->target->stat.is_dir) {
+ (void) fprintf(stderr,
+ catgets(catd, 1, 171, "not removed.\n"),
+ rp->target->string_mb);
+ } else if (unlink(rp->target->string_mb) == 0) {
+ (void) fprintf(stderr,
+ catgets(catd, 1, 172, "removed.\n"),
+ rp->target->string_mb);
+ } else {
+ (void) fprintf(stderr,
+ catgets(catd, 1, 173, "could not be removed: %s.\n"),
+ rp->target->string_mb,
+ errmsg(errno));
+ }
+ }
+ }
+ }
+
+#ifdef SGE_SUPPORT
+ /* Remove SGE script file */
+ if (grid) {
+ unlink(script_file);
+ }
+#endif
+
+ /* Have we locked .make.state or .nse_depinfo? */
+ if ((make_state_lockfile != NULL) && (make_state_locked)) {
+ unlink(make_state_lockfile);
+ make_state_lockfile = NULL;
+ make_state_locked = false;
+ }
+#ifdef NSE
+ if ((nse_depinfo_lockfile[0] != '\0') && (nse_depinfo_locked)) {
+ unlink(nse_depinfo_lockfile);
+ nse_depinfo_lockfile[0] = '\0';
+ nse_depinfo_locked = false;
+ }
+#endif
+ /*
+ * Re-read .make.state file (it might be changed by recursive make)
+ */
+ check_state(NULL);
+
+ report_dir_enter_leave(false);
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ exit_status = 2;
+#endif
+ exit(2);
+}
+
+/*
+ * doalarm(sig, ...)
+ *
+ * Handle the alarm interrupt but do nothing. Side effect is to
+ * cause return from wait3.
+ *
+ * Parameters:
+ * sig
+ *
+ * Global variables used:
+ */
+/*ARGSUSED*/
+static void
+doalarm(int)
+{
+ return;
+}
+
+
+/*
+ * read_command_options(argc, argv)
+ *
+ * Scan the cmd line options and process the ones that start with "-"
+ *
+ * Return value:
+ * -M argument, if any
+ *
+ * Parameters:
+ * argc You know what this is
+ * argv You know what this is
+ *
+ * Global variables used:
+ */
+static void
+read_command_options(register int argc, register char **argv)
+{
+ register int ch;
+ int current_optind = 1;
+ int last_optind_with_double_hyphen = 0;
+ int last_optind;
+ int last_current_optind;
+ register int i;
+ register int j;
+ register int k;
+ register int makefile_next = 0; /*
+ * flag to note options:
+ * -c, f, g, j, m, o
+ */
+ const char *tptr;
+ const char *CMD_OPTS;
+
+ extern char *optarg;
+ extern int optind, opterr, optopt;
+
+#define SUNPRO_CMD_OPTS "-~Bbc:Ddef:g:ij:K:kM:m:NnO:o:PpqRrSsTtuVvwx:"
+
+#ifdef TEAMWARE_MAKE_CMN
+# define SVR4_CMD_OPTS "-c:ef:g:ij:km:nO:o:pqrsTtVv"
+#else
+# define SVR4_CMD_OPTS "-ef:iknpqrstV"
+#endif
+
+ /*
+ * Added V in SVR4_CMD_OPTS also, which is going to be a hidden
+ * option, just to make sure that the getopt doesn't fail when some
+ * users leave their USE_SVR4_MAKE set and try to use the makefiles
+ * that are designed to issue commands like $(MAKE) -V. Anyway it
+ * sets the same flag but ensures that getopt doesn't fail.
+ */
+
+ opterr = 0;
+ optind = 1;
+ while (1) {
+ last_optind=optind; /* Save optind and current_optind values */
+ last_current_optind=current_optind; /* in case we have to repeat this round. */
+ if (svr4) {
+ CMD_OPTS=SVR4_CMD_OPTS;
+ ch = getopt(argc, argv, SVR4_CMD_OPTS);
+ } else {
+ CMD_OPTS=SUNPRO_CMD_OPTS;
+ ch = getopt(argc, argv, SUNPRO_CMD_OPTS);
+ }
+ if (ch == EOF) {
+ if(optind < argc) {
+ /*
+ * Fixing bug 4102537:
+ * Strange behaviour of command make using -- option.
+ * Not all argv have been processed
+ * Skip non-flag argv and continue processing.
+ */
+ optind++;
+ current_optind++;
+ continue;
+ } else {
+ break;
+ }
+
+ }
+ if (ch == '?') {
+ if (optopt == '-') {
+ /* Bug 5060758: getopt() changed behavior (s10_60),
+ * and now we have to deal with cases when options
+ * with double hyphen appear here, from -$(MAKEFLAGS)
+ */
+ i = current_optind;
+ if (argv[i][0] == '-') {
+ if (argv[i][1] == '-') {
+ if (argv[i][2] != '\0') {
+ /* Check if this option is allowed */
+ tptr = strchr(CMD_OPTS, argv[i][2]);
+ if (tptr) {
+ if (last_optind_with_double_hyphen != current_optind) {
+ /* This is first time we are trying to fix "--"
+ * problem with this option. If we come here second
+ * time, we will go to fatal error.
+ */
+ last_optind_with_double_hyphen = current_optind;
+
+ /* Eliminate first hyphen character */
+ for (j=0; argv[i][j] != '\0'; j++) {
+ argv[i][j] = argv[i][j+1];
+ }
+
+ /* Repeat the processing of this argument */
+ optind=last_optind;
+ current_optind=last_current_optind;
+ continue;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (ch == '?') {
+ if (svr4) {
+#ifdef TEAMWARE_MAKE_CMN
+ fprintf(stderr,
+ catgets(catd, 1, 267, "Usage : dmake [ -f makefile ][ -c dmake_rcfile ][ -g dmake_group ]\n"));
+ fprintf(stderr,
+ catgets(catd, 1, 268, " [ -j dmake_max_jobs ][ -m dmake_mode ][ -o dmake_odir ]...\n"));
+ fprintf(stderr,
+ catgets(catd, 1, 269, " [ -e ][ -i ][ -k ][ -n ][ -p ][ -q ][ -r ][ -s ][ -t ][ -v ]\n"));
+#else
+ fprintf(stderr,
+ catgets(catd, 1, 270, "Usage : make [ -f makefile ]... [ -e ][ -i ][ -k ][ -n ][ -p ][ -q ][ -r ]\n"));
+ fprintf(stderr,
+ catgets(catd, 1, 271, " [ -s ][ -t ]\n"));
+#endif
+ tptr = strchr(SVR4_CMD_OPTS, optopt);
+ } else {
+#ifdef TEAMWARE_MAKE_CMN
+ fprintf(stderr,
+ catgets(catd, 1, 272, "Usage : dmake [ -f makefile ][ -c dmake_rcfile ][ -g dmake_group ]\n"));
+ fprintf(stderr,
+ catgets(catd, 1, 273, " [ -j dmake_max_jobs ][ -K statefile ][ -m dmake_mode ][ -x MODE_NAME=VALUE ][ -o dmake_odir ]...\n"));
+ fprintf(stderr,
+ catgets(catd, 1, 274, " [ -d ][ -dd ][ -D ][ -DD ][ -e ][ -i ][ -k ][ -n ][ -p ][ -P ][ -u ][ -w ]\n"));
+ fprintf(stderr,
+ catgets(catd, 1, 275, " [ -q ][ -r ][ -s ][ -S ][ -t ][ -v ][ -V ][ target... ][ macro=value... ][ \"macro +=value\"... ]\n"));
+#else
+ fprintf(stderr,
+ catgets(catd, 1, 276, "Usage : make [ -f makefile ][ -K statefile ]... [ -d ][ -dd ][ -D ][ -DD ]\n"));
+ fprintf(stderr,
+ catgets(catd, 1, 277, " [ -e ][ -i ][ -k ][ -n ][ -p ][ -P ][ -q ][ -r ][ -s ][ -S ][ -t ]\n"));
+ fprintf(stderr,
+ catgets(catd, 1, 278, " [ -u ][ -w ][ -V ][ target... ][ macro=value... ][ \"macro +=value\"... ]\n"));
+#endif
+ tptr = strchr(SUNPRO_CMD_OPTS, optopt);
+ }
+ if (!tptr) {
+ fatal(catgets(catd, 1, 279, "Unknown option `-%c'"), optopt);
+ } else {
+ fatal(catgets(catd, 1, 280, "Missing argument after `-%c'"), optopt);
+ }
+ }
+
+#if defined(linux)
+ if (ch == 1) {
+ if(optind < argc) {
+ //optind++;
+ //current_optind++;
+ makefile_next = 0;
+ current_optind = optind;
+ continue;
+ } else {
+ break;
+ }
+ }
+#endif
+
+
+ makefile_next |= parse_command_option(ch);
+ /*
+ * If we're done processing all of the options of
+ * ONE argument string...
+ */
+ if (current_optind < optind) {
+ i = current_optind;
+ k = 0;
+ /* If there's an argument for an option... */
+ if ((optind - current_optind) > 1) {
+ k = i + 1;
+ }
+ switch (makefile_next) {
+ case 0:
+ argv[i] = NULL;
+ /* This shouldn't happen */
+ if (k) {
+ argv[k] = NULL;
+ }
+ break;
+ case 1: /* -f seen */
+ argv[i] = NOCATGETS("-f");
+ break;
+ case 2: /* -c seen */
+ argv[i] = NOCATGETS("-c");
+#ifndef TEAMWARE_MAKE_CMN
+ warning(catgets(catd, 1, 281, "Ignoring DistributedMake -c option"));
+#endif
+ break;
+ case 4: /* -g seen */
+ argv[i] = NOCATGETS("-g");
+#ifndef TEAMWARE_MAKE_CMN
+ warning(catgets(catd, 1, 282, "Ignoring DistributedMake -g option"));
+#endif
+ break;
+ case 8: /* -j seen */
+ argv[i] = NOCATGETS("-j");
+#ifndef TEAMWARE_MAKE_CMN
+ warning(catgets(catd, 1, 283, "Ignoring DistributedMake -j option"));
+#endif
+ break;
+ case 16: /* -M seen */
+ argv[i] = NOCATGETS("-M");
+#ifndef TEAMWARE_MAKE_CMN
+ warning(catgets(catd, 1, 284, "Ignoring ParallelMake -M option"));
+#endif
+ break;
+ case 32: /* -m seen */
+ argv[i] = NOCATGETS("-m");
+#ifndef TEAMWARE_MAKE_CMN
+ warning(catgets(catd, 1, 285, "Ignoring DistributedMake -m option"));
+#endif
+ break;
+#ifndef PARALLEL
+ case 128: /* -O seen */
+ argv[i] = NOCATGETS("-O");
+ break;
+#endif
+ case 256: /* -K seen */
+ argv[i] = NOCATGETS("-K");
+ break;
+ case 512: /* -o seen */
+ argv[i] = NOCATGETS("-o");
+#ifndef TEAMWARE_MAKE_CMN
+ warning(catgets(catd, 1, 311, "Ignoring DistributedMake -o option"));
+#endif
+ break;
+ case 1024: /* -x seen */
+ argv[i] = NOCATGETS("-x");
+#ifndef TEAMWARE_MAKE_CMN
+ warning(catgets(catd, 1, 353, "Ignoring DistributedMake -x option"));
+#endif
+ break;
+ default: /* > 1 of -c, f, g, j, K, M, m, O, o, x seen */
+ fatal(catgets(catd, 1, 286, "Illegal command line. More than one option requiring\nan argument given in the same argument group"));
+ }
+
+ makefile_next = 0;
+ current_optind = optind;
+ }
+ }
+}
+
+static void
+quote_str(char *str, char *qstr)
+{
+ char *to;
+ char *from;
+
+ to = qstr;
+ for (from = str; *from; from++) {
+ switch (*from) {
+ case ';': /* End of command */
+ case '(': /* Start group */
+ case ')': /* End group */
+ case '{': /* Start group */
+ case '}': /* End group */
+ case '[': /* Reg expr - any of a set of chars */
+ case ']': /* End of set of chars */
+ case '|': /* Pipe or logical-or */
+ case '^': /* Old-fashioned pipe */
+ case '&': /* Background or logical-and */
+ case '<': /* Redirect stdin */
+ case '>': /* Redirect stdout */
+ case '*': /* Reg expr - any sequence of chars */
+ case '?': /* Reg expr - any single char */
+ case '$': /* Variable substitution */
+ case '\'': /* Singe quote - turn off all magic */
+ case '"': /* Double quote - span whitespace */
+ case '`': /* Backquote - run a command */
+ case '#': /* Comment */
+ case ' ': /* Space (for MACRO=value1 value2 */
+ case '\\': /* Escape char - turn off magic of next char */
+ *to++ = '\\';
+ break;
+
+ default:
+ break;
+ }
+ *to++ = *from;
+ }
+ *to = '\0';
+}
+
+static void
+unquote_str(char *str, char *qstr)
+{
+ char *to;
+ char *from;
+
+ to = qstr;
+ for (from = str; *from; from++) {
+ if (*from == '\\') {
+ from++;
+ }
+ *to++ = *from;
+ }
+ *to = '\0';
+}
+
+/*
+ * Convert the MAKEFLAGS string value into a vector of char *, similar
+ * to argv.
+ */
+static void
+setup_makeflags_argv()
+{
+ char *cp;
+ char *cp1;
+ char *cp2;
+ char *cp3;
+ char *cp_orig;
+ Boolean add_hyphen;
+ int i;
+ char tmp_char;
+
+ mf_argc = 1;
+ cp = getenv(makeflags->string_mb);
+ cp_orig = cp;
+
+ if (cp) {
+ /*
+ * If new MAKEFLAGS format, no need to add hyphen.
+ * If old MAKEFLAGS format, add hyphen before flags.
+ */
+
+ if ((strchr(cp, (int) hyphen_char) != NULL) ||
+ (strchr(cp, (int) equal_char) != NULL)) {
+
+ /* New MAKEFLAGS format */
+
+ add_hyphen = false;
+#ifdef ADDFIX5060758
+ /* Check if MAKEFLAGS value begins with multiple
+ * hyphen characters, and remove all duplicates.
+ * Usually it happens when the next command is
+ * used: $(MAKE) -$(MAKEFLAGS)
+ * This is a workaround for BugID 5060758.
+ */
+ while (*cp) {
+ if (*cp != (int) hyphen_char) {
+ break;
+ }
+ cp++;
+ if (*cp == (int) hyphen_char) {
+ /* There are two hyphens. Skip one */
+ cp_orig = cp;
+ cp++;
+ }
+ if (!(*cp)) {
+ /* There are hyphens only. Skip all */
+ cp_orig = cp;
+ break;
+ }
+ }
+#endif
+ } else {
+
+ /* Old MAKEFLAGS format */
+
+ add_hyphen = true;
+ }
+ }
+
+ /* Find the number of arguments in MAKEFLAGS */
+ while (cp && *cp) {
+ /* Skip white spaces */
+ while (cp && *cp && isspace(*cp)) {
+ cp++;
+ }
+ if (cp && *cp) {
+ /* Increment arg count */
+ mf_argc++;
+ /* Go to next white space */
+ while (cp && *cp && !isspace(*cp)) {
+ if(*cp == (int) backslash_char) {
+ cp++;
+ }
+ cp++;
+ }
+ }
+ }
+ /* Allocate memory for the new MAKEFLAGS argv */
+ mf_argv = (char **) malloc((mf_argc + 1) * sizeof(char *));
+ mf_argv[0] = NOCATGETS("MAKEFLAGS");
+ /*
+ * Convert the MAKEFLAGS string value into a vector of char *,
+ * similar to argv.
+ */
+ cp = cp_orig;
+ for (i = 1; i < mf_argc; i++) {
+ /* Skip white spaces */
+ while (cp && *cp && isspace(*cp)) {
+ cp++;
+ }
+ if (cp && *cp) {
+ cp_orig = cp;
+ /* Go to next white space */
+ while (cp && *cp && !isspace(*cp)) {
+ if(*cp == (int) backslash_char) {
+ cp++;
+ }
+ cp++;
+ }
+ tmp_char = *cp;
+ *cp = (int) nul_char;
+ if (add_hyphen) {
+ mf_argv[i] = getmem(2 + strlen(cp_orig));
+ mf_argv[i][0] = '\0';
+ (void) strcat(mf_argv[i], "-");
+ // (void) strcat(mf_argv[i], cp_orig);
+ unquote_str(cp_orig, mf_argv[i]+1);
+ } else {
+ mf_argv[i] = getmem(2 + strlen(cp_orig));
+ //mf_argv[i] = strdup(cp_orig);
+ unquote_str(cp_orig, mf_argv[i]);
+ }
+ *cp = tmp_char;
+ }
+ }
+ mf_argv[i] = NULL;
+}
+
+/*
+ * parse_command_option(ch)
+ *
+ * Parse make command line options.
+ *
+ * Return value:
+ * Indicates if any -f -c or -M were seen
+ *
+ * Parameters:
+ * ch The character to parse
+ *
+ * Static variables used:
+ * dmake_group_specified Set for make -g
+ * dmake_max_jobs_specified Set for make -j
+ * dmake_mode_specified Set for make -m
+ * dmake_add_mode_specified Set for make -x
+ * dmake_compat_mode_specified Set for make -x SUN_MAKE_COMPAT_MODE=
+ * dmake_output_mode_specified Set for make -x DMAKE_OUTPUT_MODE=
+ * dmake_odir_specified Set for make -o
+ * dmake_rcfile_specified Set for make -c
+ * env_wins Set for make -e
+ * ignore_default_mk Set for make -r
+ * trace_status Set for make -p
+ *
+ * Global variables used:
+ * .make.state path & name set for make -K
+ * continue_after_error Set for make -k
+ * debug_level Set for make -d
+ * do_not_exec_rule Set for make -n
+ * filter_stderr Set for make -X
+ * ignore_errors_all Set for make -i
+ * no_parallel Set for make -R
+ * quest Set for make -q
+ * read_trace_level Set for make -D
+ * report_dependencies Set for make -P
+ * send_mtool_msgs Set for make -K
+ * silent_all Set for make -s
+ * touch Set for make -t
+ */
+static int
+parse_command_option(register char ch)
+{
+ static int invert_next = 0;
+ int invert_this = invert_next;
+
+ invert_next = 0;
+ switch (ch) {
+ case '-': /* Ignore "--" */
+ return 0;
+ case '~': /* Invert next option */
+ invert_next = 1;
+ return 0;
+ case 'B': /* Obsolete */
+ return 0;
+ case 'b': /* Obsolete */
+ return 0;
+ case 'c': /* Read alternative dmakerc file */
+ if (invert_this) {
+ dmake_rcfile_specified = false;
+ } else {
+ dmake_rcfile_specified = true;
+ }
+ return 2;
+ case 'D': /* Show lines read */
+ if (invert_this) {
+ read_trace_level--;
+ } else {
+ read_trace_level++;
+ }
+ return 0;
+ case 'd': /* Debug flag */
+ if (invert_this) {
+ debug_level--;
+ } else {
+#if defined( HP_UX) || defined(linux)
+ if (debug_level < 2) /* Fixes a bug on HP-UX */
+#endif
+ debug_level++;
+ }
+ return 0;
+#ifdef NSE
+ case 'E':
+ if (invert_this) {
+ nse = false;
+ } else {
+ nse = true;
+ }
+ nse_init_source_suffixes();
+ return 0;
+#endif
+ case 'e': /* Environment override flag */
+ if (invert_this) {
+ env_wins = false;
+ } else {
+ env_wins = true;
+ }
+ return 0;
+ case 'f': /* Read alternative makefile(s) */
+ return 1;
+ case 'g': /* Use alternative DMake group */
+ if (invert_this) {
+ dmake_group_specified = false;
+ } else {
+ dmake_group_specified = true;
+ }
+ return 4;
+ case 'i': /* Ignore errors */
+ if (invert_this) {
+ ignore_errors_all = false;
+ } else {
+ ignore_errors_all = true;
+ }
+ return 0;
+ case 'j': /* Use alternative DMake max jobs */
+ if (invert_this) {
+ dmake_max_jobs_specified = false;
+ } else {
+ dmake_max_jobs_specified = true;
+ }
+ return 8;
+ case 'K': /* Read alternative .make.state */
+ return 256;
+ case 'k': /* Keep making even after errors */
+ if (invert_this) {
+ continue_after_error = false;
+ } else {
+ continue_after_error = true;
+ continue_after_error_ever_seen = true;
+ }
+ return 0;
+ case 'M': /* Read alternative make.machines file */
+ if (invert_this) {
+ pmake_machinesfile_specified = false;
+ } else {
+ pmake_machinesfile_specified = true;
+ dmake_mode_type = parallel_mode;
+ no_parallel = false;
+ }
+ return 16;
+ case 'm': /* Use alternative DMake build mode */
+ if (invert_this) {
+ dmake_mode_specified = false;
+ } else {
+ dmake_mode_specified = true;
+ }
+ return 32;
+ case 'x': /* Use alternative DMake mode */
+ if (invert_this) {
+ dmake_add_mode_specified = false;
+ } else {
+ dmake_add_mode_specified = true;
+ }
+ return 1024;
+ case 'N': /* Reverse -n */
+ if (invert_this) {
+ do_not_exec_rule = true;
+ } else {
+ do_not_exec_rule = false;
+ }
+ return 0;
+ case 'n': /* Print, not exec commands */
+ if (invert_this) {
+ do_not_exec_rule = false;
+ } else {
+ do_not_exec_rule = true;
+ }
+ return 0;
+#ifndef PARALLEL
+ case 'O': /* Send job start & result msgs */
+ if (invert_this) {
+ send_mtool_msgs = false;
+ } else {
+#ifdef DISTRIBUTED
+ send_mtool_msgs = true;
+#endif
+ }
+ return 128;
+#endif
+ case 'o': /* Use alternative dmake output dir */
+ if (invert_this) {
+ dmake_odir_specified = false;
+ } else {
+ dmake_odir_specified = true;
+ }
+ return 512;
+ case 'P': /* Print for selected targets */
+ if (invert_this) {
+ report_dependencies_level--;
+ } else {
+ report_dependencies_level++;
+ }
+ return 0;
+ case 'p': /* Print description */
+ if (invert_this) {
+ trace_status = false;
+ do_not_exec_rule = false;
+ } else {
+ trace_status = true;
+ do_not_exec_rule = true;
+ }
+ return 0;
+ case 'q': /* Question flag */
+ if (invert_this) {
+ quest = false;
+ } else {
+ quest = true;
+ }
+ return 0;
+ case 'R': /* Don't run in parallel */
+#ifdef TEAMWARE_MAKE_CMN
+ if (invert_this) {
+ pmake_cap_r_specified = false;
+ no_parallel = false;
+ } else {
+ pmake_cap_r_specified = true;
+ dmake_mode_type = serial_mode;
+ no_parallel = true;
+ }
+#else
+ warning(catgets(catd, 1, 182, "Ignoring ParallelMake -R option"));
+#endif
+ return 0;
+ case 'r': /* Turn off internal rules */
+ if (invert_this) {
+ ignore_default_mk = false;
+ } else {
+ ignore_default_mk = true;
+ }
+ return 0;
+ case 'S': /* Reverse -k */
+ if (invert_this) {
+ continue_after_error = true;
+ } else {
+ continue_after_error = false;
+ stop_after_error_ever_seen = true;
+ }
+ return 0;
+ case 's': /* Silent flag */
+ if (invert_this) {
+ silent_all = false;
+ } else {
+ silent_all = true;
+ }
+ return 0;
+ case 'T': /* Print target list */
+ if (invert_this) {
+ list_all_targets = false;
+ do_not_exec_rule = false;
+ } else {
+ list_all_targets = true;
+ do_not_exec_rule = true;
+ }
+ return 0;
+ case 't': /* Touch flag */
+ if (invert_this) {
+ touch = false;
+ } else {
+ touch = true;
+ }
+ return 0;
+ case 'u': /* Unconditional flag */
+ if (invert_this) {
+ build_unconditional = false;
+ } else {
+ build_unconditional = true;
+ }
+ return 0;
+ case 'V': /* SVR4 mode */
+ svr4 = true;
+ return 0;
+ case 'v': /* Version flag */
+ if (invert_this) {
+ } else {
+#ifdef TEAMWARE_MAKE_CMN
+ fprintf(stdout, NOCATGETS("dmake: %s\n"), verstring);
+#ifdef SUN5_0
+ exit_status = 0;
+#endif
+ exit(0);
+#else
+ warning(catgets(catd, 1, 324, "Ignoring DistributedMake -v option"));
+#endif
+ }
+ return 0;
+ case 'w': /* Unconditional flag */
+ if (invert_this) {
+ report_cwd = false;
+ } else {
+ report_cwd = true;
+ }
+ return 0;
+#if 0
+ case 'X': /* Filter stdout */
+ if (invert_this) {
+ filter_stderr = false;
+ } else {
+ filter_stderr = true;
+ }
+ return 0;
+#endif
+ default:
+ break;
+ }
+ return 0;
+}
+
+/*
+ * setup_for_projectdir()
+ *
+ * Read the PROJECTDIR variable, if defined, and set the sccs path
+ *
+ * Parameters:
+ *
+ * Global variables used:
+ * sccs_dir_path Set to point to SCCS dir to use
+ */
+static void
+setup_for_projectdir(void)
+{
+static char path[MAXPATHLEN];
+char cwdpath[MAXPATHLEN];
+uid_t uid;
+int done=0;
+
+ /* Check if we should use PROJECTDIR when reading the SCCS dir. */
+ sccs_dir_path = getenv(NOCATGETS("PROJECTDIR"));
+ if ((sccs_dir_path != NULL) &&
+ (sccs_dir_path[0] != (int) slash_char)) {
+ struct passwd *pwent;
+
+ {
+ uid = getuid();
+ pwent = getpwuid(uid);
+ if (pwent == NULL) {
+ fatal(catgets(catd, 1, 188, "Bogus USERID "));
+ }
+ if ((pwent = getpwnam(sccs_dir_path)) == NULL) {
+ /*empty block : it'll go & check cwd */
+ }
+ else {
+ (void) sprintf(path, NOCATGETS("%s/src"), pwent->pw_dir);
+ if (access(path, F_OK) == 0) {
+ sccs_dir_path = path;
+ done = 1;
+ } else {
+ (void) sprintf(path, NOCATGETS("%s/source"), pwent->pw_dir);
+ if (access(path, F_OK) == 0) {
+ sccs_dir_path = path;
+ done = 1;
+ }
+ }
+ }
+ if (!done) {
+ if (getcwd(cwdpath, MAXPATHLEN - 1 )) {
+
+ (void) sprintf(path, NOCATGETS("%s/%s"), cwdpath,sccs_dir_path);
+ if (access(path, F_OK) == 0) {
+ sccs_dir_path = path;
+ done = 1;
+ } else {
+ fatal(catgets(catd, 1, 189, "Bogus PROJECTDIR '%s'"), sccs_dir_path);
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
+ * set_sgs_support()
+ *
+ * Add the libmakestate.so.1 lib to the env var SGS_SUPPORT
+ * if it's not already in there.
+ * The SGS_SUPPORT env var and libmakestate.so.1 is used by
+ * the linker ld to report .make.state info back to make.
+ */
+static void
+set_sgs_support()
+{
+ int len;
+ char *newpath;
+ char *oldpath;
+ static char *prev_path;
+
+ oldpath = getenv(LD_SUPPORT_ENV_VAR);
+ if (oldpath == NULL) {
+ len = strlen(LD_SUPPORT_ENV_VAR) + 1 +
+ strlen(LD_SUPPORT_MAKE_LIB) + 1;
+ newpath = (char *) malloc(len);
+ sprintf(newpath, "%s=", LD_SUPPORT_ENV_VAR);
+ } else {
+ len = strlen(LD_SUPPORT_ENV_VAR) + 1 + strlen(oldpath) + 1 +
+ strlen(LD_SUPPORT_MAKE_LIB) + 1;
+ newpath = (char *) malloc(len);
+ sprintf(newpath, "%s=%s", LD_SUPPORT_ENV_VAR, oldpath);
+ }
+
+#if defined(TEAMWARE_MAKE_CMN)
+
+ /* function maybe_append_str_to_env_var() is defined in avo_util library
+ * Serial make should not use this library !!!
+ */
+ maybe_append_str_to_env_var(newpath, LD_SUPPORT_MAKE_LIB);
+#else
+ if (oldpath == NULL) {
+ sprintf(newpath, "%s%s", newpath, LD_SUPPORT_MAKE_LIB);
+ } else {
+ sprintf(newpath, "%s:%s", newpath, LD_SUPPORT_MAKE_LIB);
+ }
+#endif
+ putenv(newpath);
+ if (prev_path) {
+ free(prev_path);
+ }
+ prev_path = newpath;
+}
+
+/*
+ * read_files_and_state(argc, argv)
+ *
+ * Read the makefiles we care about and the environment
+ * Also read the = style command line options
+ *
+ * Parameters:
+ * argc You know what this is
+ * argv You know what this is
+ *
+ * Static variables used:
+ * env_wins make -e, determines if env vars are RO
+ * ignore_default_mk make -r, determines if make.rules is read
+ * not_auto_depen dwight
+ *
+ * Global variables used:
+ * default_target_to_build Set to first proper target from file
+ * do_not_exec_rule Set to false when makfile is made
+ * dot The Name ".", used to read current dir
+ * empty_name The Name "", use as macro value
+ * keep_state Set if KEEP_STATE is in environment
+ * make_state The Name ".make.state", used to read file
+ * makefile_type Set to type of file being read
+ * makeflags The Name "MAKEFLAGS", used to set macro value
+ * not_auto dwight
+ * nse Set if NSE_ENV is in the environment
+ * read_trace_level Checked to se if the reader should trace
+ * report_dependencies If -P is on we do not read .make.state
+ * trace_reader Set if reader should trace
+ * virtual_root The Name "VIRTUAL_ROOT", used to check value
+ */
+static void
+read_files_and_state(int argc, char **argv)
+{
+ wchar_t buffer[1000];
+ wchar_t buffer_posix[1000];
+ register char ch;
+ register char *cp;
+ Property def_make_macro = NULL;
+ Name def_make_name;
+ Name default_makefile;
+ String_rec dest;
+ wchar_t destbuffer[STRING_BUFFER_LENGTH];
+ register int i;
+ register int j;
+ Name keep_state_name;
+ int length;
+ Name Makefile;
+ register Property macro;
+ struct stat make_state_stat;
+ Name makefile_name;
+ register int makefile_next = 0;
+ register Boolean makefile_read = false;
+ String_rec makeflags_string;
+ String_rec makeflags_string_posix;
+ String_rec * makeflags_string_current;
+ Name makeflags_value_saved;
+ register Name name;
+ Name new_make_value;
+ Boolean save_do_not_exec_rule;
+ Name sdotMakefile;
+ Name sdotmakefile_name;
+ static wchar_t state_file_str;
+ static char state_file_str_mb[MAXPATHLEN];
+ static struct _Name state_filename;
+ Boolean temp;
+ char tmp_char;
+ wchar_t *tmp_wcs_buffer;
+ register Name value;
+ ASCII_Dyn_Array makeflags_and_macro;
+ Boolean is_xpg4;
+
+/*
+ * Remember current mode. It may be changed after reading makefile
+ * and we will have to correct MAKEFLAGS variable.
+ */
+ is_xpg4 = posix;
+
+ MBSTOWCS(wcs_buffer, NOCATGETS("KEEP_STATE"));
+ keep_state_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("Makefile"));
+ Makefile = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("makefile"));
+ makefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("s.makefile"));
+ sdotmakefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("s.Makefile"));
+ sdotMakefile = GETNAME(wcs_buffer, FIND_LENGTH);
+
+/*
+ * Set flag if NSE is active
+ */
+#ifdef NSE
+ if (getenv(NOCATGETS("NSE_ENV")) != NULL) {
+ nse = true;
+ }
+#endif
+
+/*
+ * initialize global dependency entry for .NOT_AUTO
+ */
+ not_auto_depen->next = NULL;
+ not_auto_depen->name = not_auto;
+ not_auto_depen->automatic = not_auto_depen->stale = false;
+
+/*
+ * Read internal definitions and rules.
+ */
+ if (read_trace_level > 1) {
+ trace_reader = true;
+ }
+ if (!ignore_default_mk) {
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ if (svr4) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("svr4.make.rules"));
+ default_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
+ } else {
+ MBSTOWCS(wcs_buffer, NOCATGETS("make.rules"));
+ default_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
+ }
+#else
+ MBSTOWCS(wcs_buffer, NOCATGETS("default.mk"));
+ default_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
+#endif
+ default_makefile->stat.is_file = true;
+
+ (void) read_makefile(default_makefile,
+ true,
+ false,
+ true);
+ }
+
+ /*
+ * If the user did not redefine the MAKE macro in the
+ * default makefile (make.rules), then we'd like to
+ * change the macro value of MAKE to be some form
+ * of argv[0] for recursive MAKE builds.
+ */
+ MBSTOWCS(wcs_buffer, NOCATGETS("MAKE"));
+ def_make_name = GETNAME(wcs_buffer, wslen(wcs_buffer));
+ def_make_macro = get_prop(def_make_name->prop, macro_prop);
+ if ((def_make_macro != NULL) &&
+ (IS_EQUAL(def_make_macro->body.macro.value->string_mb,
+ NOCATGETS("make")))) {
+ MBSTOWCS(wcs_buffer, argv_zero_string);
+ new_make_value = GETNAME(wcs_buffer, wslen(wcs_buffer));
+ (void) SETVAR(def_make_name,
+ new_make_value,
+ false);
+ }
+
+ default_target_to_build = NULL;
+ trace_reader = false;
+
+/*
+ * Read environment args. Let file args which follow override unless
+ * -e option seen. If -e option is not mentioned.
+ */
+ read_environment(env_wins);
+ if (getvar(virtual_root)->hash.length == 0) {
+ maybe_append_prop(virtual_root, macro_prop)
+ ->body.macro.exported = true;
+ MBSTOWCS(wcs_buffer, "/");
+ (void) SETVAR(virtual_root,
+ GETNAME(wcs_buffer, FIND_LENGTH),
+ false);
+ }
+
+/*
+ * We now scan mf_argv and argv to see if we need to set
+ * any of the DMake-added options/variables in MAKEFLAGS.
+ */
+
+ makeflags_and_macro.start = 0;
+ makeflags_and_macro.size = 0;
+ enter_argv_values(mf_argc, mf_argv, &makeflags_and_macro);
+ enter_argv_values(argc, argv, &makeflags_and_macro);
+
+/*
+ * Set MFLAGS and MAKEFLAGS
+ *
+ * Before reading makefile we do not know exactly which mode
+ * (posix or not) is used. So prepare two MAKEFLAGS strings
+ * for both posix and solaris modes because they are different.
+ */
+ INIT_STRING_FROM_STACK(makeflags_string, buffer);
+ INIT_STRING_FROM_STACK(makeflags_string_posix, buffer_posix);
+ append_char((int) hyphen_char, &makeflags_string);
+ append_char((int) hyphen_char, &makeflags_string_posix);
+
+ switch (read_trace_level) {
+ case 2:
+ append_char('D', &makeflags_string);
+ append_char('D', &makeflags_string_posix);
+ case 1:
+ append_char('D', &makeflags_string);
+ append_char('D', &makeflags_string_posix);
+ }
+ switch (debug_level) {
+ case 2:
+ append_char('d', &makeflags_string);
+ append_char('d', &makeflags_string_posix);
+ case 1:
+ append_char('d', &makeflags_string);
+ append_char('d', &makeflags_string_posix);
+ }
+#ifdef NSE
+ if (nse) {
+ append_char('E', &makeflags_string);
+ }
+#endif
+ if (env_wins) {
+ append_char('e', &makeflags_string);
+ append_char('e', &makeflags_string_posix);
+ }
+ if (ignore_errors_all) {
+ append_char('i', &makeflags_string);
+ append_char('i', &makeflags_string_posix);
+ }
+ if (continue_after_error) {
+ if (stop_after_error_ever_seen) {
+ append_char('S', &makeflags_string_posix);
+ append_char((int) space_char, &makeflags_string_posix);
+ append_char((int) hyphen_char, &makeflags_string_posix);
+ }
+ append_char('k', &makeflags_string);
+ append_char('k', &makeflags_string_posix);
+ } else {
+ if (stop_after_error_ever_seen
+ && continue_after_error_ever_seen) {
+ append_char('k', &makeflags_string_posix);
+ append_char((int) space_char, &makeflags_string_posix);
+ append_char((int) hyphen_char, &makeflags_string_posix);
+ append_char('S', &makeflags_string_posix);
+ }
+ }
+ if (do_not_exec_rule) {
+ append_char('n', &makeflags_string);
+ append_char('n', &makeflags_string_posix);
+ }
+ switch (report_dependencies_level) {
+ case 4:
+ append_char('P', &makeflags_string);
+ append_char('P', &makeflags_string_posix);
+ case 3:
+ append_char('P', &makeflags_string);
+ append_char('P', &makeflags_string_posix);
+ case 2:
+ append_char('P', &makeflags_string);
+ append_char('P', &makeflags_string_posix);
+ case 1:
+ append_char('P', &makeflags_string);
+ append_char('P', &makeflags_string_posix);
+ }
+ if (trace_status) {
+ append_char('p', &makeflags_string);
+ append_char('p', &makeflags_string_posix);
+ }
+ if (quest) {
+ append_char('q', &makeflags_string);
+ append_char('q', &makeflags_string_posix);
+ }
+ if (silent_all) {
+ append_char('s', &makeflags_string);
+ append_char('s', &makeflags_string_posix);
+ }
+ if (touch) {
+ append_char('t', &makeflags_string);
+ append_char('t', &makeflags_string_posix);
+ }
+ if (build_unconditional) {
+ append_char('u', &makeflags_string);
+ append_char('u', &makeflags_string_posix);
+ }
+ if (report_cwd) {
+ append_char('w', &makeflags_string);
+ append_char('w', &makeflags_string_posix);
+ }
+#ifndef PARALLEL
+ /* -c dmake_rcfile */
+ if (dmake_rcfile_specified) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
+ dmake_rcfile = GETNAME(wcs_buffer, FIND_LENGTH);
+ append_makeflags_string(dmake_rcfile, &makeflags_string);
+ append_makeflags_string(dmake_rcfile, &makeflags_string_posix);
+ }
+ /* -g dmake_group */
+ if (dmake_group_specified) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_GROUP"));
+ dmake_group = GETNAME(wcs_buffer, FIND_LENGTH);
+ append_makeflags_string(dmake_group, &makeflags_string);
+ append_makeflags_string(dmake_group, &makeflags_string_posix);
+ }
+ /* -j dmake_max_jobs */
+ if (dmake_max_jobs_specified) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MAX_JOBS"));
+ dmake_max_jobs = GETNAME(wcs_buffer, FIND_LENGTH);
+ append_makeflags_string(dmake_max_jobs, &makeflags_string);
+ append_makeflags_string(dmake_max_jobs, &makeflags_string_posix);
+ }
+ /* -m dmake_mode */
+ if (dmake_mode_specified) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
+ dmake_mode = GETNAME(wcs_buffer, FIND_LENGTH);
+ append_makeflags_string(dmake_mode, &makeflags_string);
+ append_makeflags_string(dmake_mode, &makeflags_string_posix);
+ }
+ /* -x dmake_compat_mode */
+// if (dmake_compat_mode_specified) {
+// MBSTOWCS(wcs_buffer, NOCATGETS("SUN_MAKE_COMPAT_MODE"));
+// dmake_compat_mode = GETNAME(wcs_buffer, FIND_LENGTH);
+// append_makeflags_string(dmake_compat_mode, &makeflags_string);
+// append_makeflags_string(dmake_compat_mode, &makeflags_string_posix);
+// }
+ /* -x dmake_output_mode */
+ if (dmake_output_mode_specified) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
+ dmake_output_mode = GETNAME(wcs_buffer, FIND_LENGTH);
+ append_makeflags_string(dmake_output_mode, &makeflags_string);
+ append_makeflags_string(dmake_output_mode, &makeflags_string_posix);
+ }
+ /* -o dmake_odir */
+ if (dmake_odir_specified) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_ODIR"));
+ dmake_odir = GETNAME(wcs_buffer, FIND_LENGTH);
+ append_makeflags_string(dmake_odir, &makeflags_string);
+ append_makeflags_string(dmake_odir, &makeflags_string_posix);
+ }
+ /* -M pmake_machinesfile */
+ if (pmake_machinesfile_specified) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("PMAKE_MACHINESFILE"));
+ pmake_machinesfile = GETNAME(wcs_buffer, FIND_LENGTH);
+ append_makeflags_string(pmake_machinesfile, &makeflags_string);
+ append_makeflags_string(pmake_machinesfile, &makeflags_string_posix);
+ }
+ /* -R */
+ if (pmake_cap_r_specified) {
+ append_char((int) space_char, &makeflags_string);
+ append_char((int) hyphen_char, &makeflags_string);
+ append_char('R', &makeflags_string);
+ append_char((int) space_char, &makeflags_string_posix);
+ append_char((int) hyphen_char, &makeflags_string_posix);
+ append_char('R', &makeflags_string_posix);
+ }
+#endif
+
+/*
+ * Make sure MAKEFLAGS is exported
+ */
+ maybe_append_prop(makeflags, macro_prop)->
+ body.macro.exported = true;
+
+ if (makeflags_string.buffer.start[1] != (int) nul_char) {
+ if (makeflags_string.buffer.start[1] != (int) space_char) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("MFLAGS"));
+ (void) SETVAR(GETNAME(wcs_buffer, FIND_LENGTH),
+ GETNAME(makeflags_string.buffer.start,
+ FIND_LENGTH),
+ false);
+ } else {
+ MBSTOWCS(wcs_buffer, NOCATGETS("MFLAGS"));
+ (void) SETVAR(GETNAME(wcs_buffer, FIND_LENGTH),
+ GETNAME(makeflags_string.buffer.start + 2,
+ FIND_LENGTH),
+ false);
+ }
+ }
+
+/*
+ * Add command line macro to POSIX makeflags_string
+ */
+ if (makeflags_and_macro.start) {
+ tmp_char = (char) space_char;
+ cp = makeflags_and_macro.start;
+ do {
+ append_char(tmp_char, &makeflags_string_posix);
+ } while ( tmp_char = *cp++ );
+ retmem_mb(makeflags_and_macro.start);
+ }
+
+/*
+ * Now set the value of MAKEFLAGS macro in accordance
+ * with current mode.
+ */
+ macro = maybe_append_prop(makeflags, macro_prop);
+ temp = (Boolean) macro->body.macro.read_only;
+ macro->body.macro.read_only = false;
+ if(posix || gnu_style) {
+ makeflags_string_current = &makeflags_string_posix;
+ } else {
+ makeflags_string_current = &makeflags_string;
+ }
+ if (makeflags_string_current->buffer.start[1] == (int) nul_char) {
+ makeflags_value_saved =
+ GETNAME( makeflags_string_current->buffer.start + 1
+ , FIND_LENGTH
+ );
+ } else {
+ if (makeflags_string_current->buffer.start[1] != (int) space_char) {
+ makeflags_value_saved =
+ GETNAME( makeflags_string_current->buffer.start
+ , FIND_LENGTH
+ );
+ } else {
+ makeflags_value_saved =
+ GETNAME( makeflags_string_current->buffer.start + 2
+ , FIND_LENGTH
+ );
+ }
+ }
+ (void) SETVAR( makeflags
+ , makeflags_value_saved
+ , false
+ );
+ macro->body.macro.read_only = temp;
+
+/*
+ * Read command line "-f" arguments and ignore -c, g, j, K, M, m, O and o args.
+ */
+ save_do_not_exec_rule = do_not_exec_rule;
+ do_not_exec_rule = false;
+ if (read_trace_level > 0) {
+ trace_reader = true;
+ }
+
+ for (i = 1; i < argc; i++) {
+ if (argv[i] &&
+ (argv[i][0] == (int) hyphen_char) &&
+ (argv[i][1] == 'f') &&
+ (argv[i][2] == (int) nul_char)) {
+ argv[i] = NULL; /* Remove -f */
+ if (i >= argc - 1) {
+ fatal(catgets(catd, 1, 190, "No filename argument after -f flag"));
+ }
+ MBSTOWCS(wcs_buffer, argv[++i]);
+ primary_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
+ (void) read_makefile(primary_makefile, true, true, true);
+ argv[i] = NULL; /* Remove filename */
+ makefile_read = true;
+ } else if (argv[i] &&
+ (argv[i][0] == (int) hyphen_char) &&
+ (argv[i][1] == 'c' ||
+ argv[i][1] == 'g' ||
+ argv[i][1] == 'j' ||
+ argv[i][1] == 'K' ||
+ argv[i][1] == 'M' ||
+ argv[i][1] == 'm' ||
+ argv[i][1] == 'O' ||
+ argv[i][1] == 'o') &&
+ (argv[i][2] == (int) nul_char)) {
+ argv[i] = NULL;
+ argv[++i] = NULL;
+ }
+ }
+
+/*
+ * If no command line "-f" args then look for "makefile", and then for
+ * "Makefile" if "makefile" isn't found.
+ */
+ if (!makefile_read) {
+ (void) read_dir(dot,
+ (wchar_t *) NULL,
+ (Property) NULL,
+ (wchar_t *) NULL);
+ if (!posix) {
+ if (makefile_name->stat.is_file) {
+ if (Makefile->stat.is_file) {
+ warning(catgets(catd, 1, 310, "Both `makefile' and `Makefile' exist"));
+ }
+ primary_makefile = makefile_name;
+ makefile_read = read_makefile(makefile_name,
+ false,
+ false,
+ true);
+ }
+ if (!makefile_read &&
+ Makefile->stat.is_file) {
+ primary_makefile = Makefile;
+ makefile_read = read_makefile(Makefile,
+ false,
+ false,
+ true);
+ }
+ } else {
+
+ enum sccs_stat save_m_has_sccs = NO_SCCS;
+ enum sccs_stat save_M_has_sccs = NO_SCCS;
+
+ if (makefile_name->stat.is_file) {
+ if (Makefile->stat.is_file) {
+ warning(catgets(catd, 1, 191, "Both `makefile' and `Makefile' exist"));
+ }
+ }
+ if (makefile_name->stat.is_file) {
+ if (makefile_name->stat.has_sccs == NO_SCCS) {
+ primary_makefile = makefile_name;
+ makefile_read = read_makefile(makefile_name,
+ false,
+ false,
+ true);
+ } else {
+ save_m_has_sccs = makefile_name->stat.has_sccs;
+ makefile_name->stat.has_sccs = NO_SCCS;
+ primary_makefile = makefile_name;
+ makefile_read = read_makefile(makefile_name,
+ false,
+ false,
+ true);
+ }
+ }
+ if (!makefile_read &&
+ Makefile->stat.is_file) {
+ if (Makefile->stat.has_sccs == NO_SCCS) {
+ primary_makefile = Makefile;
+ makefile_read = read_makefile(Makefile,
+ false,
+ false,
+ true);
+ } else {
+ save_M_has_sccs = Makefile->stat.has_sccs;
+ Makefile->stat.has_sccs = NO_SCCS;
+ primary_makefile = Makefile;
+ makefile_read = read_makefile(Makefile,
+ false,
+ false,
+ true);
+ }
+ }
+ if (!makefile_read &&
+ makefile_name->stat.is_file) {
+ makefile_name->stat.has_sccs = save_m_has_sccs;
+ primary_makefile = makefile_name;
+ makefile_read = read_makefile(makefile_name,
+ false,
+ false,
+ true);
+ }
+ if (!makefile_read &&
+ Makefile->stat.is_file) {
+ Makefile->stat.has_sccs = save_M_has_sccs;
+ primary_makefile = Makefile;
+ makefile_read = read_makefile(Makefile,
+ false,
+ false,
+ true);
+ }
+ }
+ }
+ do_not_exec_rule = save_do_not_exec_rule;
+ allrules_read = makefile_read;
+ trace_reader = false;
+
+/*
+ * Now get current value of MAKEFLAGS and compare it with
+ * the saved value we set before reading makefile.
+ * If they are different then MAKEFLAGS is subsequently set by
+ * makefile, just leave it there. Otherwise, if make mode
+ * is changed by using .POSIX target in makefile we need
+ * to correct MAKEFLAGS value.
+ */
+ Name mf_val = getvar(makeflags);
+ if( (posix != is_xpg4)
+ && (!strcmp(mf_val->string_mb, makeflags_value_saved->string_mb)))
+ {
+ if (makeflags_string_posix.buffer.start[1] == (int) nul_char) {
+ (void) SETVAR(makeflags,
+ GETNAME(makeflags_string_posix.buffer.start + 1,
+ FIND_LENGTH),
+ false);
+ } else {
+ if (makeflags_string_posix.buffer.start[1] != (int) space_char) {
+ (void) SETVAR(makeflags,
+ GETNAME(makeflags_string_posix.buffer.start,
+ FIND_LENGTH),
+ false);
+ } else {
+ (void) SETVAR(makeflags,
+ GETNAME(makeflags_string_posix.buffer.start + 2,
+ FIND_LENGTH),
+ false);
+ }
+ }
+ }
+
+ if (makeflags_string.free_after_use) {
+ retmem(makeflags_string.buffer.start);
+ }
+ if (makeflags_string_posix.free_after_use) {
+ retmem(makeflags_string_posix.buffer.start);
+ }
+ makeflags_string.buffer.start = NULL;
+ makeflags_string_posix.buffer.start = NULL;
+
+ if (posix) {
+ /*
+ * If the user did not redefine the ARFLAGS macro in the
+ * default makefile (make.rules), then we'd like to
+ * change the macro value of ARFLAGS to be in accordance
+ * with "POSIX" requirements.
+ */
+ MBSTOWCS(wcs_buffer, NOCATGETS("ARFLAGS"));
+ name = GETNAME(wcs_buffer, wslen(wcs_buffer));
+ macro = get_prop(name->prop, macro_prop);
+ if ((macro != NULL) && /* Maybe (macro == NULL) || ? */
+ (IS_EQUAL(macro->body.macro.value->string_mb,
+ NOCATGETS("rv")))) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("-rv"));
+ value = GETNAME(wcs_buffer, wslen(wcs_buffer));
+ (void) SETVAR(name,
+ value,
+ false);
+ }
+ }
+
+ if (!posix && !svr4) {
+ set_sgs_support();
+ }
+
+
+/*
+ * Make sure KEEP_STATE is in the environment if KEEP_STATE is on.
+ */
+ macro = get_prop(keep_state_name->prop, macro_prop);
+ if ((macro != NULL) &&
+ macro->body.macro.exported) {
+ keep_state = true;
+ }
+ if (keep_state) {
+ if (macro == NULL) {
+ macro = maybe_append_prop(keep_state_name,
+ macro_prop);
+ }
+ macro->body.macro.exported = true;
+ (void) SETVAR(keep_state_name,
+ empty_name,
+ false);
+
+ /*
+ * Read state file
+ */
+
+ /* Before we read state, let's make sure we have
+ ** right state file.
+ */
+ /* just in case macro references are used in make_state file
+ ** name, we better expand them at this stage using expand_value.
+ */
+ INIT_STRING_FROM_STACK(dest, destbuffer);
+ expand_value(make_state, &dest, false);
+
+ make_state = GETNAME(dest.buffer.start, FIND_LENGTH);
+
+ if(!stat(make_state->string_mb, &make_state_stat)) {
+ if(!(make_state_stat.st_mode & S_IFREG) ) {
+ /* copy the make_state structure to the other
+ ** and then let make_state point to the new
+ ** one.
+ */
+ memcpy(&state_filename, make_state,sizeof(state_filename));
+ state_filename.string_mb = state_file_str_mb;
+ /* Just a kludge to avoid two slashes back to back */
+ if((make_state->hash.length == 1)&&
+ (make_state->string_mb[0] == '/')) {
+ make_state->hash.length = 0;
+ make_state->string_mb[0] = '\0';
+ }
+ sprintf(state_file_str_mb,NOCATGETS("%s%s"),
+ make_state->string_mb,NOCATGETS("/.make.state"));
+ make_state = &state_filename;
+ /* adjust the length to reflect the appended string */
+ make_state->hash.length += 12;
+ }
+ } else { /* the file doesn't exist or no permission */
+ char tmp_path[MAXPATHLEN];
+ char *slashp;
+
+ if (slashp = strrchr(make_state->string_mb, '/')) {
+ strncpy(tmp_path, make_state->string_mb,
+ (slashp - make_state->string_mb));
+ tmp_path[slashp - make_state->string_mb]=0;
+ if(strlen(tmp_path)) {
+ if(stat(tmp_path, &make_state_stat)) {
+ warning(catgets(catd, 1, 192, "directory %s for .KEEP_STATE_FILE does not exist"),tmp_path);
+ }
+ if (access(tmp_path, F_OK) != 0) {
+ warning(catgets(catd, 1, 193, "can't access dir %s"),tmp_path);
+ }
+ }
+ }
+ }
+ if (report_dependencies_level != 1) {
+ Makefile_type makefile_type_temp = makefile_type;
+ makefile_type = reading_statefile;
+ if (read_trace_level > 1) {
+ trace_reader = true;
+ }
+ (void) read_simple_file(make_state,
+ false,
+ false,
+ false,
+ false,
+ false,
+ true);
+ trace_reader = false;
+ makefile_type = makefile_type_temp;
+ }
+ }
+}
+
+/*
+ * Scan the argv for options and "=" type args and make them readonly.
+ */
+static void
+enter_argv_values(int argc, char *argv[], ASCII_Dyn_Array *makeflags_and_macro)
+{
+ register char *cp;
+ register int i;
+ int length;
+ register Name name;
+ int opt_separator = argc;
+ char tmp_char;
+ wchar_t *tmp_wcs_buffer;
+ register Name value;
+ Boolean append = false;
+ Property macro;
+ struct stat statbuf;
+
+
+ /* Read argv options and "=" type args and make them readonly. */
+ makefile_type = reading_nothing;
+ for (i = 1; i < argc; ++i) {
+ append = false;
+ if (argv[i] == NULL) {
+ continue;
+ } else if (((argv[i][0] == '-') && (argv[i][1] == '-')) ||
+ ((argv[i][0] == (int) ' ') &&
+ (argv[i][1] == (int) '-') &&
+ (argv[i][2] == (int) ' ') &&
+ (argv[i][3] == (int) '-'))) {
+ argv[i] = NULL;
+ opt_separator = i;
+ continue;
+ } else if ((i < opt_separator) && (argv[i][0] == (int) hyphen_char)) {
+ switch (parse_command_option(argv[i][1])) {
+ case 1: /* -f seen */
+ ++i;
+ continue;
+ case 2: /* -c seen */
+ if (argv[i+1] == NULL) {
+ fatal(catgets(catd, 1, 194, "No dmake rcfile argument after -c flag"));
+ }
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
+ name = GETNAME(wcs_buffer, FIND_LENGTH);
+ break;
+ case 4: /* -g seen */
+ if (argv[i+1] == NULL) {
+ fatal(catgets(catd, 1, 195, "No dmake group argument after -g flag"));
+ }
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_GROUP"));
+ name = GETNAME(wcs_buffer, FIND_LENGTH);
+ break;
+ case 8: /* -j seen */
+ if (argv[i+1] == NULL) {
+ fatal(catgets(catd, 1, 196, "No dmake max jobs argument after -j flag"));
+ }
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MAX_JOBS"));
+ name = GETNAME(wcs_buffer, FIND_LENGTH);
+ break;
+ case 16: /* -M seen */
+ if (argv[i+1] == NULL) {
+ fatal(catgets(catd, 1, 323, "No pmake machinesfile argument after -M flag"));
+ }
+ MBSTOWCS(wcs_buffer, NOCATGETS("PMAKE_MACHINESFILE"));
+ name = GETNAME(wcs_buffer, FIND_LENGTH);
+ break;
+ case 32: /* -m seen */
+ if (argv[i+1] == NULL) {
+ fatal(catgets(catd, 1, 197, "No dmake mode argument after -m flag"));
+ }
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
+ name = GETNAME(wcs_buffer, FIND_LENGTH);
+ break;
+ case 128: /* -O seen */
+ if (argv[i+1] == NULL) {
+ fatal(catgets(catd, 1, 287, "No file descriptor argument after -O flag"));
+ }
+ mtool_msgs_fd = atoi(argv[i+1]);
+ /* find out if mtool_msgs_fd is a valid file descriptor */
+ if (fstat(mtool_msgs_fd, &statbuf) < 0) {
+ fatal(catgets(catd, 1, 355, "Invalid file descriptor %d after -O flag"), mtool_msgs_fd);
+ }
+ argv[i] = NULL;
+ argv[i+1] = NULL;
+ continue;
+ case 256: /* -K seen */
+ if (argv[i+1] == NULL) {
+ fatal(catgets(catd, 1, 288, "No makestate filename argument after -K flag"));
+ }
+ MBSTOWCS(wcs_buffer, argv[i+1]);
+ make_state = GETNAME(wcs_buffer, FIND_LENGTH);
+ keep_state = true;
+ argv[i] = NULL;
+ argv[i+1] = NULL;
+ continue;
+ case 512: /* -o seen */
+ if (argv[i+1] == NULL) {
+ fatal(catgets(catd, 1, 312, "No dmake output dir argument after -o flag"));
+ }
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_ODIR"));
+ name = GETNAME(wcs_buffer, FIND_LENGTH);
+ break;
+ case 1024: /* -x seen */
+ if (argv[i+1] == NULL) {
+ fatal(catgets(catd, 1, 351, "No argument after -x flag"));
+ }
+ length = strlen( NOCATGETS("SUN_MAKE_COMPAT_MODE="));
+ if (strncmp(argv[i+1], NOCATGETS("SUN_MAKE_COMPAT_MODE="), length) == 0) {
+ argv[i+1] = &argv[i+1][length];
+ MBSTOWCS(wcs_buffer, NOCATGETS("SUN_MAKE_COMPAT_MODE"));
+ name = GETNAME(wcs_buffer, FIND_LENGTH);
+ dmake_compat_mode_specified = dmake_add_mode_specified;
+ break;
+ }
+ length = strlen( NOCATGETS("DMAKE_OUTPUT_MODE="));
+ if (strncmp(argv[i+1], NOCATGETS("DMAKE_OUTPUT_MODE="), length) == 0) {
+ argv[i+1] = &argv[i+1][length];
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
+ name = GETNAME(wcs_buffer, FIND_LENGTH);
+ dmake_output_mode_specified = dmake_add_mode_specified;
+ } else {
+ warning(catgets(catd, 1, 354, "Unknown argument `%s' after -x flag (ignored)"),
+ argv[i+1]);
+ argv[i] = argv[i + 1] = NULL;
+ continue;
+ }
+ break;
+ default: /* Shouldn't reach here */
+ argv[i] = NULL;
+ continue;
+ }
+ argv[i] = NULL;
+ if (i == (argc - 1)) {
+ break;
+ }
+ if ((length = strlen(argv[i+1])) >= MAXPATHLEN) {
+ tmp_wcs_buffer = ALLOC_WC(length + 1);
+ (void) mbstowcs(tmp_wcs_buffer, argv[i+1], length + 1);
+ value = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
+ retmem(tmp_wcs_buffer);
+ } else {
+ MBSTOWCS(wcs_buffer, argv[i+1]);
+ value = GETNAME(wcs_buffer, FIND_LENGTH);
+ }
+ argv[i+1] = NULL;
+ } else if ((cp = strchr(argv[i], (int) equal_char)) != NULL) {
+/*
+ * Combine all macro in dynamic array
+ */
+ if(*(cp-1) == (int) plus_char)
+ {
+ if(isspace(*(cp-2))) {
+ append = true;
+ cp--;
+ }
+ }
+ if(!append)
+ append_or_replace_macro_in_dyn_array(makeflags_and_macro, argv[i]);
+
+ while (isspace(*(cp-1))) {
+ cp--;
+ }
+ tmp_char = *cp;
+ *cp = (int) nul_char;
+ MBSTOWCS(wcs_buffer, argv[i]);
+ *cp = tmp_char;
+ name = GETNAME(wcs_buffer, wslen(wcs_buffer));
+ while (*cp != (int) equal_char) {
+ cp++;
+ }
+ cp++;
+ while (isspace(*cp) && (*cp != (int) nul_char)) {
+ cp++;
+ }
+ if ((length = strlen(cp)) >= MAXPATHLEN) {
+ tmp_wcs_buffer = ALLOC_WC(length + 1);
+ (void) mbstowcs(tmp_wcs_buffer, cp, length + 1);
+ value = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
+ retmem(tmp_wcs_buffer);
+ } else {
+ MBSTOWCS(wcs_buffer, cp);
+ value = GETNAME(wcs_buffer, FIND_LENGTH);
+ }
+ argv[i] = NULL;
+ } else {
+ /* Illegal MAKEFLAGS argument */
+ continue;
+ }
+ if(append) {
+ setvar_append(name, value);
+ append = false;
+ } else {
+ macro = maybe_append_prop(name, macro_prop);
+ macro->body.macro.exported = true;
+ SETVAR(name, value, false)->body.macro.read_only = true;
+ }
+ }
+}
+
+/*
+ * Append the DMake option and value to the MAKEFLAGS string.
+ */
+static void
+append_makeflags_string(Name name, register String makeflags_string)
+{
+ char *option;
+
+ if (strcmp(name->string_mb, NOCATGETS("DMAKE_GROUP")) == 0) {
+ option = NOCATGETS(" -g ");
+ } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_MAX_JOBS")) == 0) {
+ option = NOCATGETS(" -j ");
+ } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_MODE")) == 0) {
+ option = NOCATGETS(" -m ");
+ } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_ODIR")) == 0) {
+ option = NOCATGETS(" -o ");
+ } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_RCFILE")) == 0) {
+ option = NOCATGETS(" -c ");
+ } else if (strcmp(name->string_mb, NOCATGETS("PMAKE_MACHINESFILE")) == 0) {
+ option = NOCATGETS(" -M ");
+ } else if (strcmp(name->string_mb, NOCATGETS("DMAKE_OUTPUT_MODE")) == 0) {
+ option = NOCATGETS(" -x DMAKE_OUTPUT_MODE=");
+ } else if (strcmp(name->string_mb, NOCATGETS("SUN_MAKE_COMPAT_MODE")) == 0) {
+ option = NOCATGETS(" -x SUN_MAKE_COMPAT_MODE=");
+ } else {
+ fatal(catgets(catd, 1, 289, "Internal error: name not recognized in append_makeflags_string()"));
+ }
+ Property prop = maybe_append_prop(name, macro_prop);
+ if( prop == 0 || prop->body.macro.value == 0 ||
+ prop->body.macro.value->string_mb == 0 ) {
+ return;
+ }
+ char mbs_value[MAXPATHLEN + 100];
+ strcpy(mbs_value, option);
+ strcat(mbs_value, prop->body.macro.value->string_mb);
+ MBSTOWCS(wcs_buffer, mbs_value);
+ append_string(wcs_buffer, makeflags_string, FIND_LENGTH);
+}
+
+/*
+ * read_environment(read_only)
+ *
+ * This routine reads the process environment when make starts and enters
+ * it as make macros. The environment variable SHELL is ignored.
+ *
+ * Parameters:
+ * read_only Should we make env vars read only?
+ *
+ * Global variables used:
+ * report_pwd Set if this make was started by other make
+ */
+static void
+read_environment(Boolean read_only)
+{
+ register char **environment;
+ int length;
+ wchar_t *tmp_wcs_buffer;
+ Boolean alloced_tmp_wcs_buffer = false;
+ register wchar_t *name;
+ register wchar_t *value;
+ register Name macro;
+ Property val;
+ Boolean read_only_saved;
+
+ reading_environment = true;
+ environment = environ;
+ for (; *environment; environment++) {
+ read_only_saved = read_only;
+ if ((length = strlen(*environment)) >= MAXPATHLEN) {
+ tmp_wcs_buffer = ALLOC_WC(length + 1);
+ alloced_tmp_wcs_buffer = true;
+ (void) mbstowcs(tmp_wcs_buffer, *environment, length + 1);
+ name = tmp_wcs_buffer;
+ } else {
+ MBSTOWCS(wcs_buffer, *environment);
+ name = wcs_buffer;
+ }
+ value = (wchar_t *) wschr(name, (int) equal_char);
+
+ /*
+ * Looks like there's a bug in the system, but sometimes
+ * you can get blank lines in *environment.
+ */
+ if (!value) {
+ continue;
+ }
+ MBSTOWCS(wcs_buffer2, NOCATGETS("SHELL="));
+ if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
+ continue;
+ }
+ MBSTOWCS(wcs_buffer2, NOCATGETS("MAKEFLAGS="));
+ if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
+ report_pwd = true;
+ /*
+ * In POSIX mode we do not want MAKEFLAGS to be readonly.
+ * If the MAKEFLAGS macro is subsequently set by the makefile,
+ * it replaces the MAKEFLAGS variable currently found in the
+ * environment.
+ * See Assertion 50 in section 6.2.5.3 of standard P1003.3.2/D8.
+ */
+ if(posix) {
+ read_only_saved = false;
+ }
+ }
+
+ /*
+ * We ignore SUNPRO_DEPENDENCIES and NSE_DEP. Those
+ * environment variables are set by make and read by
+ * cpp which then writes info to .make.dependency.xxx and
+ * .nse_depinfo. When make is invoked by another make
+ * (recursive make), we don't want to read this because
+ * then the child make will end up writing to the parent
+ * directory's .make.state and .nse_depinfo and clobbering
+ * them.
+ */
+ MBSTOWCS(wcs_buffer2, NOCATGETS("SUNPRO_DEPENDENCIES"));
+ if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
+ continue;
+ }
+#ifdef NSE
+ MBSTOWCS(wcs_buffer2, NOCATGETS("NSE_DEP"));
+ if (IS_WEQUALN(name, wcs_buffer2, wslen(wcs_buffer2))) {
+ continue;
+ }
+#endif
+
+ macro = GETNAME(name, value - name);
+ maybe_append_prop(macro, macro_prop)->body.macro.exported =
+ true;
+ if ((value == NULL) || ((value + 1)[0] == (int) nul_char)) {
+ val = setvar_daemon(macro,
+ (Name) NULL,
+ false, no_daemon, false, debug_level);
+ } else {
+ val = setvar_daemon(macro,
+ GETNAME(value + 1, FIND_LENGTH),
+ false, no_daemon, false, debug_level);
+ }
+#ifdef NSE
+ /*
+ * Must be after the call to setvar() as it sets
+ * imported to false.
+ */
+ maybe_append_prop(macro, macro_prop)->body.macro.imported = true;
+#endif
+ val->body.macro.read_only = read_only_saved;
+ if (alloced_tmp_wcs_buffer) {
+ retmem(tmp_wcs_buffer);
+ alloced_tmp_wcs_buffer = false;
+ }
+ }
+ reading_environment = false;
+}
+
+/*
+ * read_makefile(makefile, complain, must_exist, report_file)
+ *
+ * Read one makefile and check the result
+ *
+ * Return value:
+ * false is the read failed
+ *
+ * Parameters:
+ * makefile The file to read
+ * complain Passed thru to read_simple_file()
+ * must_exist Passed thru to read_simple_file()
+ * report_file Passed thru to read_simple_file()
+ *
+ * Global variables used:
+ * makefile_type Set to indicate we are reading main file
+ * recursion_level Initialized
+ */
+static Boolean
+read_makefile(register Name makefile, Boolean complain, Boolean must_exist, Boolean report_file)
+{
+ Boolean b;
+
+ makefile_type = reading_makefile;
+ recursion_level = 0;
+#ifdef NSE
+ wscpy(current_makefile, makefile->string);
+#endif
+ reading_dependencies = true;
+ b = read_simple_file(makefile, true, true, complain,
+ must_exist, report_file, false);
+ reading_dependencies = false;
+ return b;
+}
+
+/*
+ * make_targets(argc, argv, parallel_flag)
+ *
+ * Call doname on the specified targets
+ *
+ * Parameters:
+ * argc You know what this is
+ * argv You know what this is
+ * parallel_flag True if building in parallel
+ *
+ * Global variables used:
+ * build_failed_seen Used to generated message after failed -k
+ * commands_done Used to generate message "Up to date"
+ * default_target_to_build First proper target in makefile
+ * init The Name ".INIT", use to run command
+ * parallel Global parallel building flag
+ * quest make -q, suppresses messages
+ * recursion_level Initialized, used for tracing
+ * report_dependencies make -P, regroves whole process
+ */
+static void
+make_targets(int argc, char **argv, Boolean parallel_flag)
+{
+ int i;
+ char *cp;
+ Doname result;
+ register Boolean target_to_make_found = false;
+
+ (void) doname(init, true, true);
+ recursion_level = 1;
+ parallel = parallel_flag;
+/*
+ * make remaining args
+ */
+#ifdef TEAMWARE_MAKE_CMN
+/*
+ if ((report_dependencies_level == 0) && parallel) {
+ */
+ if (parallel) {
+ /*
+ * If building targets in parallel, start all of the
+ * remaining args to build in parallel.
+ */
+ for (i = 1; i < argc; i++) {
+ if ((cp = argv[i]) != NULL) {
+ commands_done = false;
+ if ((cp[0] == (int) period_char) &&
+ (cp[1] == (int) slash_char)) {
+ cp += 2;
+ }
+ if((cp[0] == (int) ' ') &&
+ (cp[1] == (int) '-') &&
+ (cp[2] == (int) ' ') &&
+ (cp[3] == (int) '-')) {
+ argv[i] = NULL;
+ continue;
+ }
+ MBSTOWCS(wcs_buffer, cp);
+ //default_target_to_build = GETNAME(wcs_buffer,
+ // FIND_LENGTH);
+ default_target_to_build = normalize_name(wcs_buffer,
+ wslen(wcs_buffer));
+ if (default_target_to_build == wait_name) {
+ if (parallel_process_cnt > 0) {
+ finish_running();
+ }
+ continue;
+ }
+ top_level_target = get_wstring(default_target_to_build->string_mb);
+ /*
+ * If we can't execute the current target in
+ * parallel, hold off the target processing
+ * to preserve the order of the targets as they appeared
+ * in command line.
+ */
+ if (!parallel_ok(default_target_to_build, false)
+ && parallel_process_cnt > 0) {
+ finish_running();
+ }
+ result = doname_check(default_target_to_build,
+ true,
+ false,
+ false);
+ gather_recursive_deps();
+ if (/* !commands_done && */
+ (result == build_ok) &&
+ !quest &&
+ (report_dependencies_level == 0) /* &&
+ (exists(default_target_to_build) > file_doesnt_exist) */) {
+ if (posix) {
+ if (!commands_done) {
+ (void) printf(catgets(catd, 1, 293, "`%s' is updated.\n"),
+ default_target_to_build->string_mb);
+ } else {
+ if (no_action_was_taken) {
+ (void) printf(catgets(catd, 1, 294, "`%s': no action was taken.\n"),
+ default_target_to_build->string_mb);
+ }
+ }
+ } else {
+ default_target_to_build->stat.time = file_no_time;
+ if (!commands_done &&
+ (exists(default_target_to_build) > file_doesnt_exist)) {
+ (void) printf(catgets(catd, 1, 295, "`%s' is up to date.\n"),
+ default_target_to_build->string_mb);
+ }
+ }
+ }
+ }
+ }
+ /* Now wait for all of the targets to finish running */
+ finish_running();
+ // setjmp(jmpbuffer);
+
+ }
+#endif
+ for (i = 1; i < argc; i++) {
+ if ((cp = argv[i]) != NULL) {
+ target_to_make_found = true;
+ if ((cp[0] == (int) period_char) &&
+ (cp[1] == (int) slash_char)) {
+ cp += 2;
+ }
+ if((cp[0] == (int) ' ') &&
+ (cp[1] == (int) '-') &&
+ (cp[2] == (int) ' ') &&
+ (cp[3] == (int) '-')) {
+ argv[i] = NULL;
+ continue;
+ }
+ MBSTOWCS(wcs_buffer, cp);
+ default_target_to_build = normalize_name(wcs_buffer, wslen(wcs_buffer));
+ top_level_target = get_wstring(default_target_to_build->string_mb);
+ report_recursion(default_target_to_build);
+ commands_done = false;
+ if (parallel) {
+ result = (Doname) default_target_to_build->state;
+ } else {
+ result = doname_check(default_target_to_build,
+ true,
+ false,
+ false);
+ }
+ gather_recursive_deps();
+ if (build_failed_seen) {
+ build_failed_ever_seen = true;
+ warning(catgets(catd, 1, 200, "Target `%s' not remade because of errors"),
+ default_target_to_build->string_mb);
+ }
+ build_failed_seen = false;
+ if (report_dependencies_level > 0) {
+ print_dependencies(default_target_to_build,
+ get_prop(default_target_to_build->prop,
+ line_prop));
+ }
+ default_target_to_build->stat.time =
+ file_no_time;
+ if (default_target_to_build->colon_splits > 0) {
+ default_target_to_build->state =
+ build_dont_know;
+ }
+ if (!parallel &&
+ /* !commands_done && */
+ (result == build_ok) &&
+ !quest &&
+ (report_dependencies_level == 0) /* &&
+ (exists(default_target_to_build) > file_doesnt_exist) */) {
+ if (posix) {
+ if (!commands_done) {
+ (void) printf(catgets(catd, 1, 296, "`%s' is updated.\n"),
+ default_target_to_build->string_mb);
+ } else {
+ if (no_action_was_taken) {
+ (void) printf(catgets(catd, 1, 297, "`%s': no action was taken.\n"),
+ default_target_to_build->string_mb);
+ }
+ }
+ } else {
+ if (!commands_done &&
+ (exists(default_target_to_build) > file_doesnt_exist)) {
+ (void) printf(catgets(catd, 1, 298, "`%s' is up to date.\n"),
+ default_target_to_build->string_mb);
+ }
+ }
+ }
+ }
+ }
+
+/*
+ * If no file arguments have been encountered,
+ * make the first name encountered that doesnt start with a dot
+ */
+ if (!target_to_make_found) {
+ if (default_target_to_build == NULL) {
+ fatal(catgets(catd, 1, 202, "No arguments to build"));
+ }
+ commands_done = false;
+ top_level_target = get_wstring(default_target_to_build->string_mb);
+ report_recursion(default_target_to_build);
+
+
+ if (getenv(NOCATGETS("SPRO_EXPAND_ERRORS"))){
+ (void) printf(NOCATGETS("::(%s)\n"),
+ default_target_to_build->string_mb);
+ }
+
+
+#ifdef TEAMWARE_MAKE_CMN
+ result = doname_parallel(default_target_to_build, true, false);
+#else
+ result = doname_check(default_target_to_build, true,
+ false, false);
+#endif
+ gather_recursive_deps();
+ if (build_failed_seen) {
+ build_failed_ever_seen = true;
+ warning(catgets(catd, 1, 203, "Target `%s' not remade because of errors"),
+ default_target_to_build->string_mb);
+ }
+ build_failed_seen = false;
+ if (report_dependencies_level > 0) {
+ print_dependencies(default_target_to_build,
+ get_prop(default_target_to_build->
+ prop,
+ line_prop));
+ }
+ default_target_to_build->stat.time = file_no_time;
+ if (default_target_to_build->colon_splits > 0) {
+ default_target_to_build->state = build_dont_know;
+ }
+ if (/* !commands_done && */
+ (result == build_ok) &&
+ !quest &&
+ (report_dependencies_level == 0) /* &&
+ (exists(default_target_to_build) > file_doesnt_exist) */) {
+ if (posix) {
+ if (!commands_done) {
+ (void) printf(catgets(catd, 1, 299, "`%s' is updated.\n"),
+ default_target_to_build->string_mb);
+ } else {
+ if (no_action_was_taken) {
+ (void) printf(catgets(catd, 1, 300, "`%s': no action was taken.\n"),
+ default_target_to_build->string_mb);
+ }
+ }
+ } else {
+ if (!commands_done &&
+ (exists(default_target_to_build) > file_doesnt_exist)) {
+ (void) printf(catgets(catd, 1, 301, "`%s' is up to date.\n"),
+ default_target_to_build->string_mb);
+ }
+ }
+ }
+ }
+}
+
+/*
+ * report_recursion(target)
+ *
+ * If this is a recursive make and the parent make has KEEP_STATE on
+ * this routine reports the dependency to the parent make
+ *
+ * Parameters:
+ * target Target to report
+ *
+ * Global variables used:
+ * makefiles_used List of makefiles read
+ * recursive_name The Name ".RECURSIVE", printed
+ * report_dependency dwight
+ */
+static void
+report_recursion(register Name target)
+{
+ register FILE *report_file = get_report_file();
+
+ if ((report_file == NULL) || (report_file == (FILE*)-1)) {
+ return;
+ }
+ if (primary_makefile == NULL) {
+ /*
+ * This can happen when there is no makefile and
+ * only implicit rules are being used.
+ */
+#ifdef NSE
+ nse_no_makefile(target);
+#endif
+ return;
+ }
+ (void) fprintf(report_file,
+ "%s: %s ",
+ get_target_being_reported_for(),
+ recursive_name->string_mb);
+ report_dependency(get_current_path());
+ report_dependency(target->string_mb);
+ report_dependency(primary_makefile->string_mb);
+ (void) fprintf(report_file, "\n");
+}
+
+/* Next function "append_or_replace_macro_in_dyn_array" must be in "misc.cc". */
+/* NIKMOL */
+extern void
+append_or_replace_macro_in_dyn_array(ASCII_Dyn_Array *Ar, char *macro)
+{
+ register char *cp0; /* work pointer in macro */
+ register char *cp1; /* work pointer in array */
+ register char *cp2; /* work pointer in array */
+ register char *cp3; /* work pointer in array */
+ register char *name; /* macro name */
+ register char *value; /* macro value */
+ register int len_array;
+ register int len_macro;
+
+ char * esc_value = NULL;
+ int esc_len;
+
+ if (!(len_macro = strlen(macro))) return;
+ name = macro;
+ while (isspace(*(name))) {
+ name++;
+ }
+ if (!(value = strchr(name, (int) equal_char))) {
+ /* no '=' in macro */
+ goto ERROR_MACRO;
+ }
+ cp0 = value;
+ value++;
+ while (isspace(*(value))) {
+ value++;
+ }
+ while (isspace(*(cp0-1))) {
+ cp0--;
+ }
+ if (cp0 <= name) goto ERROR_MACRO; /* no name */
+ if (!(Ar->size)) goto ALLOC_ARRAY;
+ cp1 = Ar->start;
+
+LOOK_FOR_NAME:
+ if (!(cp1 = strchr(cp1, name[0]))) goto APPEND_MACRO;
+ if (!(cp2 = strchr(cp1, (int) equal_char))) goto APPEND_MACRO;
+ if (strncmp(cp1, name, (size_t)(cp0-name))) {
+ /* another name */
+ cp1++;
+ goto LOOK_FOR_NAME;
+ }
+ if (cp1 != Ar->start) {
+ if (!isspace(*(cp1-1))) {
+ /* another name */
+ cp1++;
+ goto LOOK_FOR_NAME;
+ }
+ }
+ for (cp3 = cp1 + (cp0-name); cp3 < cp2; cp3++) {
+ if (isspace(*cp3)) continue;
+ /* else: another name */
+ cp1++;
+ goto LOOK_FOR_NAME;
+ }
+ /* Look for the next macro name in array */
+ cp3 = cp2+1;
+ if (*cp3 != (int) doublequote_char) {
+ /* internal error */
+ goto ERROR_MACRO;
+ }
+ if (!(cp3 = strchr(cp3+1, (int) doublequote_char))) {
+ /* internal error */
+ goto ERROR_MACRO;
+ }
+ cp3++;
+ while (isspace(*cp3)) {
+ cp3++;
+ }
+
+ cp2 = cp1; /* remove old macro */
+ if ((*cp3) && (cp3 < Ar->start + Ar->size)) {
+ for (; cp3 < Ar->start + Ar->size; cp3++) {
+ *cp2++ = *cp3;
+ }
+ }
+ for (; cp2 < Ar->start + Ar->size; cp2++) {
+ *cp2 = 0;
+ }
+ if (*cp1) {
+ /* check next name */
+ goto LOOK_FOR_NAME;
+ }
+ goto APPEND_MACRO;
+
+ALLOC_ARRAY:
+ if (Ar->size) {
+ cp1 = Ar->start;
+ } else {
+ cp1 = 0;
+ }
+ Ar->size += 128;
+ Ar->start = getmem(Ar->size);
+ for (len_array=0; len_array < Ar->size; len_array++) {
+ Ar->start[len_array] = 0;
+ }
+ if (cp1) {
+ strcpy(Ar->start, cp1);
+ retmem((wchar_t *) cp1);
+ }
+
+APPEND_MACRO:
+ len_array = strlen(Ar->start);
+ esc_value = (char*)malloc(strlen(value)*2 + 1);
+ quote_str(value, esc_value);
+ esc_len = strlen(esc_value) - strlen(value);
+ if (len_array + len_macro + esc_len + 5 >= Ar->size) goto ALLOC_ARRAY;
+ strcat(Ar->start, " ");
+ strncat(Ar->start, name, cp0-name);
+ strcat(Ar->start, "=");
+ strncat(Ar->start, esc_value, strlen(esc_value));
+ free(esc_value);
+ return;
+ERROR_MACRO:
+ /* Macro without '=' or with invalid left/right part */
+ return;
+}
+
+#ifdef TEAMWARE_MAKE_CMN
+/*
+ * This function, if registered w/ avo_cli_get_license(), will be called
+ * if the application is about to exit because:
+ * 1) there has been certain unrecoverable error(s) that cause the
+ * application to exit immediately.
+ * 2) the user has lost a license while the application is running.
+ */
+extern "C" void
+dmake_exit_callback(void)
+{
+ fatal(catgets(catd, 1, 306, "can not get a license, exiting..."));
+ exit(1);
+}
+
+/*
+ * This function, if registered w/ avo_cli_get_license(), will be called
+ * if the application can not get a license.
+ */
+extern "C" void
+dmake_message_callback(char *err_msg)
+{
+ static Boolean first = true;
+
+ if (!first) {
+ return;
+ }
+ first = false;
+ if ((!list_all_targets) &&
+ (report_dependencies_level == 0) &&
+ (dmake_mode_type != serial_mode)) {
+ warning(catgets(catd, 1, 313, "can not get a TeamWare license, defaulting to serial mode..."));
+ }
+}
+#endif
+
+#ifdef DISTRIBUTED
+/*
+ * Returns whether -c is set or not.
+ */
+Boolean
+get_dmake_rcfile_specified(void)
+{
+ return(dmake_rcfile_specified);
+}
+
+/*
+ * Returns whether -g is set or not.
+ */
+Boolean
+get_dmake_group_specified(void)
+{
+ return(dmake_group_specified);
+}
+
+/*
+ * Returns whether -j is set or not.
+ */
+Boolean
+get_dmake_max_jobs_specified(void)
+{
+ return(dmake_max_jobs_specified);
+}
+
+/*
+ * Returns whether -m is set or not.
+ */
+Boolean
+get_dmake_mode_specified(void)
+{
+ return(dmake_mode_specified);
+}
+
+/*
+ * Returns whether -o is set or not.
+ */
+Boolean
+get_dmake_odir_specified(void)
+{
+ return(dmake_odir_specified);
+}
+
+#endif
+
+static void
+report_dir_enter_leave(Boolean entering)
+{
+ char rcwd[MAXPATHLEN];
+static char * mlev = NULL;
+ char * make_level_str = NULL;
+ int make_level_val = 0;
+
+ make_level_str = getenv(NOCATGETS("MAKELEVEL"));
+ if(make_level_str) {
+ make_level_val = atoi(make_level_str);
+ }
+ if(mlev == NULL) {
+ mlev = (char*) malloc(MAXPATHLEN);
+ }
+ if(entering) {
+ sprintf(mlev, NOCATGETS("MAKELEVEL=%d"), make_level_val + 1);
+ } else {
+ make_level_val--;
+ sprintf(mlev, NOCATGETS("MAKELEVEL=%d"), make_level_val);
+ }
+ putenv(mlev);
+
+ if(report_cwd) {
+ if(make_level_val <= 0) {
+ if(entering) {
+#ifdef TEAMWARE_MAKE_CMN
+ sprintf( rcwd
+ , catgets(catd, 1, 329, "dmake: Entering directory `%s'\n")
+ , get_current_path());
+#else
+ sprintf( rcwd
+ , catgets(catd, 1, 330, "make: Entering directory `%s'\n")
+ , get_current_path());
+#endif
+ } else {
+#ifdef TEAMWARE_MAKE_CMN
+ sprintf( rcwd
+ , catgets(catd, 1, 331, "dmake: Leaving directory `%s'\n")
+ , get_current_path());
+#else
+ sprintf( rcwd
+ , catgets(catd, 1, 332, "make: Leaving directory `%s'\n")
+ , get_current_path());
+#endif
+ }
+ } else {
+ if(entering) {
+#ifdef TEAMWARE_MAKE_CMN
+ sprintf( rcwd
+ , catgets(catd, 1, 333, "dmake[%d]: Entering directory `%s'\n")
+ , make_level_val, get_current_path());
+#else
+ sprintf( rcwd
+ , catgets(catd, 1, 334, "make[%d]: Entering directory `%s'\n")
+ , make_level_val, get_current_path());
+#endif
+ } else {
+#ifdef TEAMWARE_MAKE_CMN
+ sprintf( rcwd
+ , catgets(catd, 1, 335, "dmake[%d]: Leaving directory `%s'\n")
+ , make_level_val, get_current_path());
+#else
+ sprintf( rcwd
+ , catgets(catd, 1, 336, "make[%d]: Leaving directory `%s'\n")
+ , make_level_val, get_current_path());
+#endif
+ }
+ }
+ printf(NOCATGETS("%s"), rcwd);
+ }
+}
diff --git a/usr/src/make_src/Make/bin/make/common/make.cc b/usr/src/make_src/Make/bin/make/common/make.cc
new file mode 100644
index 0000000..8096f2a
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/make.cc
@@ -0,0 +1,29 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)make.cc 1.2 06/12/12
+ */
+
+#pragma ident "@(#)make.cc 1.2 06/12/12"
diff --git a/usr/src/make_src/Make/bin/make/common/make.rules.file b/usr/src/make_src/Make/bin/make/common/make.rules.file
new file mode 100644
index 0000000..3b4b7bf
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/make.rules.file
@@ -0,0 +1,500 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)make.rules.file 1.22 06/12/12
+#
+
+SUFFIXES = .o .c .c~ .cc .cc~ .y .y~ .l .l~ .s .s~ .sh .sh~ .S .S~ .i .ln \
+ .h .h~ .f .f~ .for .for~ .F .F~ .f90 .f90~ .ftn .ftn~ .mod .mod~ \
+ .sym .def .def~ .p .p~ .r .r~ .cps .cps~ .C .C~ .Y .Y~ .L .L~ \
+ .java .java~ .class
+
+.SUFFIXES: $(SUFFIXES)
+
+# OUTPUT_OPTION should be defined to "-o $@" when
+# the default rules are used for non-local files.
+OUTPUT_OPTION=
+
+# C language section.
+CC=cc
+CFLAGS=
+CPPFLAGS=
+LINT=lint
+LINTFLAGS=
+COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c
+LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
+LINT.c=$(LINT) $(LINTFLAGS) $(CPPFLAGS)
+.c:
+ $(LINK.c) -o $@ $< $(LDLIBS)
+.c~:
+ $(GET) $(GFLAGS) -p $< > $*.c
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $*.c
+.c.o:
+ $(COMPILE.c) $(OUTPUT_OPTION) $<
+.c~.o:
+ $(GET) $(GFLAGS) -p $< > $*.c
+ $(CC) $(CFLAGS) -c $*.c
+.c.i:
+ $(CC) $(CFLAGS) $(CPPFLAGS) -P $<
+.c~.i:
+ $(GET) $(GFLAGS) -p $< > $*.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -P $*.c
+.c.ln:
+ $(LINT.c) $(OUTPUT_OPTION) -c $<
+.c~.ln:
+ $(GET) $(GFLAGS) -p $< > $*.c
+ $(LINT.c) $(OUTPUT_OPTION) -c $*.c
+.c.a:
+ $(COMPILE.c) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.c~.a:
+ $(GET) $(GFLAGS) -p $< > $*.c
+ $(COMPILE.c) -o $% $*.c
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# C language section. yacc.
+YACC=yacc
+YFLAGS=
+YACC.y=$(YACC) $(YFLAGS)
+.y:
+ $(YACC.y) $<
+ $(LINK.c) -o $@ y.tab.c $(LDLIBS)
+ $(RM) y.tab.c
+.y~:
+ $(GET) $(GFLAGS) -p $< > $*.y
+ $(YACC) $(YFLAGS) $*.y
+ $(COMPILE.c) -o $@ y.tab.c
+ $(RM) y.tab.c
+
+.y.c:
+ $(YACC.y) $<
+ mv y.tab.c $@
+.y~.c:
+ $(GET) $(GFLAGS) -p $< > $*.y
+ $(YACC) $(YFLAGS) $*.y
+ mv y.tab.c $@
+.y.ln:
+ $(YACC.y) $<
+ $(LINT.c) -o $@ -i y.tab.c
+ $(RM) y.tab.c
+.y~.ln:
+ $(GET) $(GFLAGS) -p $< > $*.y
+ $(YACC.y) $*.y
+ $(LINT.c) -o $@ -i y.tab.c
+ $(RM) y.tab.c
+.y.o:
+ $(YACC.y) $<
+ $(COMPILE.c) -o $@ y.tab.c
+ $(RM) y.tab.c
+.y~.o:
+ $(GET) $(GFLAGS) -p $< > $*.y
+ $(YACC) $(YFLAGS) $*.y
+ $(CC) $(CFLAGS) -c y.tab.c
+ rm -f y.tab.c
+ mv y.tab.o $@
+
+# C language section. lex.
+LEX=lex
+LFLAGS=
+LEX.l=$(LEX) $(LFLAGS) -t
+.l:
+ $(RM) $*.c
+ $(LEX.l) $< > $*.c
+ $(LINK.c) -o $@ $*.c -ll $(LDLIBS)
+ $(RM) $*.c
+.l~:
+ $(GET) $(GFLAGS) -p $< > $*.l
+ $(LEX) $(LFLAGS) $*.l
+ $(CC) $(CFLAGS) -c lex.yy.c
+ rm -f lex.yy.c
+ mv lex.yy.c $@
+
+.l.c :
+ $(RM) $@
+ $(LEX.l) $< > $@
+.l~.c:
+ $(GET) $(GFLAGS) -p $< > $*.l
+ $(LEX) $(LFLAGS) $*.l
+ mv lex.yy.c $@
+.l.ln:
+ $(RM) $*.c
+ $(LEX.l) $< > $*.c
+ $(LINT.c) -o $@ -i $*.c
+ $(RM) $*.c
+.l~.ln:
+ $(GET) $(GFLAGS) -p $< > $*.l
+ $(RM) $*.c
+ $(LEX.l) $*.l > $*.c
+ $(LINT.c) -o $@ -i $*.c
+ $(RM) $*.c
+.l.o:
+ $(RM) $*.c
+ $(LEX.l) $< > $*.c
+ $(COMPILE.c) -o $@ $*.c
+ $(RM) $*.c
+.l~.o:
+ $(GET) $(GFLAGS) -p $< > $*.l
+ $(LEX) $(LFLAGS) $*.l
+ $(CC) $(CFLAGS) -c lex.yy.c
+ rm -f lex.yy.c
+ mv lex.yy.c $@
+
+# C++ language section.
+CCC=CC
+CCFLAGS=
+COMPILE.cc=$(CCC) $(CCFLAGS) $(CPPFLAGS) -c
+LINK.cc=$(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS)
+COMPILE.C=$(CCC) $(CCFLAGS) $(CPPFLAGS) -c
+LINK.C=$(CCC) $(CCFLAGS) $(CPPFLAGS) $(LDFLAGS)
+.cc:
+ $(LINK.cc) -o $@ $< $(LDLIBS)
+.cc~:
+ $(GET) $(GFLAGS) -p $< > $*.cc
+ $(LINK.cc) -o $@ $*.cc $(LDLIBS)
+.cc.o:
+ $(COMPILE.cc) $(OUTPUT_OPTION) $<
+.cc~.o:
+ $(GET) $(GFLAGS) -p $< > $*.cc
+ $(COMPILE.cc) $(OUTPUT_OPTION) $*.cc
+.cc.i:
+ $(CCC) $(CCFLAGS) $(CPPFLAGS) -P $<
+.cc~.i:
+ $(GET) $(GFLAGS) -p $< > $*.cc
+ $(CCC) $(CCFLAGS) $(CPPFLAGS) -P $*.cc
+.cc.a:
+ $(COMPILE.cc) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.cc~.a:
+ $(GET) $(GFLAGS) -p $< > $*.cc
+ $(COMPILE.cc) -o $% $*.cc
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+.C:
+ $(LINK.C) -o $@ $< $(LDLIBS)
+.C~:
+ $(GET) $(GFLAGS) -p $< > $*.C
+ $(LINK.C) -o $@ $*.C $(LDLIBS)
+.C.o:
+ $(COMPILE.C) $(OUTPUT_OPTION) $<
+.C~.o:
+ $(GET) $(GFLAGS) -p $< > $*.C
+ $(COMPILE.C) $(OUTPUT_OPTION) $*.C
+.C.i:
+ $(CCC) $(CCFLAGS) $(CPPFLAGS) -P $<
+.C~.i:
+ $(GET) $(GFLAGS) -p $< > $*.C
+ $(CCC) $(CCFLAGS) $(CPPFLAGS) -P $*.C
+.C.a:
+ $(COMPILE.C) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.C~.a:
+ $(GET) $(GFLAGS) -p $< > $*.C
+ $(COMPILE.C) -o $% $*.C
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# FORTRAN section.
+FC=f77
+FFLAGS=
+COMPILE.f=$(FC) $(FFLAGS) -c
+LINK.f=$(FC) $(FFLAGS) $(LDFLAGS)
+COMPILE.F=$(FC) $(FFLAGS) $(CPPFLAGS) -c
+LINK.F=$(FC) $(FFLAGS) $(CPPFLAGS) $(LDFLAGS)
+.f:
+ $(LINK.f) -o $@ $< $(LDLIBS)
+.f~:
+ $(GET) $(GFLAGS) -p $< > $*.f
+ $(FC) $(FFLAGS) $(LDFLAGS) -o $@ $*.f
+.f.o:
+ $(COMPILE.f) $(OUTPUT_OPTION) $<
+.f~.o:
+ $(GET) $(GFLAGS) -p $< > $*.f
+ $(FC) $(FFLAGS) -c $*.f
+.f.a:
+ $(COMPILE.f) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.f~.a:
+ $(GET) $(GFLAGS) -p $< > $*.f
+ $(COMPILE.f) -o $% $*.f
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.for:
+ $(LINK.f) -o $@ $< $(LDLIBS)
+.for~:
+ $(GET) $(GFLAGS) -p $< > $*.for
+ $(FC) $(FFLAGS) $(LDFLAGS) -o $@ $*.for
+.for.o:
+ $(COMPILE.f) $(OUTPUT_OPTION) $<
+.for~.o:
+ $(GET) $(GFLAGS) -p $< > $*.for
+ $(FC) $(FFLAGS) -c $*.for
+.for.a:
+ $(COMPILE.f) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.for~.a:
+ $(GET) $(GFLAGS) -p $< > $*.for
+ $(COMPILE.f) -o $% $*.for
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.F:
+ $(LINK.F) -o $@ $< $(LDLIBS)
+.F~:
+ $(GET) $(GFLAGS) -p $< > $*.F
+ $(FC) $(FFLAGS) $(LDFLAGS) -o $@ $*.F
+.F.o:
+ $(COMPILE.F) $(OUTPUT_OPTION) $<
+.F~.o:
+ $(GET) $(GFLAGS) -p $< > $*.F
+ $(FC) $(FFLAGS) -c $*.F
+.F.a:
+ $(COMPILE.F) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.F~.a:
+ $(GET) $(GFLAGS) -p $< > $*.F
+ $(COMPILE.F) -o $% $*.F
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# FORTRAN section. ratfor.
+RFLAGS=
+COMPILE.r=$(FC) $(FFLAGS) $(RFLAGS) -c
+LINK.r=$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS)
+.r:
+ $(LINK.r) -o $@ $< $(LDLIBS)
+.r~:
+ $(GET) $(GFLAGS) -p $< > $*.r
+ $(LINK.r) -o $@ $*.r $(LDLIBS)
+.r.o:
+ $(COMPILE.r) $(OUTPUT_OPTION) $<
+.r~.o:
+ $(GET) $(GFLAGS) -p $< > $*.r
+ $(COMPILE.r) $(OUTPUT_OPTION) $*.r
+.r.a:
+ $(COMPILE.r) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.r~.a:
+ $(GET) $(GFLAGS) -p $< > $*.r
+ $(COMPILE.r) -o $% $*.r
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# FORTRAN 90 section.
+F90C=f90
+F90FLAGS=
+COMPILE.f90=$(F90C) $(F90FLAGS) -c
+LINK.f90=$(F90C) $(F90FLAGS) $(LDFLAGS)
+COMPILE.ftn=$(F90C) $(F90FLAGS) -c
+LINK.ftn=$(F90C) $(F90FLAGS) $(LDFLAGS)
+.f90:
+ $(LINK.f90) -o $@ $< $(LDLIBS)
+.f90~:
+ $(GET) $(GFLAGS) -p $< > $*.f90
+ $(LINK.f90) -o $@ $*.f90 $(LDLIBS)
+.f90.o:
+ $(COMPILE.f90) $(OUTPUT_OPTION) $<
+.f90~.o:
+ $(GET) $(GFLAGS) -p $< > $*.f90
+ $(COMPILE.f90) $(OUTPUT_OPTION) $*.f90
+.f90.a:
+ $(COMPILE.f90) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.f90~.a:
+ $(GET) $(GFLAGS) -p $< > $*.f90
+ $(COMPILE.f90) -o $% $*.f90
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.ftn:
+ $(LINK.ftn) -o $@ $< $(LDLIBS)
+.ftn~:
+ $(GET) $(GFLAGS) -p $< > $*.ftn
+ $(LINK.ftn) -o $@ $*.ftn $(LDLIBS)
+.ftn.o:
+ $(COMPILE.ftn) $(OUTPUT_OPTION) $<
+.ftn~.o:
+ $(GET) $(GFLAGS) -p $< > $*.ftn
+ $(COMPILE.ftn) $(OUTPUT_OPTION) $*.ftn
+.ftn.a:
+ $(COMPILE.ftn) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.ftn~.a:
+ $(GET) $(GFLAGS) -p $< > $*.ftn
+ $(COMPILE.ftn) -o $% $*.ftn
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# Modula-2 section.
+M2C=m2c
+M2FLAGS=
+MODFLAGS=
+DEFFLAGS=
+COMPILE.def=$(M2C) $(M2FLAGS) $(DEFFLAGS)
+COMPILE.mod=$(M2C) $(M2FLAGS) $(MODFLAGS)
+.def.sym:
+ $(COMPILE.def) -o $@ $<
+.def~.sym:
+ $(GET) $(GFLAGS) -p $< > $*.def
+ $(COMPILE.def) -o $@ $*.def
+.mod:
+ $(COMPILE.mod) -o $@ -e $@ $<
+.mod~:
+ $(GET) $(GFLAGS) -p $< > $*.mod
+ $(COMPILE.mod) -o $@ -e $@ $*.mod
+.mod.o:
+ $(COMPILE.mod) -o $@ $<
+.mod~.o:
+ $(GET) $(GFLAGS) -p $< > $*.mod
+ $(COMPILE.mod) -o $@ $*.mod
+.mod.a:
+ $(COMPILE.mod) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.mod~.a:
+ $(GET) $(GFLAGS) -p $< > $*.mod
+ $(COMPILE.mod) -o $% $*.mod
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# Pascal section.
+PC=pc
+PFLAGS=
+COMPILE.p=$(PC) $(PFLAGS) $(CPPFLAGS) -c
+LINK.p=$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS)
+.p:
+ $(LINK.p) -o $@ $< $(LDLIBS)
+.p~:
+ $(GET) $(GFLAGS) -p $< > $*.p
+ $(LINK.p) -o $@ $*.p $(LDLIBS)
+.p.o:
+ $(COMPILE.p) $(OUTPUT_OPTION) $<
+.p~.o:
+ $(GET) $(GFLAGS) -p $< > $*.p
+ $(COMPILE.p) $(OUTPUT_OPTION) $*.p
+.p.a:
+ $(COMPILE.p) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.p~.a:
+ $(GET) $(GFLAGS) -p $< > $*.p
+ $(COMPILE.p) -o $% $*.p
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# Assembly section.
+AS=as
+ASFLAGS=
+COMPILE.s=$(AS) $(ASFLAGS)
+COMPILE.S=$(CC) $(ASFLAGS) $(CPPFLAGS) -c
+.s.o:
+ $(COMPILE.s) -o $@ $<
+.s~.o:
+ $(GET) $(GFLAGS) -p $< > $*.s
+ $(COMPILE.s) -o $@ $*.s
+.s.a:
+ $(COMPILE.s) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.s~.a:
+ $(GET) $(GFLAGS) -p $< > $*.s
+ $(COMPILE.s) -o $% $*.s
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.S.o:
+ $(COMPILE.S) -o $@ $<
+.S~.o:
+ $(GET) $(GFLAGS) -p $< > $*.S
+ $(COMPILE.S) -o $@ $*.S
+.S.a:
+ $(COMPILE.S) -o $% $<
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+.S~.a:
+ $(GET) $(GFLAGS) -p $< > $*.S
+ $(COMPILE.S) -o $% $*.S
+ $(AR) $(ARFLAGS) $@ $%
+ $(RM) $%
+
+# Shell section.
+.sh:
+ $(RM) $@
+ cat $< > $@
+ chmod +x $@
+.sh~:
+ $(GET) $(GFLAGS) -p $< > $*.sh
+ cp $*.sh $@
+ chmod a+x $@
+
+# NeWS section
+CPS=cps
+CPSFLAGS=
+.cps.h:
+ $(CPS) $(CPSFLAGS) $*.cps
+.cps~.h:
+ $(GET) $(GFLAGS) -p $< > $*.cps
+ $(CPS) $(CPSFLAGS) $*.cps
+
+# JAVA section
+JAVAC=javac
+JAVACFLAGS=
+.java.class:
+ $(JAVAC) $(JAVACFLAGS) $<
+.java~.class:
+ $(GET) $(GFLAGS) -p $< > $*.java
+ $(JAVAC) $(JAVACFLAGS) $<
+
+# Miscellaneous section.
+LD=ld
+LDFLAGS=
+LDLIBS=
+MAKE=make
+RM=rm -f
+AR=ar
+ARFLAGS=rv
+GET=get
+GFLAGS=
+
+markfile.o: markfile
+ echo "static char _sccsid[] = \"`grep @'(#)' markfile`\";" > markfile.c
+ cc -c markfile.c
+ $(RM) markfile.c
+
+SCCSFLAGS=
+SCCSGETFLAGS=-s
+.SCCS_GET:
+ sccs $(SCCSFLAGS) get $(SCCSGETFLAGS) $@ -G$@
+
+.SCCS_GET_POSIX:
+ sccs $(SCCSFLAGS) get $(SCCSGETFLAGS) $@
+
+.GET_POSIX:
+ $(GET) $(GFLAGS) s.$@
diff --git a/usr/src/make_src/Make/bin/make/common/misc.cc b/usr/src/make_src/Make/bin/make/common/misc.cc
new file mode 100644
index 0000000..d718de0
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/misc.cc
@@ -0,0 +1,1007 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)misc.cc 1.50 06/12/12
+ */
+
+#pragma ident "@(#)misc.cc 1.34 95/10/04"
+
+/*
+ * misc.cc
+ *
+ * This file contains various unclassified routines. Some main groups:
+ * getname
+ * Memory allocation
+ * String handling
+ * Property handling
+ * Error message handling
+ * Make internal state dumping
+ * main routine support
+ */
+
+/*
+ * Included files
+ */
+#include <errno.h>
+#include <mk/defs.h>
+#include <mksh/macro.h> /* SETVAR() */
+#include <mksh/misc.h> /* enable_interrupt() */
+#include <stdarg.h> /* va_list, va_start(), va_end() */
+#include <vroot/report.h> /* SUNPRO_DEPENDENCIES */
+
+#if defined(HP_UX) || defined(linux)
+#include <unistd.h>
+#endif
+
+#ifdef TEAMWARE_MAKE_CMN
+#define MAXJOBS_ADJUST_RFE4694000
+
+#ifdef MAXJOBS_ADJUST_RFE4694000
+extern void job_adjust_fini();
+#endif /* MAXJOBS_ADJUST_RFE4694000 */
+#endif /* TEAMWARE_MAKE_CMN */
+
+#if defined(linux)
+#include <time.h> /* localtime() */
+#endif
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+static void print_rule(register Name target);
+static void print_target_n_deps(register Name target);
+
+/*****************************************
+ *
+ * getname
+ */
+
+/*****************************************
+ *
+ * Memory allocation
+ */
+
+/*
+ * free_chain()
+ *
+ * frees a chain of Name_vector's
+ *
+ * Parameters:
+ * ptr Pointer to the first element in the chain
+ * to be freed.
+ *
+ * Global variables used:
+ */
+void
+free_chain(Name_vector ptr)
+{
+ if (ptr != NULL) {
+ if (ptr->next != NULL) {
+ free_chain(ptr->next);
+ }
+ free((char *) ptr);
+ }
+}
+
+/*****************************************
+ *
+ * String manipulation
+ */
+
+/*****************************************
+ *
+ * Nameblock property handling
+ */
+
+/*****************************************
+ *
+ * Error message handling
+ */
+
+/*
+ * fatal(format, args...)
+ *
+ * Print a message and die
+ *
+ * Parameters:
+ * format printf type format string
+ * args Arguments to match the format
+ *
+ * Global variables used:
+ * fatal_in_progress Indicates if this is a recursive call
+ * parallel_process_cnt Do we need to wait for anything?
+ * report_pwd Should we report the current path?
+ */
+/*VARARGS*/
+void
+fatal(char * message, ...)
+{
+ va_list args;
+
+ va_start(args, message);
+ (void) fflush(stdout);
+#ifdef DISTRIBUTED
+ (void) fprintf(stderr, catgets(catd, 1, 262, "dmake: Fatal error: "));
+#else
+ (void) fprintf(stderr, catgets(catd, 1, 263, "make: Fatal error: "));
+#endif
+ (void) vfprintf(stderr, message, args);
+ (void) fprintf(stderr, "\n");
+ va_end(args);
+ if (report_pwd) {
+ (void) fprintf(stderr,
+ catgets(catd, 1, 156, "Current working directory %s\n"),
+ get_current_path());
+ }
+ (void) fflush(stderr);
+ if (fatal_in_progress) {
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ exit_status = 1;
+#endif
+ exit(1);
+ }
+ fatal_in_progress = true;
+#ifdef TEAMWARE_MAKE_CMN
+ /* Let all parallel children finish */
+ if ((dmake_mode_type == parallel_mode) &&
+ (parallel_process_cnt > 0)) {
+ (void) fprintf(stderr,
+ catgets(catd, 1, 157, "Waiting for %d %s to finish\n"),
+ parallel_process_cnt,
+ parallel_process_cnt == 1 ?
+ catgets(catd, 1, 158, "job") : catgets(catd, 1, 159, "jobs"));
+ (void) fflush(stderr);
+ }
+
+ while (parallel_process_cnt > 0) {
+#ifdef DISTRIBUTED
+ if (dmake_mode_type == distributed_mode) {
+ (void) await_dist(false);
+ } else {
+ await_parallel(true);
+ }
+#else
+ await_parallel(true);
+#endif
+ finish_children(false);
+ }
+#endif
+
+#if defined (TEAMWARE_MAKE_CMN) && defined (MAXJOBS_ADJUST_RFE4694000)
+ job_adjust_fini();
+#endif
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ exit_status = 1;
+#endif
+ exit(1);
+}
+
+/*
+ * warning(format, args...)
+ *
+ * Print a message and continue.
+ *
+ * Parameters:
+ * format printf type format string
+ * args Arguments to match the format
+ *
+ * Global variables used:
+ * report_pwd Should we report the current path?
+ */
+/*VARARGS*/
+void
+warning(char * message, ...)
+{
+ va_list args;
+
+ va_start(args, message);
+ (void) fflush(stdout);
+#ifdef DISTRIBUTED
+ (void) fprintf(stderr, catgets(catd, 1, 264, "dmake: Warning: "));
+#else
+ (void) fprintf(stderr, catgets(catd, 1, 265, "make: Warning: "));
+#endif
+ (void) vfprintf(stderr, message, args);
+ (void) fprintf(stderr, "\n");
+ va_end(args);
+ if (report_pwd) {
+ (void) fprintf(stderr,
+ catgets(catd, 1, 161, "Current working directory %s\n"),
+ get_current_path());
+ }
+ (void) fflush(stderr);
+}
+
+/*
+ * time_to_string(time)
+ *
+ * Take a numeric time value and produce
+ * a proper string representation.
+ *
+ * Return value:
+ * The string representation of the time
+ *
+ * Parameters:
+ * time The time we need to translate
+ *
+ * Global variables used:
+ */
+char *
+time_to_string(const timestruc_t &time)
+{
+ struct tm *tm;
+ char buf[128];
+
+ if (time == file_doesnt_exist) {
+ return catgets(catd, 1, 163, "File does not exist");
+ }
+ if (time == file_max_time) {
+ return catgets(catd, 1, 164, "Younger than any file");
+ }
+ tm = localtime(&time.tv_sec);
+ strftime(buf, sizeof (buf), NOCATGETS("%c %Z"), tm);
+ buf[127] = (int) nul_char;
+ return strdup(buf);
+}
+
+/*
+ * get_current_path()
+ *
+ * Stuff current_path with the current path if it isnt there already.
+ *
+ * Parameters:
+ *
+ * Global variables used:
+ */
+char *
+get_current_path(void)
+{
+ char pwd[(MAXPATHLEN * MB_LEN_MAX)];
+ static char *current_path;
+
+ if (current_path == NULL) {
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ getcwd(pwd, sizeof(pwd));
+#else
+ (void) getwd(pwd);
+#endif
+ if (pwd[0] == (int) nul_char) {
+ pwd[0] = (int) slash_char;
+ pwd[1] = (int) nul_char;
+#ifdef DISTRIBUTED
+ current_path = strdup(pwd);
+ } else if (IS_EQUALN(pwd, NOCATGETS("/tmp_mnt"), 8)) {
+ current_path = strdup(pwd + 8);
+ } else {
+ current_path = strdup(pwd);
+ }
+#else
+ }
+ current_path = strdup(pwd);
+#endif
+ }
+ return current_path;
+}
+
+/*****************************************
+ *
+ * Make internal state dumping
+ *
+ * This is a set of routines for dumping the internal make state
+ * Used for the -p option
+ */
+
+/*
+ * dump_make_state()
+ *
+ * Dump make's internal state to stdout
+ *
+ * Parameters:
+ *
+ * Global variables used:
+ * svr4 Was ".SVR4" seen in makefile?
+ * svr4_name The Name ".SVR4", printed
+ * posix Was ".POSIX" seen in makefile?
+ * posix_name The Name ".POSIX", printed
+ * default_rule Points to the .DEFAULT rule
+ * default_rule_name The Name ".DEFAULT", printed
+ * default_target_to_build The first target to print
+ * dot_keep_state The Name ".KEEP_STATE", printed
+ * dot_keep_state_file The Name ".KEEP_STATE_FILE", printed
+ * hashtab The make hash table for Name blocks
+ * ignore_errors Was ".IGNORE" seen in makefile?
+ * ignore_name The Name ".IGNORE", printed
+ * keep_state Was ".KEEP_STATE" seen in makefile?
+ * percent_list The list of % rules
+ * precious The Name ".PRECIOUS", printed
+ * sccs_get_name The Name ".SCCS_GET", printed
+ * sccs_get_posix_name The Name ".SCCS_GET_POSIX", printed
+ * get_name The Name ".GET", printed
+ * get_posix_name The Name ".GET_POSIX", printed
+ * sccs_get_rule Points to the ".SCCS_GET" rule
+ * silent Was ".SILENT" seen in makefile?
+ * silent_name The Name ".SILENT", printed
+ * suffixes The suffix list from ".SUFFIXES"
+ * suffixes_name The Name ".SUFFIX", printed
+ */
+void
+dump_make_state(void)
+{
+ Name_set::iterator p, e;
+ register Property prop;
+ register Dependency dep;
+ register Cmd_line rule;
+ Percent percent, percent_depe;
+
+ /* Default target */
+ if (default_target_to_build != NULL) {
+ print_rule(default_target_to_build);
+ }
+ (void) printf("\n");
+
+ /* .POSIX */
+ if (posix) {
+ (void) printf("%s:\n", posix_name->string_mb);
+ }
+
+ /* .DEFAULT */
+ if (default_rule != NULL) {
+ (void) printf("%s:\n", default_rule_name->string_mb);
+ for (rule = default_rule; rule != NULL; rule = rule->next) {
+ (void) printf("\t%s\n", rule->command_line->string_mb);
+ }
+ }
+
+ /* .IGNORE */
+ if (ignore_errors) {
+ (void) printf("%s:\n", ignore_name->string_mb);
+ }
+
+ /* .KEEP_STATE: */
+ if (keep_state) {
+ (void) printf("%s:\n\n", dot_keep_state->string_mb);
+ }
+
+ /* .PRECIOUS */
+ (void) printf("%s:", precious->string_mb);
+ for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
+ if ((p->stat.is_precious) || (all_precious)) {
+ (void) printf(" %s", p->string_mb);
+ }
+ }
+ (void) printf("\n");
+
+ /* .SCCS_GET */
+ if (sccs_get_rule != NULL) {
+ (void) printf("%s:\n", sccs_get_name->string_mb);
+ for (rule = sccs_get_rule; rule != NULL; rule = rule->next) {
+ (void) printf("\t%s\n", rule->command_line->string_mb);
+ }
+ }
+
+ /* .SILENT */
+ if (silent) {
+ (void) printf("%s:\n", silent_name->string_mb);
+ }
+
+ /* .SUFFIXES: */
+ (void) printf("%s:", suffixes_name->string_mb);
+ for (dep = suffixes; dep != NULL; dep = dep->next) {
+ (void) printf(" %s", dep->name->string_mb);
+ build_suffix_list(dep->name);
+ }
+ (void) printf("\n\n");
+
+ /* % rules */
+ for (percent = percent_list;
+ percent != NULL;
+ percent = percent->next) {
+ (void) printf("%s:",
+ percent->name->string_mb);
+
+ for (percent_depe = percent->dependencies;
+ percent_depe != NULL;
+ percent_depe = percent_depe->next) {
+ (void) printf(" %s", percent_depe->name->string_mb);
+ }
+
+ (void) printf("\n");
+
+ for (rule = percent->command_template;
+ rule != NULL;
+ rule = rule->next) {
+ (void) printf("\t%s\n", rule->command_line->string_mb);
+ }
+ }
+
+ /* Suffix rules */
+ for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
+ Wstring wcb(p);
+ if (wcb.get_string()[0] == (int) period_char) {
+ print_rule(p);
+ }
+ }
+
+ /* Macro assignments */
+ for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
+ if (((prop = get_prop(p->prop, macro_prop)) != NULL) &&
+ (prop->body.macro.value != NULL)) {
+ (void) printf("%s", p->string_mb);
+ print_value(prop->body.macro.value,
+ (Daemon) prop->body.macro.daemon);
+ }
+ }
+ (void) printf("\n");
+
+ /* Conditional macro assignments */
+ for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
+ for (prop = get_prop(p->prop, conditional_prop);
+ prop != NULL;
+ prop = get_prop(prop->next, conditional_prop)) {
+ (void) printf("%s := %s",
+ p->string_mb,
+ prop->body.conditional.name->
+ string_mb);
+ if (prop->body.conditional.append) {
+ printf(" +");
+ }
+ else {
+ printf(" ");
+ }
+ print_value(prop->body.conditional.value,
+ no_daemon);
+ }
+ }
+ (void) printf("\n");
+
+ /* All other dependencies */
+ for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
+ if (p->colons != no_colon) {
+ print_rule(p);
+ }
+ }
+ (void) printf("\n");
+}
+
+/*
+ * print_rule(target)
+ *
+ * Print the rule for one target
+ *
+ * Parameters:
+ * target Target we print rule for
+ *
+ * Global variables used:
+ */
+static void
+print_rule(register Name target)
+{
+ register Cmd_line rule;
+ register Property line;
+ register Dependency dependency;
+
+ if (target->dependency_printed ||
+ ((line = get_prop(target->prop, line_prop)) == NULL) ||
+ ((line->body.line.command_template == NULL) &&
+ (line->body.line.dependencies == NULL))) {
+ return;
+ }
+ target->dependency_printed = true;
+
+ (void) printf("%s:", target->string_mb);
+
+ for (dependency = line->body.line.dependencies;
+ dependency != NULL;
+ dependency = dependency->next) {
+ (void) printf(" %s", dependency->name->string_mb);
+ }
+
+ (void) printf("\n");
+
+ for (rule = line->body.line.command_template;
+ rule != NULL;
+ rule = rule->next) {
+ (void) printf("\t%s\n", rule->command_line->string_mb);
+ }
+}
+
+void
+dump_target_list(void)
+{
+ Name_set::iterator p, e;
+ Wstring str;
+
+ for (p = hashtab.begin(), e = hashtab.end(); p != e; p++) {
+ str.init(p);
+ wchar_t * wcb = str.get_string();
+ if ((p->colons != no_colon) &&
+ ((wcb[0] != (int) period_char) ||
+ ((wcb[0] == (int) period_char) &&
+ (wschr(wcb, (int) slash_char))))) {
+ print_target_n_deps(p);
+ }
+ }
+}
+
+static void
+print_target_n_deps(register Name target)
+{
+ register Cmd_line rule;
+ register Property line;
+ register Dependency dependency;
+
+ if (target->dependency_printed) {
+ return;
+ }
+ target->dependency_printed = true;
+
+ (void) printf("%s\n", target->string_mb);
+
+ if ((line = get_prop(target->prop, line_prop)) == NULL) {
+ return;
+ }
+ for (dependency = line->body.line.dependencies;
+ dependency != NULL;
+ dependency = dependency->next) {
+ if (!dependency->automatic) {
+ print_target_n_deps(dependency->name);
+ }
+ }
+}
+
+/*****************************************
+ *
+ * main() support
+ */
+
+/*
+ * load_cached_names()
+ *
+ * Load the vector of cached names
+ *
+ * Parameters:
+ *
+ * Global variables used:
+ * Many many pointers to Name blocks.
+ */
+void
+load_cached_names(void)
+{
+ char *cp;
+ Name dollar;
+
+ /* Load the cached_names struct */
+ MBSTOWCS(wcs_buffer, NOCATGETS(".BUILT_LAST_MAKE_RUN"));
+ built_last_make_run = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("@"));
+ c_at = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(" *conditionals* "));
+ conditionals = GETNAME(wcs_buffer, FIND_LENGTH);
+ /*
+ * A version of make was released with NSE 1.0 that used
+ * VERSION-1.1 but this version is identical to VERSION-1.0.
+ * The version mismatch code makes a special case for this
+ * situation. If the version number is changed from 1.0
+ * it should go to 1.2.
+ */
+ MBSTOWCS(wcs_buffer, NOCATGETS("VERSION-1.0"));
+ current_make_version = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".SVR4"));
+ svr4_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".POSIX"));
+ posix_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".DEFAULT"));
+ default_rule_name = GETNAME(wcs_buffer, FIND_LENGTH);
+#ifdef NSE
+ MBSTOWCS(wcs_buffer, NOCATGETS(".DERIVED_SRC"));
+ derived_src= GETNAME(wcs_buffer, FIND_LENGTH);
+#endif
+ MBSTOWCS(wcs_buffer, NOCATGETS("$"));
+ dollar = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".DONE"));
+ done = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("."));
+ dot = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".KEEP_STATE"));
+ dot_keep_state = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".KEEP_STATE_FILE"));
+ dot_keep_state_file = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(""));
+ empty_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(" FORCE"));
+ force = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("HOST_ARCH"));
+ host_arch = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("HOST_MACH"));
+ host_mach = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".IGNORE"));
+ ignore_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".INIT"));
+ init = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".LOCAL"));
+ localhost_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".make.state"));
+ make_state = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("MAKEFLAGS"));
+ makeflags = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".MAKE_VERSION"));
+ make_version = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".NO_PARALLEL"));
+ no_parallel_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".NOT_AUTO"));
+ not_auto = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".PARALLEL"));
+ parallel_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("PATH"));
+ path_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("+"));
+ plus = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".PRECIOUS"));
+ precious = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("?"));
+ query = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("^"));
+ hat = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".RECURSIVE"));
+ recursive_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".SCCS_GET"));
+ sccs_get_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".SCCS_GET_POSIX"));
+ sccs_get_posix_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".GET"));
+ get_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".GET_POSIX"));
+ get_posix_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("SHELL"));
+ shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".SILENT"));
+ silent_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".SUFFIXES"));
+ suffixes_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, SUNPRO_DEPENDENCIES);
+ sunpro_dependencies = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("TARGET_ARCH"));
+ target_arch = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("TARGET_MACH"));
+ target_mach = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("VIRTUAL_ROOT"));
+ virtual_root = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("VPATH"));
+ vpath_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS(".WAIT"));
+ wait_name = GETNAME(wcs_buffer, FIND_LENGTH);
+
+ wait_name->state = build_ok;
+
+ /* Mark special targets so that the reader treats them properly */
+ svr4_name->special_reader = svr4_special;
+ posix_name->special_reader = posix_special;
+ built_last_make_run->special_reader = built_last_make_run_special;
+ default_rule_name->special_reader = default_special;
+#ifdef NSE
+ derived_src->special_reader= derived_src_special;
+#endif
+ dot_keep_state->special_reader = keep_state_special;
+ dot_keep_state_file->special_reader = keep_state_file_special;
+ ignore_name->special_reader = ignore_special;
+ make_version->special_reader = make_version_special;
+ no_parallel_name->special_reader = no_parallel_special;
+ parallel_name->special_reader = parallel_special;
+ localhost_name->special_reader = localhost_special;
+ precious->special_reader = precious_special;
+ sccs_get_name->special_reader = sccs_get_special;
+ sccs_get_posix_name->special_reader = sccs_get_posix_special;
+ get_name->special_reader = get_special;
+ get_posix_name->special_reader = get_posix_special;
+ silent_name->special_reader = silent_special;
+ suffixes_name->special_reader = suffixes_special;
+
+ /* The value of $$ is $ */
+ (void) SETVAR(dollar, dollar, false);
+ dollar->dollar = false;
+
+ /* Set the value of $(SHELL) */
+ #ifdef HP_UX
+ MBSTOWCS(wcs_buffer, NOCATGETS("/bin/posix/sh"));
+ #else
+ #if defined(SUN5_0)
+ if (posix) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("/usr/xpg4/bin/sh"));
+ } else {
+ MBSTOWCS(wcs_buffer, NOCATGETS("/bin/sh"));
+ }
+ #else /* ^SUN5_0 */
+ MBSTOWCS(wcs_buffer, NOCATGETS("/bin/sh"));
+ #endif /* ^SUN5_0 */
+ #endif
+ (void) SETVAR(shell_name, GETNAME(wcs_buffer, FIND_LENGTH), false);
+
+ /*
+ * Use " FORCE" to simulate a FRC dependency for :: type
+ * targets with no dependencies.
+ */
+ (void) append_prop(force, line_prop);
+ force->stat.time = file_max_time;
+
+ /* Make sure VPATH is defined before current dir is read */
+ if ((cp = getenv(vpath_name->string_mb)) != NULL) {
+ MBSTOWCS(wcs_buffer, cp);
+ (void) SETVAR(vpath_name,
+ GETNAME(wcs_buffer, FIND_LENGTH),
+ false);
+ }
+
+ /* Check if there is NO PATH variable. If not we construct one. */
+ if (getenv(path_name->string_mb) == NULL) {
+ vroot_path = NULL;
+ add_dir_to_path(NOCATGETS("."), &vroot_path, -1);
+ add_dir_to_path(NOCATGETS("/bin"), &vroot_path, -1);
+ add_dir_to_path(NOCATGETS("/usr/bin"), &vroot_path, -1);
+ }
+}
+
+/*
+ * iterate on list of conditional macros in np, and place them in
+ * a String_rec starting with, and separated by the '$' character.
+ */
+void
+cond_macros_into_string(Name np, String_rec *buffer)
+{
+ Macro_list macro_list;
+
+ /*
+ * Put the version number at the start of the string
+ */
+ MBSTOWCS(wcs_buffer, DEPINFO_FMT_VERSION);
+ append_string(wcs_buffer, buffer, FIND_LENGTH);
+ /*
+ * Add the rest of the conditional macros to the buffer
+ */
+ if (np->depends_on_conditional){
+ for (macro_list = np->conditional_macro_list;
+ macro_list != NULL; macro_list = macro_list->next){
+ append_string(macro_list->macro_name, buffer,
+ FIND_LENGTH);
+ append_char((int) equal_char, buffer);
+ append_string(macro_list->value, buffer, FIND_LENGTH);
+ append_char((int) dollar_char, buffer);
+ }
+ }
+}
+/*
+ * Copyright (c) 1987-1992 Sun Microsystems, Inc. All Rights Reserved.
+ * Sun considers its source code as an unpublished, proprietary
+ * trade secret, and it is available only under strict license
+ * provisions. This copyright notice is placed here only to protect
+ * Sun in the event the source is deemed a published work. Dissassembly,
+ * decompilation, or other means of reducing the object code to human
+ * readable form is prohibited by the license agreement under which
+ * this code is provided to the user or company in possession of this
+ * copy.
+ * RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the
+ * Government is subject to restrictions as set forth in subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 52.227-7013 and in similar clauses in the FAR and
+ * NASA FAR Supplement.
+ *
+ * 1.3 91/09/30
+ */
+
+
+/* Some includes are commented because of the includes at the beginning */
+/* #include <signal.h> */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+/* #include <string.h> */
+#include <unistd.h>
+#include <stdlib.h>
+/* #include <stdio.h> */
+/* #include <avo/find_dir.h> */
+/* #ifndef TEAMWARE_MAKE_CMN
+#include <avo/find_dir.h>
+#endif */
+
+/* Routines to find the base directory name from which the various components
+ * -executables, *crt* libraries etc will be accessed
+ */
+
+/* This routine checks to see if a given filename is an executable or not.
+ Logically similar to the csh statement : if ( -x $i && ! -d $i )
+ */
+
+static int
+check_if_exec(char *file)
+{
+ struct stat stb;
+ if (stat(file, &stb) < 0) {
+ return ( -1);
+ }
+ if (S_ISDIR(stb.st_mode)) {
+ return (-1);
+ }
+ if (!(stb.st_mode & S_IEXEC)) {
+ return ( -1);
+ }
+ return (0);
+}
+
+/* resolve - check for specified file in specified directory
+ * sets up dir, following symlinks.
+ * returns zero for success, or
+ * -1 for error (with errno set properly)
+ */
+static int
+resolve (char *indir, /* search directory */
+ char *cmd, /* search for name */
+ char *dir, /* directory buffer */
+ char **run) /* resultion name ptr ptr */
+{
+ char *p;
+ int rv = -1;
+ int sll;
+ char symlink[MAXPATHLEN + 1];
+
+ do {
+ errno = ENAMETOOLONG;
+ if ((strlen (indir) + strlen (cmd) + 2) > (size_t) MAXPATHLEN)
+ break;
+
+ sprintf(dir, "%s/%s", indir, cmd);
+ if (check_if_exec(dir) != 0) /* check if dir is an executable */
+ {
+ break; /* Not an executable program */
+ }
+
+ /* follow symbolic links */
+ while ((sll = readlink (dir, symlink, MAXPATHLEN)) >= 0) {
+ symlink[sll] = 0;
+ if (*symlink == '/')
+ strcpy (dir, symlink);
+ else
+ sprintf (strrchr (dir, '/'), "/%s", symlink);
+ }
+ if (errno != EINVAL)
+ break;
+
+ p = strrchr (dir, '/');
+ *p++ = 0;
+ if (run) /* user wants resolution name */
+ *run = p;
+ rv = 0; /* complete, with success! */
+
+ } while (0);
+
+ return rv;
+}
+
+/*
+ *find_run_directory - find executable file in PATH
+ *
+ * PARAMETERS:
+ * cmd filename as typed by user (argv[0])
+ * cwd buffer from which is read the working directory
+ * if first character is '/' or into which is
+ * copied working directory name otherwise
+ * dir buffer into which is copied program's directory
+ * pgm where to return pointer to tail of cmd (may be NULL
+ * if not wanted)
+ * run where to return pointer to tail of final resolved
+ * name ( dir/run is the program) (may be NULL
+ * if not wanted)
+ * path user's path from environment
+ *
+ * Note: run and pgm will agree except when symbolic links have
+ * renamed files
+ *
+ * RETURNS:
+ * returns zero for success,
+ * -1 for error (with errno set properly).
+ *
+ * EXAMPLE:
+ * find_run_directory (argv[0], ".", &charray1, (char **) 0, (char **) 0,
+ * getenv(NOGETTEXT("PATH")));
+ */
+extern int
+find_run_directory (char *cmd,
+ char *cwd,
+ char *dir,
+ char **pgm,
+ char **run,
+ char *path)
+{
+ int rv = 0;
+ char *f, *s;
+ int i;
+ char tmp_path[MAXPATHLEN];
+
+ if (!cmd || !*cmd || !cwd || !dir) {
+ errno = EINVAL; /* stupid arguments! */
+ return -1;
+ }
+
+ if (*cwd != '/')
+ if (!(getcwd (cwd, MAXPATHLEN)))
+ return -1; /* can not get working directory */
+
+ f = strrchr (cmd, '/');
+ if (pgm) /* user wants program name */
+ *pgm = f ? f + 1 : cmd;
+
+ /* get program directory */
+ rv = -1;
+ if (*cmd == '/') /* absname given */
+ rv = resolve ("", cmd + 1, dir, run);
+ else if (f) /* relname given */
+ rv = resolve (cwd, cmd, dir, run);
+ else { /* from searchpath */
+ if (!path || !*path) { /* if missing or null path */
+ tmp_path[0] = '.'; /* assume sanity */
+ tmp_path[1] = '\0';
+ } else {
+ strcpy(tmp_path, path);
+ }
+ f = tmp_path;
+ rv = -1;
+ errno = ENOENT; /* errno gets this if path empty */
+ while (*f && (rv < 0)) {
+ s = f;
+ while (*f && (*f != ':'))
+ ++f;
+ if (*f)
+ *f++ = 0;
+ if (*s == '/')
+ rv = resolve (s, cmd, dir, run);
+ else {
+ char abuf[MAXPATHLEN];
+
+ sprintf (abuf, "%s/%s", cwd, s);
+ rv = resolve (abuf, cmd, dir, run);
+ }
+ }
+ }
+
+ /* Remove any trailing /. */
+ i = strlen(dir);
+ if ( dir[i-2] == '/' && dir[i-1] == '.') {
+ dir[i-2] = '\0';
+ }
+
+ return rv;
+}
+
diff --git a/usr/src/make_src/Make/bin/make/common/nse.cc b/usr/src/make_src/Make/bin/make/common/nse.cc
new file mode 100644
index 0000000..4cc75e4
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/nse.cc
@@ -0,0 +1,610 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1994 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)nse.cc 1.15 06/12/12
+ */
+
+#pragma ident "@(#)nse.cc 1.15 06/12/12"
+
+#ifdef NSE
+
+/*
+ * Included files
+ */
+#include <mk/defs.h>
+#include <mksh/macro.h> /* expand_value() */
+#include <mksh/misc.h> /* get_prop() */
+
+/*
+ * This file does some extra checking on behalf of the NSE.
+ * It does some stuff that is analogous to lint in that it
+ * looks for things which may be legal but that give the NSE
+ * trouble. Currently it looks for:
+ * 1) recursion by cd'ing to a directory specified by a
+ * make variable that is defined from the shell environment.
+ * 2) recursion by cd'ing to a directory specified by a
+ * make variable that has backquotes in it.
+ * 3) recursion to another makefile in the same directory.
+ * 4) a dependency upon an SCCS file (SCCS/s.*)
+ * 5) backquotes in a file name
+ * 6) a make variable being defined on the command-line that
+ * ends up affecting dependencies
+ * 7) wildcards (*[) in dependencies
+ * 8) recursion to the same directory
+ * 9) potential source files on the left-hand-side so
+ * that they appear as derived files
+ *
+ * Things it should look for:
+ * 1) makefiles that are symlinks (why are these a problem?)
+ */
+
+#define TARG_SUFX "/usr/nse/lib/nse_targ.sufx"
+
+typedef struct _Nse_suffix *Nse_suffix, Nse_suffix_rec;
+struct _Nse_suffix {
+ wchar_t *suffix; /* The suffix */
+ struct _Nse_suffix *next; /* Linked list */
+};
+static Nse_suffix sufx_hdr;
+static int our_exit_status;
+
+static void nse_warning(void);
+static Boolean nse_gettoken(wchar_t **, wchar_t *);
+
+/*
+ * Given a command that has just recursed to a sub make
+ * try to determine if it cd'ed to a directory that was
+ * defined by a make variable imported from the shell
+ * environment or a variable with backquotes in it.
+ * This routine will find something like:
+ * cd $(DIR); $(MAKE)
+ * where DIR is imported from the shell environment.
+ * However it well not find:
+ * CD = cd
+ * $(CD) $(DIR); $(MAKE)
+ * or
+ * CD = cd $(DIR)
+ * $(CD); $(MAKE)
+ *
+ * This routine also checks for recursion to the same
+ * directory.
+ */
+void
+nse_check_cd(Property prop)
+{
+ wchar_t tok[512];
+ wchar_t *p;
+ wchar_t *our_template;
+ int len;
+ Boolean cd;
+#ifdef SUNOS4_AND_AFTER
+ String_rec string;
+#else
+ String string;
+#endif
+ Name name;
+ Name target;
+ struct Line *line;
+ struct Recursive *r;
+ Property recurse;
+ wchar_t strbuf[STRING_BUFFER_LENGTH];
+ wchar_t tmpbuf[STRING_BUFFER_LENGTH];
+
+#ifdef LTEST
+ printf("In nse_check_cd, nse = %d, nse_did_recursion = %d\n", nse, nse_did_recursion);
+#endif
+#ifdef SUNOS4_AND_AFTER
+ if (!nse_did_recursion || !nse) {
+#else
+ if (is_false(nse_did_recursion) || is_false(flag.nse)) {
+#endif
+#ifdef LTEST
+ printf ("returning, nse = %d, nse_did_recursion = %d\n", nse, nse_did_recursion);
+#endif
+ return;
+ }
+ line = &prop->body.line;
+#ifdef LTEST
+ printf("string = %s\n", line->command_template->command_line->string_mb);
+#endif
+
+ wscpy(tmpbuf, line->command_template->command_line->string);
+ our_template = tmpbuf;
+ cd = false;
+ while (nse_gettoken(&our_template, tok)) {
+#ifdef LTEST
+ printf("in gettoken loop\n");
+#endif
+#ifdef SUNOS4_AND_AFTER
+ if (IS_WEQUAL(tok, (wchar_t *) "cd")) {
+#else
+ if (is_equal(tok, "cd")) {
+#endif
+ cd = true;
+ } else if (cd && tok[0] == '$') {
+ nse_backquote_seen = NULL;
+ nse_shell_var_used = NULL;
+ nse_watch_vars = true;
+#ifdef SUNOS4_AND_AFTER
+ INIT_STRING_FROM_STACK(string, strbuf);
+ name = GETNAME(tok, FIND_LENGTH);
+#else
+ init_string_from_stack(string, strbuf);
+ name = getname(tok, FIND_LENGTH);
+#endif
+ expand_value(name, &string, false);
+ nse_watch_vars = false;
+
+#ifdef LTEST
+ printf("cd = %d, tok = $\n", cd);
+#endif
+ /*
+ * Try to trim tok to just
+ * the variable.
+ */
+ if (nse_shell_var_used != NULL) {
+ nse_warning();
+ fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tdefined by the shell environment variable %s\n\tCommand line: %s\n",
+ nse_shell_var_used->string_mb,
+ line->command_template->command_line->string_mb);
+ }
+ if (nse_backquote_seen != NULL) {
+ nse_warning();
+ fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tdefined by a variable (%s) with backquotes in it\n\tCommand line: %s\n",
+ nse_backquote_seen->string_mb,
+ line->command_template->command_line->string_mb);
+ }
+ cd = false;
+ } else if (cd && nse_backquotes(tok)) {
+ nse_warning();
+ fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tspecified by a command in backquotes\n\tCommand line: %s\n",
+ line->command_template->command_line->string_mb);
+ cd = false;
+ } else {
+ cd = false;
+ }
+ }
+
+ /*
+ * Now check for recursion to ".".
+ */
+ if (primary_makefile != NULL) {
+ target = prop->body.line.target;
+ recurse = get_prop(target->prop, recursive_prop);
+ while (recurse != NULL) {
+ r = &recurse->body.recursive;
+#ifdef SUNOS4_AND_AFTER
+ if (IS_WEQUAL(r->directory->string, (wchar_t *) ".") &&
+ !IS_WEQUAL(r->makefiles->name->string,
+ primary_makefile->string)) {
+#else
+ if (is_equal(r->directory->string, ".") &&
+ !is_equal(r->makefiles->name->string,
+ primary_makefile->string)) {
+#endif
+ nse_warning();
+ fprintf(stderr, "\tRecursion to makefile `%s' in the same directory\n\tCommand line: %s\n",
+ r->makefiles->name->string_mb,
+ line->command_template->command_line->string_mb);
+ }
+ recurse = get_prop(recurse->next, recursive_prop);
+ }
+ }
+}
+
+/*
+ * Print an NSE make warning line.
+ * If the -P flag was given then consider this a fatal
+ * error, otherwise, just a warning.
+ */
+static void
+nse_warning(void)
+{
+#ifdef SUNOS4_AND_AFTER
+ if (report_dependencies_level > 0) {
+#else
+ if (is_true(flag.report_dependencies)) {
+#endif
+ our_exit_status = 1;
+ }
+ if (primary_makefile != NULL) {
+ fprintf(stderr, "make: NSE warning from makefile %s/%s:\n",
+ get_current_path(), primary_makefile->string_mb);
+ } else {
+ fprintf(stderr, "make: NSE warning from directory %s:\n",
+ get_current_path());
+ }
+}
+
+/*
+ * Get the next whitespace delimited token pointed to by *cp.
+ * Return it in tok.
+ */
+static Boolean
+nse_gettoken(wchar_t **cp, wchar_t *tok)
+{
+ wchar_t *to;
+ wchar_t *p;
+
+ p = *cp;
+ while (*p && iswspace(*p)) {
+ p++;
+ }
+ if (*p == '\0') {
+ return false;
+ }
+ to = tok;
+ while (*p && !iswspace(*p)) {
+ *to++ = *p++;
+ }
+ if (*p == '\0') {
+ return false;
+ }
+ *to = '\0';
+ *cp = p;
+ return true;
+}
+
+/*
+ * Given a dependency and a target, see if the dependency
+ * is an SCCS file. Check for the last component of its name
+ * beginning with "s." and the component before that being "SCCS".
+ * The NSE does not consider a source file to be derived from
+ * an SCCS file.
+ */
+void
+nse_check_sccs(wchar_t *targ, wchar_t *dep)
+{
+ wchar_t *slash;
+ wchar_t *p;
+
+#ifdef SUNOS4_AND_AFTER
+ if (!nse) {
+#else
+ if (is_false(flag.nse)) {
+#endif
+ return;
+ }
+#ifdef SUNOS4_AND_AFTER
+ slash = wsrchr(dep, (int) slash_char);
+#else
+ slash = rindex(dep, '/');
+#endif
+ if (slash == NULL) {
+ return;
+ }
+ if (slash[1] != 's' || slash[2] != '.') {
+ return;
+ }
+
+ /*
+ * Find the next to last filename component.
+ */
+ for (p = slash - 1; p >= dep; p--) {
+ if (*p == '/') {
+ break;
+ }
+ }
+ p++;
+#ifdef SUNOS4_AND_AFTER
+ MBSTOWCS(wcs_buffer, "SCCS/");
+ if (IS_WEQUALN(p, wcs_buffer, wslen(wcs_buffer))) {
+#else
+ if (is_equaln(p, "SCCS/", 5)) {
+#endif
+ nse_warning();
+ WCSTOMBS(mbs_buffer, targ);
+ WCSTOMBS(mbs_buffer2, dep);
+ fprintf(stderr, "\tFile `%s' depends upon SCCS file `%s'\n",
+ mbs_buffer, mbs_buffer2);
+ }
+ return;
+}
+
+/*
+ * Given a filename check to see if it has 2 backquotes in it.
+ * Complain about this because the shell expands the backquotes
+ * but make does not so the files always appear to be out of date.
+ */
+void
+nse_check_file_backquotes(wchar_t *file)
+{
+#ifdef SUNOS4_AND_AFTER
+ if (!nse) {
+#else
+ if (is_false(flag.nse)) {
+#endif
+ return;
+ }
+ if (nse_backquotes(file)) {
+ nse_warning();
+ WCSTOMBS(mbs_buffer, file);
+ fprintf(stderr, "\tFilename \"%s\" has backquotes in it\n",
+ mbs_buffer);
+ }
+}
+
+/*
+ * Return true if the string has two backquotes in it.
+ */
+Boolean
+nse_backquotes(wchar_t *str)
+{
+ wchar_t *bq;
+
+#ifdef SUNOS4_AND_AFTER
+ bq = wschr(str, (int) backquote_char);
+ if (bq) {
+ bq = wschr(&bq[1], (int) backquote_char);
+#else
+ bq = index(str, '`');
+ if (bq) {
+ bq = index(&bq[1], '`');
+#endif
+ if (bq) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * A macro that was defined on the command-line was found to affect the
+ * set of dependencies. The NSE "target explode" will not know about
+ * this and will not get the same set of dependencies.
+ */
+void
+nse_dep_cmdmacro(wchar_t *macro)
+{
+#ifdef SUNOS4_AND_AFTER
+ if (!nse) {
+#else
+ if (is_false(flag.nse)) {
+#endif
+ return;
+ }
+ nse_warning();
+ WCSTOMBS(mbs_buffer, macro);
+ fprintf(stderr, "\tVariable `%s' is defined on the command-line and\n\taffects dependencies\n",
+ mbs_buffer);
+}
+
+/*
+ * A macro that was defined on the command-line was found to
+ * be part of the argument to a cd before a recursive make.
+ * This make cause the make to recurse to different places
+ * depending upon how it is invoked.
+ */
+void
+nse_rule_cmdmacro(wchar_t *macro)
+{
+#ifdef SUNOS4_AND_AFTER
+ if (!nse) {
+#else
+ if (is_false(flag.nse)) {
+#endif
+ return;
+ }
+ nse_warning();
+ WCSTOMBS(mbs_buffer, macro);
+ fprintf(stderr, "\tMake invoked recursively by cd'ing to a directory\n\tspecified by a variable (%s) defined on the command-line\n",
+ mbs_buffer);
+}
+
+/*
+ * A dependency has been found with a wildcard in it.
+ * This causes the NSE problems because the set of dependencies
+ * can change without changing the Makefile.
+ */
+void
+nse_wildcard(wchar_t *targ, wchar_t *dep)
+{
+#ifdef SUNOS4_AND_AFTER
+ if (!nse) {
+#else
+ if (is_false(flag.nse)) {
+#endif
+ return;
+ }
+ nse_warning();
+ WCSTOMBS(mbs_buffer, targ);
+ WCSTOMBS(mbs_buffer2, dep);
+ fprintf(stderr, "\tFile `%s' has a wildcard in dependency `%s'\n",
+ mbs_buffer, mbs_buffer2);
+}
+
+/*
+ * Read in the list of suffixes that are interpreted as source
+ * files.
+ */
+void
+nse_init_source_suffixes(void)
+{
+ FILE *fp;
+ wchar_t suffix[100];
+ Nse_suffix sufx;
+ Nse_suffix *bpatch;
+
+ fp = fopen(TARG_SUFX, "r");
+ if (fp == NULL) {
+ return;
+ }
+ bpatch = &sufx_hdr;
+ while (fscanf(fp, "%s %*s", suffix) == 1) {
+#ifdef SUNOS4_AND_AFTER
+ sufx = ALLOC(Nse_suffix);
+ sufx->suffix = wscpy(ALLOC_WC(wslen(suffix) + 1), suffix);
+#else
+ sufx = alloc(Nse_suffix);
+ sufx->suffix = strcpy(malloc(strlen(suffix) + 1), suffix);
+#endif
+ sufx->next = NULL;
+ *bpatch = sufx;
+ bpatch = &sufx->next;
+ }
+ fclose(fp);
+}
+
+/*
+ * Check if a derived file (something with a dependency) appears
+ * to be a source file (by its suffix) but has no rule to build it.
+ * If so, complain.
+ *
+ * This generally arises from the old-style of make-depend that
+ * produces:
+ * foo.c: foo.h
+ */
+void
+nse_check_derived_src(Name target, wchar_t *dep, Cmd_line command_template)
+{
+ Nse_suffix sufx;
+ wchar_t *suffix;
+ wchar_t *depsufx;
+
+#ifdef SUNOS4_AND_AFTER
+ if (!nse) {
+#else
+ if (is_false(flag.nse)) {
+#endif
+ return;
+ }
+#ifdef SUNOS4_AND_AFTER
+ if (target->stat.is_derived_src) {
+#else
+ if (is_true(target->stat.is_derived_src)) {
+#endif
+ return;
+ }
+ if (command_template != NULL) {
+ return;
+ }
+#ifdef SUNOS4_AND_AFTER
+ suffix = wsrchr(target->string, (int) period_char );
+#else
+ suffix = rindex(target->string, '.');
+#endif
+ if (suffix != NULL) {
+ for (sufx = sufx_hdr; sufx != NULL; sufx = sufx->next) {
+#ifdef SUNOS4_AND_AFTER
+ if (IS_WEQUAL(sufx->suffix, suffix)) {
+#else
+ if (is_equal(sufx->suffix, suffix)) {
+#endif
+ nse_warning();
+ WCSTOMBS(mbs_buffer, dep);
+ fprintf(stderr, "\tProbable source file `%s' appears as a derived file\n\tas it depends upon file `%s', but there is\n\tno rule to build it\n",
+ target->string_mb, mbs_buffer);
+ break;
+ }
+ }
+ }
+}
+
+/*
+ * See if a target is a potential source file and has no
+ * dependencies and no rule but shows up on the right-hand
+ * side. This tends to occur from old "make depend" output.
+ */
+void
+nse_check_no_deps_no_rule(Name target, Property line, Property command)
+{
+ Nse_suffix sufx;
+ wchar_t *suffix;
+
+#ifdef SUNOS4_AND_AFTER
+ if (!nse) {
+#else
+ if (is_false(flag.nse)) {
+#endif
+ return;
+ }
+#ifdef SUNOS4_AND_AFTER
+ if (target->stat.is_derived_src) {
+#else
+ if (is_true(target->stat.is_derived_src)) {
+#endif
+ return;
+ }
+ if (line != NULL && line->body.line.dependencies != NULL) {
+ return;
+ }
+#ifdef SUNOS4_AND_AFTER
+ if (command->body.line.sccs_command) {
+#else
+ if (is_true(command->body.line.sccs_command)) {
+#endif
+ return;
+ }
+#ifdef SUNOS4_AND_AFTER
+ suffix = wsrchr(target->string, (int) period_char);
+#else
+ suffix = rindex(target->string, '.');
+#endif
+ if (suffix != NULL) {
+ for (sufx = sufx_hdr; sufx != NULL; sufx = sufx->next) {
+#ifdef SUNOS4_AND_AFTER
+ if (IS_WEQUAL(sufx->suffix, suffix)) {
+#else
+ if (is_equal(sufx->suffix, suffix)) {
+#endif
+ if (command->body.line.command_template == NULL) {
+ nse_warning();
+ fprintf(stderr, "\tProbable source file `%s' appears as a derived file because\n\tit is on the left-hand side, but it has no dependencies and\n\tno rule to build it\n",
+ target->string_mb);
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Detected a situation where a recursive make derived a file
+ * without using a makefile.
+ */
+void
+nse_no_makefile(Name target)
+{
+#ifdef SUNOS4_AND_AFTER
+ if (!nse) {
+#else
+ if (is_false(flag.nse)) {
+#endif
+ return;
+ }
+ nse_warning();
+ fprintf(stderr, "Recursive make to derive %s did not use a makefile\n",
+ target->string_mb);
+}
+
+/*
+ * Return the NSE exit status.
+ * If the -P flag was given then a warning is considered fatal
+ */
+int
+nse_exit_status(void)
+{
+ return our_exit_status;
+}
+#endif
diff --git a/usr/src/make_src/Make/bin/make/common/nse_printdep.cc b/usr/src/make_src/Make/bin/make/common/nse_printdep.cc
new file mode 100644
index 0000000..cda02f8
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/nse_printdep.cc
@@ -0,0 +1,517 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)nse_printdep.cc 1.18 06/12/12
+ */
+
+#pragma ident "@(#)nse_printdep.cc 1.18 06/12/12"
+
+/*
+ * Included files
+ */
+#include <mk/defs.h>
+#include <mksh/misc.h> /* get_prop() */
+
+/*
+ * File table of contents
+ */
+void print_dependencies(register Name target, register Property line);
+static void print_deps(register Name target, register Property line);
+static void print_more_deps(Name target, Name name);
+static void print_filename(Name name);
+static Boolean should_print_dep(Property line);
+static void print_forest(Name target);
+static void print_deplist(Dependency head);
+void print_value(register Name value, Daemon daemon);
+static void print_rule(register Name target);
+static void print_rec_info(Name target);
+static Boolean is_out_of_date(Property line);
+extern void depvar_print_results (void);
+extern int printf (const char *, ...);
+extern int _flsbuf (unsigned int, FILE *);
+
+/*
+ * print_dependencies(target, line)
+ *
+ * Print all the dependencies of a target. First print all the Makefiles.
+ * Then print all the dependencies. Finally, print all the .INIT
+ * dependencies.
+ *
+ * Parameters:
+ * target The target we print dependencies for
+ * line We get the dependency list from here
+ *
+ * Global variables used:
+ * done The Name ".DONE"
+ * init The Name ".INIT"
+ * makefiles_used List of all makefiles read
+ */
+void
+print_dependencies(register Name target, register Property line)
+{
+ Dependency dp;
+ static Boolean makefiles_printed = false;
+
+#ifdef SUNOS4_AND_AFTER
+ if (target_variants) {
+#else
+ if (is_true(flag.target_variants)) {
+#endif
+ depvar_print_results();
+ }
+
+ if (!makefiles_printed) {
+ /*
+ * Search the makefile list for the primary makefile,
+ * then print it and its inclusions. After that go back
+ * and print the default.mk file and its inclusions.
+ */
+ for (dp = makefiles_used; dp != NULL; dp = dp->next) {
+ if (dp->name == primary_makefile) {
+ break;
+ }
+ }
+ if (dp) {
+ print_deplist(dp);
+ for (dp = makefiles_used; dp != NULL; dp = dp->next) {
+ if (dp->name == primary_makefile) {
+ break;
+ }
+ (void)printf(" %s", dp->name->string_mb);
+ }
+ }
+ (void) printf("\n");
+ makefiles_printed = true;
+ }
+ print_deps(target, line);
+#ifdef SUNOS4_AND_AFTER
+/*
+ print_more_deps(target, init);
+ print_more_deps(target, done);
+ */
+ if (target_variants) {
+#else
+ print_more_deps(target, cached_names.init);
+ print_more_deps(target, cached_names.done);
+ if (is_true(flag.target_variants)) {
+#endif
+ print_forest(target);
+ }
+}
+
+/*
+ * print_more_deps(target, name)
+ *
+ * Print some special dependencies.
+ * These are the dependencies for the .INIT and .DONE targets.
+ *
+ * Parameters:
+ * target Target built during make run
+ * name Special target to print dependencies for
+ *
+ * Global variables used:
+ */
+static void
+print_more_deps(Name target, Name name)
+{
+ Property line;
+ register Dependency dependencies;
+
+ line = get_prop(name->prop, line_prop);
+ if (line != NULL && line->body.line.dependencies != NULL) {
+ (void) printf("%s:\t", target->string_mb);
+ print_deplist(line->body.line.dependencies);
+ (void) printf("\n");
+ for (dependencies= line->body.line.dependencies;
+ dependencies != NULL;
+ dependencies= dependencies->next) {
+ print_deps(dependencies->name,
+ get_prop(dependencies->name->prop, line_prop));
+ }
+ }
+}
+
+/*
+ * print_deps(target, line, go_recursive)
+ *
+ * Print a regular dependency list. Append to this information which
+ * indicates whether or not the target is recursive.
+ *
+ * Parameters:
+ * target target to print dependencies for
+ * line We get the dependency list from here
+ * go_recursive Should we show all dependencies recursively?
+ *
+ * Global variables used:
+ * recursive_name The Name ".RECURSIVE", printed
+ */
+static void
+print_deps(register Name target, register Property line)
+{
+ register Dependency dep;
+
+#ifdef SUNOS4_AND_AFTER
+ if ((target->dependency_printed) ||
+ (target == force)) {
+#else
+ if (is_true(target->dependency_printed)) {
+#endif
+ return;
+ }
+ target->dependency_printed = true;
+
+ /* only print entries that are actually derived and are not leaf
+ * files and are not the result of sccs get.
+ */
+ if (should_print_dep(line)) {
+#ifdef NSE
+ nse_check_no_deps_no_rule(target, line, line);
+#endif
+ if ((report_dependencies_level == 2) ||
+ (report_dependencies_level == 4)) {
+ if (is_out_of_date(line)) {
+ (void) printf("1 ");
+ } else {
+ (void) printf("0 ");
+ }
+ }
+ print_filename(target);
+ (void) printf(":\t");
+ print_deplist(line->body.line.dependencies);
+ print_rec_info(target);
+ (void) printf("\n");
+ for (dep = line->body.line.dependencies;
+ dep != NULL;
+ dep = dep->next) {
+ print_deps(dep->name,
+ get_prop(dep->name->prop, line_prop));
+ }
+ }
+}
+
+static Boolean
+is_out_of_date(Property line)
+{
+ Dependency dep;
+ Property line2;
+
+ if (line == NULL) {
+ return false;
+ }
+ if (line->body.line.is_out_of_date) {
+ return true;
+ }
+ for (dep = line->body.line.dependencies;
+ dep != NULL;
+ dep = dep->next) {
+ line2 = get_prop(dep->name->prop, line_prop);
+ if (is_out_of_date(line2)) {
+ line->body.line.is_out_of_date = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Given a dependency print it and all its siblings.
+ */
+static void
+print_deplist(Dependency head)
+{
+ Dependency dp;
+
+ for (dp = head; dp != NULL; dp = dp->next) {
+ if ((report_dependencies_level != 2) ||
+ ((!dp->automatic) ||
+ (dp->name->is_double_colon))) {
+ if (dp->name != force) {
+ putwchar(' ');
+ print_filename(dp->name);
+ }
+ }
+ }
+}
+
+/*
+ * Print the name of a file for the -P option.
+ * If the file is a directory put on a trailing slash.
+ */
+static void
+print_filename(Name name)
+{
+ (void) printf("%s", name->string_mb);
+/*
+ if (name->stat.is_dir) {
+ putwchar('/');
+ }
+ */
+}
+
+/*
+ * should_print_dep(line)
+ *
+ * Test if we should print the dependencies of this target.
+ * The line must exist and either have children dependencies
+ * or have a command that is not an SCCS command.
+ *
+ * Return value:
+ * true if the dependencies should be printed
+ *
+ * Parameters:
+ * line We get the dependency list from here
+ *
+ * Global variables used:
+ */
+static Boolean
+should_print_dep(Property line)
+{
+ if (line == NULL) {
+ return false;
+ }
+ if (line->body.line.dependencies != NULL) {
+ return true;
+ }
+#ifdef SUNOS4_AND_AFTER
+ if (line->body.line.sccs_command) {
+#else
+ if (is_true(line->body.line.sccs_command)) {
+#endif
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Print out the root nodes of all the dependency trees
+ * in this makefile.
+ */
+static void
+print_forest(Name target)
+{
+ Name_set::iterator np, e;
+ Property line;
+
+ for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
+#ifdef SUNOS4_AND_AFTER
+ if (np->is_target && !np->has_parent && np != target) {
+#else
+ if (is_true(np->is_target) &&
+ is_false(np->has_parent) &&
+ np != target) {
+#endif
+ (void) doname_check(np, true, false, false);
+ line = get_prop(np->prop, line_prop);
+ printf("-\n");
+ print_deps(np, line);
+ }
+ }
+}
+
+#ifndef SUNOS4_AND_AFTER
+printdesc()
+{
+ Name_set::iterator p, e;
+ register Property prop;
+ register Dependency dep;
+ register Cmd_line rule;
+ Percent percent, percent_depe;
+
+ /* Default target */
+ if (default_target_to_build != NULL) {
+ print_rule(default_target_to_build);
+ default_target_to_build->dependency_printed= true;
+ };
+ (void)printf("\n");
+
+ /* .AR_REPLACE */
+ if (ar_replace_rule != NULL) {
+ (void)printf("%s:\n", cached_names.ar_replace->string_mb);
+ for (rule= ar_replace_rule; rule != NULL; rule= rule->next)
+ (void)printf("\t%s\n", rule->command_line->string_mb);
+ };
+
+ /* .DEFAULT */
+ if (default_rule != NULL) {
+ (void)printf("%s:\n", cached_names.default_rule->string_mb);
+ for (rule= default_rule; rule != NULL; rule= rule->next)
+ (void)printf("\t%s\n", rule->command_line->string_mb);
+ };
+
+ /* .IGNORE */
+ if (is_true(flag.ignore_errors))
+ (void)printf("%s:\n", cached_names.ignore->string_mb);
+
+ /* .KEEP_STATE: */
+ if (is_true(flag.keep_state))
+ (void)printf("%s:\n\n", cached_names.dot_keep_state->string_mb);
+
+ /* .PRECIOUS */
+ (void)printf("%s: ", cached_names.precious->string_mb);
+ for (p = hashtab.begin(), e = hashtab.end(); p != e; p++)
+ if (is_true(p->stat.is_precious | all_precious))
+ (void)printf("%s ", p->string_mb);
+ (void)printf("\n");
+
+ /* .SCCS_GET */
+ if (sccs_get_rule != NULL) {
+ (void)printf("%s:\n", cached_names.sccs_get->string_mb);
+ for (rule= sccs_get_rule; rule != NULL; rule= rule->next)
+ (void)printf("\t%s\n", rule->command_line->string_mb);
+ };
+
+ /* .SILENT */
+ if (is_true(flag.silent))
+ (void)printf("%s:\n", cached_names.silent->string_mb);
+
+ /* .SUFFIXES: */
+ (void)printf("%s: ", cached_names.suffixes->string_mb);
+ for (dep= suffixes; dep != NULL; dep= dep->next) {
+ (void)printf("%s ", dep->name->string_mb);
+ build_suffix_list(dep->name);
+ };
+ (void)printf("\n\n");
+
+ /* % rules */
+ for (percent= percent_list; percent != NULL; percent= percent->next) {
+ (void) printf("%s:", percent->name->string_mb);
+
+ for (percent_depe= percent->dependencies; percent_depe != NULL; percent_depe = percent_depe->next)
+ (void) printf(" %s", percent_depe->name->string_mb);
+
+ (void) printf("\n");
+
+ for (rule= percent->command_template; rule != NULL; rule= rule->next)
+ (void)printf("\t%s\n", rule->command_line->string_mb);
+ };
+
+ /* Suffix rules */
+ for (p = hashtab.begin(), e = hashtab.end(); p != e; p++)
+ if (is_false(p->dependency_printed) && (p->string[0] == PERIOD)) {
+ print_rule(p);
+ p->dependency_printed= true;
+ };
+
+ /* Macro assignments */
+ for (p = hashtab.begin(), e = hashtab.end(); p != e; p++)
+ if (((prop= get_prop(p->prop, macro_prop)) != NULL) &&
+ (prop->body.macro.value != NULL)) {
+ (void)printf("%s", p->string_mb);
+ print_value(prop->body.macro.value,
+ prop->body.macro.daemon);
+ };
+ (void)printf("\n");
+
+ /* Delays */
+ for (p = hashtab.begin(), e = hashtab.end(); p != e; p++)
+ for (prop= get_prop(p->prop, conditional_prop);
+ prop != NULL;
+ prop= get_prop(prop->next, conditional_prop)) {
+ (void)printf("%s := %s",
+ p->string_mb,
+ prop->body.conditional.name->string_mb);
+ print_value(prop->body.conditional.value, no_daemon);
+ };
+ (void)printf("\n");
+
+ /* All other dependencies */
+ for (p = hashtab.begin(), e = hashtab.end(); p != e; p++)
+ if (is_false(p->dependency_printed) && (p->colons != no_colon))
+ print_rule(p);
+ (void)printf("\n");
+ exit(0);
+}
+#endif
+
+/*
+ * This is a set of routines for dumping the internal make state
+ * Used for the -p option
+ */
+void
+print_value(register Name value, Daemon daemon)
+
+#ifdef SUNOS4_AND_AFTER
+
+#else
+
+#endif
+{
+ Chain cp;
+
+ if (value == NULL)
+ (void)printf("=\n");
+ else
+ switch (daemon) {
+ case no_daemon:
+ (void)printf("= %s\n", value->string_mb);
+ break;
+ case chain_daemon:
+ for (cp= (Chain) value; cp != NULL; cp= cp->next)
+ (void)printf(cp->next == NULL ? "%s" : "%s ",
+ cp->name->string_mb);
+ (void)printf("\n");
+ break;
+ };
+}
+
+static void
+print_rule(register Name target)
+{
+ register Cmd_line rule;
+ register Property line;
+
+ if (((line= get_prop(target->prop, line_prop)) == NULL) ||
+ ((line->body.line.command_template == NULL) &&
+ (line->body.line.dependencies == NULL)))
+ return;
+ print_dependencies(target, line);
+ for (rule= line->body.line.command_template; rule != NULL; rule= rule->next)
+ (void)printf("\t%s\n", rule->command_line->string_mb);
+}
+
+
+/*
+ * If target is recursive, print the following to standard out:
+ * .RECURSIVE subdir targ Makefile
+ */
+static void
+print_rec_info(Name target)
+{
+ Recursive_make rp;
+ wchar_t *colon;
+
+ report_recursive_init();
+
+ rp = find_recursive_target(target);
+
+ if (rp) {
+ /*
+ * if found, print starting with the space after the ':'
+ */
+ colon = (wchar_t *) wschr(rp->oldline, (int) colon_char);
+ (void) printf("%s", colon + 1);
+ }
+}
+
diff --git a/usr/src/make_src/Make/bin/make/common/parallel.cc b/usr/src/make_src/Make/bin/make/common/parallel.cc
new file mode 100644
index 0000000..1831415
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/parallel.cc
@@ -0,0 +1,2477 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)parallel.cc 1.75 06/12/12
+ */
+
+#pragma ident "@(#)parallel.cc 1.75 06/12/12"
+
+#ifdef TEAMWARE_MAKE_CMN
+
+/*
+ * parallel.cc
+ *
+ * Deal with the parallel processing
+ */
+
+/*
+ * Included files
+ */
+#ifdef DISTRIBUTED
+#include <avo/strings.h> /* AVO_STRDUP() */
+#include <dm/Avo_DoJobMsg.h>
+#include <dm/Avo_MToolJobResultMsg.h>
+#endif
+#include <errno.h> /* errno */
+#include <fcntl.h>
+#include <avo/util.h> /* avo_get_user(), avo_hostname() */
+#include <mk/defs.h>
+#include <mksh/dosys.h> /* redirect_io() */
+#include <mksh/macro.h> /* expand_value() */
+#include <mksh/misc.h> /* getmem() */
+#include <sys/signal.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#ifdef SGE_SUPPORT
+#include <dmthread/Avo_PathNames.h>
+#endif
+
+
+/*
+ * Defined macros
+ */
+#define MAXRULES 100
+
+/*
+ * This const should be in avo_dms/include/AvoDmakeCommand.h
+ */
+const int local_host_mask = 0x20;
+
+
+/*
+ * typedefs & structs
+ */
+
+
+/*
+ * Static variables
+ */
+#ifdef TEAMWARE_MAKE_CMN
+static Boolean just_did_subtree = false;
+static char local_host[MAXNAMELEN] = "";
+static char user_name[MAXNAMELEN] = "";
+#endif
+static int pmake_max_jobs = 0;
+static pid_t process_running = -1;
+static Running *running_tail = &running_list;
+static Name subtree_conflict;
+static Name subtree_conflict2;
+
+
+/*
+ * File table of contents
+ */
+#ifdef DISTRIBUTED
+static void append_dmake_cmd(Avo_DoJobMsg *dmake_job_msg, char *orig_cmd_line, int cmd_options);
+static void append_job_result_msg(Avo_MToolJobResultMsg *msg, char *outFn, char *errFn);
+static void send_job_result_msg(Running rp);
+#endif
+static void delete_running_struct(Running rp);
+static Boolean dependency_conflict(Name target);
+static Doname distribute_process(char **commands, Property line);
+static void doname_subtree(Name target, Boolean do_get, Boolean implicit);
+static void dump_out_file(char *filename, Boolean err);
+static void finish_doname(Running rp);
+static void maybe_reread_make_state(void);
+static void process_next(void);
+static void reset_conditionals(int cnt, Name *targets, Property *locals);
+static pid_t run_rule_commands(char *host, char **commands);
+static Property *set_conditionals(int cnt, Name *targets);
+static void store_conditionals(Running rp);
+
+
+/*
+ * execute_parallel(line, waitflg)
+ *
+ * DMake 2.x:
+ * parallel mode: spawns a parallel process to execute the command group.
+ * distributed mode: sends the command group down the pipe to rxm.
+ *
+ * Return value:
+ * The result of the execution
+ *
+ * Parameters:
+ * line The command group to execute
+ */
+Doname
+execute_parallel(Property line, Boolean waitflg, Boolean local)
+{
+ int argcnt;
+ int cmd_options = 0;
+ char *commands[MAXRULES + 5];
+ char *cp;
+#ifdef DISTRIBUTED
+ Avo_DoJobMsg *dmake_job_msg = NULL;
+#endif
+ Name dmake_name;
+ Name dmake_value;
+ int ignore;
+ Name make_machines_name;
+ char **p;
+ Property prop;
+ Doname result = build_ok;
+ Cmd_line rule;
+ Boolean silent_flag;
+ Name target = line->body.line.target;
+ Boolean wrote_state_file = false;
+
+ if ((pmake_max_jobs == 0) &&
+ (dmake_mode_type == parallel_mode)) {
+ if (user_name[0] == '\0') {
+ avo_get_user(user_name, NULL);
+ }
+ if (local_host[0] == '\0') {
+ strcpy(local_host, avo_hostname());
+ }
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MAX_JOBS"));
+ dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+ ((dmake_value = prop->body.macro.value) != NULL)) {
+ pmake_max_jobs = atoi(dmake_value->string_mb);
+ if (pmake_max_jobs <= 0) {
+ warning(catgets(catd, 1, 308, "DMAKE_MAX_JOBS cannot be less than or equal to zero."));
+ warning(catgets(catd, 1, 309, "setting DMAKE_MAX_JOBS to %d."), PMAKE_DEF_MAX_JOBS);
+ pmake_max_jobs = PMAKE_DEF_MAX_JOBS;
+ }
+ } else {
+ /*
+ * For backwards compatibility w/ PMake 1.x, when
+ * DMake 2.x is being run in parallel mode, DMake
+ * should parse the PMake startup file
+ * $(HOME)/.make.machines to get the pmake_max_jobs.
+ */
+ MBSTOWCS(wcs_buffer, NOCATGETS("PMAKE_MACHINESFILE"));
+ dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
+ ((dmake_value = prop->body.macro.value) != NULL)) {
+ make_machines_name = dmake_value;
+ } else {
+ make_machines_name = NULL;
+ }
+ if ((pmake_max_jobs = read_make_machines(make_machines_name)) <= 0) {
+ pmake_max_jobs = PMAKE_DEF_MAX_JOBS;
+ }
+ }
+#ifdef DISTRIBUTED
+ if (send_mtool_msgs) {
+ send_rsrc_info_msg(pmake_max_jobs, local_host, user_name);
+ }
+#endif
+ }
+
+ if ((dmake_mode_type == serial_mode) ||
+ ((dmake_mode_type == parallel_mode) && (waitflg))) {
+ return (execute_serial(line));
+ }
+
+#ifdef DISTRIBUTED
+ if (dmake_mode_type == distributed_mode) {
+ if(local) {
+// return (execute_serial(line));
+ waitflg = true;
+ }
+ dmake_job_msg = new Avo_DoJobMsg();
+ dmake_job_msg->setJobId(++job_msg_id);
+ dmake_job_msg->setTarget(target->string_mb);
+ dmake_job_msg->setImmediateOutput(0);
+ called_make = false;
+ } else
+#endif
+ {
+ p = commands;
+ }
+
+ argcnt = 0;
+ for (rule = line->body.line.command_used;
+ rule != NULL;
+ rule = rule->next) {
+ if (posix && (touch || quest) && !rule->always_exec) {
+ continue;
+ }
+ if (vpath_defined) {
+ rule->command_line =
+ vpath_translation(rule->command_line);
+ }
+ if (dmake_mode_type == distributed_mode) {
+ cmd_options = 0;
+ if(local) {
+ cmd_options |= local_host_mask;
+ }
+ } else {
+ silent_flag = false;
+ ignore = 0;
+ }
+ if (rule->command_line->hash.length > 0) {
+ if (++argcnt == MAXRULES) {
+ if (dmake_mode_type == distributed_mode) {
+ /* XXX - tell rxm to execute on local host. */
+ /* I WAS HERE!!! */
+ } else {
+ /* Too many rules, run serially instead. */
+ return build_serial;
+ }
+ }
+#ifdef DISTRIBUTED
+ if (dmake_mode_type == distributed_mode) {
+ /*
+ * XXX - set assign_mask to tell rxm
+ * to do the following.
+ */
+/* From execute_serial():
+ if (rule->assign) {
+ result = build_ok;
+ do_assign(rule->command_line, target);
+ */
+ if (0) {
+ } else if (report_dependencies_level == 0) {
+ if (rule->ignore_error) {
+ cmd_options |= ignore_mask;
+ }
+ if (rule->silent) {
+ cmd_options |= silent_mask;
+ }
+ if (rule->command_line->meta) {
+ cmd_options |= meta_mask;
+ }
+ if (rule->make_refd) {
+ cmd_options |= make_refd_mask;
+ }
+ if (do_not_exec_rule) {
+ cmd_options |= do_not_exec_mask;
+ }
+ append_dmake_cmd(dmake_job_msg,
+ rule->command_line->string_mb,
+ cmd_options);
+ /* Copying dosys()... */
+ if (rule->make_refd) {
+ if (waitflg) {
+ dmake_job_msg->setImmediateOutput(1);
+ }
+ called_make = true;
+ if (command_changed &&
+ !wrote_state_file) {
+ write_state_file(0, false);
+ wrote_state_file = true;
+ }
+ }
+ }
+ } else
+#endif
+ {
+ if (rule->silent && !silent) {
+ silent_flag = true;
+ }
+ if (rule->ignore_error) {
+ ignore++;
+ }
+ /* XXX - need to add support for + prefix */
+ if (silent_flag || ignore) {
+ *p = getmem((silent_flag ? 1 : 0) +
+ ignore +
+ (strlen(rule->
+ command_line->
+ string_mb)) +
+ 1);
+ cp = *p++;
+ if (silent_flag) {
+ *cp++ = (int) at_char;
+ }
+ if (ignore) {
+ *cp++ = (int) hyphen_char;
+ }
+ (void) strcpy(cp, rule->command_line->string_mb);
+ } else {
+ *p++ = rule->command_line->string_mb;
+ }
+ }
+ }
+ }
+ if ((argcnt == 0) ||
+ (report_dependencies_level > 0)) {
+#ifdef DISTRIBUTED
+ if (dmake_job_msg) {
+ delete dmake_job_msg;
+ }
+#endif
+ return build_ok;
+ }
+#ifdef DISTRIBUTED
+ if (dmake_mode_type == distributed_mode) {
+ // Send a DoJob message to the rxm process.
+ distribute_rxm(dmake_job_msg);
+
+ // Wait for an acknowledgement.
+ Avo_AcknowledgeMsg *ackMsg = getAcknowledgeMsg();
+ if (ackMsg) {
+ delete ackMsg;
+ }
+
+ if (waitflg) {
+ // Wait for, and process a job result.
+ result = await_dist(waitflg);
+ if (called_make) {
+ maybe_reread_make_state();
+ }
+ check_state(temp_file_name);
+ if (result == build_failed) {
+ if (!continue_after_error) {
+
+#ifdef PRINT_EXIT_STATUS
+ warning(NOCATGETS("I'm in execute_parallel. await_dist() returned build_failed"));
+#endif
+
+ fatal(catgets(catd, 1, 252, "Command failed for target `%s'"),
+ target->string_mb);
+ }
+ /*
+ * Make sure a failing command is not
+ * saved in .make.state.
+ */
+ line->body.line.command_used = NULL;
+ }
+ if (temp_file_name != NULL) {
+ free_name(temp_file_name);
+ }
+ temp_file_name = NULL;
+ Property spro = get_prop(sunpro_dependencies->prop, macro_prop);
+ if(spro != NULL) {
+ Name val = spro->body.macro.value;
+ if(val != NULL) {
+ free_name(val);
+ spro->body.macro.value = NULL;
+ }
+ }
+ spro = get_prop(sunpro_dependencies->prop, env_mem_prop);
+ if(spro) {
+ char *val = spro->body.env_mem.value;
+ if(val != NULL) {
+ retmem_mb(val);
+ spro->body.env_mem.value = NULL;
+ }
+ }
+ return result;
+ } else {
+ parallel_process_cnt++;
+ return build_running;
+ }
+ } else
+#endif
+ {
+ *p = NULL;
+
+ Doname res = distribute_process(commands, line);
+ if (res == build_running) {
+ parallel_process_cnt++;
+ }
+
+ /*
+ * Return only those memory that were specially allocated
+ * for part of commands.
+ */
+ for (int i = 0; commands[i] != NULL; i++) {
+ if ((commands[i][0] == (int) at_char) ||
+ (commands[i][0] == (int) hyphen_char)) {
+ retmem_mb(commands[i]);
+ }
+ }
+ return res;
+ }
+}
+
+#ifdef DISTRIBUTED
+/*
+ * append_dmake_cmd()
+ *
+ * Replaces all escaped newline's (\<cr>)
+ * in the original command line with space's,
+ * then append the new command line to the DoJobMsg object.
+ */
+static void
+append_dmake_cmd(Avo_DoJobMsg *dmake_job_msg,
+ char *orig_cmd_line,
+ int cmd_options)
+{
+/*
+ Avo_DmakeCommand *tmp_dmake_command;
+
+ tmp_dmake_command = new Avo_DmakeCommand(orig_cmd_line, cmd_options);
+ dmake_job_msg->appendCmd(tmp_dmake_command);
+ delete tmp_dmake_command;
+ */
+ dmake_job_msg->appendCmd(new Avo_DmakeCommand(orig_cmd_line, cmd_options));
+}
+#endif
+
+#ifdef TEAMWARE_MAKE_CMN
+#define MAXJOBS_ADJUST_RFE4694000
+
+#ifdef MAXJOBS_ADJUST_RFE4694000
+
+#include <unistd.h> /* sysconf(_SC_NPROCESSORS_ONLN) */
+#include <sys/ipc.h> /* ftok() */
+#include <sys/shm.h> /* shmget(), shmat(), shmdt(), shmctl() */
+#include <semaphore.h> /* sem_init(), sem_trywait(), sem_post(), sem_destroy() */
+#if defined(linux)
+#define LOADAVG_1MIN 0
+#else
+#include <sys/loadavg.h> /* getloadavg() */
+#endif /* linux */
+
+/*
+ * adjust_pmake_max_jobs (int pmake_max_jobs)
+ *
+ * Parameters:
+ * pmake_max_jobs - max jobs limit set by user
+ *
+ * External functions used:
+ * sysconf()
+ * getloadavg()
+ */
+static int
+adjust_pmake_max_jobs (int pmake_max_jobs)
+{
+ static int ncpu = 0;
+ double loadavg[3];
+ int adjustment;
+ int adjusted_max_jobs;
+
+ if (ncpu <= 0) {
+ if ((ncpu = sysconf(_SC_NPROCESSORS_ONLN)) <= 0) {
+ ncpu = 1;
+ }
+ }
+ if (getloadavg(loadavg, 3) != 3) return(pmake_max_jobs);
+ adjustment = ((int)loadavg[LOADAVG_1MIN]);
+ if (adjustment < 2) return(pmake_max_jobs);
+ if (ncpu > 1) {
+ adjustment = adjustment / ncpu;
+ }
+ adjusted_max_jobs = pmake_max_jobs - adjustment;
+ if (adjusted_max_jobs < 1) adjusted_max_jobs = 1;
+ return(adjusted_max_jobs);
+}
+
+/*
+ * M2 adjust mode data and functions
+ *
+ * m2_init() - initializes M2 shared semaphore
+ * m2_acquire_job() - decrements M2 semaphore counter
+ * m2_release_job() - increments M2 semaphore counter
+ * m2_fini() - destroys M2 semaphore and shared memory*
+ *
+ * Environment variables:
+ * __DMAKE_M2_FILE__
+ *
+ * External functions:
+ * ftok(), shmget(), shmat(), shmdt(), shmctl()
+ * sem_init(), sem_trywait(), sem_post(), sem_destroy()
+ * creat(), close(), unlink()
+ * getenv(), putenv()
+ *
+ * Static variables:
+ * m2_file - tmp file name to create ipc key for shared memory
+ * m2_shm_id - shared memory id
+ * m2_shm_sem - shared memory semaphore
+ */
+
+static char m2_file[MAXPATHLEN];
+static int m2_shm_id = -1;
+static sem_t* m2_shm_sem = 0;
+
+static int
+m2_init() {
+ char *var;
+ key_t key;
+
+ if ((var = getenv(NOCATGETS("__DMAKE_M2_FILE__"))) == 0) {
+ /* compose tmp file name */
+ sprintf(m2_file, NOCATGETS("%s/dmake.m2.%d.XXXXXX"), tmpdir, getpid());
+
+ /* create tmp file */
+ int fd = mkstemp(m2_file);
+ if (fd < 0) {
+ return -1;
+ } else {
+ close(fd);
+ }
+ } else {
+ /* using existing semaphore */
+ strcpy(m2_file, var);
+ }
+
+ /* combine IPC key */
+ if ((key = ftok(m2_file, 38)) == (key_t) -1) {
+ return -1;
+ }
+
+ /* create shared memory */
+ if ((m2_shm_id = shmget(key, sizeof(*m2_shm_sem), 0666 | (var ? 0 : IPC_CREAT|IPC_EXCL))) == -1) {
+ return -1;
+ }
+
+ /* attach shared memory */
+ if ((m2_shm_sem = (sem_t*) shmat(m2_shm_id, 0, 0666)) == (sem_t*)-1) {
+ return -1;
+ }
+
+ /* root process */
+ if (var == 0) {
+ /* initialize semaphore */
+ if (sem_init(m2_shm_sem, 1, pmake_max_jobs)) {
+ return -1;
+ }
+
+ /* alloc memory for env variable */
+ if ((var = (char*) malloc(MAXPATHLEN)) == 0) {
+ return -1;
+ }
+
+ /* put key to env */
+ sprintf(var, NOCATGETS("__DMAKE_M2_FILE__=%s"), m2_file);
+ if (putenv(var)) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static void
+m2_fini() {
+ if (m2_shm_id >= 0) {
+ struct shmid_ds stat;
+
+ /* determine the number of attached processes */
+ if (shmctl(m2_shm_id, IPC_STAT, &stat) == 0) {
+ if (stat.shm_nattch <= 1) {
+ /* destroy semaphore */
+ if (m2_shm_sem != 0) {
+ (void) sem_destroy(m2_shm_sem);
+ }
+
+ /* destroy shared memory */
+ (void) shmctl(m2_shm_id, IPC_RMID, &stat);
+
+ /* remove tmp file created for the key */
+ (void) unlink(m2_file);
+ } else {
+ /* detach shared memory */
+ if (m2_shm_sem != 0) {
+ (void) shmdt((char*) m2_shm_sem);
+ }
+ }
+ }
+
+ m2_shm_id = -1;
+ m2_shm_sem = 0;
+ }
+}
+
+static int
+m2_acquire_job() {
+ if ((m2_shm_id >= 0) && (m2_shm_sem != 0)) {
+ if (sem_trywait(m2_shm_sem) == 0) {
+ return 1;
+ }
+ if (errno == EAGAIN) {
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static int
+m2_release_job() {
+ if ((m2_shm_id >= 0) && (m2_shm_sem != 0)) {
+ if (sem_post(m2_shm_sem) == 0) {
+ return 0;
+ }
+ }
+ return -1;
+}
+
+/*
+ * job adjust mode
+ *
+ * Possible values:
+ * ADJUST_M1 - adjustment by system load (default)
+ * ADJUST_M2 - fixed limit of jobs for the group of nested dmakes
+ * ADJUST_NONE - no adjustment - fixed limit of jobs for the current dmake
+ */
+static enum {
+ ADJUST_UNKNOWN,
+ ADJUST_M1,
+ ADJUST_M2,
+ ADJUST_NONE
+} job_adjust_mode = ADJUST_UNKNOWN;
+
+/*
+ * void job_adjust_fini()
+ *
+ * Description:
+ * Cleans up job adjust data.
+ *
+ * Static variables:
+ * job_adjust_mode Current job adjust mode
+ */
+void
+job_adjust_fini() {
+ if (job_adjust_mode == ADJUST_M2) {
+ m2_fini();
+ }
+}
+
+/*
+ * void job_adjust_error()
+ *
+ * Description:
+ * Prints warning message, cleans up job adjust data, and disables job adjustment
+ *
+ * Environment:
+ * DMAKE_ADJUST_MAX_JOBS
+ *
+ * External functions:
+ * putenv()
+ *
+ * Static variables:
+ * job_adjust_mode Current job adjust mode
+ */
+static void
+job_adjust_error() {
+ if (job_adjust_mode != ADJUST_NONE) {
+ /* cleanup internals */
+ job_adjust_fini();
+
+ /* warning message for the user */
+ warning(catgets(catd, 1, 339, "Encountered max jobs auto adjustment error - disabling auto adjustment."));
+
+ /* switch off job adjustment for the children */
+ putenv(NOCATGETS("DMAKE_ADJUST_MAX_JOBS=NO"));
+
+ /* and for this dmake */
+ job_adjust_mode = ADJUST_NONE;
+ }
+}
+
+/*
+ * void job_adjust_init()
+ *
+ * Description:
+ * Parses DMAKE_ADJUST_MAX_JOBS env variable
+ * and performs appropriate initializations.
+ *
+ * Environment:
+ * DMAKE_ADJUST_MAX_JOBS
+ * DMAKE_ADJUST_MAX_JOBS == "NO" - no adjustment
+ * DMAKE_ADJUST_MAX_JOBS == "M2" - M2 adjust mode
+ * other - M1 adjust mode
+ *
+ * External functions:
+ * getenv()
+ *
+ * Static variables:
+ * job_adjust_mode Current job adjust mode
+ */
+static void
+job_adjust_init() {
+ if (job_adjust_mode == ADJUST_UNKNOWN) {
+ /* default mode */
+ job_adjust_mode = ADJUST_M1;
+
+ /* determine adjust mode */
+ if (char *var = getenv(NOCATGETS("DMAKE_ADJUST_MAX_JOBS"))) {
+ if (strcasecmp(var, NOCATGETS("NO")) == 0) {
+ job_adjust_mode = ADJUST_NONE;
+ } else if (strcasecmp(var, NOCATGETS("M2")) == 0) {
+ job_adjust_mode = ADJUST_M2;
+ }
+ }
+
+ /* M2 specific initialization */
+ if (job_adjust_mode == ADJUST_M2) {
+ if (m2_init()) {
+ job_adjust_error();
+ }
+ }
+ }
+}
+
+#endif /* MAXJOBS_ADJUST_RFE4694000 */
+#endif /* TEAMWARE_MAKE_CMN */
+
+/*
+ * distribute_process(char **commands, Property line)
+ *
+ * Parameters:
+ * commands argv vector of commands to execute
+ *
+ * Return value:
+ * The result of the execution
+ *
+ * Static variables used:
+ * process_running Set to the pid of the process set running
+ * #if defined (TEAMWARE_MAKE_CMN) && defined (MAXJOBS_ADJUST_RFE4694000)
+ * job_adjust_mode Current job adjust mode
+ * #endif
+ */
+static Doname
+distribute_process(char **commands, Property line)
+{
+ static unsigned file_number = 0;
+ wchar_t string[MAXPATHLEN];
+ char mbstring[MAXPATHLEN];
+ int filed;
+ int res;
+ int tmp_index;
+ char *tmp_index_str_ptr;
+
+#if !defined (TEAMWARE_MAKE_CMN) || !defined (MAXJOBS_ADJUST_RFE4694000)
+ while (parallel_process_cnt >= pmake_max_jobs) {
+ await_parallel(false);
+ finish_children(true);
+ }
+#else /* TEAMWARE_MAKE_CMN && MAXJOBS_ADJUST_RFE4694000 */
+ /* initialize adjust mode, if not initialized */
+ if (job_adjust_mode == ADJUST_UNKNOWN) {
+ job_adjust_init();
+ }
+
+ /* actions depend on adjust mode */
+ switch (job_adjust_mode) {
+ case ADJUST_M1:
+ while (parallel_process_cnt >= adjust_pmake_max_jobs (pmake_max_jobs)) {
+ await_parallel(false);
+ finish_children(true);
+ }
+ break;
+ case ADJUST_M2:
+ if ((res = m2_acquire_job()) == 0) {
+ if (parallel_process_cnt > 0) {
+ await_parallel(false);
+ finish_children(true);
+
+ if ((res = m2_acquire_job()) == 0) {
+ return build_serial;
+ }
+ } else {
+ return build_serial;
+ }
+ }
+ if (res < 0) {
+ /* job adjustment error */
+ job_adjust_error();
+
+ /* no adjustment */
+ while (parallel_process_cnt >= pmake_max_jobs) {
+ await_parallel(false);
+ finish_children(true);
+ }
+ }
+ break;
+ default:
+ while (parallel_process_cnt >= pmake_max_jobs) {
+ await_parallel(false);
+ finish_children(true);
+ }
+ }
+#endif /* TEAMWARE_MAKE_CMN && MAXJOBS_ADJUST_RFE4694000 */
+#ifdef DISTRIBUTED
+ if (send_mtool_msgs) {
+ send_job_start_msg(line);
+ }
+#endif
+#ifdef DISTRIBUTED
+ setvar_envvar((Avo_DoJobMsg *)NULL);
+#else
+ setvar_envvar();
+#endif
+ /*
+ * Tell the user what DMake is doing.
+ */
+ if (!silent && output_mode != txt2_mode) {
+ /*
+ * Print local_host --> x job(s).
+ */
+ (void) fprintf(stdout,
+ catgets(catd, 1, 325, "%s --> %d %s\n"),
+ local_host,
+ parallel_process_cnt + 1,
+ (parallel_process_cnt == 0) ? catgets(catd, 1, 124, "job") : catgets(catd, 1, 125, "jobs"));
+
+ /* Print command line(s). */
+ tmp_index = 0;
+ while (commands[tmp_index] != NULL) {
+ /* No @ char. */
+ /* XXX - need to add [2] when + prefix is added */
+ if ((commands[tmp_index][0] != (int) at_char) &&
+ (commands[tmp_index][1] != (int) at_char)) {
+ tmp_index_str_ptr = commands[tmp_index];
+ if (*tmp_index_str_ptr == (int) hyphen_char) {
+ tmp_index_str_ptr++;
+ }
+ (void) fprintf(stdout, "%s\n", tmp_index_str_ptr);
+ }
+ tmp_index++;
+ }
+ (void) fflush(stdout);
+ }
+
+ (void) sprintf(mbstring,
+ NOCATGETS("%s/dmake.stdout.%d.%d.XXXXXX"),
+ tmpdir,
+ getpid(),
+ file_number++);
+
+ mktemp(mbstring);
+
+ stdout_file = strdup(mbstring);
+ stderr_file = NULL;
+#if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR)
+ if (!out_err_same) {
+ (void) sprintf(mbstring,
+ NOCATGETS("%s/dmake.stderr.%d.%d.XXXXXX"),
+ tmpdir,
+ getpid(),
+ file_number++);
+
+ mktemp(mbstring);
+
+ stderr_file = strdup(mbstring);
+ }
+#endif
+
+#ifdef SGE_SUPPORT
+ if (grid) {
+ static char *dir4gridscripts = NULL;
+ static char *hostName = NULL;
+ if (dir4gridscripts == NULL) {
+ Name dmakeOdir_name, dmakeOdir_value;
+ Property prop;
+ MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_ODIR"));
+ dmakeOdir_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ if (((prop = get_prop(dmakeOdir_name->prop, macro_prop)) != NULL) &&
+ ((dmakeOdir_value = prop->body.macro.value) != NULL)) {
+ dir4gridscripts = dmakeOdir_value->string_mb;
+ }
+ dir4gridscripts = Avo_PathNames::pathname_output_directory(dir4gridscripts);
+ hostName = Avo_PathNames::pathname_local_host();
+ }
+ (void) sprintf(script_file,
+ NOCATGETS("%s/dmake.script.%s.%d.%d.XXXXXX"),
+ dir4gridscripts,
+ hostName,
+ getpid(),
+ file_number++);
+ }
+#endif /* SGE_SUPPORT */
+ process_running = run_rule_commands(local_host, commands);
+
+ return build_running;
+}
+
+/*
+ * doname_parallel(target, do_get, implicit)
+ *
+ * Processes the given target and finishes up any parallel
+ * processes left running.
+ *
+ * Return value:
+ * Result of target build
+ *
+ * Parameters:
+ * target Target to build
+ * do_get True if sccs get to be done
+ * implicit True if this is an implicit target
+ */
+Doname
+doname_parallel(Name target, Boolean do_get, Boolean implicit)
+{
+ Doname result;
+
+ result = doname_check(target, do_get, implicit, false);
+ if (result == build_ok || result == build_failed) {
+ return result;
+ }
+ finish_running();
+ return (Doname) target->state;
+}
+
+/*
+ * doname_subtree(target, do_get, implicit)
+ *
+ * Completely computes an object and its dependents for a
+ * serial subtree build.
+ *
+ * Parameters:
+ * target Target to build
+ * do_get True if sccs get to be done
+ * implicit True if this is an implicit target
+ *
+ * Static variables used:
+ * running_tail Tail of the list of running processes
+ *
+ * Global variables used:
+ * running_list The list of running processes
+ */
+static void
+doname_subtree(Name target, Boolean do_get, Boolean implicit)
+{
+ Running save_running_list;
+ Running *save_running_tail;
+
+ save_running_list = running_list;
+ save_running_tail = running_tail;
+ running_list = NULL;
+ running_tail = &running_list;
+ target->state = build_subtree;
+ target->checking_subtree = true;
+ while(doname_check(target, do_get, implicit, false) == build_running) {
+ target->checking_subtree = false;
+ finish_running();
+ target->state = build_subtree;
+ }
+ target->checking_subtree = false;
+ running_list = save_running_list;
+ running_tail = save_running_tail;
+}
+
+/*
+ * finish_running()
+ *
+ * Keeps processing until the running_list is emptied out.
+ *
+ * Parameters:
+ *
+ * Global variables used:
+ * running_list The list of running processes
+ */
+void
+finish_running(void)
+{
+ while (running_list != NULL) {
+#ifdef DISTRIBUTED
+ if (dmake_mode_type == distributed_mode) {
+ if ((just_did_subtree) ||
+ (parallel_process_cnt == 0)) {
+ just_did_subtree = false;
+ } else {
+ (void) await_dist(false);
+ finish_children(true);
+ }
+ } else
+#endif
+ {
+ await_parallel(false);
+ finish_children(true);
+ }
+ if (running_list != NULL) {
+ process_next();
+ }
+ }
+}
+
+/*
+ * process_next()
+ *
+ * Searches the running list for any targets which can start processing.
+ * This can be a pending target, a serial target, or a subtree target.
+ *
+ * Parameters:
+ *
+ * Static variables used:
+ * running_tail The end of the list of running procs
+ * subtree_conflict A target which conflicts with a subtree
+ * subtree_conflict2 The other target which conflicts
+ *
+ * Global variables used:
+ * commands_done True if commands executed
+ * debug_level Controls debug output
+ * parallel_process_cnt Number of parallel process running
+ * recursion_level Indentation for debug output
+ * running_list List of running processes
+ */
+static void
+process_next(void)
+{
+ Running rp;
+ Running *rp_prev;
+ Property line;
+ Chain target_group;
+ Dependency dep;
+ Boolean quiescent = true;
+ Running *subtree_target;
+ Boolean saved_commands_done;
+ Property *conditionals;
+
+ subtree_target = NULL;
+ subtree_conflict = NULL;
+ subtree_conflict2 = NULL;
+ /*
+ * If nothing currently running, build a serial target, if any.
+ */
+start_loop_1:
+ for (rp_prev = &running_list, rp = running_list;
+ rp != NULL && parallel_process_cnt == 0;
+ rp = rp->next) {
+ if (rp->state == build_serial) {
+ *rp_prev = rp->next;
+ if (rp->next == NULL) {
+ running_tail = rp_prev;
+ }
+ recursion_level = rp->recursion_level;
+ rp->target->state = build_pending;
+ (void) doname_check(rp->target,
+ rp->do_get,
+ rp->implicit,
+ false);
+ quiescent = false;
+ delete_running_struct(rp);
+ goto start_loop_1;
+ } else {
+ rp_prev = &rp->next;
+ }
+ }
+ /*
+ * Find a target to build. The target must be pending, have all
+ * its dependencies built, and not be in a target group with a target
+ * currently building.
+ */
+start_loop_2:
+ for (rp_prev = &running_list, rp = running_list;
+ rp != NULL;
+ rp = rp->next) {
+ if (!(rp->state == build_pending ||
+ rp->state == build_subtree)) {
+ quiescent = false;
+ rp_prev = &rp->next;
+ } else if (rp->state == build_pending) {
+ line = get_prop(rp->target->prop, line_prop);
+ for (dep = line->body.line.dependencies;
+ dep != NULL;
+ dep = dep->next) {
+ if (dep->name->state == build_running ||
+ dep->name->state == build_pending ||
+ dep->name->state == build_serial) {
+ break;
+ }
+ }
+ if (dep == NULL) {
+ for (target_group = line->body.line.target_group;
+ target_group != NULL;
+ target_group = target_group->next) {
+ if (is_running(target_group->name)) {
+ break;
+ }
+ }
+ if (target_group == NULL) {
+ *rp_prev = rp->next;
+ if (rp->next == NULL) {
+ running_tail = rp_prev;
+ }
+ recursion_level = rp->recursion_level;
+ rp->target->state = rp->redo ?
+ build_dont_know : build_pending;
+ saved_commands_done = commands_done;
+ conditionals =
+ set_conditionals
+ (rp->conditional_cnt,
+ rp->conditional_targets);
+ rp->target->dont_activate_cond_values = true;
+ if ((doname_check(rp->target,
+ rp->do_get,
+ rp->implicit,
+ rp->target->has_target_prop ? true : false) !=
+ build_running) &&
+ !commands_done) {
+ commands_done =
+ saved_commands_done;
+ }
+ rp->target->dont_activate_cond_values = false;
+ reset_conditionals
+ (rp->conditional_cnt,
+ rp->conditional_targets,
+ conditionals);
+ quiescent = false;
+ delete_running_struct(rp);
+ goto start_loop_2;
+ } else {
+ rp_prev = &rp->next;
+ }
+ } else {
+ rp_prev = &rp->next;
+ }
+ } else {
+ rp_prev = &rp->next;
+ }
+ }
+ /*
+ * If nothing has been found to build and there exists a subtree
+ * target with no dependency conflicts, build it.
+ */
+ if (quiescent) {
+start_loop_3:
+ for (rp_prev = &running_list, rp = running_list;
+ rp != NULL;
+ rp = rp->next) {
+ if (rp->state == build_subtree) {
+ if (!dependency_conflict(rp->target)) {
+ *rp_prev = rp->next;
+ if (rp->next == NULL) {
+ running_tail = rp_prev;
+ }
+ recursion_level = rp->recursion_level;
+ doname_subtree(rp->target,
+ rp->do_get,
+ rp->implicit);
+#ifdef DISTRIBUTED
+ just_did_subtree = true;
+#endif
+ quiescent = false;
+ delete_running_struct(rp);
+ goto start_loop_3;
+ } else {
+ subtree_target = rp_prev;
+ rp_prev = &rp->next;
+ }
+ } else {
+ rp_prev = &rp->next;
+ }
+ }
+ }
+ /*
+ * If still nothing found to build, we either have a deadlock
+ * or a subtree with a dependency conflict with something waiting
+ * to build.
+ */
+ if (quiescent) {
+ if (subtree_target == NULL) {
+ fatal(catgets(catd, 1, 126, "Internal error: deadlock detected in process_next"));
+ } else {
+ rp = *subtree_target;
+ if (debug_level > 0) {
+ warning(catgets(catd, 1, 127, "Conditional macro conflict encountered for %s between %s and %s"),
+ subtree_conflict2->string_mb,
+ rp->target->string_mb,
+ subtree_conflict->string_mb);
+ }
+ *subtree_target = (*subtree_target)->next;
+ if (rp->next == NULL) {
+ running_tail = subtree_target;
+ }
+ recursion_level = rp->recursion_level;
+ doname_subtree(rp->target, rp->do_get, rp->implicit);
+#ifdef DISTRIBUTED
+ just_did_subtree = true;
+#endif
+ delete_running_struct(rp);
+ }
+ }
+}
+
+/*
+ * set_conditionals(cnt, targets)
+ *
+ * Sets the conditional macros for the targets given in the array of
+ * targets. The old macro values are returned in an array of
+ * Properties for later resetting.
+ *
+ * Return value:
+ * Array of conditional macro settings
+ *
+ * Parameters:
+ * cnt Number of targets
+ * targets Array of targets
+ */
+static Property *
+set_conditionals(int cnt, Name *targets)
+{
+ Property *locals, *lp;
+ Name *tp;
+
+ locals = (Property *) getmem(cnt * sizeof(Property));
+ for (lp = locals, tp = targets;
+ cnt > 0;
+ cnt--, lp++, tp++) {
+ *lp = (Property) getmem((*tp)->conditional_cnt *
+ sizeof(struct _Property));
+ set_locals(*tp, *lp);
+ }
+ return locals;
+}
+
+/*
+ * reset_conditionals(cnt, targets, locals)
+ *
+ * Resets the conditional macros as saved in the given array of
+ * Properties. The resets are done in reverse order. Afterwards the
+ * data structures are freed.
+ *
+ * Parameters:
+ * cnt Number of targets
+ * targets Array of targets
+ * locals Array of dependency macro settings
+ */
+static void
+reset_conditionals(int cnt, Name *targets, Property *locals)
+{
+ Name *tp;
+ Property *lp;
+
+ for (tp = targets + (cnt - 1), lp = locals + (cnt - 1);
+ cnt > 0;
+ cnt--, tp--, lp--) {
+ reset_locals(*tp,
+ *lp,
+ get_prop((*tp)->prop, conditional_prop),
+ 0);
+ retmem_mb((caddr_t) *lp);
+ }
+ retmem_mb((caddr_t) locals);
+}
+
+/*
+ * dependency_conflict(target)
+ *
+ * Returns true if there is an intersection between
+ * the subtree of the target and any dependents of the pending targets.
+ *
+ * Return value:
+ * True if conflict found
+ *
+ * Parameters:
+ * target Subtree target to check
+ *
+ * Static variables used:
+ * subtree_conflict Target conflict found
+ * subtree_conflict2 Second conflict found
+ *
+ * Global variables used:
+ * running_list List of running processes
+ * wait_name .WAIT, not a real dependency
+ */
+static Boolean
+dependency_conflict(Name target)
+{
+ Property line;
+ Property pending_line;
+ Dependency dp;
+ Dependency pending_dp;
+ Running rp;
+
+ /* Return if we are already checking this target */
+ if (target->checking_subtree) {
+ return false;
+ }
+ target->checking_subtree = true;
+ line = get_prop(target->prop, line_prop);
+ if (line == NULL) {
+ target->checking_subtree = false;
+ return false;
+ }
+ /* Check each dependency of the target for conflicts */
+ for (dp = line->body.line.dependencies; dp != NULL; dp = dp->next) {
+ /* Ignore .WAIT dependency */
+ if (dp->name == wait_name) {
+ continue;
+ }
+ /*
+ * For each pending target, look for a dependency which
+ * is the same as a dependency of the subtree target. Since
+ * we can't build the subtree until all pending targets have
+ * finished which depend on the same dependency, this is
+ * a conflict.
+ */
+ for (rp = running_list; rp != NULL; rp = rp->next) {
+ if (rp->state == build_pending) {
+ pending_line = get_prop(rp->target->prop,
+ line_prop);
+ if (pending_line == NULL) {
+ continue;
+ }
+ for(pending_dp = pending_line->
+ body.line.dependencies;
+ pending_dp != NULL;
+ pending_dp = pending_dp->next) {
+ if (dp->name == pending_dp->name) {
+ target->checking_subtree
+ = false;
+ subtree_conflict = rp->target;
+ subtree_conflict2 = dp->name;
+ return true;
+ }
+ }
+ }
+ }
+ if (dependency_conflict(dp->name)) {
+ target->checking_subtree = false;
+ return true;
+ }
+ }
+ target->checking_subtree = false;
+ return false;
+}
+
+/*
+ * await_parallel(waitflg)
+ *
+ * Waits for parallel children to exit and finishes their processing.
+ * If waitflg is false, the function returns after update_delay.
+ *
+ * Parameters:
+ * waitflg dwight
+ */
+void
+await_parallel(Boolean waitflg)
+{
+#ifdef _CHECK_UPDATE_H
+ static int number_of_unknown_children = 0;
+#endif /* _CHECK_UPDATE_H */
+ Boolean nohang;
+ pid_t pid;
+ int status;
+ Running rp;
+ int waiterr;
+
+ nohang = false;
+ for ( ; ; ) {
+ if (!nohang) {
+ (void) alarm((int) update_delay);
+ }
+ pid = waitpid((pid_t)-1,
+ &status,
+ nohang ? WNOHANG : 0);
+ waiterr = errno;
+ if (!nohang) {
+ (void) alarm(0);
+ }
+ if (pid <= 0) {
+ if (waiterr == EINTR) {
+ if (waitflg) {
+ continue;
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+ }
+ for (rp = running_list;
+ (rp != NULL) && (rp->pid != pid);
+ rp = rp->next) {
+ ;
+ }
+ if (rp == NULL) {
+#ifdef _CHECK_UPDATE_H
+ /* Ignore first child - it is check_update */
+ if (number_of_unknown_children <= 0) {
+ number_of_unknown_children = 1;
+ return;
+ }
+#endif /* _CHECK_UPDATE_H */
+ if (send_mtool_msgs) {
+ continue;
+ } else {
+ fatal(catgets(catd, 1, 128, "Internal error: returned child pid not in running_list"));
+ }
+ } else {
+ rp->state = (WIFEXITED(status) && WEXITSTATUS(status) == 0) ? build_ok : build_failed;
+ }
+ nohang = true;
+ parallel_process_cnt--;
+
+#if defined (TEAMWARE_MAKE_CMN) && defined (MAXJOBS_ADJUST_RFE4694000)
+ if (job_adjust_mode == ADJUST_M2) {
+ if (m2_release_job()) {
+ job_adjust_error();
+ }
+ }
+#endif
+ }
+}
+
+/*
+ * finish_children(docheck)
+ *
+ * Finishes the processing for all targets which were running
+ * and have now completed.
+ *
+ * Parameters:
+ * docheck Completely check the finished target
+ *
+ * Static variables used:
+ * running_tail The tail of the running list
+ *
+ * Global variables used:
+ * continue_after_error -k flag
+ * fatal_in_progress True if we are finishing up after fatal err
+ * running_list List of running processes
+ */
+void
+finish_children(Boolean docheck)
+{
+ int cmds_length;
+ Property line;
+ Property line2;
+ struct stat out_buf;
+ Running rp;
+ Running *rp_prev;
+ Cmd_line rule;
+ Boolean silent_flag;
+
+ for (rp_prev = &running_list, rp = running_list;
+ rp != NULL;
+ rp = rp->next) {
+bypass_for_loop_inc_4:
+ /*
+ * If the state is ok or failed, then this target has
+ * finished building.
+ * In parallel_mode, output the accumulated stdout/stderr.
+ * Read the auto dependency stuff, handle a failed build,
+ * update the target, then finish the doname process for
+ * that target.
+ */
+ if (rp->state == build_ok || rp->state == build_failed) {
+ *rp_prev = rp->next;
+ if (rp->next == NULL) {
+ running_tail = rp_prev;
+ }
+ if ((line2 = rp->command) == NULL) {
+ line2 = get_prop(rp->target->prop, line_prop);
+ }
+ if (dmake_mode_type == distributed_mode) {
+ if (rp->make_refd) {
+ maybe_reread_make_state();
+ }
+ } else {
+ /*
+ * Send an Avo_MToolJobResultMsg to maketool.
+ */
+#ifdef DISTRIBUTED
+ if (send_mtool_msgs) {
+ send_job_result_msg(rp);
+ }
+#endif
+ /*
+ * Check if there were any job output
+ * from the parallel build.
+ */
+ if (rp->stdout_file != NULL) {
+ if (stat(rp->stdout_file, &out_buf) < 0) {
+ fatal(catgets(catd, 1, 130, "stat of %s failed: %s"),
+ rp->stdout_file,
+ errmsg(errno));
+ }
+ if ((line2 != NULL) &&
+ (out_buf.st_size > 0)) {
+ cmds_length = 0;
+ for (rule = line2->body.line.command_used,
+ silent_flag = silent;
+ rule != NULL;
+ rule = rule->next) {
+ cmds_length += rule->command_line->hash.length + 1;
+ silent_flag = BOOLEAN(silent_flag || rule->silent);
+ }
+ if (out_buf.st_size != cmds_length || silent_flag ||
+ output_mode == txt2_mode) {
+ dump_out_file(rp->stdout_file, false);
+ }
+ }
+ (void) unlink(rp->stdout_file);
+ retmem_mb(rp->stdout_file);
+ rp->stdout_file = NULL;
+ }
+#if defined(REDIRECT_ERR)
+ if (!out_err_same && (rp->stderr_file != NULL)) {
+ if (stat(rp->stderr_file, &out_buf) < 0) {
+ fatal(catgets(catd, 1, 130, "stat of %s failed: %s"),
+ rp->stderr_file,
+ errmsg(errno));
+ }
+ if ((line2 != NULL) &&
+ (out_buf.st_size > 0)) {
+ dump_out_file(rp->stderr_file, true);
+ }
+ (void) unlink(rp->stderr_file);
+ retmem_mb(rp->stderr_file);
+ rp->stderr_file = NULL;
+ }
+#endif
+ }
+ check_state(rp->temp_file);
+ if (rp->temp_file != NULL) {
+ free_name(rp->temp_file);
+ }
+ rp->temp_file = NULL;
+ if (rp->state == build_failed) {
+ line = get_prop(rp->target->prop, line_prop);
+ if (line != NULL) {
+ line->body.line.command_used = NULL;
+ }
+ if (continue_after_error ||
+ fatal_in_progress ||
+ !docheck) {
+ warning(catgets(catd, 1, 256, "Command failed for target `%s'"),
+ rp->command ? line2->body.line.target->string_mb : rp->target->string_mb);
+ build_failed_seen = true;
+ } else {
+ /*
+ * XXX??? - DMake needs to exit(),
+ * but shouldn't call fatal().
+ */
+#ifdef PRINT_EXIT_STATUS
+ warning(NOCATGETS("I'm in finish_children. rp->state == build_failed."));
+#endif
+
+ fatal(catgets(catd, 1, 258, "Command failed for target `%s'"),
+ rp->command ? line2->body.line.target->string_mb : rp->target->string_mb);
+ }
+ }
+ if (!docheck) {
+ delete_running_struct(rp);
+ rp = *rp_prev;
+ if (rp == NULL) {
+ break;
+ } else {
+ goto bypass_for_loop_inc_4;
+ }
+ }
+ update_target(get_prop(rp->target->prop, line_prop),
+ rp->state);
+ finish_doname(rp);
+ delete_running_struct(rp);
+ rp = *rp_prev;
+ if (rp == NULL) {
+ break;
+ } else {
+ goto bypass_for_loop_inc_4;
+ }
+ } else {
+ rp_prev = &rp->next;
+ }
+ }
+}
+
+/*
+ * dump_out_file(filename, err)
+ *
+ * Write the contents of the file to stdout, then unlink the file.
+ *
+ * Parameters:
+ * filename Name of temp file containing output
+ *
+ * Global variables used:
+ */
+static void
+dump_out_file(char *filename, Boolean err)
+{
+ int chars_read;
+ char copybuf[BUFSIZ];
+ int fd;
+ int out_fd = (err ? 2 : 1);
+
+ if ((fd = open(filename, O_RDONLY)) < 0) {
+ fatal(catgets(catd, 1, 141, "open failed for output file %s: %s"),
+ filename,
+ errmsg(errno));
+ }
+ if (!silent && output_mode != txt2_mode) {
+ (void) fprintf(err ? stderr : stdout,
+ err ?
+ catgets(catd, 1, 338, "%s --> Job errors\n") :
+ catgets(catd, 1, 259, "%s --> Job output\n"),
+ local_host);
+ (void) fflush(err ? stderr : stdout);
+ }
+ for (chars_read = read(fd, copybuf, BUFSIZ);
+ chars_read > 0;
+ chars_read = read(fd, copybuf, BUFSIZ)) {
+ /*
+ * Read buffers from the source file until end or error.
+ */
+ if (write(out_fd, copybuf, chars_read) < 0) {
+ fatal(catgets(catd, 1, 260, "write failed for output file %s: %s"),
+ filename,
+ errmsg(errno));
+ }
+ }
+ (void) close(fd);
+ (void) unlink(filename);
+}
+
+/*
+ * finish_doname(rp)
+ *
+ * Completes the processing for a target which was left running.
+ *
+ * Parameters:
+ * rp Running list entry for target
+ *
+ * Global variables used:
+ * debug_level Debug flag
+ * recursion_level Indentation for debug output
+ */
+static void
+finish_doname(Running rp)
+{
+ int auto_count = rp->auto_count;
+ Name *automatics = rp->automatics;
+ Doname result = rp->state;
+ Name target = rp->target;
+ Name true_target = rp->true_target;
+ Property *conditionals;
+
+ recursion_level = rp->recursion_level;
+ if (result == build_ok) {
+ if (true_target == NULL) {
+ (void) printf(NOCATGETS("Target = %s\n"), target->string_mb);
+ (void) printf(NOCATGETS(" State = %d\n"), result);
+ fatal(NOCATGETS("Internal error: NULL true_target in finish_doname"));
+ }
+ /* If all went OK, set a nice timestamp */
+ if (true_target->stat.time == file_doesnt_exist) {
+ true_target->stat.time = file_max_time;
+ }
+ }
+ target->state = result;
+ if (target->is_member) {
+ Property member;
+
+ /* Propagate the timestamp from the member file to the member */
+ if ((target->stat.time != file_max_time) &&
+ ((member = get_prop(target->prop, member_prop)) != NULL) &&
+ (exists(member->body.member.member) > file_doesnt_exist)) {
+ target->stat.time =
+/*
+ exists(member->body.member.member);
+ */
+ member->body.member.member->stat.time;
+ }
+ }
+ /*
+ * Check if we found any new auto dependencies when we
+ * built the target.
+ */
+ if ((result == build_ok) && check_auto_dependencies(target,
+ auto_count,
+ automatics)) {
+ if (debug_level > 0) {
+ (void) printf(catgets(catd, 1, 261, "%*sTarget `%s' acquired new dependencies from build, checking all dependencies\n"),
+ recursion_level,
+ "",
+ true_target->string_mb);
+ }
+ target->rechecking_target = true;
+ target->state = build_running;
+
+ /* [tolik, Tue Mar 25 1997]
+ * Fix for bug 4038824:
+ * command line options set by conditional macros get dropped
+ * rp->conditional_cnt and rp->conditional_targets must be copied
+ * to new 'rp' during add_pending(). Set_conditionals() stores
+ * rp->conditional_targets to the global variable 'conditional_targets'
+ * Add_pending() will use this variable to set up 'rp'.
+ */
+ conditionals = set_conditionals(rp->conditional_cnt, rp->conditional_targets);
+ add_pending(target,
+ recursion_level,
+ rp->do_get,
+ rp->implicit,
+ true);
+ reset_conditionals(rp->conditional_cnt, rp->conditional_targets, conditionals);
+ }
+}
+
+/*
+ * new_running_struct()
+ *
+ * Constructor for Running struct. Creates a structure and initializes
+ * its fields.
+ *
+ */
+static Running new_running_struct()
+{
+ Running rp;
+
+ rp = ALLOC(Running);
+ rp->target = NULL;
+ rp->true_target = NULL;
+ rp->command = NULL;
+ rp->sprodep_value = NULL;
+ rp->sprodep_env = NULL;
+ rp->auto_count = 0;
+ rp->automatics = NULL;
+ rp->pid = -1;
+ rp->job_msg_id = -1;
+ rp->stdout_file = NULL;
+ rp->stderr_file = NULL;
+ rp->temp_file = NULL;
+ rp->next = NULL;
+ return rp;
+}
+
+/*
+ * add_running(target, true_target, command, recursion_level, auto_count,
+ * automatics, do_get, implicit)
+ *
+ * Adds a record on the running list for this target, which
+ * was just spawned and is running.
+ *
+ * Parameters:
+ * target Target being built
+ * true_target True target for target
+ * command Running command.
+ * recursion_level Debug indentation level
+ * auto_count Count of automatic dependencies
+ * automatics List of automatic dependencies
+ * do_get Sccs get flag
+ * implicit Implicit flag
+ *
+ * Static variables used:
+ * running_tail Tail of running list
+ * process_running PID of process
+ *
+ * Global variables used:
+ * current_line Current line for target
+ * current_target Current target being built
+ * stderr_file Temporary file for stdout
+ * stdout_file Temporary file for stdout
+ * temp_file_name Temporary file for auto dependencies
+ */
+void
+add_running(Name target, Name true_target, Property command, int recursion_level, int auto_count, Name *automatics, Boolean do_get, Boolean implicit)
+{
+ Running rp;
+ Name *p;
+
+ rp = new_running_struct();
+ rp->state = build_running;
+ rp->target = target;
+ rp->true_target = true_target;
+ rp->command = command;
+ Property spro_val = get_prop(sunpro_dependencies->prop, macro_prop);
+ if(spro_val) {
+ rp->sprodep_value = spro_val->body.macro.value;
+ spro_val->body.macro.value = NULL;
+ spro_val = get_prop(sunpro_dependencies->prop, env_mem_prop);
+ if(spro_val) {
+ rp->sprodep_env = spro_val->body.env_mem.value;
+ spro_val->body.env_mem.value = NULL;
+ }
+ }
+ rp->recursion_level = recursion_level;
+ rp->do_get = do_get;
+ rp->implicit = implicit;
+ rp->auto_count = auto_count;
+ if (auto_count > 0) {
+ rp->automatics = (Name *) getmem(auto_count * sizeof (Name));
+ for (p = rp->automatics; auto_count > 0; auto_count--) {
+ *p++ = *automatics++;
+ }
+ } else {
+ rp->automatics = NULL;
+ }
+#ifdef DISTRIBUTED
+ if (dmake_mode_type == distributed_mode) {
+ rp->make_refd = called_make;
+ called_make = false;
+ } else
+#endif
+ {
+ rp->pid = process_running;
+ process_running = -1;
+ childPid = -1;
+ }
+ rp->job_msg_id = job_msg_id;
+ rp->stdout_file = stdout_file;
+ rp->stderr_file = stderr_file;
+ rp->temp_file = temp_file_name;
+ rp->redo = false;
+ rp->next = NULL;
+ store_conditionals(rp);
+ stdout_file = NULL;
+ stderr_file = NULL;
+ temp_file_name = NULL;
+ current_target = NULL;
+ current_line = NULL;
+ *running_tail = rp;
+ running_tail = &rp->next;
+}
+
+/*
+ * add_pending(target, recursion_level, do_get, implicit, redo)
+ *
+ * Adds a record on the running list for a pending target
+ * (waiting for its dependents to finish running).
+ *
+ * Parameters:
+ * target Target being built
+ * recursion_level Debug indentation level
+ * do_get Sccs get flag
+ * implicit Implicit flag
+ * redo True if this target is being redone
+ *
+ * Static variables used:
+ * running_tail Tail of running list
+ */
+void
+add_pending(Name target, int recursion_level, Boolean do_get, Boolean implicit, Boolean redo)
+{
+ Running rp;
+ rp = new_running_struct();
+ rp->state = build_pending;
+ rp->target = target;
+ rp->recursion_level = recursion_level;
+ rp->do_get = do_get;
+ rp->implicit = implicit;
+ rp->redo = redo;
+ store_conditionals(rp);
+ *running_tail = rp;
+ running_tail = &rp->next;
+}
+
+/*
+ * add_serial(target, recursion_level, do_get, implicit)
+ *
+ * Adds a record on the running list for a target which must be
+ * executed in serial after others have finished.
+ *
+ * Parameters:
+ * target Target being built
+ * recursion_level Debug indentation level
+ * do_get Sccs get flag
+ * implicit Implicit flag
+ *
+ * Static variables used:
+ * running_tail Tail of running list
+ */
+void
+add_serial(Name target, int recursion_level, Boolean do_get, Boolean implicit)
+{
+ Running rp;
+
+ rp = new_running_struct();
+ rp->target = target;
+ rp->recursion_level = recursion_level;
+ rp->do_get = do_get;
+ rp->implicit = implicit;
+ rp->state = build_serial;
+ rp->redo = false;
+ store_conditionals(rp);
+ *running_tail = rp;
+ running_tail = &rp->next;
+}
+
+/*
+ * add_subtree(target, recursion_level, do_get, implicit)
+ *
+ * Adds a record on the running list for a target which must be
+ * executed in isolation after others have finished.
+ *
+ * Parameters:
+ * target Target being built
+ * recursion_level Debug indentation level
+ * do_get Sccs get flag
+ * implicit Implicit flag
+ *
+ * Static variables used:
+ * running_tail Tail of running list
+ */
+void
+add_subtree(Name target, int recursion_level, Boolean do_get, Boolean implicit)
+{
+ Running rp;
+
+ rp = new_running_struct();
+ rp->target = target;
+ rp->recursion_level = recursion_level;
+ rp->do_get = do_get;
+ rp->implicit = implicit;
+ rp->state = build_subtree;
+ rp->redo = false;
+ store_conditionals(rp);
+ *running_tail = rp;
+ running_tail = &rp->next;
+}
+
+/*
+ * store_conditionals(rp)
+ *
+ * Creates an array of the currently active targets with conditional
+ * macros (found in the chain conditional_targets) and puts that
+ * array in the Running struct.
+ *
+ * Parameters:
+ * rp Running struct for storing chain
+ *
+ * Global variables used:
+ * conditional_targets Chain of current dynamic conditionals
+ */
+static void
+store_conditionals(Running rp)
+{
+ int cnt;
+ Chain cond_name;
+
+ if (conditional_targets == NULL) {
+ rp->conditional_cnt = 0;
+ rp->conditional_targets = NULL;
+ return;
+ }
+ cnt = 0;
+ for (cond_name = conditional_targets;
+ cond_name != NULL;
+ cond_name = cond_name->next) {
+ cnt++;
+ }
+ rp->conditional_cnt = cnt;
+ rp->conditional_targets = (Name *) getmem(cnt * sizeof(Name));
+ for (cond_name = conditional_targets;
+ cond_name != NULL;
+ cond_name = cond_name->next) {
+ rp->conditional_targets[--cnt] = cond_name->name;
+ }
+}
+
+/*
+ * parallel_ok(target, line_prop_must_exists)
+ *
+ * Returns true if the target can be run in parallel
+ *
+ * Return value:
+ * True if can run in parallel
+ *
+ * Parameters:
+ * target Target being tested
+ *
+ * Global variables used:
+ * all_parallel True if all targets default to parallel
+ * only_parallel True if no targets default to parallel
+ */
+Boolean
+parallel_ok(Name target, Boolean line_prop_must_exists)
+{
+ Boolean assign;
+ Boolean make_refd;
+ Property line;
+ Cmd_line rule;
+
+ assign = make_refd = false;
+ if (((line = get_prop(target->prop, line_prop)) == NULL) &&
+ line_prop_must_exists) {
+ return false;
+ }
+ if (line != NULL) {
+ for (rule = line->body.line.command_used;
+ rule != NULL;
+ rule = rule->next) {
+ if (rule->assign) {
+ assign = true;
+ } else if (rule->make_refd) {
+ make_refd = true;
+ }
+ }
+ }
+ if (assign) {
+ return false;
+ } else if (target->parallel) {
+ return true;
+ } else if (target->no_parallel) {
+ return false;
+ } else if (all_parallel) {
+ return true;
+ } else if (only_parallel) {
+ return false;
+ } else if (make_refd) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+/*
+ * is_running(target)
+ *
+ * Returns true if the target is running.
+ *
+ * Return value:
+ * True if target is running
+ *
+ * Parameters:
+ * target Target to check
+ *
+ * Global variables used:
+ * running_list List of running processes
+ */
+Boolean
+is_running(Name target)
+{
+ Running rp;
+
+ if (target->state != build_running) {
+ return false;
+ }
+ for (rp = running_list;
+ rp != NULL && target != rp->target;
+ rp = rp->next);
+ if (rp == NULL) {
+ return false;
+ } else {
+ return (rp->state == build_running) ? true : false;
+ }
+}
+
+/*
+ * This function replaces the makesh binary.
+ */
+
+#ifdef SGE_SUPPORT
+#define DO_CHECK(f) if (f <= 0) { \
+ fprintf(stderr, \
+ catgets(catd, 1, 347, "Could not write to file: %s: %s\n"), \
+ script_file, errmsg(errno)); \
+ _exit(1); \
+ }
+#endif /* SGE_SUPPORT */
+
+static pid_t
+run_rule_commands(char *host, char **commands)
+{
+ Boolean always_exec;
+ Name command;
+ Boolean ignore;
+ int length;
+ Doname result;
+ Boolean silent_flag;
+#ifdef SGE_SUPPORT
+ wchar_t *wcmd, *tmp_wcs_buffer = NULL;
+ char *cmd, *tmp_mbs_buffer = NULL;
+ FILE *scrfp;
+ Name shell = getvar(shell_name);
+#else
+ wchar_t *tmp_wcs_buffer;
+#endif /* SGE_SUPPORT */
+
+ childPid = fork();
+ switch (childPid) {
+ case -1: /* Error */
+ fatal(catgets(catd, 1, 337, "Could not fork child process for dmake job: %s"),
+ errmsg(errno));
+ break;
+ case 0: /* Child */
+ /* To control the processed targets list is not the child's business */
+ running_list = NULL;
+#if defined(REDIRECT_ERR)
+ if(out_err_same) {
+ redirect_io(stdout_file, (char*)NULL);
+ } else {
+ redirect_io(stdout_file, stderr_file);
+ }
+#else
+ redirect_io(stdout_file, (char*)NULL);
+#endif
+#ifdef SGE_SUPPORT
+ if (grid) {
+ int fdes = mkstemp(script_file);
+ if ((fdes < 0) || (scrfp = fdopen(fdes, "w")) == NULL) {
+ fprintf(stderr,
+ catgets(catd, 1, 341, "Could not create file: %s: %s\n"),
+ script_file, errmsg(errno));
+ _exit(1);
+ }
+ if (IS_EQUAL(shell->string_mb, "")) {
+ shell = shell_name;
+ }
+ }
+#endif /* SGE_SUPPORT */
+ for (commands = commands;
+ (*commands != (char *)NULL);
+ commands++) {
+ silent_flag = silent;
+ ignore = false;
+ always_exec = false;
+ while ((**commands == (int) at_char) ||
+ (**commands == (int) hyphen_char) ||
+ (**commands == (int) plus_char)) {
+ if (**commands == (int) at_char) {
+ silent_flag = true;
+ }
+ if (**commands == (int) hyphen_char) {
+ ignore = true;
+ }
+ if (**commands == (int) plus_char) {
+ always_exec = true;
+ }
+ (*commands)++;
+ }
+#ifdef SGE_SUPPORT
+ if (grid) {
+ if ((length = strlen(*commands)) >= MAXPATHLEN / 2) {
+ wcmd = tmp_wcs_buffer = ALLOC_WC(length * 2 + 1);
+ (void) mbstowcs(tmp_wcs_buffer, *commands, length * 2 + 1);
+ } else {
+ MBSTOWCS(wcs_buffer, *commands);
+ wcmd = wcs_buffer;
+ cmd = mbs_buffer;
+ }
+ wchar_t *from = wcmd + wslen(wcmd);
+ wchar_t *to = from + (from - wcmd);
+ *to = (int) nul_char;
+ while (from > wcmd) {
+ *--to = *--from;
+ if (*from == (int) newline_char) { // newline symbols are already quoted
+ *--to = *--from;
+ } else if (wschr(char_semantics_char, *from)) {
+ *--to = (int) backslash_char;
+ }
+ }
+ if (length >= MAXPATHLEN*MB_LEN_MAX/2) { // sizeof(mbs_buffer) / 2
+ cmd = tmp_mbs_buffer = getmem((length * MB_LEN_MAX * 2) + 1);
+ (void) wcstombs(tmp_mbs_buffer, to, (length * MB_LEN_MAX * 2) + 1);
+ } else {
+ WCSTOMBS(mbs_buffer, to);
+ cmd = mbs_buffer;
+ }
+ char *mbst, *mbend;
+ if ((length > 0) &&
+ !silent_flag) {
+ for (mbst = cmd; (mbend = strstr(mbst, "\\\n")) != NULL; mbst = mbend + 2) {
+ *mbend = '\0';
+ DO_CHECK(fprintf(scrfp, NOCATGETS("/usr/bin/printf '%%s\\n' %s\\\\\n"), mbst));
+ *mbend = '\\';
+ }
+ DO_CHECK(fprintf(scrfp, NOCATGETS("/usr/bin/printf '%%s\\n' %s\n"), mbst));
+ }
+ if (!do_not_exec_rule ||
+ !working_on_targets ||
+ always_exec) {
+#if defined(linux)
+ if (0 != strcmp(shell->string_mb, (char*)NOCATGETS("/bin/sh"))) {
+ DO_CHECK(fprintf(scrfp, NOCATGETS("%s -c %s\n"), shell->string_mb, cmd));
+ } else
+#endif
+ DO_CHECK(fprintf(scrfp, NOCATGETS("%s -ce %s\n"), shell->string_mb, cmd));
+ DO_CHECK(fputs(NOCATGETS("__DMAKECMDEXITSTAT=$?\nif [ ${__DMAKECMDEXITSTAT} -ne 0 ]; then\n"), scrfp));
+ if (ignore) {
+ DO_CHECK(fprintf(scrfp, NOCATGETS("\techo %s ${__DMAKECMDEXITSTAT} %s\n"),
+ catgets(catd, 1, 343, "\"*** Error code"),
+ catgets(catd, 1, 344, "(ignored)\"")));
+ } else {
+ DO_CHECK(fprintf(scrfp, NOCATGETS("\techo %s ${__DMAKECMDEXITSTAT}\n"),
+ catgets(catd, 1, 342, "\"*** Error code\"")));
+ }
+ if (silent_flag) {
+ DO_CHECK(fprintf(scrfp, NOCATGETS("\techo %s\n"),
+ catgets(catd, 1, 345, "The following command caused the error:")));
+ for (mbst = cmd; (mbend = strstr(mbst, "\\\n")) != NULL; mbst = mbend + 2) {
+ *mbend = '\0';
+ DO_CHECK(fprintf(scrfp, NOCATGETS("\t/usr/bin/printf '%%s\\n' %s\\\\\n"), mbst));
+ *mbend = '\\';
+ }
+ DO_CHECK(fprintf(scrfp, NOCATGETS("\t/usr/bin/printf '%%s\\n' %s\n"), mbst));
+ }
+ if (!ignore) {
+ DO_CHECK(fputs(NOCATGETS("\texit ${__DMAKECMDEXITSTAT}\n"), scrfp));
+ }
+ DO_CHECK(fputs(NOCATGETS("fi\n"), scrfp));
+ }
+ if (tmp_wcs_buffer) {
+ retmem_mb(tmp_mbs_buffer);
+ tmp_mbs_buffer = NULL;
+ }
+ if (tmp_wcs_buffer) {
+ retmem(tmp_wcs_buffer);
+ tmp_wcs_buffer = NULL;
+ }
+ continue;
+ }
+#endif /* SGE_SUPPORT */
+ if ((length = strlen(*commands)) >= MAXPATHLEN) {
+ tmp_wcs_buffer = ALLOC_WC(length + 1);
+ (void) mbstowcs(tmp_wcs_buffer, *commands, length + 1);
+ command = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
+ retmem(tmp_wcs_buffer);
+ } else {
+ MBSTOWCS(wcs_buffer, *commands);
+ command = GETNAME(wcs_buffer, FIND_LENGTH);
+ }
+ if ((command->hash.length > 0) &&
+ !silent_flag) {
+ (void) printf("%s\n", command->string_mb);
+ }
+ result = dosys(command,
+ ignore,
+ false,
+ false, /* bugs #4085164 & #4990057 */
+ /* BOOLEAN(silent_flag && ignore), */
+ always_exec,
+ (Name) NULL,
+ false);
+ if (result == build_failed) {
+ if (silent_flag) {
+ (void) printf(catgets(catd, 1, 152, "The following command caused the error:\n%s\n"), command->string_mb);
+ }
+ if (!ignore) {
+ _exit(1);
+ }
+ }
+ }
+#ifndef SGE_SUPPORT
+ _exit(0);
+#else
+ if (!grid) {
+ _exit(0);
+ }
+ DO_CHECK(fputs(NOCATGETS("exit 0\n"), scrfp));
+ if (fclose(scrfp) != 0) {
+ fprintf(stderr,
+ catgets(catd, 1, 346, "Could not close file: %s: %s\n"),
+ script_file, errmsg(errno));
+ _exit(1);
+ }
+ {
+
+#define DEFAULT_QRSH_TRIES_NUMBER 1
+#define DEFAULT_QRSH_TIMEOUT 0
+
+ static char *sge_env_var = NULL;
+ static int qrsh_tries_number = DEFAULT_QRSH_TRIES_NUMBER;
+ static int qrsh_timeout = DEFAULT_QRSH_TIMEOUT;
+#define SGE_DEBUG
+#ifdef SGE_DEBUG
+ static Boolean do_not_remove = false;
+#endif /* SGE_DEBUG */
+ if (sge_env_var == NULL) {
+ sge_env_var = getenv(NOCATGETS("__SPRO_DMAKE_SGE_TRIES"));
+ if (sge_env_var != NULL) {
+ qrsh_tries_number = atoi(sge_env_var);
+ if (qrsh_tries_number < 1 || qrsh_tries_number > 9) {
+ qrsh_tries_number = DEFAULT_QRSH_TRIES_NUMBER;
+ }
+ }
+ sge_env_var = getenv(NOCATGETS("__SPRO_DMAKE_SGE_TIMEOUT"));
+ if (sge_env_var != NULL) {
+ qrsh_timeout = atoi(sge_env_var);
+ if (qrsh_timeout <= 0) {
+ qrsh_timeout = DEFAULT_QRSH_TIMEOUT;
+ }
+ } else {
+ sge_env_var = "";
+ }
+#ifdef SGE_DEBUG
+ sge_env_var = getenv(NOCATGETS("__SPRO_DMAKE_SGE_DEBUG"));
+ if (sge_env_var == NULL) {
+ sge_env_var = "";
+ }
+ if (strstr(sge_env_var, NOCATGETS("noqrsh")) != NULL)
+ qrsh_tries_number = 0;
+ if (strstr(sge_env_var, NOCATGETS("donotremove")) != NULL)
+ do_not_remove = true;
+#endif /* SGE_DEBUG */
+ }
+ for (int i = qrsh_tries_number; ; i--)
+ if ((childPid = fork()) < 0) {
+ fatal(catgets(catd, 1, 348, "Could not fork child process for qrsh job: %s"),
+ errmsg(errno));
+ _exit(1);
+ } else if (childPid == 0) {
+ enable_interrupt((void (*) (int))SIG_DFL);
+ if (i > 0) {
+ static char qrsh_cmd[50+MAXPATHLEN] = NOCATGETS("qrsh -cwd -V -noshell -nostdin /bin/sh ");
+ static char *fname_ptr = NULL;
+ static char *argv[] = { NOCATGETS("sh"),
+ NOCATGETS("-fce"),
+ qrsh_cmd,
+ NULL};
+ if (fname_ptr == NULL) {
+ fname_ptr = qrsh_cmd + strlen(qrsh_cmd);
+ }
+ strcpy(fname_ptr, script_file);
+ (void) execve(NOCATGETS("/bin/sh"), argv, environ);
+ } else {
+ static char *argv[] = { NOCATGETS("sh"),
+ script_file,
+ NULL};
+ (void) execve(NOCATGETS("/bin/sh"), argv, environ);
+ }
+ fprintf(stderr,
+ catgets(catd, 1, 349, "Could not load `qrsh': %s\n"),
+ errmsg(errno));
+ _exit(1);
+ } else {
+#if defined (HP_UX) || defined (linux) || defined (SUN5_0)
+ int status;
+#else
+ union wait status;
+#endif
+ pid_t pid;
+ while ((pid = wait(&status)) != childPid) {
+ if (pid == -1) {
+ fprintf(stderr,
+ catgets(catd, 1, 350, "wait() failed: %s\n"),
+ errmsg(errno));
+ _exit(1);
+ }
+ }
+ if (status != 0 && i > 0) {
+ if (i > 1) {
+ sleep(qrsh_timeout);
+ }
+ continue;
+ }
+#ifdef SGE_DEBUG
+ if (do_not_remove) {
+ if (status) {
+ fprintf(stderr,
+ NOCATGETS("SGE script failed: %s\n"),
+ script_file);
+ }
+ _exit(status ? 1 : 0);
+ }
+#endif /* SGE_DEBUG */
+ (void) unlink(script_file);
+ _exit(status ? 1 : 0);
+ }
+ }
+#endif /* SGE_SUPPORT */
+ break;
+ default:
+ break;
+ }
+ return childPid;
+}
+
+static void
+maybe_reread_make_state(void)
+{
+ /* Copying dosys()... */
+ if (report_dependencies_level == 0) {
+ make_state->stat.time = file_no_time;
+ (void) exists(make_state);
+ if (make_state_before == make_state->stat.time) {
+ return;
+ }
+ makefile_type = reading_statefile;
+ if (read_trace_level > 1) {
+ trace_reader = true;
+ }
+ temp_file_number++;
+ (void) read_simple_file(make_state,
+ false,
+ false,
+ false,
+ false,
+ false,
+ true);
+ trace_reader = false;
+ }
+}
+
+#ifdef DISTRIBUTED
+/*
+ * Create and send an Avo_MToolJobResultMsg.
+ */
+static void
+send_job_result_msg(Running rp)
+{
+ Avo_MToolJobResultMsg *msg;
+ RWCollectable *xdr_msg;
+
+ msg = new Avo_MToolJobResultMsg();
+ msg->setResult(rp->job_msg_id,
+ (rp->state == build_ok) ? 0 : 1,
+ DONE);
+ append_job_result_msg(msg,
+ rp->stdout_file,
+ rp->stderr_file);
+
+ xdr_msg = (RWCollectable *)msg;
+ xdr(get_xdrs_ptr(), xdr_msg);
+ (void) fflush(get_mtool_msgs_fp());
+
+ delete msg;
+}
+
+/*
+ * Append the stdout/err to Avo_MToolJobResultMsg.
+ */
+static void
+append_job_result_msg(Avo_MToolJobResultMsg *msg, char *outFn, char *errFn)
+{
+ FILE *fp;
+ char line[MAXPATHLEN];
+
+ fp = fopen(outFn, "r");
+ if (fp == NULL) {
+ /* Hmmm... what should we do here? */
+ return;
+ }
+ while (fgets(line, MAXPATHLEN, fp) != NULL) {
+ if (line[strlen(line) - 1] == '\n') {
+ line[strlen(line) - 1] = '\0';
+ }
+ msg->appendOutput(AVO_STRDUP(line));
+ }
+ (void) fclose(fp);
+}
+#endif
+
+static void
+delete_running_struct(Running rp)
+{
+ if ((rp->conditional_cnt > 0) &&
+ (rp->conditional_targets != NULL)) {
+ retmem_mb((char *) rp->conditional_targets);
+ }
+/**/
+ if ((rp->auto_count > 0) &&
+ (rp->automatics != NULL)) {
+ retmem_mb((char *) rp->automatics);
+ }
+/**/
+ if(rp->sprodep_value) {
+ free_name(rp->sprodep_value);
+ }
+ if(rp->sprodep_env) {
+ retmem_mb(rp->sprodep_env);
+ }
+ retmem_mb((char *) rp);
+
+}
+
+#endif
+
diff --git a/usr/src/make_src/Make/bin/make/common/pmake.cc b/usr/src/make_src/Make/bin/make/common/pmake.cc
new file mode 100644
index 0000000..3544077
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/pmake.cc
@@ -0,0 +1,434 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)pmake.cc 1.9 06/12/12
+ */
+
+#pragma ident "@(#)pmake.cc 1.9 06/12/12"
+
+#ifdef TEAMWARE_MAKE_CMN
+
+/*
+ * Included files
+ */
+#include <arpa/inet.h>
+#include <mk/defs.h>
+#include <mksh/misc.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <rpc/rpc.h> /* host2netname(), netname2host() */
+#ifdef linux
+# include <unistd.h> /* getdomainname() */
+#endif
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+static int get_max(wchar_t **ms_address, wchar_t *hostname);
+static Boolean pskip_comment(wchar_t **cp_address);
+static void pskip_till_next_word(wchar_t **cp);
+static Boolean pskip_white_space(wchar_t **cp_address);
+
+
+/*
+ * read_make_machines(Name make_machines_name)
+ *
+ * For backwards compatibility w/ PMake 1.x, when DMake 2.x is
+ * being run in parallel mode, DMake should parse the PMake startup
+ * file $(HOME)/.make.machines to get the PMake max jobs.
+ *
+ * Return value:
+ * int of PMake max jobs
+ *
+ * Parameters:
+ * make_machines_name Name of .make.machines file
+ *
+ */
+int
+read_make_machines(Name make_machines_name)
+{
+ wchar_t c;
+ Boolean default_make_machines;
+ struct hostent *hp;
+ wchar_t local_host[MAX_HOSTNAMELEN + 1];
+ char local_host_mb[MAX_HOSTNAMELEN + 1] = "";
+ int local_host_wslen;
+ wchar_t full_host[MAXNETNAMELEN + 1];
+ int full_host_wslen = 0;
+ char *homedir;
+ Name MAKE_MACHINES;
+ struct stat make_machines_buf;
+ FILE *make_machines_file;
+ wchar_t *make_machines_list = NULL;
+ char *make_machines_list_mb = NULL;
+ wchar_t make_machines_path[MAXPATHLEN];
+ char mb_make_machines_path[MAXPATHLEN];
+ wchar_t *mp;
+ wchar_t *ms;
+ int pmake_max_jobs = 0;
+ struct utsname uts_info;
+
+
+ MBSTOWCS(wcs_buffer, NOCATGETS("MAKE_MACHINES"));
+ MAKE_MACHINES = GETNAME(wcs_buffer, FIND_LENGTH);
+ /* Did the user specify a .make.machines file on the command line? */
+ default_make_machines = false;
+ if (make_machines_name == NULL) {
+ /* Try reading the default .make.machines file, in $(HOME). */
+ homedir = getenv(NOCATGETS("HOME"));
+ if ((homedir != NULL) && (strlen(homedir) < (sizeof(mb_make_machines_path) - 16))) {
+ sprintf(mb_make_machines_path,
+ NOCATGETS("%s/.make.machines"), homedir);
+ MBSTOWCS(make_machines_path, mb_make_machines_path);
+ make_machines_name = GETNAME(make_machines_path, FIND_LENGTH);
+ default_make_machines = true;
+ }
+ if (make_machines_name == NULL) {
+ /*
+ * No $(HOME)/.make.machines file.
+ * Return 0 for PMake max jobs.
+ */
+ return(0);
+ }
+ }
+/*
+ make_machines_list_mb = getenv(MAKE_MACHINES->string_mb);
+ */
+ /* Open the .make.machines file. */
+ if ((make_machines_file = fopen(make_machines_name->string_mb, "r")) == NULL) {
+ if (!default_make_machines) {
+ /* Error opening .make.machines file. */
+ fatal(catgets(catd, 1, 314, "Open of %s failed: %s"),
+ make_machines_name->string_mb,
+ errmsg(errno));
+ } else {
+ /*
+ * No $(HOME)/.make.machines file.
+ * Return 0 for PMake max jobs.
+ */
+ return(0);
+ }
+ /* Stat the .make.machines file to get the size of the file. */
+ } else if (fstat(fileno(make_machines_file), &make_machines_buf) < 0) {
+ /* Error stat'ing .make.machines file. */
+ fatal(catgets(catd, 1, 315, "Stat of %s failed: %s"),
+ make_machines_name->string_mb,
+ errmsg(errno));
+ } else {
+ /* Allocate memory for "MAKE_MACHINES=<contents of .m.m>" */
+ make_machines_list_mb =
+ (char *) getmem((int) (strlen(MAKE_MACHINES->string_mb) +
+ 2 +
+ make_machines_buf.st_size));
+ sprintf(make_machines_list_mb,
+ "%s=",
+ MAKE_MACHINES->string_mb);
+ /* Read in the .make.machines file. */
+ if (fread(make_machines_list_mb + strlen(MAKE_MACHINES->string_mb) + 1,
+ sizeof(char),
+ (int) make_machines_buf.st_size,
+ make_machines_file) != make_machines_buf.st_size) {
+ /*
+ * Error reading .make.machines file.
+ * Return 0 for PMake max jobs.
+ */
+ warning(catgets(catd, 1, 316, "Unable to read %s"),
+ make_machines_name->string_mb);
+ (void) fclose(make_machines_file);
+ retmem_mb((caddr_t) make_machines_list_mb);
+ return(0);
+ } else {
+ (void) fclose(make_machines_file);
+ /* putenv "MAKE_MACHINES=<contents of .m.m>" */
+ *(make_machines_list_mb +
+ strlen(MAKE_MACHINES->string_mb) +
+ 1 +
+ make_machines_buf.st_size) = (int) nul_char;
+ if (putenv(make_machines_list_mb) != 0) {
+ warning(catgets(catd, 1, 317, "Couldn't put contents of %s in environment"),
+ make_machines_name->string_mb);
+ } else {
+ make_machines_list_mb += strlen(MAKE_MACHINES->string_mb) + 1;
+ make_machines_list = ALLOC_WC(strlen(make_machines_list_mb) + 1);
+ (void) mbstowcs(make_machines_list,
+ make_machines_list_mb,
+ (strlen(make_machines_list_mb) + 1));
+ }
+ }
+ }
+
+ uname(&uts_info);
+ strcpy(local_host_mb, &uts_info.nodename[0]);
+ MBSTOWCS(local_host, local_host_mb);
+ local_host_wslen = wslen(local_host);
+
+ // There is no getdomainname() function on Solaris.
+ // And netname2host() function does not work on Linux.
+ // So we have to use different APIs.
+#ifdef linux
+ if (getdomainname(mbs_buffer, MAXNETNAMELEN+1) == 0) {
+ sprintf(mbs_buffer2, "%s.%s", local_host_mb, mbs_buffer);
+#else
+ if (host2netname(mbs_buffer, NULL, NULL) &&
+ netname2host(mbs_buffer, mbs_buffer2, MAXNETNAMELEN+1)) {
+#endif
+ MBSTOWCS(full_host, mbs_buffer2);
+ full_host_wslen = wslen(full_host);
+ }
+
+ for (ms = make_machines_list;
+ (ms) && (*ms );
+ ) {
+ /*
+ * Skip white space and comments till you reach
+ * a machine name.
+ */
+ pskip_till_next_word(&ms);
+
+ /*
+ * If we haven't reached the end of file, process the
+ * machine name.
+ */
+ if (*ms) {
+ /*
+ * If invalid machine name decrement counter
+ * and skip line.
+ */
+ mp = ms;
+ SKIPWORD(ms);
+ c = *ms;
+ *ms++ = '\0'; /* Append null to machine name. */
+ /*
+ * If this was the beginning of a comment
+ * (we overwrote a # sign) and it's not
+ * end of line yet, shift the # sign.
+ */
+ if ((c == '#') && (*ms != '\n') && (*ms)) {
+ *ms = '#';
+ }
+ WCSTOMBS(mbs_buffer, mp);
+ /*
+ * Print "Ignoring unknown host" if:
+ * 1) hostname is longer than MAX_HOSTNAMELEN, or
+ * 2) hostname is unknown
+ */
+ if ((wslen(mp) > MAX_HOSTNAMELEN) ||
+ ((hp = gethostbyname(mbs_buffer)) == NULL)) {
+ warning(catgets(catd, 1, 318, "Ignoring unknown host %s"),
+ mbs_buffer);
+ SKIPTOEND(ms);
+ /* Increment ptr if not end of file. */
+ if (*ms) {
+ ms++;
+ }
+ } else {
+ /* Compare current hostname with local_host. */
+ if (wslen(mp) == local_host_wslen &&
+ IS_WEQUALN(mp, local_host, local_host_wslen)) {
+ /*
+ * Bingo, local_host is in .make.machines.
+ * Continue reading.
+ */
+ pmake_max_jobs = PMAKE_DEF_MAX_JOBS;
+ /* Compare current hostname with full_host. */
+ } else if (wslen(mp) == full_host_wslen &&
+ IS_WEQUALN(mp, full_host, full_host_wslen)) {
+ /*
+ * Bingo, full_host is in .make.machines.
+ * Continue reading.
+ */
+ pmake_max_jobs = PMAKE_DEF_MAX_JOBS;
+ } else {
+ if (c != '\n') {
+ SKIPTOEND(ms);
+ if (*ms) {
+ ms++;
+ }
+ }
+ continue;
+ }
+ /* If we get here, local_host is in .make.machines. */
+ if (c != '\n') {
+ /* Now look for keyword 'max'. */
+ MBSTOWCS(wcs_buffer, NOCATGETS("max"));
+ SKIPSPACE(ms);
+ while ((*ms != '\n') && (*ms)) {
+ if (*ms == '#') {
+ pskip_comment(&ms);
+ } else if (IS_WEQUALN(ms, wcs_buffer, 3)) {
+ /* Skip "max". */
+ ms += 3;
+ pmake_max_jobs = get_max(&ms, mp);
+ SKIPSPACE(ms);
+ } else {
+ warning(catgets(catd, 1, 322, "unknown option for host %s"), mbs_buffer);
+ SKIPTOEND(ms);
+ break;
+ }
+ }
+ }
+ break; /* out of outermost for() loop. */
+ }
+ }
+ }
+ retmem(make_machines_list);
+ return(pmake_max_jobs);
+}
+
+/*
+ * pskip_till_next_word(cp)
+ *
+ * Parameters:
+ * cp the address of the string pointer.
+ *
+ * On return:
+ * cp points to beginning of machine name.
+ *
+ */
+static void
+pskip_till_next_word(wchar_t **cp)
+{
+ /*
+ * Keep recursing until all combinations of white spaces
+ * and comments have been skipped.
+ */
+ if (pskip_white_space(cp) || pskip_comment(cp)) {
+ pskip_till_next_word(cp);
+ }
+}
+
+/*
+ * pskip_white_space(cp_address)
+ *
+ * Advances the string pointer so that it points to the first
+ * non white character (space/tab/linefeed).
+ *
+ * Parameters:
+ * cp_address the address of the string pointer.
+ *
+ * Return Value:
+ * True if the pointer was changed.
+ *
+ */
+static Boolean
+pskip_white_space(wchar_t **cp_address)
+{
+ wchar_t *cp = *cp_address;
+
+ while (*cp && iswspace(*cp)) {
+ cp++;
+ }
+ /* Have we skipped any characters? */
+ if (cp != *cp_address) {
+ *cp_address = cp;
+ return(true);
+ } else {
+ return(false);
+ }
+}
+
+/*
+ * pskip_comment(cp_address)
+ *
+ * If cp_address is pointing to '#' (the beginning of a comment),
+ * increment the pointer till you reach end of line.
+ *
+ * Parameters:
+ * cp_address the address of the string pointer.
+ *
+ * Return Value:
+ * True if the pointer was changed.
+ *
+ */
+static Boolean
+pskip_comment(wchar_t **cp_address)
+{
+ wchar_t *cp = *cp_address;
+
+ /* Is this the beginning of a comment? Skip till end of line. */
+ if (*cp == '#') {
+ SKIPTOEND(cp);
+ }
+ /* Have we skipped a comment line? */
+ if (cp != *cp_address) {
+ *cp_address = cp;
+ return(true);
+ } else {
+ return(false);
+ }
+}
+
+static int
+get_max(wchar_t **ms_address, wchar_t *hostname)
+{
+ wchar_t *ms = *ms_address;
+ int limit = PMAKE_DEF_MAX_JOBS; /* Default setting. */
+
+ WCSTOMBS(mbs_buffer, hostname);
+ /* Look for `='. */
+ SKIPSPACE(ms);
+ if ((!*ms) || (*ms == '\n') || (*ms != '=')) {
+ SKIPTOEND(ms);
+ warning(catgets(catd, 1, 319, "expected `=' after max, ignoring rest of line for host %s"),
+ mbs_buffer);
+ *ms_address = ms;
+ return((int) limit);
+ } else {
+ ms++;
+ SKIPSPACE(ms);
+ if ((*ms != '\n') && (*ms != '\0')) {
+ /* We've found, hopefully, a valid "max" value. */
+ limit = (int) wcstol(ms, &ms, 10);
+ if (limit < 1) {
+ limit = PMAKE_DEF_MAX_JOBS;
+ warning(catgets(catd, 1, 320, "max value cannot be less than or equal to zero for host %s"), mbs_buffer);
+ }
+ } else {
+ /* No "max" value after "max=". */
+ warning(catgets(catd, 1, 321, "no max value specified for host %s"), mbs_buffer);
+ }
+ *ms_address = ms;
+ return(limit);
+ }
+}
+
+#endif
+
diff --git a/usr/src/make_src/Make/bin/make/common/read.cc b/usr/src/make_src/Make/bin/make/common/read.cc
new file mode 100644
index 0000000..586d609
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/read.cc
@@ -0,0 +1,2197 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)read.cc 1.64 06/12/12
+ */
+
+#pragma ident "@(#)read.cc 1.64 06/12/12"
+
+/*
+ * read.c
+ *
+ * This file contains the makefile reader.
+ */
+
+/*
+ * Included files
+ */
+#include <avo/avo_alloca.h> /* alloca() */
+#include <errno.h> /* errno */
+#include <fcntl.h> /* fcntl() */
+#include <mk/defs.h>
+#include <mksh/macro.h> /* expand_value(), expand_macro() */
+#include <mksh/misc.h> /* getmem() */
+#include <mksh/read.h> /* get_next_block_fn() */
+#include <sys/uio.h> /* read() */
+#include <unistd.h> /* read(), unlink() */
+
+#if defined(HP_UX) || defined(linux)
+#include <avo/types.h>
+extern "C" Avo_err *avo_find_run_dir(char **dirp);
+#endif
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+static int line_started_with_space=0; // Used to diagnose spaces instead of tabs
+
+/*
+ * File table of contents
+ */
+static void parse_makefile(register Name true_makefile_name, register Source source);
+static Source push_macro_value(register Source bp, register wchar_t *buffer, int size, register Source source);
+extern void enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen);
+extern Name normalize_name(register wchar_t *name_string, register int length);
+
+/*
+ * read_simple_file(makefile_name, chase_path, doname_it,
+ * complain, must_exist, report_file, lock_makefile)
+ *
+ * Make the makefile and setup to read it. Actually read it if it is stdio
+ *
+ * Return value:
+ * false if the read failed
+ *
+ * Parameters:
+ * makefile_name Name of the file to read
+ * chase_path Use the makefile path when opening file
+ * doname_it Call doname() to build the file first
+ * complain Print message if doname/open fails
+ * must_exist Generate fatal if file is missing
+ * report_file Report file when running -P
+ * lock_makefile Lock the makefile when reading
+ *
+ * Static variables used:
+ *
+ * Global variables used:
+ * do_not_exec_rule Is -n on?
+ * file_being_read Set to the name of the new file
+ * line_number The number of the current makefile line
+ * makefiles_used A list of all makefiles used, appended to
+ */
+
+
+Boolean
+read_simple_file(register Name makefile_name, register Boolean chase_path, register Boolean doname_it, Boolean complain, Boolean must_exist, Boolean report_file, Boolean lock_makefile)
+{
+ static short max_include_depth;
+ register Property makefile = maybe_append_prop(makefile_name,
+ makefile_prop);
+ Boolean forget_after_parse = false;
+ static pathpt makefile_path;
+ register int n;
+ char *path;
+ register Source source = ALLOC(Source);
+ Property orig_makefile = makefile;
+ Dependency *dpp;
+ Dependency dp;
+ register int length;
+ wchar_t *previous_file_being_read = file_being_read;
+ int previous_line_number = line_number;
+ wchar_t previous_current_makefile[MAXPATHLEN];
+ Makefile_type save_makefile_type;
+ Name normalized_makefile_name;
+ register wchar_t *string_start;
+ register wchar_t *string_end;
+
+
+#if defined(HP_UX) || defined(linux)
+ Avo_err *findrundir_err;
+ char *run_dir, makerules_dir[BUFSIZ];
+#endif
+
+ wchar_t * wcb = get_wstring(makefile_name->string_mb);
+
+#ifdef NSE
+ if (report_file){
+ wscpy(previous_current_makefile, current_makefile);
+ wscpy(current_makefile, wcb);
+ }
+#endif
+ if (max_include_depth++ >= 40) {
+ fatal(catgets(catd, 1, 66, "Too many nested include statements"));
+ }
+ if (makefile->body.makefile.contents != NULL) {
+ retmem(makefile->body.makefile.contents);
+ }
+ source->inp_buf =
+ source->inp_buf_ptr =
+ source->inp_buf_end = NULL;
+ source->error_converting = false;
+ makefile->body.makefile.contents = NULL;
+ makefile->body.makefile.size = 0;
+ if ((makefile_name->hash.length != 1) ||
+ (wcb[0] != (int) hyphen_char)) {
+ if ((makefile->body.makefile.contents == NULL) &&
+ (doname_it)) {
+ if (makefile_path == NULL) {
+ add_dir_to_path(".",
+ &makefile_path,
+ -1);
+#ifdef SUN5_0
+ add_dir_to_path(NOCATGETS("/usr/share/lib/make"),
+ &makefile_path,
+ -1);
+ add_dir_to_path(NOCATGETS("/etc/default"),
+ &makefile_path,
+ -1);
+#elif defined(HP_UX)
+ findrundir_err = avo_find_run_dir(&run_dir);
+ if (! findrundir_err) {
+ (void) sprintf(makerules_dir, NOCATGETS("%s/../share/lib/make"), run_dir);
+ add_dir_to_path(makerules_dir,
+ &makefile_path,
+ -1);
+ }
+
+ add_dir_to_path(NOCATGETS("/opt/SUNWspro/share/lib/make"),
+ &makefile_path,
+ -1);
+ add_dir_to_path(NOCATGETS("/usr/share/lib/make"),
+ &makefile_path,
+ -1);
+#elif defined(linux)
+ findrundir_err = avo_find_run_dir(&run_dir);
+ if (! findrundir_err) {
+ (void) sprintf(makerules_dir, NOCATGETS("%s/../lib"), run_dir);
+ add_dir_to_path(makerules_dir,
+ &makefile_path,
+ -1);
+ }
+
+ add_dir_to_path(NOCATGETS("/usr/SUNWspro/lib"),
+ &makefile_path,
+ -1);
+ add_dir_to_path(NOCATGETS("/opt/SUNWspro/share/lib/make"),
+ &makefile_path,
+ -1);
+ add_dir_to_path(NOCATGETS("/usr/share/lib/make"),
+ &makefile_path,
+ -1);
+#else
+ add_dir_to_path(NOCATGETS("/usr/include/make"),
+ &makefile_path,
+ -1);
+#endif
+ }
+ save_makefile_type = makefile_type;
+ makefile_type = reading_nothing;
+ if (doname(makefile_name, true, false) == build_dont_know) {
+ /* Try normalized filename */
+ string_start=get_wstring(makefile_name->string_mb);
+ for (string_end=string_start+1; *string_end != NULL; string_end++);
+ normalized_makefile_name=normalize_name(string_start, string_end - string_start);
+ if ((strcmp(makefile_name->string_mb, normalized_makefile_name->string_mb) == 0) ||
+ (doname(normalized_makefile_name, true, false) == build_dont_know)) {
+ n = access_vroot(makefile_name->string_mb,
+ 4,
+ chase_path ?
+ makefile_path : NULL,
+ VROOT_DEFAULT);
+ if (n == 0) {
+ get_vroot_path((char **) NULL,
+ &path,
+ (char **) NULL);
+ if ((path[0] == (int) period_char) &&
+ (path[1] == (int) slash_char)) {
+ path += 2;
+ }
+ MBSTOWCS(wcs_buffer, path);
+ makefile_name = GETNAME(wcs_buffer,
+ FIND_LENGTH);
+ }
+ }
+ retmem(string_start);
+ /*
+ * Commented out: retmem_mb(normalized_makefile_name->string_mb);
+ * We have to return this memory, but it seems to trigger a bug
+ * in dmake or in Sun C++ 5.7 compiler (it works ok if this code
+ * is compiled using Sun C++ 5.6).
+ */
+ // retmem_mb(normalized_makefile_name->string_mb);
+ }
+ makefile_type = save_makefile_type;
+ }
+ source->string.free_after_use = false;
+ source->previous = NULL;
+ source->already_expanded = false;
+ /* Lock the file for read, but not when -n. */
+ if (lock_makefile &&
+ !do_not_exec_rule) {
+
+ make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(NOCATGETS(".lock")) + 1);
+ (void) sprintf(make_state_lockfile,
+ NOCATGETS("%s.lock"),
+ make_state->string_mb);
+ (void) file_lock(make_state->string_mb,
+ make_state_lockfile,
+ (int *) &make_state_locked,
+ 0);
+ if(!make_state_locked) {
+ printf(NOCATGETS("-- NO LOCKING for read\n"));
+ retmem_mb(make_state_lockfile);
+ make_state_lockfile = 0;
+ return failed;
+ }
+ }
+ if (makefile->body.makefile.contents == NULL) {
+ save_makefile_type = makefile_type;
+ makefile_type = reading_nothing;
+ if ((doname_it) &&
+ (doname(makefile_name, true, false) == build_failed)) {
+ if (complain) {
+ (void) fprintf(stderr,
+#ifdef DISTRIBUTED
+ catgets(catd, 1, 67, "dmake: Couldn't dmake `%s'\n"),
+#else
+ catgets(catd, 1, 237, "make: Couldn't make `%s'\n"),
+#endif
+ makefile_name->string_mb);
+ }
+ max_include_depth--;
+ makefile_type = save_makefile_type;
+ return failed;
+ }
+ makefile_type = save_makefile_type;
+ //
+ // Before calling exists() make sure that we have the right timestamp
+ //
+ makefile_name->stat.time = file_no_time;
+
+ if (exists(makefile_name) == file_doesnt_exist) {
+ if (complain ||
+ (makefile_name->stat.stat_errno != ENOENT)) {
+ if (must_exist) {
+ fatal(catgets(catd, 1, 68, "Can't find `%s': %s"),
+ makefile_name->string_mb,
+ errmsg(makefile_name->
+ stat.stat_errno));
+ } else {
+ warning(catgets(catd, 1, 69, "Can't find `%s': %s"),
+ makefile_name->string_mb,
+ errmsg(makefile_name->
+ stat.stat_errno));
+ }
+ }
+ max_include_depth--;
+ if(make_state_locked && (make_state_lockfile != NULL)) {
+ (void) unlink(make_state_lockfile);
+ retmem_mb(make_state_lockfile);
+ make_state_lockfile = NULL;
+ make_state_locked = false;
+ }
+ retmem(wcb);
+ retmem_mb((char *)source);
+ return failed;
+ }
+ /*
+ * These values are the size and bytes of
+ * the MULTI-BYTE makefile.
+ */
+ orig_makefile->body.makefile.size =
+ makefile->body.makefile.size =
+ source->bytes_left_in_file =
+ makefile_name->stat.size;
+ if (report_file) {
+ for (dpp = &makefiles_used;
+ *dpp != NULL;
+ dpp = &(*dpp)->next);
+ dp = ALLOC(Dependency);
+ dp->next = NULL;
+ dp->name = makefile_name;
+ dp->automatic = false;
+ dp->stale = false;
+ dp->built = false;
+ *dpp = dp;
+ }
+ source->fd = open_vroot(makefile_name->string_mb,
+ O_RDONLY,
+ 0,
+ NULL,
+ VROOT_DEFAULT);
+ if (source->fd < 0) {
+ if (complain || (errno != ENOENT)) {
+ if (must_exist) {
+ fatal(catgets(catd, 1, 70, "Can't open `%s': %s"),
+ makefile_name->string_mb,
+ errmsg(errno));
+ } else {
+ warning(catgets(catd, 1, 71, "Can't open `%s': %s"),
+ makefile_name->string_mb,
+ errmsg(errno));
+ }
+ }
+ max_include_depth--;
+ return failed;
+ }
+ (void) fcntl(source->fd, F_SETFD, 1);
+ orig_makefile->body.makefile.contents =
+ makefile->body.makefile.contents =
+ source->string.text.p =
+ source->string.buffer.start =
+ ALLOC_WC((int) (makefile_name->stat.size + 2));
+ if (makefile_type == reading_cpp_file) {
+ forget_after_parse = true;
+ }
+ source->string.text.end = source->string.text.p;
+ source->string.buffer.end =
+ source->string.text.p + makefile_name->stat.size;
+ } else {
+ /* Do we ever reach here? */
+ source->fd = -1;
+ source->string.text.p =
+ source->string.buffer.start =
+ makefile->body.makefile.contents;
+ source->string.text.end =
+ source->string.buffer.end =
+ source->string.text.p + makefile->body.makefile.size;
+ source->bytes_left_in_file =
+ makefile->body.makefile.size;
+ }
+ file_being_read = wcb;
+ } else {
+ char *stdin_text_p;
+ char *stdin_text_end;
+ char *stdin_buffer_start;
+ char *stdin_buffer_end;
+ char *p_mb;
+ int num_mb_chars;
+ size_t num_wc_chars;
+
+ MBSTOWCS(wcs_buffer, NOCATGETS("Standard in"));
+ makefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ /*
+ * Memory to read standard in, then convert it
+ * to wide char strings.
+ */
+ stdin_buffer_start =
+ stdin_text_p = getmem(length = 1024);
+ stdin_buffer_end = stdin_text_p + length;
+ MBSTOWCS(wcs_buffer, NOCATGETS("standard input"));
+ file_being_read = (wchar_t *) wsdup(wcs_buffer);
+ line_number = 0;
+ while ((n = read(fileno(stdin),
+ stdin_text_p,
+ length)) > 0) {
+ length -= n;
+ stdin_text_p += n;
+ if (length == 0) {
+ p_mb = getmem(length = 1024 +
+ (stdin_buffer_end -
+ stdin_buffer_start));
+ (void) strncpy(p_mb,
+ stdin_buffer_start,
+ (stdin_buffer_end -
+ stdin_buffer_start));
+ retmem_mb(stdin_buffer_start);
+ stdin_text_p = p_mb +
+ (stdin_buffer_end - stdin_buffer_start);
+ stdin_buffer_start = p_mb;
+ stdin_buffer_end =
+ stdin_buffer_start + length;
+ length = 1024;
+ }
+ }
+ if (n < 0) {
+ fatal(catgets(catd, 1, 72, "Error reading standard input: %s"),
+ errmsg(errno));
+ }
+ stdin_text_p = stdin_buffer_start;
+ stdin_text_end = stdin_buffer_end - length;
+ num_mb_chars = stdin_text_end - stdin_text_p;
+
+ /*
+ * Now, convert the sequence of multibyte chars into
+ * a sequence of corresponding wide character codes.
+ */
+ source->string.free_after_use = false;
+ source->previous = NULL;
+ source->bytes_left_in_file = 0;
+ source->fd = -1;
+ source->already_expanded = false;
+ source->string.buffer.start =
+ source->string.text.p = ALLOC_WC(num_mb_chars + 1);
+ source->string.buffer.end =
+ source->string.text.p + num_mb_chars;
+ num_wc_chars = mbstowcs(source->string.text.p,
+ stdin_text_p,
+ num_mb_chars);
+ if ((int) num_wc_chars >= 0) {
+ source->string.text.end =
+ source->string.text.p + num_wc_chars;
+ }
+ (void) retmem_mb(stdin_text_p);
+ }
+ line_number = 1;
+ if (trace_reader) {
+ (void) printf(catgets(catd, 1, 73, ">>>>>>>>>>>>>>>> Reading makefile %s\n"),
+ makefile_name->string_mb);
+ }
+ parse_makefile(makefile_name, source);
+ if (trace_reader) {
+ (void) printf(catgets(catd, 1, 74, ">>>>>>>>>>>>>>>> End of makefile %s\n"),
+ makefile_name->string_mb);
+ }
+#ifdef NSE
+ if (report_file && (previous_current_makefile[0] != NULL)) {
+ wscpy(current_makefile, previous_current_makefile);
+ }
+#endif
+ if(file_being_read) {
+ retmem(file_being_read);
+ }
+ file_being_read = previous_file_being_read;
+ line_number = previous_line_number;
+ makefile_type = reading_nothing;
+ max_include_depth--;
+ if (make_state_locked) {
+ /* Unlock .make.state. */
+ unlink(make_state_lockfile);
+ make_state_locked = false;
+ retmem_mb(make_state_lockfile);
+ }
+ if (forget_after_parse) {
+ retmem(makefile->body.makefile.contents);
+ makefile->body.makefile.contents = NULL;
+ }
+ retmem_mb((char *)source);
+ return succeeded;
+}
+
+/*
+ * parse_makefile(true_makefile_name, source)
+ *
+ * Strings are read from Sources.
+ * When macros are found, their values are represented by a
+ * Source that is pushed on a stack. At end of string
+ * (that is returned from GET_CHAR() as 0), the block is popped.
+ *
+ * Parameters:
+ * true_makefile_name The name of makefile we are parsing
+ * source The source block to read from
+ *
+ * Global variables used:
+ * do_not_exec_rule Is -n on?
+ * line_number The number of the current makefile line
+ * makefile_type What kind of makefile are we reading?
+ * empty_name The Name ""
+ */
+static void
+parse_makefile(register Name true_makefile_name, register Source source)
+{
+/*
+ char mb_buffer[MB_LEN_MAX];
+ */
+ register wchar_t *source_p;
+ register wchar_t *source_end;
+ register wchar_t *string_start;
+ wchar_t *string_end;
+ register Boolean macro_seen_in_string;
+ Boolean append;
+ String_rec name_string;
+ wchar_t name_buffer[STRING_BUFFER_LENGTH];
+ register int distance;
+ register int paren_count;
+ int brace_count;
+ int char_number;
+ Cmd_line command;
+ Cmd_line command_tail;
+ Name macro_value;
+
+ Name_vector_rec target;
+ Name_vector_rec depes;
+ Name_vector_rec extra_name_vector;
+ Name_vector current_names;
+ Name_vector extra_names = &extra_name_vector;
+ Name_vector nvp;
+ Boolean target_group_seen;
+
+ register Reader_state state;
+ register Reader_state on_eoln_state;
+ register Separator separator;
+
+ wchar_t buffer[4 * STRING_BUFFER_LENGTH];
+ Source extrap;
+
+ Boolean save_do_not_exec_rule = do_not_exec_rule;
+ Name makefile_name;
+
+ static Name sh_name;
+ static Name shell_name;
+ int i;
+
+ static wchar_t include_space[10];
+ static wchar_t include_tab[10];
+ int tmp_bytes_left_in_string;
+ Boolean tmp_maybe_include = false;
+ int emptycount = 0;
+ Boolean first_target;
+
+ String_rec include_name;
+ wchar_t include_buffer[STRING_BUFFER_LENGTH];
+
+ target.next = depes.next = NULL;
+ /* Move some values from their struct to register declared locals */
+ CACHE_SOURCE(0);
+
+ start_new_line:
+ /*
+ * Read whitespace on old line. Leave pointer on first char on
+ * next line.
+ */
+ first_target = true;
+ on_eoln_state = exit_state;
+/*
+ for (WCTOMB(mb_buffer, GET_CHAR());
+ 1;
+ source_p++, WCTOMB(mb_buffer, GET_CHAR()))
+ switch (mb_buffer[0]) {
+ */
+ for (char_number=0; 1; source_p++,char_number++) switch (GET_CHAR()) {
+ case nul_char:
+ /* End of this string. Pop it and return to the previous one */
+ GET_NEXT_BLOCK(source);
+ source_p--;
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ break;
+ case newline_char:
+ end_of_line:
+ source_p++;
+ if (source->fd >= 0) {
+ line_number++;
+ }
+ switch (GET_CHAR()) {
+ case nul_char:
+ GET_NEXT_BLOCK(source);
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ /* Go back to the top of this loop */
+ goto start_new_line;
+ case newline_char:
+ case numbersign_char:
+ case dollar_char:
+ case space_char:
+ case tab_char:
+ /*
+ * Go back to the top of this loop since the
+ * new line does not start with a regular char.
+ */
+ goto start_new_line;
+ default:
+ /* We found the first proper char on the new line */
+ goto start_new_line_no_skip;
+ }
+ case space_char:
+ if (char_number == 0)
+ line_started_with_space=line_number;
+ case tab_char:
+ /* Whitespace. Just keep going in this loop */
+ break;
+ case numbersign_char:
+ /* Comment. Skip over it */
+ for (; 1; source_p++) {
+ switch (GET_CHAR()) {
+ case nul_char:
+ GET_NEXT_BLOCK_NOCHK(source);
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ if (source->error_converting) {
+ // Illegal byte sequence - skip its first byte
+ source->inp_buf_ptr++;
+ }
+ source_p--;
+ break;
+ case backslash_char:
+ /* Comments can be continued */
+ if (*++source_p == (int) nul_char) {
+ GET_NEXT_BLOCK_NOCHK(source);
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ if (source->error_converting) {
+ // Illegal byte sequence - skip its first byte
+ source->inp_buf_ptr++;
+ source_p--;
+ break;
+ }
+ }
+ if(*source_p == (int) newline_char) {
+ if (source->fd >= 0) {
+ line_number++;
+ }
+ }
+ break;
+ case newline_char:
+ /*
+ * After we skip the comment we go to
+ * the end of line handler since end of
+ * line terminates comments.
+ */
+ goto end_of_line;
+ }
+ }
+ case dollar_char:
+ /* Macro reference */
+ if (source->already_expanded) {
+ /*
+ * If we are reading from the expansion of a
+ * macro we already expanded everything enough.
+ */
+ goto start_new_line_no_skip;
+ }
+ /*
+ * Expand the value and push the Source on the stack of
+ * things being read.
+ */
+ source_p++;
+ UNCACHE_SOURCE();
+ {
+ Source t = (Source) alloca((int) sizeof (Source_rec));
+ source = push_macro_value(t,
+ buffer,
+ sizeof buffer,
+ source);
+ }
+ CACHE_SOURCE(1);
+ break;
+ default:
+ /* We found the first proper char on the new line */
+ goto start_new_line_no_skip;
+ }
+
+ /*
+ * We found the first normal char (one that starts an identifier)
+ * on the newline.
+ */
+start_new_line_no_skip:
+ /* Inspect that first char to see if it maybe is special anyway */
+ switch (GET_CHAR()) {
+ case nul_char:
+ GET_NEXT_BLOCK(source);
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ goto start_new_line_no_skip;
+ case newline_char:
+ /* Just in case */
+ goto start_new_line;
+ case exclam_char:
+ /* Evaluate the line before it is read */
+ string_start = source_p + 1;
+ macro_seen_in_string = false;
+ /* Stuff the line in a string so we can eval it. */
+ for (; 1; source_p++) {
+ switch (GET_CHAR()) {
+ case newline_char:
+ goto eoln_1;
+ case nul_char:
+ if (source->fd > 0) {
+ if (!macro_seen_in_string) {
+ macro_seen_in_string = true;
+ INIT_STRING_FROM_STACK(
+ name_string, name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ GET_NEXT_BLOCK(source);
+ string_start = source_p;
+ source_p--;
+ break;
+ }
+ eoln_1:
+ if (!macro_seen_in_string) {
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ extrap = (Source)
+ alloca((int) sizeof (Source_rec));
+ extrap->string.buffer.start = NULL;
+ extrap->inp_buf =
+ extrap->inp_buf_ptr =
+ extrap->inp_buf_end = NULL;
+ extrap->error_converting = false;
+ if (*source_p == (int) nul_char) {
+ source_p++;
+ }
+ /* Eval the macro */
+ expand_value(GETNAME(name_string.buffer.start,
+ FIND_LENGTH),
+ &extrap->string,
+ false);
+ if (name_string.free_after_use) {
+ retmem(name_string.buffer.start);
+ }
+ UNCACHE_SOURCE();
+ extrap->string.text.p =
+ extrap->string.buffer.start;
+ extrap->fd = -1;
+ /* And push the value */
+ extrap->previous = source;
+ source = extrap;
+ CACHE_SOURCE(0);
+ goto line_evald;
+ }
+ }
+ default:
+ goto line_evald;
+ }
+
+ /* We now have a line we can start reading */
+ line_evald:
+ if (source == NULL) {
+ GOTO_STATE(exit_state);
+ }
+ /* Check if this is an include command */
+ if ((makefile_type == reading_makefile) &&
+ !source->already_expanded) {
+ if (include_space[0] == (int) nul_char) {
+ MBSTOWCS(include_space, NOCATGETS("include "));
+ MBSTOWCS(include_tab, NOCATGETS("include\t"));
+ }
+ if ((IS_WEQUALN(source_p, include_space, 8)) ||
+ (IS_WEQUALN(source_p, include_tab, 8))) {
+ source_p += 7;
+ if (iswspace(*source_p)) {
+ Makefile_type save_makefile_type;
+ wchar_t *name_start;
+ int name_length;
+
+ /*
+ * Yes, this is an include.
+ * Skip spaces to get to the filename.
+ */
+ while (iswspace(*source_p) ||
+ (*source_p == (int) nul_char)) {
+ switch (GET_CHAR()) {
+ case nul_char:
+ GET_NEXT_BLOCK(source);
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ break;
+
+ default:
+ source_p++;
+ break;
+ }
+ }
+
+ string_start = source_p;
+ /* Find the end of the filename */
+ macro_seen_in_string = false;
+ while (!iswspace(*source_p) ||
+ (*source_p == (int) nul_char)) {
+ switch (GET_CHAR()) {
+ case nul_char:
+ if (!macro_seen_in_string) {
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ macro_seen_in_string = true;
+ GET_NEXT_BLOCK(source);
+ string_start = source_p;
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ break;
+
+ default:
+ source_p++;
+ break;
+ }
+ }
+
+ source->string.text.p = source_p;
+ if (macro_seen_in_string) {
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ name_start = name_string.buffer.start;
+ name_length = name_string.text.p - name_start;
+ } else {
+ name_start = string_start;
+ name_length = source_p - string_start;
+ }
+
+ /* Strip "./" from the head of the name */
+ if ((name_start[0] == (int) period_char) &&
+ (name_start[1] == (int) slash_char)) {
+ name_start += 2;
+ name_length -= 2;
+ }
+ /* if include file name is surrounded by double quotes */
+ if ((name_start[0] == (int) doublequote_char) &&
+ (name_start[name_length - 1] == (int) doublequote_char)) {
+ name_start += 1;
+ name_length -= 2;
+
+ /* if name does not begin with a slash char */
+ if (name_start[0] != (int) slash_char) {
+ if ((name_start[0] == (int) period_char) &&
+ (name_start[1] == (int) slash_char)) {
+ name_start += 2;
+ name_length -= 2;
+ }
+
+ INIT_STRING_FROM_STACK(include_name, include_buffer);
+ APPEND_NAME(true_makefile_name,
+ &include_name,
+ true_makefile_name->hash.length);
+
+ wchar_t *slash = wsrchr(include_name.buffer.start, (int) slash_char);
+ if (slash != NULL) {
+ include_name.text.p = slash + 1;
+ append_string(name_start,
+ &include_name,
+ name_length);
+
+ name_start = include_name.buffer.start;
+ name_length = include_name.text.p - name_start;
+ }
+ }
+ }
+
+ /* Even when we run -n we want to create makefiles */
+ do_not_exec_rule = false;
+ makefile_name = GETNAME(name_start, name_length);
+ if (makefile_name->dollar) {
+ String_rec destination;
+ wchar_t buffer[STRING_BUFFER_LENGTH];
+ wchar_t *p;
+ wchar_t *q;
+
+ INIT_STRING_FROM_STACK(destination, buffer);
+ expand_value(makefile_name,
+ &destination,
+ false);
+ for (p = destination.buffer.start;
+ (*p != (int) nul_char) && iswspace(*p);
+ p++);
+ for (q = p;
+ (*q != (int) nul_char) && !iswspace(*q);
+ q++);
+ makefile_name = GETNAME(p, q-p);
+ if (destination.free_after_use) {
+ retmem(destination.buffer.start);
+ }
+ }
+ source_p++;
+ UNCACHE_SOURCE();
+ /* Read the file */
+ save_makefile_type = makefile_type;
+ if (read_simple_file(makefile_name,
+ true,
+ true,
+ true,
+ false,
+ true,
+ false) == failed) {
+ fatal_reader(catgets(catd, 1, 75, "Read of include file `%s' failed"),
+ makefile_name->string_mb);
+ }
+ makefile_type = save_makefile_type;
+ do_not_exec_rule = save_do_not_exec_rule;
+ CACHE_SOURCE(0);
+ goto start_new_line;
+ } else {
+ source_p -= 7;
+ }
+ } else {
+ /* Check if the word include was split across 8K boundary. */
+
+ tmp_bytes_left_in_string = source->string.text.end - source_p;
+ if (tmp_bytes_left_in_string < 8) {
+ tmp_maybe_include = false;
+ if (IS_WEQUALN(source_p,
+ include_space,
+ tmp_bytes_left_in_string)) {
+ tmp_maybe_include = true;
+ }
+ if (tmp_maybe_include) {
+ GET_NEXT_BLOCK(source);
+ tmp_maybe_include = false;
+ goto line_evald;
+ }
+ }
+ }
+ }
+
+ /* Reset the status in preparation for the new line */
+ for (nvp = &target; nvp != NULL; nvp = nvp->next) {
+ nvp->used = 0;
+ }
+ for (nvp = &depes; nvp != NULL; nvp = nvp->next) {
+ nvp->used = 0;
+ }
+ target_group_seen = false;
+ command = command_tail = NULL;
+ macro_value = NULL;
+ append = false;
+ current_names = &target;
+ SET_STATE(scan_name_state);
+ on_eoln_state = illegal_eoln_state;
+ separator = none_seen;
+
+ /* The state machine starts here */
+ enter_state:
+ while (1) switch (state) {
+
+/****************************************************************
+ * Scan name state
+ */
+case scan_name_state:
+ /* Scan an identifier. We skip over chars until we find a break char */
+ /* First skip white space. */
+ for (; 1; source_p++) switch (GET_CHAR()) {
+ case nul_char:
+ GET_NEXT_BLOCK(source);
+ source_p--;
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ break;
+ case newline_char:
+ /* We found the end of the line. */
+ /* Do postprocessing or return error */
+ source_p++;
+ if (source->fd >= 0) {
+ line_number++;
+ }
+ GOTO_STATE(on_eoln_state);
+ case backslash_char:
+ /* Continuation */
+ if (*++source_p == (int) nul_char) {
+ GET_NEXT_BLOCK(source);
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ }
+ if (*source_p == (int) newline_char) {
+ if (source->fd >= 0) {
+ line_number++;
+ }
+ } else {
+ source_p--;
+ }
+ break;
+ case tab_char:
+ case space_char:
+ /* Whitespace is skipped */
+ break;
+ case numbersign_char:
+ /* Comment. Skip over it */
+ for (; 1; source_p++) {
+ switch (GET_CHAR()) {
+ case nul_char:
+ GET_NEXT_BLOCK_NOCHK(source);
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ if (source->error_converting) {
+ // Illegal byte sequence - skip its first byte
+ source->inp_buf_ptr++;
+ }
+ source_p--;
+ break;
+ case backslash_char:
+ if (*++source_p == (int) nul_char) {
+ GET_NEXT_BLOCK_NOCHK(source);
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ if (source->error_converting) {
+ // Illegal byte sequence - skip its first byte
+ source->inp_buf_ptr++;
+ source_p--;
+ break;
+ }
+ }
+ if(*source_p == (int) newline_char) {
+ if (source->fd >= 0) {
+ line_number++;
+ }
+ }
+ break;
+ case newline_char:
+ source_p++;
+ if (source->fd >= 0) {
+ line_number++;
+ }
+ GOTO_STATE(on_eoln_state);
+ }
+ }
+ case dollar_char:
+ /* Macro reference. Expand and push value */
+ if (source->already_expanded) {
+ goto scan_name;
+ }
+ source_p++;
+ UNCACHE_SOURCE();
+ {
+ Source t = (Source) alloca((int) sizeof (Source_rec));
+ source = push_macro_value(t,
+ buffer,
+ sizeof buffer,
+ source);
+ }
+ CACHE_SOURCE(1);
+ break;
+ default:
+ /* End of white space */
+ goto scan_name;
+ }
+
+ /* First proper identifier character */
+ scan_name:
+
+ string_start = source_p;
+ paren_count = brace_count = 0;
+ macro_seen_in_string = false;
+ resume_name_scan:
+ for (; 1; source_p++) {
+ switch (GET_CHAR()) {
+ case nul_char:
+ /* Save what we have seen so far of the identifier */
+ if (source_p != string_start) {
+ if (!macro_seen_in_string) {
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ macro_seen_in_string = true;
+ }
+ /* Get more text to read */
+ GET_NEXT_BLOCK(source);
+ string_start = source_p;
+ source_p--;
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ break;
+ case newline_char:
+ if (paren_count > 0) {
+ fatal_reader(catgets(catd, 1, 76, "Unmatched `(' on line"));
+ }
+ if (brace_count > 0) {
+ fatal_reader(catgets(catd, 1, 77, "Unmatched `{' on line"));
+ }
+ source_p++;
+ /* Enter name */
+ current_names = enter_name(&name_string,
+ macro_seen_in_string,
+ string_start,
+ source_p - 1,
+ current_names,
+ &extra_names,
+ &target_group_seen);
+ first_target = false;
+ if (extra_names == NULL) {
+ extra_names = (Name_vector)
+ alloca((int) sizeof (Name_vector_rec));
+ }
+ /* Do postprocessing or return error */
+ if (source->fd >= 0) {
+ line_number++;
+ }
+ GOTO_STATE(on_eoln_state);
+ case backslash_char:
+ /* Check if this is a quoting backslash */
+ if (!macro_seen_in_string) {
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ macro_seen_in_string = true;
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ if (*++source_p == (int) nul_char) {
+ GET_NEXT_BLOCK(source);
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ }
+ if (*source_p == (int) newline_char) {
+ if (source->fd >= 0) {
+ line_number++;
+ }
+ *source_p = (int) space_char;
+ string_start = source_p;
+ goto resume_name_scan;
+ } else {
+ string_start = source_p;
+ break;
+ }
+ break;
+ case numbersign_char:
+ if (paren_count + brace_count > 0) {
+ break;
+ }
+ fatal_reader(catgets(catd, 1, 78, "Unexpected comment seen"));
+ case dollar_char:
+ if (source->already_expanded) {
+ break;
+ }
+ /* Save the identifier so far */
+ if (source_p != string_start) {
+ if (!macro_seen_in_string) {
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ macro_seen_in_string = true;
+ }
+ /* Eval and push the macro */
+ source_p++;
+ UNCACHE_SOURCE();
+ {
+ Source t =
+ (Source) alloca((int) sizeof (Source_rec));
+ source = push_macro_value(t,
+ buffer,
+ sizeof buffer,
+ source);
+ }
+ CACHE_SOURCE(1);
+ string_start = source_p + 1;
+ break;
+ case parenleft_char:
+ paren_count++;
+ break;
+ case parenright_char:
+ if (--paren_count < 0) {
+ fatal_reader(catgets(catd, 1, 79, "Unmatched `)' on line"));
+ }
+ break;
+ case braceleft_char:
+ brace_count++;
+ break;
+ case braceright_char:
+ if (--brace_count < 0) {
+ fatal_reader(catgets(catd, 1, 80, "Unmatched `}' on line"));
+ }
+ break;
+ case ampersand_char:
+ case greater_char:
+ case bar_char:
+ if (paren_count + brace_count == 0) {
+ source_p++;
+ }
+ /* Fall into */
+ case tab_char:
+ case space_char:
+ if (paren_count + brace_count > 0) {
+ break;
+ }
+ current_names = enter_name(&name_string,
+ macro_seen_in_string,
+ string_start,
+ source_p,
+ current_names,
+ &extra_names,
+ &target_group_seen);
+ first_target = false;
+ if (extra_names == NULL) {
+ extra_names = (Name_vector)
+ alloca((int) sizeof (Name_vector_rec));
+ }
+ goto enter_state;
+ case colon_char:
+ if (paren_count + brace_count > 0) {
+ break;
+ }
+ if (separator == conditional_seen) {
+ break;
+ }
+/** POSIX **/
+#if 0
+ if(posix) {
+ emptycount = 0;
+ }
+#endif
+/** END POSIX **/
+ /* End of the target list. We now start reading */
+ /* dependencies or a conditional assignment */
+ if (separator != none_seen) {
+ fatal_reader(catgets(catd, 1, 81, "Extra `:', `::', or `:=' on dependency line"));
+ }
+ /* Enter the last target */
+ if ((string_start != source_p) ||
+ macro_seen_in_string) {
+ current_names =
+ enter_name(&name_string,
+ macro_seen_in_string,
+ string_start,
+ source_p,
+ current_names,
+ &extra_names,
+ &target_group_seen);
+ first_target = false;
+ if (extra_names == NULL) {
+ extra_names = (Name_vector)
+ alloca((int)
+ sizeof (Name_vector_rec));
+ }
+ }
+ /* Check if it is ":" "::" or ":=" */
+ scan_colon_label:
+ switch (*++source_p) {
+ case nul_char:
+ GET_NEXT_BLOCK(source);
+ source_p--;
+ if (source == NULL) {
+ GOTO_STATE(enter_dependencies_state);
+ }
+ goto scan_colon_label;
+ case equal_char:
+ if(svr4) {
+ fatal_reader(catgets(catd, 1, 82, "syntax error"));
+ }
+ separator = conditional_seen;
+ source_p++;
+ current_names = &depes;
+ GOTO_STATE(scan_name_state);
+ case colon_char:
+ separator = two_colon;
+ source_p++;
+ break;
+ default:
+ separator = one_colon;
+ }
+ current_names = &depes;
+ on_eoln_state = enter_dependencies_state;
+ GOTO_STATE(scan_name_state);
+ case semicolon_char:
+ if (paren_count + brace_count > 0) {
+ break;
+ }
+ /* End of reading names. Start reading the rule */
+ if ((separator != one_colon) &&
+ (separator != two_colon)) {
+ fatal_reader(catgets(catd, 1, 83, "Unexpected command seen"));
+ }
+ /* Enter the last dependency */
+ if ((string_start != source_p) ||
+ macro_seen_in_string) {
+ current_names =
+ enter_name(&name_string,
+ macro_seen_in_string,
+ string_start,
+ source_p,
+ current_names,
+ &extra_names,
+ &target_group_seen);
+ first_target = false;
+ if (extra_names == NULL) {
+ extra_names = (Name_vector)
+ alloca((int)
+ sizeof (Name_vector_rec));
+ }
+ }
+ source_p++;
+ /* Make sure to enter a rule even if the is */
+ /* no text here */
+ command = command_tail = ALLOC(Cmd_line);
+ command->next = NULL;
+ command->command_line = empty_name;
+ command->make_refd = false;
+ command->ignore_command_dependency = false;
+ command->assign = false;
+ command->ignore_error = false;
+ command->silent = false;
+
+ GOTO_STATE(scan_command_state);
+ case plus_char:
+ /*
+ ** following code drops the target separator plus char if it starts
+ ** a line.
+ */
+ if(first_target && !macro_seen_in_string &&
+ source_p == string_start) {
+ for (; 1; source_p++)
+ switch (GET_CHAR()) {
+ case nul_char:
+ if (source_p != string_start) {
+ if (!macro_seen_in_string) {
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ macro_seen_in_string = true;
+ }
+ GET_NEXT_BLOCK(source);
+ string_start = source_p;
+ source_p--;
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ break;
+ case plus_char:
+ source_p++;
+ while (*source_p == (int) nul_char) {
+ if (source_p != string_start) {
+ if (!macro_seen_in_string) {
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ macro_seen_in_string = true;
+ }
+ GET_NEXT_BLOCK(source);
+ string_start = source_p;
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ }
+ if (*source_p == (int) tab_char ||
+ *source_p == (int) space_char) {
+ macro_seen_in_string = false;
+ string_start = source_p + 1;
+ } else {
+ goto resume_name_scan;
+ }
+ break;
+ case tab_char:
+ case space_char:
+ string_start = source_p + 1;
+ break;
+ default:
+ goto resume_name_scan;
+ }
+ }
+ if (paren_count + brace_count > 0) {
+ break;
+ }
+ /* We found "+=" construct */
+ if (source_p != string_start) {
+ /* "+" is not a break char. */
+ /* Ignore it if it is part of an identifier */
+ source_p++;
+ goto resume_name_scan;
+ }
+ /* Make sure the "+" is followed by a "=" */
+ scan_append:
+ switch (*++source_p) {
+ case nul_char:
+ if (!macro_seen_in_string) {
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ GET_NEXT_BLOCK(source);
+ source_p--;
+ string_start = source_p;
+ if (source == NULL) {
+ GOTO_STATE(illegal_eoln_state);
+ }
+ goto scan_append;
+ case equal_char:
+ if(!svr4) {
+ append = true;
+ } else {
+ fatal_reader(catgets(catd, 1, 84, "Must be a separator on rules"));
+ }
+ break;
+ default:
+ /* The "+" just starts a regular name. */
+ /* Start reading that name */
+ goto resume_name_scan;
+ }
+ /* Fall into */
+ case equal_char:
+ if (paren_count + brace_count > 0) {
+ break;
+ }
+ /* We found macro assignment. */
+ /* Check if it is legal and if it is appending */
+ switch (separator) {
+ case none_seen:
+ separator = equal_seen;
+ on_eoln_state = enter_equal_state;
+ break;
+ case conditional_seen:
+ on_eoln_state = enter_conditional_state;
+ break;
+ default:
+ /* Reader must special check for "MACRO:sh=" */
+ /* notation */
+ if (sh_name == NULL) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("sh"));
+ sh_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, NOCATGETS("shell"));
+ shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ }
+
+ if (!macro_seen_in_string) {
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start
+ );
+
+ if ( (((target.used == 1) &&
+ (depes.used == 1) &&
+ (depes.names[0] == sh_name)) ||
+ ((target.used == 1) &&
+ (depes.used == 0) &&
+ (separator == one_colon) &&
+ (GETNAME(name_string.buffer.start,FIND_LENGTH) == sh_name))) &&
+ (!svr4)) {
+ String_rec macro_name;
+ wchar_t buffer[100];
+
+ INIT_STRING_FROM_STACK(macro_name,
+ buffer);
+ APPEND_NAME(target.names[0],
+ &macro_name,
+ FIND_LENGTH);
+ append_char((int) colon_char,
+ &macro_name);
+ APPEND_NAME(sh_name,
+ &macro_name,
+ FIND_LENGTH);
+ target.names[0] =
+ GETNAME(macro_name.buffer.start,
+ FIND_LENGTH);
+ separator = equal_seen;
+ on_eoln_state = enter_equal_state;
+ break;
+ } else if ( (((target.used == 1) &&
+ (depes.used == 1) &&
+ (depes.names[0] == shell_name)) ||
+ ((target.used == 1) &&
+ (depes.used == 0) &&
+ (separator == one_colon) &&
+ (GETNAME(name_string.buffer.start,FIND_LENGTH) == shell_name))) &&
+ (!svr4)) {
+ String_rec macro_name;
+ wchar_t buffer[100];
+
+ INIT_STRING_FROM_STACK(macro_name,
+ buffer);
+ APPEND_NAME(target.names[0],
+ &macro_name,
+ FIND_LENGTH);
+ append_char((int) colon_char,
+ &macro_name);
+ APPEND_NAME(shell_name,
+ &macro_name,
+ FIND_LENGTH);
+ target.names[0] =
+ GETNAME(macro_name.buffer.start,
+ FIND_LENGTH);
+ separator = equal_seen;
+ on_eoln_state = enter_equal_state;
+ break;
+ }
+ if(svr4) {
+ fatal_reader(catgets(catd, 1, 85, "syntax error"));
+ }
+ else {
+ fatal_reader(catgets(catd, 1, 86, "Macro assignment on dependency line"));
+ }
+ }
+ if (append) {
+ source_p--;
+ }
+ /* Enter the macro name */
+ if ((string_start != source_p) ||
+ macro_seen_in_string) {
+ current_names =
+ enter_name(&name_string,
+ macro_seen_in_string,
+ string_start,
+ source_p,
+ current_names,
+ &extra_names,
+ &target_group_seen);
+ first_target = false;
+ if (extra_names == NULL) {
+ extra_names = (Name_vector)
+ alloca((int)
+ sizeof (Name_vector_rec));
+ }
+ }
+ if (append) {
+ source_p++;
+ }
+ macro_value = NULL;
+ source_p++;
+ distance = 0;
+ /* Skip whitespace to the start of the value */
+ macro_seen_in_string = false;
+ for (; 1; source_p++) {
+ switch (GET_CHAR()) {
+ case nul_char:
+ GET_NEXT_BLOCK(source);
+ source_p--;
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ break;
+ case backslash_char:
+ if (*++source_p == (int) nul_char) {
+ GET_NEXT_BLOCK(source);
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ }
+ if (*source_p != (int) newline_char) {
+ if (!macro_seen_in_string) {
+ macro_seen_in_string =
+ true;
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_char((int)
+ backslash_char,
+ &name_string);
+ append_char(*source_p,
+ &name_string);
+ string_start = source_p+1;
+ goto macro_value_start;
+ } else {
+ if (source->fd >= 0) {
+ line_number++;
+ }
+ }
+ break;
+ case newline_char:
+ case numbersign_char:
+ string_start = source_p;
+ goto macro_value_end;
+ case tab_char:
+ case space_char:
+ break;
+ default:
+ string_start = source_p;
+ goto macro_value_start;
+ }
+ }
+ macro_value_start:
+ /* Find the end of the value */
+ for (; 1; source_p++) {
+ if (distance != 0) {
+ *source_p = *(source_p + distance);
+ }
+ switch (GET_CHAR()) {
+ case nul_char:
+ if (!macro_seen_in_string) {
+ macro_seen_in_string = true;
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ GET_NEXT_BLOCK(source);
+ string_start = source_p;
+ source_p--;
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ break;
+ case backslash_char:
+ source_p++;
+ if (distance != 0) {
+ *source_p =
+ *(source_p + distance);
+ }
+ if (*source_p == (int) nul_char) {
+ if (!macro_seen_in_string) {
+ macro_seen_in_string =
+ true;
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+
+/* BID_1225561 */
+ *(source_p - 1) = (int) space_char;
+ append_string(string_start,
+ &name_string,
+ source_p -
+ string_start - 1);
+ GET_NEXT_BLOCK(source);
+ string_start = source_p;
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ if (distance != 0) {
+ *source_p =
+ *(source_p +
+ distance);
+ }
+ if (*source_p == (int) newline_char) {
+ append_char((int) space_char, &name_string);
+ } else {
+ append_char((int) backslash_char, &name_string);
+ }
+/****************/
+ }
+ if (*source_p == (int) newline_char) {
+ source_p--;
+ line_number++;
+ distance++;
+ *source_p = (int) space_char;
+ while ((*(source_p +
+ distance + 1) ==
+ (int) tab_char) ||
+ (*(source_p +
+ distance + 1) ==
+ (int) space_char)) {
+ distance++;
+ }
+ }
+ break;
+ case newline_char:
+ case numbersign_char:
+ goto macro_value_end;
+ }
+ }
+ macro_value_end:
+ /* Complete the value in the string */
+ if (!macro_seen_in_string) {
+ macro_seen_in_string = true;
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ if (name_string.buffer.start != name_string.text.p) {
+ macro_value =
+ GETNAME(name_string.buffer.start,
+ FIND_LENGTH);
+ }
+ if (name_string.free_after_use) {
+ retmem(name_string.buffer.start);
+ }
+ for (; distance > 0; distance--) {
+ *source_p++ = (int) space_char;
+ }
+ GOTO_STATE(on_eoln_state);
+ }
+ }
+
+/****************************************************************
+ * enter dependencies state
+ */
+ case enter_dependencies_state:
+ enter_dependencies_label:
+/* Expects pointer on first non whitespace char after last dependency. (On */
+/* next line.) We end up here after having read a "targets : dependencies" */
+/* line. The state checks if there is a rule to read and if so dispatches */
+/* to scan_command_state scan_command_state reads one rule line and the */
+/* returns here */
+
+ /* First check if the first char on the next line is special */
+ switch (GET_CHAR()) {
+ case nul_char:
+ GET_NEXT_BLOCK(source);
+ if (source == NULL) {
+ break;
+ }
+ goto enter_dependencies_label;
+ case exclam_char:
+ /* The line should be evaluate before it is read */
+ macro_seen_in_string = false;
+ string_start = source_p + 1;
+ for (; 1; source_p++) {
+ switch (GET_CHAR()) {
+ case newline_char:
+ goto eoln_2;
+ case nul_char:
+ if (source->fd > 0) {
+ if (!macro_seen_in_string) {
+ macro_seen_in_string = true;
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ GET_NEXT_BLOCK(source);
+ string_start = source_p;
+ source_p--;
+ break;
+ }
+ eoln_2:
+ if (!macro_seen_in_string) {
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ extrap = (Source)
+ alloca((int) sizeof (Source_rec));
+ extrap->string.buffer.start = NULL;
+ extrap->inp_buf =
+ extrap->inp_buf_ptr =
+ extrap->inp_buf_end = NULL;
+ extrap->error_converting = false;
+ expand_value(GETNAME(name_string.buffer.start,
+ FIND_LENGTH),
+ &extrap->string,
+ false);
+ if (name_string.free_after_use) {
+ retmem(name_string.buffer.start);
+ }
+ UNCACHE_SOURCE();
+ extrap->string.text.p =
+ extrap->string.buffer.start;
+ extrap->fd = -1;
+ extrap->previous = source;
+ source = extrap;
+ CACHE_SOURCE(0);
+ goto enter_dependencies_label;
+ }
+ }
+ case dollar_char:
+ if (source->already_expanded) {
+ break;
+ }
+ source_p++;
+ UNCACHE_SOURCE();
+ {
+ Source t = (Source) alloca((int) sizeof (Source_rec));
+ source = push_macro_value(t,
+ buffer,
+ sizeof buffer,
+ source);
+ }
+ CACHE_SOURCE(0);
+ goto enter_dependencies_label;
+ case numbersign_char:
+ if (makefile_type != reading_makefile) {
+ source_p++;
+ GOTO_STATE(scan_command_state);
+ }
+ for (; 1; source_p++) {
+ switch (GET_CHAR()) {
+ case nul_char:
+ GET_NEXT_BLOCK_NOCHK(source);
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ if (source->error_converting) {
+ // Illegal byte sequence - skip its first byte
+ source->inp_buf_ptr++;
+ }
+ source_p--;
+ break;
+ case backslash_char:
+ if (*++source_p == (int) nul_char) {
+ GET_NEXT_BLOCK_NOCHK(source);
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ if (source->error_converting) {
+ // Illegal byte sequence - skip its first byte
+ source->inp_buf_ptr++;
+ source_p--;
+ break;
+ }
+ }
+ if(*source_p == (int) newline_char) {
+ if (source->fd >= 0) {
+ line_number++;
+ }
+ }
+ break;
+ case newline_char:
+ source_p++;
+ if (source->fd >= 0) {
+ line_number++;
+ }
+ goto enter_dependencies_label;
+ }
+ }
+
+ case tab_char:
+ GOTO_STATE(scan_command_state);
+ }
+
+ /* We read all the command lines for the target/dependency line. */
+ /* Enter the stuff */
+ enter_target_groups_and_dependencies( &target, &depes, command,
+ separator, target_group_seen);
+
+ goto start_new_line;
+
+/****************************************************************
+ * scan command state
+ */
+case scan_command_state:
+ /* We need to read one rule line. Do that and return to */
+ /* the enter dependencies state */
+ string_start = source_p;
+ macro_seen_in_string = false;
+ for (; 1; source_p++) {
+ switch (GET_CHAR()) {
+ case backslash_char:
+ if (!macro_seen_in_string) {
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ macro_seen_in_string = true;
+ if (*++source_p == (int) nul_char) {
+ GET_NEXT_BLOCK(source);
+ if (source == NULL) {
+ string_start = source_p;
+ goto command_newline;
+ }
+ }
+ append_char((int) backslash_char, &name_string);
+ append_char(*source_p, &name_string);
+ if (*source_p == (int) newline_char) {
+ if (source->fd >= 0) {
+ line_number++;
+ }
+ if (*++source_p == (int) nul_char) {
+ GET_NEXT_BLOCK(source);
+ if (source == NULL) {
+ string_start = source_p;
+ goto command_newline;
+ }
+ }
+ if (*source_p == (int) tab_char) {
+ source_p++;
+ }
+ } else {
+ if (*++source_p == (int) nul_char) {
+ GET_NEXT_BLOCK(source);
+ if (source == NULL) {
+ string_start = source_p;
+ goto command_newline;
+ }
+ }
+ }
+ string_start = source_p;
+ if ((*source_p == (int) newline_char) ||
+ (*source_p == (int) backslash_char) ||
+ (*source_p == (int) nul_char)) {
+ source_p--;
+ }
+ break;
+ case newline_char:
+ command_newline:
+ if ((string_start != source_p) ||
+ macro_seen_in_string) {
+ if (macro_seen_in_string) {
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ string_start =
+ name_string.buffer.start;
+ string_end = name_string.text.p;
+ } else {
+ string_end = source_p;
+ }
+ while ((*string_start != (int) newline_char) &&
+ iswspace(*string_start)){
+ string_start++;
+ }
+ if ((string_end > string_start) ||
+ (makefile_type == reading_statefile)) {
+ if (command_tail == NULL) {
+ command =
+ command_tail =
+ ALLOC(Cmd_line);
+ } else {
+ command_tail->next =
+ ALLOC(Cmd_line);
+ command_tail =
+ command_tail->next;
+ }
+ command_tail->next = NULL;
+ command_tail->make_refd = false;
+ command_tail->ignore_command_dependency = false;
+ command_tail->assign = false;
+ command_tail->ignore_error = false;
+ command_tail->silent = false;
+ command_tail->command_line =
+ GETNAME(string_start,
+ string_end - string_start);
+ if (macro_seen_in_string &&
+ name_string.free_after_use) {
+ retmem(name_string.
+ buffer.start);
+ }
+ }
+ }
+ do {
+ if ((source != NULL) && (source->fd >= 0)) {
+ line_number++;
+ }
+ if ((source != NULL) &&
+ (*++source_p == (int) nul_char)) {
+ GET_NEXT_BLOCK(source);
+ if (source == NULL) {
+ GOTO_STATE(on_eoln_state);
+ }
+ }
+ } while (*source_p == (int) newline_char);
+
+ GOTO_STATE(enter_dependencies_state);
+ case nul_char:
+ if (!macro_seen_in_string) {
+ INIT_STRING_FROM_STACK(name_string,
+ name_buffer);
+ }
+ append_string(string_start,
+ &name_string,
+ source_p - string_start);
+ macro_seen_in_string = true;
+ GET_NEXT_BLOCK(source);
+ string_start = source_p;
+ source_p--;
+ if (source == NULL) {
+ GOTO_STATE(enter_dependencies_state);
+ }
+ break;
+ }
+ }
+
+/****************************************************************
+ * enter equal state
+ */
+case enter_equal_state:
+ if (target.used != 1) {
+ GOTO_STATE(poorly_formed_macro_state);
+ }
+ enter_equal(target.names[0], macro_value, append);
+ goto start_new_line;
+
+/****************************************************************
+ * enter conditional state
+ */
+case enter_conditional_state:
+ if (depes.used != 1) {
+ GOTO_STATE(poorly_formed_macro_state);
+ }
+ for (nvp = &target; nvp != NULL; nvp = nvp->next) {
+ for (i = 0; i < nvp->used; i++) {
+ enter_conditional(nvp->names[i],
+ depes.names[0],
+ macro_value,
+ append);
+ }
+ }
+ goto start_new_line;
+
+/****************************************************************
+ * Error states
+ */
+case illegal_bytes_state:
+ fatal_reader(catgets(catd, 1, 340, "Invalid byte sequence"));
+case illegal_eoln_state:
+ if (line_number > 1) {
+ if (line_started_with_space == (line_number - 1)) {
+ line_number--;
+ fatal_reader(catgets(catd, 1, 90, "Unexpected end of line seen\n\t*** missing separator (did you mean TAB instead of 8 spaces?)"));
+ }
+ }
+ fatal_reader(catgets(catd, 1, 87, "Unexpected end of line seen"));
+case poorly_formed_macro_state:
+ fatal_reader(catgets(catd, 1, 88, "Badly formed macro assignment"));
+case exit_state:
+ return;
+default:
+ fatal_reader(catgets(catd, 1, 89, "Internal error. Unknown reader state"));
+}
+}
+
+/*
+ * push_macro_value(bp, buffer, size, source)
+ *
+ * Macro and function that evaluates one macro
+ * and makes the reader read from the value of it
+ *
+ * Return value:
+ * The source block to read the macro from
+ *
+ * Parameters:
+ * bp The new source block to fill in
+ * buffer Buffer to read from
+ * size size of the buffer
+ * source The old source block
+ *
+ * Global variables used:
+ */
+static Source
+push_macro_value(register Source bp, register wchar_t *buffer, int size, register Source source)
+{
+ bp->string.buffer.start = bp->string.text.p = buffer;
+ bp->string.text.end = NULL;
+ bp->string.buffer.end = buffer + (size/SIZEOFWCHAR_T);
+ bp->string.free_after_use = false;
+ bp->inp_buf =
+ bp->inp_buf_ptr =
+ bp->inp_buf_end = NULL;
+ bp->error_converting = false;
+ expand_macro(source, &bp->string, (wchar_t *) NULL, false);
+ bp->string.text.p = bp->string.buffer.start;
+
+ /* 4209588: 'make' doesn't understand a macro with whitespaces in the head as target.
+ * strip whitespace from the begining of the macro value
+ */
+ while (iswspace(*bp->string.text.p)) {
+ bp->string.text.p++;
+ }
+
+ bp->fd = -1;
+ bp->already_expanded = true;
+ bp->previous = source;
+ return bp;
+}
+
+/*
+ * enter_target_groups_and_dependencies(target, depes, command, separator,
+ * target_group_seen)
+ *
+ * Parameters:
+ * target Structure that shows the target(s) on the line
+ * we are currently parsing. This can looks like
+ * target1 .. targetN : dependencies
+ * commands
+ * or
+ * target1 + .. + targetN : dependencies
+ * commands
+ * depes Dependencies
+ * command Points to the command(s) to be executed for
+ * this target.
+ * separator : or :: or :=
+ * target_group_seen Set if we have target1 + .. + targetN
+ *
+ *
+ * After reading the command lines for a target, this routine
+ * is called to setup the dependencies and the commands for it.
+ * If the target is a % pattern or part of a target group, then
+ * the appropriate routines are called.
+ */
+
+void
+enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen)
+{
+ int i;
+ Boolean reset= true;
+ Chain target_group_member;
+ Percent percent_ptr;
+
+ for (; target != NULL; target = target->next) {
+ for (i = 0; i < target->used; i++) {
+ if (target->names[i] != NULL) {
+ if (target_group_seen) {
+ target_group_member =
+ find_target_groups(target, i, reset);
+ if(target_group_member == NULL) {
+ fatal_reader(catgets(catd, 1, 328, "Unexpected '+' on dependency line"));
+ }
+ }
+ reset = false;
+
+ /* If we saw it in the makefile it must be
+ * a file */
+ target->names[i]->stat.is_file = true;
+ /* Make sure that we use dependencies
+ * entered for makefiles */
+ target->names[i]->state = build_dont_know;
+
+ /* If the target is special we delegate
+ * the processing */
+ if (target->names[i]->special_reader
+ != no_special) {
+ special_reader(target->names[i],
+ depes,
+ command);
+ }
+ /* Check if this is a "a%b : x%y" type rule */
+ else if (target->names[i]->percent) {
+ percent_ptr =
+ enter_percent(target->names[i],
+ target->target_group[i],
+ depes, command);
+ if (target_group_seen) {
+ target_group_member->percent_member =
+ percent_ptr;
+ }
+ } else if (target->names[i]->dollar) {
+ enter_dyntarget(target->names[i]);
+ enter_dependencies
+ (target->names[i],
+ target->target_group[i],
+ depes,
+ command,
+ separator);
+ } else {
+ if (target_group_seen) {
+ target_group_member->percent_member =
+ NULL;
+ }
+
+ enter_dependencies
+ (target->names[i],
+ target->target_group[i],
+ depes,
+ command,
+ separator);
+ }
+ }
+ }
+ }
+}
+
+
diff --git a/usr/src/make_src/Make/bin/make/common/read2.cc b/usr/src/make_src/Make/bin/make/common/read2.cc
new file mode 100644
index 0000000..e1a9e1f
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/read2.cc
@@ -0,0 +1,1938 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)read2.cc 1.53 06/12/12
+ */
+
+#pragma ident "@(#)read2.cc 1.53 06/12/12"
+
+/*
+ * read.c
+ *
+ * This file contains the makefile reader.
+ */
+
+/*
+ * Included files
+ */
+#include <mk/defs.h>
+#include <mksh/dosys.h> /* sh_command2string() */
+#include <mksh/macro.h> /* expand_value() */
+#include <mksh/misc.h> /* retmem() */
+#include <stdarg.h> /* va_list, va_start(), va_end() */
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+static Boolean built_last_make_run_seen;
+
+/*
+ * File table of contents
+ */
+static Name_vector enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names);
+extern Name normalize_name(register wchar_t *name_string, register int length);
+static void read_suffixes_list(register Name_vector depes);
+static void make_relative(wchar_t *to, wchar_t *result);
+static void print_rule(register Cmd_line command);
+static void sh_transform(Name *name, Name *value);
+
+
+/*
+ * enter_name(string, tail_present, string_start, string_end,
+ * current_names, extra_names, target_group_seen)
+ *
+ * Take one string and enter it as a name. The string is passed in
+ * two parts. A make string and possibly a C string to append to it.
+ * The result is stuffed in the vector current_names.
+ * extra_names points to a vector that is used if current_names overflows.
+ * This is allocad in the calling routine.
+ * Here we handle the "lib.a[members]" notation.
+ *
+ * Return value:
+ * The name vector that was used
+ *
+ * Parameters:
+ * tail_present Indicates if both C and make string was passed
+ * string_start C string
+ * string_end Pointer to char after last in C string
+ * string make style string with head of name
+ * current_names Vector to deposit the name in
+ * extra_names Where to get next name vector if we run out
+ * target_group_seen Pointer to boolean that is set if "+" is seen
+ *
+ * Global variables used:
+ * makefile_type When we read a report file we normalize paths
+ * plus Points to the Name "+"
+ */
+
+Name_vector
+enter_name(String string, Boolean tail_present, register wchar_t *string_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names, Boolean *target_group_seen)
+{
+ Name name;
+ register wchar_t *cp;
+ wchar_t ch;
+
+ /* If we were passed a separate tail of the name we append it to the */
+ /* make string with the rest of it */
+ if (tail_present) {
+ append_string(string_start, string, string_end - string_start);
+ string_start = string->buffer.start;
+ string_end = string->text.p;
+ }
+ ch = *string_end;
+ *string_end = (int) nul_char;
+ /*
+ * Check if there are any ( or [ that are not prefixed with $.
+ * If there are, we have to deal with the lib.a(members) format.
+ */
+ for (cp = (wchar_t *) wschr(string_start, (int) parenleft_char);
+ cp != NULL;
+ cp = (wchar_t *) wschr(cp + 1, (int) parenleft_char)) {
+ if (*(cp - 1) != (int) dollar_char) {
+ *string_end = ch;
+ return enter_member_name(string_start,
+ cp,
+ string_end,
+ current_names,
+ extra_names);
+ }
+ }
+ *string_end = ch;
+
+ if (makefile_type == reading_cpp_file) {
+ /* Remove extra ../ constructs if we are reading from a report file */
+ name = normalize_name(string_start, string_end - string_start);
+ } else {
+ /*
+ * /tolik, fix bug 1197477/
+ * Normalize every target name before entering.
+ * ..//obj/a.o and ../obj//a.o are not two different targets.
+ * There is only one target ../obj/a.o
+ */
+ /*name = GETNAME(string_start, string_end - string_start);*/
+ name = normalize_name(string_start, string_end - string_start);
+ }
+
+ /* Internalize the name. Detect the name "+" (target group here) */
+if(current_names->used != 0 && current_names->names[current_names->used-1] == plus) {
+ if(name == plus) {
+ return current_names;
+ }
+}
+ /* If the current_names vector is full we patch in the one from */
+ /* extra_names */
+ if (current_names->used == VSIZEOF(current_names->names)) {
+ if (current_names->next != NULL) {
+ current_names = current_names->next;
+ } else {
+ current_names->next = *extra_names;
+ *extra_names = NULL;
+ current_names = current_names->next;
+ current_names->used = 0;
+ current_names->next = NULL;
+ }
+ }
+ current_names->target_group[current_names->used] = NULL;
+ current_names->names[current_names->used++] = name;
+ if (name == plus) {
+ *target_group_seen = true;
+ }
+ if (tail_present && string->free_after_use) {
+ retmem(string->buffer.start);
+ }
+ return current_names;
+}
+
+/*
+ * enter_member_name(lib_start, member_start, string_end,
+ * current_names, extra_names)
+ *
+ * A string has been found to contain member names.
+ * (The "lib.a[members]" and "lib.a(members)" notation)
+ * Handle it pretty much as enter_name() does for simple names.
+ *
+ * Return value:
+ * The name vector that was used
+ *
+ * Parameters:
+ * lib_start Points to the of start of "lib.a(member.o)"
+ * member_start Points to "member.o" from above string.
+ * string_end Points to char after last of above string.
+ * current_names Vector to deposit the name in
+ * extra_names Where to get next name vector if we run out
+ *
+ * Global variables used:
+ */
+static Name_vector
+enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names)
+{
+ register Boolean entry = false;
+ wchar_t buffer[STRING_BUFFER_LENGTH];
+ Name lib;
+ Name member;
+ Name name;
+ Property prop;
+ wchar_t *memberp;
+ wchar_t *q;
+ register int paren_count;
+ register Boolean has_dollar;
+ register wchar_t *cq;
+ Name long_member_name = NULL;
+
+ /* Internalize the name of the library */
+ lib = GETNAME(lib_start, member_start - lib_start);
+ lib->is_member = true;
+ member_start++;
+ if (*member_start == (int) parenleft_char) {
+ /* This is really the "lib.a((entries))" format */
+ entry = true;
+ member_start++;
+ }
+ /* Move the library name to the buffer where we intend to build the */
+ /* "lib.a(member)" for each member */
+ (void) wsncpy(buffer, lib_start, member_start - lib_start);
+ memberp = buffer + (member_start-lib_start);
+ while (1) {
+ long_member_name = NULL;
+ /* Skip leading spaces */
+ for (;
+ (member_start < string_end) && iswspace(*member_start);
+ member_start++);
+ /* Find the end of the member name. Allow nested (). Detect $*/
+ for (cq = memberp, has_dollar = false, paren_count = 0;
+ (member_start < string_end) &&
+ ((*member_start != (int) parenright_char) ||
+ (paren_count > 0)) &&
+ !iswspace(*member_start);
+ *cq++ = *member_start++) {
+ switch (*member_start) {
+ case parenleft_char:
+ paren_count++;
+ break;
+ case parenright_char:
+ paren_count--;
+ break;
+ case dollar_char:
+ has_dollar = true;
+ }
+ }
+ /* Internalize the member name */
+ member = GETNAME(memberp, cq - memberp);
+ *cq = 0;
+ if ((q = (wchar_t *) wsrchr(memberp, (int) slash_char)) == NULL) {
+ q = memberp;
+ }
+ if ((cq - q > (int) ar_member_name_len) &&
+ !has_dollar) {
+ *cq++ = (int) parenright_char;
+ if (entry) {
+ *cq++ = (int) parenright_char;
+ }
+ long_member_name = GETNAME(buffer, cq - buffer);
+ cq = q + (int) ar_member_name_len;
+ }
+ *cq++ = (int) parenright_char;
+ if (entry) {
+ *cq++ = (int) parenright_char;
+ }
+ /* Internalize the "lib.a(member)" notation for this member */
+ name = GETNAME(buffer, cq - buffer);
+ name->is_member = lib->is_member;
+ if (long_member_name != NULL) {
+ prop = append_prop(name, long_member_name_prop);
+ name->has_long_member_name = true;
+ prop->body.long_member_name.member_name =
+ long_member_name;
+ }
+ /* And add the member prop */
+ prop = append_prop(name, member_prop);
+ prop->body.member.library = lib;
+ if (entry) {
+ /* "lib.a((entry))" notation */
+ prop->body.member.entry = member;
+ prop->body.member.member = NULL;
+ } else {
+ /* "lib.a(member)" Notation */
+ prop->body.member.entry = NULL;
+ prop->body.member.member = member;
+ }
+ /* Handle overflow of current_names */
+ if (current_names->used == VSIZEOF(current_names->names)) {
+ if (current_names->next != NULL) {
+ current_names = current_names->next;
+ } else {
+ if (*extra_names == NULL) {
+ current_names =
+ current_names->next =
+ ALLOC(Name_vector);
+ } else {
+ current_names =
+ current_names->next =
+ *extra_names;
+ *extra_names = NULL;
+ }
+ current_names->used = 0;
+ current_names->next = NULL;
+ }
+ }
+ current_names->target_group[current_names->used] = NULL;
+ current_names->names[current_names->used++] = name;
+ while (iswspace(*member_start)) {
+ member_start++;
+ }
+ /* Check if there are more members */
+ if ((*member_start == (int) parenright_char) ||
+ (member_start >= string_end)) {
+ return current_names;
+ }
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * normalize_name(name_string, length)
+ *
+ * Take a namestring and remove redundant ../, // and ./ constructs
+ *
+ * Return value:
+ * The normalized name
+ *
+ * Parameters:
+ * name_string Path string to normalize
+ * length Length of that string
+ *
+ * Global variables used:
+ * dot The Name ".", compared against
+ * dotdot The Name "..", compared against
+ */
+Name
+normalize_name(register wchar_t *name_string, register int length)
+{
+ static Name dotdot;
+ register wchar_t *string = ALLOC_WC(length + 1);
+ register wchar_t *string2;
+ register wchar_t *cdp;
+ wchar_t *current_component;
+ Name name;
+ register int count;
+
+ if (dotdot == NULL) {
+ MBSTOWCS(wcs_buffer, "..");
+ dotdot = GETNAME(wcs_buffer, FIND_LENGTH);
+ }
+
+ /*
+ * Copy string removing ./ and //.
+ * First strip leading ./
+ */
+ while ((length > 1) &&
+ (name_string[0] == (int) period_char) &&
+ (name_string[1] == (int) slash_char)) {
+ name_string += 2;
+ length -= 2;
+ while ((length > 0) && (name_string[0] == (int) slash_char)) {
+ name_string++;
+ length--;
+ }
+ }
+ /* Then copy the rest of the string removing /./ & // */
+ cdp = string;
+ while (length > 0) {
+ if (((length > 2) &&
+ (name_string[0] == (int) slash_char) &&
+ (name_string[1] == (int) period_char) &&
+ (name_string[2] == (int) slash_char)) ||
+ ((length == 2) &&
+ (name_string[0] == (int) slash_char) &&
+ (name_string[1] == (int) period_char))) {
+ name_string += 2;
+ length -= 2;
+ continue;
+ }
+ if ((length > 1) &&
+ (name_string[0] == (int) slash_char) &&
+ (name_string[1] == (int) slash_char)) {
+ name_string++;
+ length--;
+ continue;
+ }
+ *cdp++ = *name_string++;
+ length--;
+ }
+ *cdp = (int) nul_char;
+ /*
+ * Now scan for <name>/../ and remove such combinations iff <name>
+ * is not another ..
+ * Each time something is removed, the whole process is restarted.
+ */
+removed_one:
+ name_string = string;
+ string2 = name_string; /*save for free*/
+ current_component =
+ cdp =
+ string =
+ ALLOC_WC((length = wslen(name_string)) + 1);
+ while (length > 0) {
+ if (((length > 3) &&
+ (name_string[0] == (int) slash_char) &&
+ (name_string[1] == (int) period_char) &&
+ (name_string[2] == (int) period_char) &&
+ (name_string[3] == (int) slash_char)) ||
+ ((length == 3) &&
+ (name_string[0] == (int) slash_char) &&
+ (name_string[1] == (int) period_char) &&
+ (name_string[2] == (int) period_char))) {
+ /* Positioned on the / that starts a /.. sequence */
+ if (((count = cdp - current_component) != 0) &&
+ (exists(name = GETNAME(string, cdp - string)) > file_doesnt_exist) &&
+ (!name->stat.is_sym_link)) {
+ name = GETNAME(current_component, count);
+ if(name != dotdot) {
+ cdp = current_component;
+ name_string += 3;
+ length -= 3;
+ if (length > 0) {
+ name_string++; /* skip slash */
+ length--;
+ while (length > 0) {
+ *cdp++ = *name_string++;
+ length--;
+ }
+ }
+ *cdp = (int) nul_char;
+ retmem(string2);
+ goto removed_one;
+ }
+ }
+ }
+ if ((*cdp++ = *name_string++) == (int) slash_char) {
+ current_component = cdp;
+ }
+ length--;
+ }
+ *cdp = (int) nul_char;
+ if (string[0] == (int) nul_char) {
+ name = dot;
+ } else {
+ name = GETNAME(string, FIND_LENGTH);
+ }
+ retmem(string);
+ retmem(string2);
+ return name;
+}
+
+/*
+ * find_target_groups(target_list)
+ *
+ * If a "+" was seen when the target list was scanned we need to extract
+ * the groups. Each target in the name vector that is a member of a
+ * group gets a pointer to a chain of all the members stuffed in its
+ * target_group vector slot
+ *
+ * Parameters:
+ * target_list The list of targets that contains "+"
+ *
+ * Global variables used:
+ * plus The Name "+", compared against
+ */
+Chain
+find_target_groups(register Name_vector target_list, register int i, Boolean reset)
+{
+ static Chain target_group = NULL;
+ static Chain tail_target_group = NULL;
+ static Name *next;
+ static Boolean clear_target_group = false;
+
+ if (reset) {
+ target_group = NULL;
+ tail_target_group = NULL;
+ clear_target_group = false;
+ }
+
+ /* Scan the list of targets */
+ /* If the previous target terminated a group */
+ /* we flush the pointer to that member chain */
+ if (clear_target_group) {
+ clear_target_group = false;
+ target_group = NULL;
+ }
+ /* Pick up a pointer to the cell with */
+ /* the next target */
+ if (i + 1 != target_list->used) {
+ next = &target_list->names[i + 1];
+ } else {
+ next = (target_list->next != NULL) ?
+ &target_list->next->names[0] : NULL;
+ }
+ /* We have four states here :
+ * 0: No target group started and next element is not "+"
+ * This is not interesting.
+ * 1: A target group is being built and the next element
+ * is not "+". This terminates the group.
+ * 2: No target group started and the next member is "+"
+ * This is the first target in a group.
+ * 3: A target group started and the next member is a "+"
+ * The group continues.
+ */
+ switch ((target_group ? 1 : 0) +
+ (next && (*next == plus) ?
+ 2 : 0)) {
+ case 0: /* Not target_group */
+ break;
+ case 1: /* Last group member */
+ /* We need to keep this pointer so */
+ /* we can stuff it for last member */
+ clear_target_group = true;
+ /* fall into */
+ case 3: /* Middle group member */
+ /* Add this target to the */
+ /* current chain */
+ tail_target_group->next = ALLOC(Chain);
+ tail_target_group = tail_target_group->next;
+ tail_target_group->next = NULL;
+ tail_target_group->name = target_list->names[i];
+ break;
+ case 2: /* First group member */
+ /* Start a new chain */
+ target_group = tail_target_group = ALLOC(Chain);
+ target_group->next = NULL;
+ target_group->name = target_list->names[i];
+ break;
+ }
+ /* Stuff the current chain, if any, in the */
+ /* targets group slot */
+ target_list->target_group[i] = target_group;
+ if ((next != NULL) &&
+ (*next == plus)) {
+ *next = NULL;
+ }
+ return (tail_target_group);
+}
+
+/*
+ * enter_dependencies(target, target_group, depes, command, separator)
+ *
+ * Take one target and a list of dependencies and process the whole thing.
+ * The target might be special in some sense in which case that is handled
+ *
+ * Parameters:
+ * target The target we want to enter
+ * target_group Non-NULL if target is part of a group this time
+ * depes A list of dependencies for the target
+ * command The command the target should be entered with
+ * separator Indicates if this is a ":" or a "::" rule
+ *
+ * Static variables used:
+ * built_last_make_run_seen If the previous target was
+ * .BUILT_LAST_MAKE_RUN we say to rewrite
+ * the state file later on
+ *
+ * Global variables used:
+ * command_changed Set to indicate if .make.state needs rewriting
+ * default_target_to_build Set to the target if reading makefile
+ * and this is the first regular target
+ * force The Name " FORCE", used with "::" targets
+ * makefile_type We do different things for makefile vs. report
+ * not_auto The Name ".NOT_AUTO", compared against
+ * recursive_name The Name ".RECURSIVE", compared against
+ * temp_file_number Used to figure out when to clear stale
+ * automatic dependencies
+ * trace_reader Indicates that we should echo stuff we read
+ */
+void
+enter_dependencies(register Name target, Chain target_group, register Name_vector depes, register Cmd_line command, register Separator separator)
+{
+ register int i;
+ register Property line;
+ Name name;
+ Name directory;
+ wchar_t *namep;
+ char *mb_namep;
+ Dependency dp;
+ Dependency *dpp;
+ Property line2;
+ wchar_t relative[MAXPATHLEN];
+ register int recursive_state;
+ Boolean register_as_auto;
+ Boolean not_auto_found;
+ char *slash;
+ Wstring depstr;
+
+ /* Check if this is a .RECURSIVE line */
+ if ((depes->used >= 3) &&
+ (depes->names[0] == recursive_name)) {
+#ifdef NSE
+ nse_did_recursion= true;
+#endif
+ target->has_recursive_dependency = true;
+ depes->names[0] = NULL;
+ recursive_state = 0;
+ dp = NULL;
+ dpp = &dp;
+ /* Read the dependencies. They are "<directory> <target-made>*/
+ /* <makefile>*" */
+ for (; depes != NULL; depes = depes->next) {
+ for (i = 0; i < depes->used; i++) {
+ if (depes->names[i] != NULL) {
+ switch (recursive_state++) {
+ case 0: /* Directory */
+ {
+ depstr.init(depes->names[i]);
+ make_relative(depstr.get_string(),
+ relative);
+ directory =
+ GETNAME(relative,
+ FIND_LENGTH);
+ }
+ break;
+ case 1: /* Target */
+ name = depes->names[i];
+ break;
+ default: /* Makefiles */
+ *dpp = ALLOC(Dependency);
+ (*dpp)->next = NULL;
+ (*dpp)->name = depes->names[i];
+ (*dpp)->automatic = false;
+ (*dpp)->stale = false;
+ (*dpp)->built = false;
+ dpp = &((*dpp)->next);
+ break;
+ }
+ }
+ }
+ }
+ /* Check if this recursion already has been reported else */
+ /* enter the recursive prop for the target */
+ /* The has_built flag is used to tell if this .RECURSIVE */
+ /* was discovered from this run (read from a tmp file) */
+ /* or was from discovered from the original .make.state */
+ /* file */
+ for (line = get_prop(target->prop, recursive_prop);
+ line != NULL;
+ line = get_prop(line->next, recursive_prop)) {
+ if ((line->body.recursive.directory == directory) &&
+ (line->body.recursive.target == name)) {
+ line->body.recursive.makefiles = dp;
+ line->body.recursive.has_built =
+ (Boolean)
+ (makefile_type == reading_cpp_file);
+ return;
+ }
+ }
+ line2 = append_prop(target, recursive_prop);
+ line2->body.recursive.directory = directory;
+ line2->body.recursive.target = name;
+ line2->body.recursive.makefiles = dp;
+ line2->body.recursive.has_built =
+ (Boolean) (makefile_type == reading_cpp_file);
+ line2->body.recursive.in_depinfo = false;
+ return;
+ }
+ /* If this is the first target that doesnt start with a "." in the */
+ /* makefile we remember that */
+ Wstring tstr(target);
+ wchar_t * wcb = tstr.get_string();
+ if ((makefile_type == reading_makefile) &&
+ (default_target_to_build == NULL) &&
+ ((wcb[0] != (int) period_char) ||
+ wschr(wcb, (int) slash_char))) {
+
+/* BID 1181577: $(EMPTY_MACRO) + $(EMPTY_MACRO):
+** The target with empty name cannot be default_target_to_build
+*/
+ if (target->hash.length != 0)
+ default_target_to_build = target;
+ }
+ /* Check if the line is ":" or "::" */
+ if (makefile_type == reading_makefile) {
+ if (target->colons == no_colon) {
+ target->colons = separator;
+ } else {
+ if (target->colons != separator) {
+ fatal_reader(catgets(catd, 1, 92, ":/:: conflict for target `%s'"),
+ target->string_mb);
+ }
+ }
+ if (target->colons == two_colon) {
+ if (depes->used == 0) {
+ /* If this is a "::" type line with no */
+ /* dependencies we add one "FRC" type */
+ /* dependency for free */
+ depes->used = 1; /* Force :: targets with no
+ * depes to always run */
+ depes->names[0] = force;
+ }
+ /* Do not delete "::" type targets when interrupted */
+ target->stat.is_precious = true;
+ /*
+ * Build a synthetic target "<number>%target"
+ * for "target".
+ */
+ mb_namep = getmem((int) (strlen(target->string_mb) + 10));
+ namep = ALLOC_WC((int) (target->hash.length + 10));
+ slash = strrchr(target->string_mb, (int) slash_char);
+ if (slash == NULL) {
+ (void) sprintf(mb_namep,
+ "%d@%s",
+ target->colon_splits++,
+ target->string_mb);
+ } else {
+ *slash = 0;
+ (void) sprintf(mb_namep,
+ "%s/%d@%s",
+ target->string_mb,
+ target->colon_splits++,
+ slash + 1);
+ *slash = (int) slash_char;
+ }
+ MBSTOWCS(namep, mb_namep);
+ retmem_mb(mb_namep);
+ name = GETNAME(namep, FIND_LENGTH);
+ retmem(namep);
+ if (trace_reader) {
+ (void) printf("%s:\t", target->string_mb);
+ }
+ /* Make "target" depend on "<number>%target */
+ line2 = maybe_append_prop(target, line_prop);
+ enter_dependency(line2, name, true);
+ line2->body.line.target = target;
+ /* Put a prop on "<number>%target that makes */
+ /* appear as "target" */
+ /* when it is processed */
+ maybe_append_prop(name, target_prop)->
+ body.target.target = target;
+ target->is_double_colon_parent = true;
+ name->is_double_colon = true;
+ name->has_target_prop = true;
+ if (trace_reader) {
+ (void) printf("\n");
+ }
+ (target = name)->stat.is_file = true;
+ }
+ }
+ /* This really is a regular dependency line. Just enter it */
+ line = maybe_append_prop(target, line_prop);
+ line->body.line.target = target;
+ /* Depending on what kind of makefile we are reading we have to */
+ /* treat things differently */
+ switch (makefile_type) {
+ case reading_makefile:
+ /* Reading regular makefile. Just notice whether this */
+ /* redefines the rule for the target */
+ if (command != NULL) {
+ if (line->body.line.command_template != NULL) {
+ line->body.line.command_template_redefined =
+ true;
+ if ((wcb[0] == (int) period_char) &&
+ !wschr(wcb, (int) slash_char)) {
+ line->body.line.command_template =
+ command;
+ }
+ } else {
+ line->body.line.command_template = command;
+ }
+ } else {
+ if ((wcb[0] == (int) period_char) &&
+ !wschr(wcb, (int) slash_char)) {
+ line->body.line.command_template = command;
+ }
+ }
+ break;
+ case rereading_statefile:
+ /* Rereading the statefile. We only enter thing that changed */
+ /* since the previous time we read it */
+ if (!built_last_make_run_seen) {
+ for (Cmd_line next, cmd = command; cmd != NULL; cmd = next) {
+ next = cmd->next;
+ free(cmd);
+ }
+ return;
+ }
+ built_last_make_run_seen = false;
+ command_changed = true;
+ target->ran_command = true;
+ case reading_statefile:
+ /* Reading the statefile for the first time. Enter the rules */
+ /* as "Commands used" not "templates to use" */
+ if (command != NULL) {
+ for (Cmd_line next, cmd = line->body.line.command_used;
+ cmd != NULL; cmd = next) {
+ next = cmd->next;
+ free(cmd);
+ }
+ line->body.line.command_used = command;
+ }
+ case reading_cpp_file:
+ /* Reading report file from programs that reports */
+ /* dependencies. If this is the first time the target is */
+ /* read from this reportfile we clear all old */
+ /* automatic depes */
+ if (target->temp_file_number == temp_file_number) {
+ break;
+ }
+ target->temp_file_number = temp_file_number;
+ command_changed = true;
+ if (line != NULL) {
+ for (dp = line->body.line.dependencies;
+ dp != NULL;
+ dp = dp->next) {
+ if (dp->automatic) {
+ dp->stale = true;
+ }
+ }
+ }
+ break;
+ default:
+ fatal_reader(catgets(catd, 1, 93, "Internal error. Unknown makefile type %d"),
+ makefile_type);
+ }
+ /* A target may only be involved in one target group */
+ if (line->body.line.target_group != NULL) {
+ if (target_group != NULL) {
+ fatal_reader(catgets(catd, 1, 94, "Too many target groups for target `%s'"),
+ target->string_mb);
+ }
+ } else {
+ line->body.line.target_group = target_group;
+ }
+
+ if (trace_reader) {
+ (void) printf("%s:\t", target->string_mb);
+ }
+ /* Enter the dependencies */
+ register_as_auto = BOOLEAN(makefile_type != reading_makefile);
+ not_auto_found = false;
+ for (;
+ (depes != NULL) && !not_auto_found;
+ depes = depes->next) {
+ for (i = 0; i < depes->used; i++) {
+ /* the dependency .NOT_AUTO signals beginning of
+ * explicit dependancies which were put at end of
+ * list in .make.state file - we stop entering
+ * dependencies at this point
+ */
+ if (depes->names[i] == not_auto) {
+ not_auto_found = true;
+ break;
+ }
+ enter_dependency(line,
+ depes->names[i],
+ register_as_auto);
+ }
+ }
+ if (trace_reader) {
+ (void) printf("\n");
+ print_rule(command);
+ }
+}
+
+/*
+ * enter_dependency(line, depe, automatic)
+ *
+ * Enter one dependency. Do not enter duplicates.
+ *
+ * Parameters:
+ * line The line block that the dependeny is
+ * entered for
+ * depe The dependency to enter
+ * automatic Used to set the field "automatic"
+ *
+ * Global variables used:
+ * makefile_type We do different things for makefile vs. report
+ * trace_reader Indicates that we should echo stuff we read
+ * wait_name The Name ".WAIT", compared against
+ */
+void
+enter_dependency(Property line, register Name depe, Boolean automatic)
+{
+ register Dependency dp;
+ register Dependency *insert;
+
+ if (trace_reader) {
+ (void) printf("%s ", depe->string_mb);
+ }
+ /* Find the end of the list and check for duplicates */
+ for (insert = &line->body.line.dependencies, dp = *insert;
+ dp != NULL;
+ insert = &dp->next, dp = *insert) {
+ if ((dp->name == depe) && (depe != wait_name)) {
+ if (dp->automatic) {
+ dp->automatic = automatic;
+ if (automatic) {
+ dp->built = false;
+ depe->stat.is_file = true;
+#ifdef NSE
+ depe->has_parent= true;
+ depe->is_target= true;
+#endif
+ }
+ }
+ dp->stale = false;
+ return;
+ }
+ }
+ /* Insert the new dependency since we couldnt find it */
+ dp = *insert = ALLOC(Dependency);
+ dp->name = depe;
+ dp->next = NULL;
+ dp->automatic = automatic;
+ dp->stale = false;
+ dp->built = false;
+ depe->stat.is_file = true;
+#ifdef NSE
+ depe->has_parent= true;
+ depe->is_target= true;
+#endif
+
+ if ((makefile_type == reading_makefile) &&
+ (line != NULL) &&
+ (line->body.line.target != NULL)) {
+ line->body.line.target->has_regular_dependency = true;
+#ifdef NSE
+ line->body.line.target->is_target= true;
+#endif
+ }
+}
+
+/*
+ * enter_percent(target, depes, command)
+ *
+ * Enter "x%y : a%b" type lines
+ * % patterns are stored in four parts head and tail for target and source
+ *
+ * Parameters:
+ * target Left hand side of pattern
+ * depes The dependency list with the rh pattern
+ * command The command for the pattern
+ *
+ * Global variables used:
+ * empty_name The Name "", compared against
+ * percent_list The list of all percent rules, added to
+ * trace_reader Indicates that we should echo stuff we read
+ */
+Percent
+enter_percent(register Name target, Chain target_group, register Name_vector depes, Cmd_line command)
+{
+ register Percent result = ALLOC(Percent);
+ register Percent depe;
+ register Percent *depe_tail = &result->dependencies;
+ register Percent *insert;
+ register wchar_t *cp, *cp1;
+ Name_vector nvp;
+ int i;
+ int pattern;
+
+ result->next = NULL;
+ result->patterns = NULL;
+ result->patterns_total = 0;
+ result->command_template = command;
+ result->being_expanded = false;
+ result->name = target;
+ result->dependencies = NULL;
+ result->target_group = target_group;
+
+ /* get patterns count */
+ Wstring wcb(target);
+ cp = wcb.get_string();
+ while (true) {
+ cp = (wchar_t *) wschr(cp, (int) percent_char);
+ if (cp != NULL) {
+ result->patterns_total++;
+ cp++;
+ } else {
+ break;
+ }
+ }
+ result->patterns_total++;
+
+ /* allocate storage for patterns */
+ result->patterns = (Name *) getmem(sizeof(Name) * result->patterns_total);
+
+ /* then create patterns */
+ cp = wcb.get_string();
+ pattern = 0;
+ while (true) {
+ cp1 = (wchar_t *) wschr(cp, (int) percent_char);
+ if (cp1 != NULL) {
+ result->patterns[pattern] = GETNAME(cp, cp1 - cp);
+ cp = cp1 + 1;
+ pattern++;
+ } else {
+ result->patterns[pattern] = GETNAME(cp, (int) target->hash.length - (cp - wcb.get_string()));
+ break;
+ }
+ }
+
+ Wstring wcb1;
+
+ /* build dependencies list */
+ for (nvp = depes; nvp != NULL; nvp = nvp->next) {
+ for (i = 0; i < nvp->used; i++) {
+ depe = ALLOC(Percent);
+ depe->next = NULL;
+ depe->patterns = NULL;
+ depe->patterns_total = 0;
+ depe->name = nvp->names[i];
+ depe->dependencies = NULL;
+ depe->command_template = NULL;
+ depe->being_expanded = false;
+ depe->target_group = NULL;
+
+ *depe_tail = depe;
+ depe_tail = &depe->next;
+
+ if (depe->name->percent) {
+ /* get patterns count */
+ wcb1.init(depe->name);
+ cp = wcb1.get_string();
+ while (true) {
+ cp = (wchar_t *) wschr(cp, (int) percent_char);
+ if (cp != NULL) {
+ depe->patterns_total++;
+ cp++;
+ } else {
+ break;
+ }
+ }
+ depe->patterns_total++;
+
+ /* allocate storage for patterns */
+ depe->patterns = (Name *) getmem(sizeof(Name) * depe->patterns_total);
+
+ /* then create patterns */
+ cp = wcb1.get_string();
+ pattern = 0;
+ while (true) {
+ cp1 = (wchar_t *) wschr(cp, (int) percent_char);
+ if (cp1 != NULL) {
+ depe->patterns[pattern] = GETNAME(cp, cp1 - cp);
+ cp = cp1 + 1;
+ pattern++;
+ } else {
+ depe->patterns[pattern] = GETNAME(cp, (int) depe->name->hash.length - (cp - wcb1.get_string()));
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* Find the end of the percent list and append the new pattern */
+ for (insert = &percent_list; (*insert) != NULL; insert = &(*insert)->next);
+ *insert = result;
+
+ if (trace_reader) {
+ (void) printf("%s:", result->name->string_mb);
+
+ for (depe = result->dependencies; depe != NULL; depe = depe->next) {
+ (void) printf(" %s", depe->name->string_mb);
+ }
+
+ (void) printf("\n");
+
+ print_rule(command);
+ }
+
+ return result;
+}
+
+/*
+ * enter_dyntarget(target)
+ *
+ * Enter "$$(MACRO) : b" type lines
+ *
+ * Parameters:
+ * target Left hand side of pattern
+ *
+ * Global variables used:
+ * dyntarget_list The list of all percent rules, added to
+ * trace_reader Indicates that we should echo stuff we read
+ */
+Dyntarget
+enter_dyntarget(register Name target)
+{
+ register Dyntarget result = ALLOC(Dyntarget);
+ Dyntarget p;
+ Dyntarget *insert;
+ int i;
+
+ result->next = NULL;
+ result->name = target;
+
+
+ /* Find the end of the dyntarget list and append the new pattern */
+ for (insert = &dyntarget_list, p = *insert;
+ p != NULL;
+ insert = &p->next, p = *insert);
+ *insert = result;
+
+ if (trace_reader) {
+ (void) printf(NOCATGETS("Dynamic target %s:\n"), result->name->string_mb);
+ }
+ return( result);
+}
+
+
+/*
+ * special_reader(target, depes, command)
+ *
+ * Read the pseudo targets make knows about
+ * This handles the special targets that should not be entered as regular
+ * target/dependency sets.
+ *
+ * Parameters:
+ * target The special target
+ * depes The list of dependencies it was entered with
+ * command The command it was entered with
+ *
+ * Static variables used:
+ * built_last_make_run_seen Set to indicate .BUILT_LAST... seen
+ *
+ * Global variables used:
+ * all_parallel Set to indicate that everything runs parallel
+ * svr4 Set when ".SVR4" target is read
+ * svr4_name The Name ".SVR4"
+ * posix Set when ".POSIX" target is read
+ * posix_name The Name ".POSIX"
+ * current_make_version The Name "<current version number>"
+ * default_rule Set when ".DEFAULT" target is read
+ * default_rule_name The Name ".DEFAULT", used for tracing
+ * dot_keep_state The Name ".KEEP_STATE", used for tracing
+ * ignore_errors Set if ".IGNORE" target is read
+ * ignore_name The Name ".IGNORE", used for tracing
+ * keep_state Set if ".KEEP_STATE" target is read
+ * no_parallel_name The Name ".NO_PARALLEL", used for tracing
+ * only_parallel Set to indicate only some targets runs parallel
+ * parallel_name The Name ".PARALLEL", used for tracing
+ * precious The Name ".PRECIOUS", used for tracing
+ * sccs_get_name The Name ".SCCS_GET", used for tracing
+ * sccs_get_posix_name The Name ".SCCS_GET_POSIX", used for tracing
+ * get_name The Name ".GET", used for tracing
+ * sccs_get_rule Set when ".SCCS_GET" target is read
+ * silent Set when ".SILENT" target is read
+ * silent_name The Name ".SILENT", used for tracing
+ * trace_reader Indicates that we should echo stuff we read
+ */
+void
+special_reader(Name target, register Name_vector depes, Cmd_line command)
+{
+ register int n;
+
+ switch (target->special_reader) {
+
+ case svr4_special:
+ if (depes->used != 0) {
+ fatal_reader(catgets(catd, 1, 98, "Illegal dependencies for target `%s'"),
+ target->string_mb);
+ }
+ svr4 = true;
+ posix = false;
+ keep_state = false;
+ all_parallel = false;
+ only_parallel = false;
+ if (trace_reader) {
+ (void) printf("%s:\n", svr4_name->string_mb);
+ }
+ break;
+
+ case posix_special:
+ if(svr4)
+ break;
+ if (depes->used != 0) {
+ fatal_reader(catgets(catd, 1, 99, "Illegal dependencies for target `%s'"),
+ target->string_mb);
+ }
+ posix = true;
+ /* with posix on, use the posix get rule */
+ sccs_get_rule = sccs_get_posix_rule;
+ /* turn keep state off being SunPro make specific */
+ keep_state = false;
+ #if defined(SUN5_0)
+ /* Use /usr/xpg4/bin/sh on Solaris */
+ MBSTOWCS(wcs_buffer, NOCATGETS("/usr/xpg4/bin/sh"));
+ (void) SETVAR(shell_name, GETNAME(wcs_buffer, FIND_LENGTH), false);
+ #endif
+ if (trace_reader) {
+ (void) printf("%s:\n", posix_name->string_mb);
+ }
+ break;
+
+ case built_last_make_run_special:
+ built_last_make_run_seen = true;
+ break;
+
+ case default_special:
+ if (depes->used != 0) {
+ warning(catgets(catd, 1, 100, "Illegal dependency list for target `%s'"),
+ target->string_mb);
+ }
+ default_rule = command;
+ if (trace_reader) {
+ (void) printf("%s:\n",
+ default_rule_name->string_mb);
+ print_rule(command);
+ }
+ break;
+
+#ifdef NSE
+ case derived_src_special:
+ for (; depes != NULL; depes= depes->next)
+ for (n= 0; n < depes->used; n++) {
+ if (trace_reader)
+ (void)printf("%s:\t%s\n",
+ precious->string_mb,
+ depes->names[n]->string_mb);
+ depes->names[n]->stat.is_derived_src= true;
+ };
+ break;
+#endif
+
+ case ignore_special:
+ if ((depes->used != 0) &&(!posix)){
+ fatal_reader(catgets(catd, 1, 101, "Illegal dependencies for target `%s'"),
+ target->string_mb);
+ }
+ if (depes->used == 0)
+ {
+ ignore_errors_all = true;
+ }
+ if(svr4) {
+ ignore_errors_all = true;
+ break;
+ }
+ for (; depes != NULL; depes = depes->next) {
+ for (n = 0; n < depes->used; n++) {
+ depes->names[n]->ignore_error_mode = true;
+ }
+ }
+ if (trace_reader) {
+ (void) printf("%s:\n", ignore_name->string_mb);
+ }
+ break;
+
+ case keep_state_special:
+ if(svr4)
+ break;
+ /* ignore keep state, being SunPro make specific */
+ if(posix)
+ break;
+ if (depes->used != 0) {
+ fatal_reader(catgets(catd, 1, 102, "Illegal dependencies for target `%s'"),
+ target->string_mb);
+ }
+ keep_state = true;
+ if (trace_reader) {
+ (void) printf("%s:\n",
+ dot_keep_state->string_mb);
+ }
+ break;
+
+ case keep_state_file_special:
+ if(svr4)
+ break;
+ if(posix)
+ break;
+ /* it's not necessary to specify KEEP_STATE, if this
+ ** is given, so set the keep_state.
+ */
+ keep_state = true;
+ if (depes->used != 0) {
+ if((!make_state) ||(!strcmp(make_state->string_mb,NOCATGETS(".make.state")))) {
+ make_state = depes->names[0];
+ }
+ }
+ break;
+ case make_version_special:
+ if(svr4)
+ break;
+ if (depes->used != 1) {
+ fatal_reader(catgets(catd, 1, 103, "Illegal dependency list for target `%s'"),
+ target->string_mb);
+ }
+ if (depes->names[0] != current_make_version) {
+ /*
+ * Special case the fact that version 1.0 and 1.1
+ * are identical.
+ */
+ if (!IS_EQUAL(depes->names[0]->string_mb,
+ NOCATGETS("VERSION-1.1")) ||
+ !IS_EQUAL(current_make_version->string_mb,
+ NOCATGETS("VERSION-1.0"))) {
+ /*
+ * Version mismatches should cause the
+ * .make.state file to be skipped.
+ * This is currently not true - it is read
+ * anyway.
+ */
+ warning(catgets(catd, 1, 104, "Version mismatch between current version `%s' and `%s'"),
+ current_make_version->string_mb,
+ depes->names[0]->string_mb);
+ }
+ }
+ break;
+
+ case no_parallel_special:
+ if(svr4)
+ break;
+ /* Set the no_parallel bit for all the targets on */
+ /* the dependency list */
+ if (depes->used == 0) {
+ /* only those explicitly made parallel */
+ only_parallel = true;
+ all_parallel = false;
+ }
+ for (; depes != NULL; depes = depes->next) {
+ for (n = 0; n < depes->used; n++) {
+ if (trace_reader) {
+ (void) printf("%s:\t%s\n",
+ no_parallel_name->string_mb,
+ depes->names[n]->string_mb);
+ }
+ depes->names[n]->no_parallel = true;
+ depes->names[n]->parallel = false;
+ }
+ }
+ break;
+
+ case parallel_special:
+ if(svr4)
+ break;
+ if (depes->used == 0) {
+ /* everything runs in parallel */
+ all_parallel = true;
+ only_parallel = false;
+ }
+ /* Set the parallel bit for all the targets on */
+ /* the dependency list */
+ for (; depes != NULL; depes = depes->next) {
+ for (n = 0; n < depes->used; n++) {
+ if (trace_reader) {
+ (void) printf("%s:\t%s\n",
+ parallel_name->string_mb,
+ depes->names[n]->string_mb);
+ }
+ depes->names[n]->parallel = true;
+ depes->names[n]->no_parallel = false;
+ }
+ }
+ break;
+
+ case localhost_special:
+ if(svr4)
+ break;
+ /* Set the no_parallel bit for all the targets on */
+ /* the dependency list */
+ if (depes->used == 0) {
+ /* only those explicitly made parallel */
+ only_parallel = true;
+ all_parallel = false;
+ }
+ for (; depes != NULL; depes = depes->next) {
+ for (n = 0; n < depes->used; n++) {
+ if (trace_reader) {
+ (void) printf("%s:\t%s\n",
+ localhost_name->string_mb,
+ depes->names[n]->string_mb);
+ }
+ depes->names[n]->no_parallel = true;
+ depes->names[n]->parallel = false;
+ depes->names[n]->localhost = true;
+ }
+ }
+ break;
+
+ case precious_special:
+ if (depes->used == 0) {
+ /* everything is precious */
+ all_precious = true;
+ } else {
+ all_precious = false;
+ }
+ if(svr4) {
+ all_precious = true;
+ break;
+ }
+ /* Set the precious bit for all the targets on */
+ /* the dependency list */
+ for (; depes != NULL; depes = depes->next) {
+ for (n = 0; n < depes->used; n++) {
+ if (trace_reader) {
+ (void) printf("%s:\t%s\n",
+ precious->string_mb,
+ depes->names[n]->string_mb);
+ }
+ depes->names[n]->stat.is_precious = true;
+ }
+ }
+ break;
+
+ case sccs_get_special:
+ if (depes->used != 0) {
+ fatal_reader(catgets(catd, 1, 105, "Illegal dependencies for target `%s'"),
+ target->string_mb);
+ }
+ sccs_get_rule = command;
+ sccs_get_org_rule = command;
+ if (trace_reader) {
+ (void) printf("%s:\n", sccs_get_name->string_mb);
+ print_rule(command);
+ }
+ break;
+
+ case sccs_get_posix_special:
+ if (depes->used != 0) {
+ fatal_reader(catgets(catd, 1, 106, "Illegal dependencies for target `%s'"),
+ target->string_mb);
+ }
+ sccs_get_posix_rule = command;
+ if (trace_reader) {
+ (void) printf("%s:\n", sccs_get_posix_name->string_mb);
+ print_rule(command);
+ }
+ break;
+
+ case get_posix_special:
+ if (depes->used != 0) {
+ fatal_reader(catgets(catd, 1, 107, "Illegal dependencies for target `%s'"),
+ target->string_mb);
+ }
+ get_posix_rule = command;
+ if (trace_reader) {
+ (void) printf("%s:\n", get_posix_name->string_mb);
+ print_rule(command);
+ }
+ break;
+
+ case get_special:
+ if(!svr4) {
+ break;
+ }
+ if (depes->used != 0) {
+ fatal_reader(catgets(catd, 1, 108, "Illegal dependencies for target `%s'"),
+ target->string_mb);
+ }
+ get_rule = command;
+ sccs_get_rule = command;
+ if (trace_reader) {
+ (void) printf("%s:\n", get_name->string_mb);
+ print_rule(command);
+ }
+ break;
+
+ case silent_special:
+ if ((depes->used != 0) && (!posix)){
+ fatal_reader(catgets(catd, 1, 109, "Illegal dependencies for target `%s'"),
+ target->string_mb);
+ }
+ if (depes->used == 0)
+ {
+ silent_all = true;
+ }
+ if(svr4) {
+ silent_all = true;
+ break;
+ }
+ for (; depes != NULL; depes = depes->next) {
+ for (n = 0; n < depes->used; n++) {
+ depes->names[n]->silent_mode = true;
+ }
+ }
+ if (trace_reader) {
+ (void) printf("%s:\n", silent_name->string_mb);
+ }
+ break;
+
+ case suffixes_special:
+ read_suffixes_list(depes);
+ break;
+
+ default:
+
+ fatal_reader(catgets(catd, 1, 110, "Internal error: Unknown special reader"));
+ }
+}
+
+/*
+ * read_suffixes_list(depes)
+ *
+ * Read the special list .SUFFIXES. If it is empty the old list is
+ * cleared. Else the new one is appended. Suffixes with ~ are extracted
+ * and marked.
+ *
+ * Parameters:
+ * depes The list of suffixes
+ *
+ * Global variables used:
+ * hashtab The central hashtable for Names.
+ * suffixes The list of suffixes, set or appended to
+ * suffixes_name The Name ".SUFFIXES", used for tracing
+ * trace_reader Indicates that we should echo stuff we read
+ */
+static void
+read_suffixes_list(register Name_vector depes)
+{
+ register int n;
+ register Dependency dp;
+ register Dependency *insert_dep;
+ register Name np;
+ Name np2;
+ register Boolean first = true;
+
+ if (depes->used == 0) {
+ /* .SUFFIXES with no dependency list clears the */
+ /* suffixes list */
+ for (Name_set::iterator np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
+ np->with_squiggle =
+ np->without_squiggle =
+ false;
+ }
+ suffixes = NULL;
+ if (trace_reader) {
+ (void) printf("%s:\n", suffixes_name->string_mb);
+ }
+ return;
+ }
+ Wstring str;
+ /* Otherwise we append to the list */
+ for (; depes != NULL; depes = depes->next) {
+ for (n = 0; n < depes->used; n++) {
+ np = depes->names[n];
+ /* Find the end of the list and check if the */
+ /* suffix already has been entered */
+ for (insert_dep = &suffixes, dp = *insert_dep;
+ dp != NULL;
+ insert_dep = &dp->next, dp = *insert_dep) {
+ if (dp->name == np) {
+ goto duplicate_suffix;
+ }
+ }
+ if (trace_reader) {
+ if (first) {
+ (void) printf("%s:\t",
+ suffixes_name->string_mb);
+ first = false;
+ }
+ (void) printf("%s ", depes->names[n]->string_mb);
+ }
+ if(!(posix|svr4)) {
+ /* If the suffix is suffixed with "~" we */
+ /* strip that and mark the suffix nameblock */
+ str.init(np);
+ wchar_t * wcb = str.get_string();
+ if (wcb[np->hash.length - 1] ==
+ (int) tilde_char) {
+ np2 = GETNAME(wcb,
+ (int)(np->hash.length - 1));
+ np2->with_squiggle = true;
+ if (np2->without_squiggle) {
+ continue;
+ }
+ np = np2;
+ }
+ }
+ np->without_squiggle = true;
+ /* Add the suffix to the list */
+ dp = *insert_dep = ALLOC(Dependency);
+ insert_dep = &dp->next;
+ dp->next = NULL;
+ dp->name = np;
+ dp->built = false;
+ duplicate_suffix:;
+ }
+ }
+ if (trace_reader) {
+ (void) printf("\n");
+ }
+}
+
+/*
+ * make_relative(to, result)
+ *
+ * Given a file name compose a relative path name from it to the
+ * current directory.
+ *
+ * Parameters:
+ * to The path we want to make relative
+ * result Where to put the resulting relative path
+ *
+ * Global variables used:
+ */
+static void
+make_relative(wchar_t *to, wchar_t *result)
+{
+ wchar_t *from;
+ wchar_t *allocated;
+ wchar_t *cp;
+ wchar_t *tocomp;
+ int ncomps;
+ int i;
+ int len;
+
+ /* Check if the path is already relative. */
+ if (to[0] != (int) slash_char) {
+ (void) wscpy(result, to);
+ return;
+ }
+
+ MBSTOWCS(wcs_buffer, get_current_path());
+ from = allocated = (wchar_t *) wsdup(wcs_buffer);
+
+ /*
+ * Find the number of components in the from name.
+ * ncomp = number of slashes + 1.
+ */
+ ncomps = 1;
+ for (cp = from; *cp != (int) nul_char; cp++) {
+ if (*cp == (int) slash_char) {
+ ncomps++;
+ }
+ }
+
+ /*
+ * See how many components match to determine how many "..",
+ * if any, will be needed.
+ */
+ result[0] = (int) nul_char;
+ tocomp = to;
+ while ((*from != (int) nul_char) && (*from == *to)) {
+ if (*from == (int) slash_char) {
+ ncomps--;
+ tocomp = &to[1];
+ }
+ from++;
+ to++;
+ }
+
+ /*
+ * Now for some special cases. Check for exact matches and
+ * for either name terminating exactly.
+ */
+ if (*from == (int) nul_char) {
+ if (*to == (int) nul_char) {
+ MBSTOWCS(wcs_buffer, ".");
+ (void) wscpy(result, wcs_buffer);
+ retmem(allocated);
+ return;
+ }
+ if (*to == (int) slash_char) {
+ ncomps--;
+ tocomp = &to[1];
+ }
+ } else if ((*from == (int) slash_char) && (*to == (int) nul_char)) {
+ ncomps--;
+ tocomp = to;
+ }
+ /* Add on the ".."s. */
+ for (i = 0; i < ncomps; i++) {
+ MBSTOWCS(wcs_buffer, "../");
+ (void) wscat(result, wcs_buffer);
+ }
+
+ /* Add on the remainder of the to name, if any. */
+ if (*tocomp == (int) nul_char) {
+ len = wslen(result);
+ result[len - 1] = (int) nul_char;
+ } else {
+ (void) wscat(result, tocomp);
+ }
+ retmem(allocated);
+ return;
+}
+
+/*
+ * print_rule(command)
+ *
+ * Used when tracing the reading of rules
+ *
+ * Parameters:
+ * command Command to print
+ *
+ * Global variables used:
+ */
+static void
+print_rule(register Cmd_line command)
+{
+ for (; command != NULL; command = command->next) {
+ (void) printf("\t%s\n", command->command_line->string_mb);
+ }
+}
+
+/*
+ * enter_conditional(target, name, value, append)
+ *
+ * Enter "target := MACRO= value" constructs
+ *
+ * Parameters:
+ * target The target the macro is for
+ * name The name of the macro
+ * value The value for the macro
+ * append Indicates if the assignment is appending or not
+ *
+ * Global variables used:
+ * conditionals A special Name that stores all conditionals
+ * where the target is a % pattern
+ * trace_reader Indicates that we should echo stuff we read
+ */
+void
+enter_conditional(register Name target, Name name, Name value, register Boolean append)
+{
+ register Property conditional;
+ static int sequence;
+ Name orig_target = target;
+
+ if (name == target_arch) {
+ enter_conditional(target, virtual_root, virtual_root, false);
+ }
+
+ if (target->percent) {
+ target = conditionals;
+ }
+
+ if (name->colon) {
+ sh_transform(&name, &value);
+ }
+
+ /* Count how many conditionals we must activate before building the */
+ /* target */
+ if (target->percent) {
+ target = conditionals;
+ }
+
+ target->conditional_cnt++;
+ maybe_append_prop(name, macro_prop)->body.macro.is_conditional = true;
+ /* Add the property for the target */
+ conditional = append_prop(target, conditional_prop);
+ conditional->body.conditional.target = orig_target;
+ conditional->body.conditional.name = name;
+ conditional->body.conditional.value = value;
+ conditional->body.conditional.sequence = sequence++;
+ conditional->body.conditional.append = append;
+ if (trace_reader) {
+ if (value == NULL) {
+ (void) printf("%s := %s %c=\n",
+ target->string_mb,
+ name->string_mb,
+ append ?
+ (int) plus_char : (int) space_char);
+ } else {
+ (void) printf("%s := %s %c= %s\n",
+ target->string_mb,
+ name->string_mb,
+ append ?
+ (int) plus_char : (int) space_char,
+ value->string_mb);
+ }
+ }
+}
+
+/*
+ * enter_equal(name, value, append)
+ *
+ * Enter "MACRO= value" constructs
+ *
+ * Parameters:
+ * name The name of the macro
+ * value The value for the macro
+ * append Indicates if the assignment is appending or not
+ *
+ * Global variables used:
+ * trace_reader Indicates that we should echo stuff we read
+ */
+void
+enter_equal(Name name, Name value, register Boolean append)
+{
+ wchar_t *string;
+ Name temp;
+
+ if (name->colon) {
+ sh_transform(&name, &value);
+ }
+ (void) SETVAR(name, value, append);
+
+ /* if we're setting FC, we want to set F77 to the same value. */
+ Wstring nms(name);
+ wchar_t * wcb = nms.get_string();
+ string = wcb;
+ if (string[0]=='F' &&
+ string[1]=='C' &&
+ string[2]=='\0') {
+ MBSTOWCS(wcs_buffer, NOCATGETS("F77"));
+ temp = GETNAME(wcs_buffer, FIND_LENGTH);
+ (void) SETVAR(temp, value, append);
+/*
+ fprintf(stderr, catgets(catd, 1, 111, "warning: FC is obsolete, use F77 instead\n"));
+ */
+ }
+
+ if (trace_reader) {
+ if (value == NULL) {
+ (void) printf("%s %c=\n",
+ name->string_mb,
+ append ?
+ (int) plus_char : (int) space_char);
+ } else {
+ (void) printf("%s %c= %s\n",
+ name->string_mb,
+ append ?
+ (int) plus_char : (int) space_char,
+ value->string_mb);
+ }
+ }
+}
+
+/*
+ * sh_transform(name, value)
+ *
+ * Parameters:
+ * name The name of the macro we might transform
+ * value The value to transform
+ *
+ */
+static void
+sh_transform(Name *name, Name *value)
+{
+ /* Check if we need :sh transform */
+ wchar_t *colon;
+ String_rec command;
+ String_rec destination;
+ wchar_t buffer[1000];
+ wchar_t buffer1[1000];
+
+ static wchar_t colon_sh[4];
+ static wchar_t colon_shell[7];
+
+ if (colon_sh[0] == (int) nul_char) {
+ MBSTOWCS(colon_sh, NOCATGETS(":sh"));
+ MBSTOWCS(colon_shell, NOCATGETS(":shell"));
+ }
+ Wstring nms((*name));
+ wchar_t * wcb = nms.get_string();
+
+ colon = (wchar_t *) wsrchr(wcb, (int) colon_char);
+ if ((colon != NULL) && (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell))) {
+ INIT_STRING_FROM_STACK(destination, buffer);
+
+ if(*value == NULL) {
+ buffer[0] = 0;
+ } else {
+ Wstring wcb1((*value));
+ if (IS_WEQUAL(colon, colon_shell)) {
+ INIT_STRING_FROM_STACK(command, buffer1);
+ expand_value(*value, &command, false);
+ } else {
+ command.text.p = wcb1.get_string() + (*value)->hash.length;
+ command.text.end = command.text.p;
+ command.buffer.start = wcb1.get_string();
+ command.buffer.end = command.text.p;
+ }
+ sh_command2string(&command, &destination);
+ }
+
+ (*value) = GETNAME(destination.buffer.start, FIND_LENGTH);
+ *colon = (int) nul_char;
+ (*name) = GETNAME(wcb, FIND_LENGTH);
+ *colon = (int) colon_char;
+ }
+}
+
+/*
+ * fatal_reader(format, args...)
+ *
+ * Parameters:
+ * format printf style format string
+ * args arguments to match the format
+ *
+ * Global variables used:
+ * file_being_read Name of the makefile being read
+ * line_number Line that is being read
+ * report_pwd Indicates whether current path should be shown
+ * temp_file_name When reading tempfile we report that name
+ */
+/*VARARGS*/
+void
+fatal_reader(char * pattern, ...)
+{
+ va_list args;
+ char message[1000];
+
+ va_start(args, pattern);
+ if (file_being_read != NULL) {
+ WCSTOMBS(mbs_buffer, file_being_read);
+ if (line_number != 0) {
+ (void) sprintf(message,
+ catgets(catd, 1, 112, "%s, line %d: %s"),
+ mbs_buffer,
+ line_number,
+ pattern);
+ } else {
+ (void) sprintf(message,
+ "%s: %s",
+ mbs_buffer,
+ pattern);
+ }
+ pattern = message;
+ }
+
+ (void) fflush(stdout);
+#ifdef DISTRIBUTED
+ (void) fprintf(stderr, catgets(catd, 1, 113, "dmake: Fatal error in reader: "));
+#else
+ (void) fprintf(stderr, catgets(catd, 1, 238, "make: Fatal error in reader: "));
+#endif
+ (void) vfprintf(stderr, pattern, args);
+ (void) fprintf(stderr, "\n");
+ va_end(args);
+
+ if (temp_file_name != NULL) {
+ (void) fprintf(stderr,
+#ifdef DISTRIBUTED
+ catgets(catd, 1, 114, "dmake: Temp-file %s not removed\n"),
+#else
+ catgets(catd, 1, 239, "make: Temp-file %s not removed\n"),
+#endif
+ temp_file_name->string_mb);
+ temp_file_name = NULL;
+ }
+
+ if (report_pwd) {
+ (void) fprintf(stderr,
+ catgets(catd, 1, 115, "Current working directory %s\n"),
+ get_current_path());
+ }
+ (void) fflush(stderr);
+#if defined(SUN5_0) || defined(HP_UX)
+ exit_status = 1;
+#endif
+ exit(1);
+}
+
diff --git a/usr/src/make_src/Make/bin/make/common/rep.cc b/usr/src/make_src/Make/bin/make/common/rep.cc
new file mode 100644
index 0000000..6ad4007
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/rep.cc
@@ -0,0 +1,529 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)rep.cc 1.25 06/12/12
+ */
+
+#pragma ident "@(#)rep.cc 1.25 06/12/12"
+
+/*
+ * rep.c
+ *
+ * This file handles the .nse_depinfo file
+ */
+
+/*
+ * Included files
+ */
+#include <mk/defs.h>
+#include <mksh/misc.h> /* retmem() */
+#include <vroot/report.h> /* NSE_DEPINFO */
+
+/*
+ * Static variables
+ */
+static Recursive_make recursive_list;
+static Recursive_make *bpatch = &recursive_list;
+static Boolean changed;
+
+/*
+ * File table of contents
+ */
+
+
+/*
+ * report_recursive_init()
+ *
+ * Read the .nse_depinfo file and make a list of all the
+ * .RECURSIVE entries.
+ *
+ * Parameters:
+ *
+ * Static variables used:
+ * bpatch Points to slot where next cell should be added
+ *
+ * Global variables used:
+ * recursive_name The Name ".RECURSIVE", compared against
+ */
+
+void
+report_recursive_init(void)
+{
+ char *search_dir;
+ char nse_depinfo[MAXPATHLEN];
+ FILE *fp;
+ int line_size, line_index;
+ wchar_t *line;
+ wchar_t *bigger_line;
+ wchar_t *colon;
+ wchar_t *dollar;
+ Recursive_make rp;
+
+ /*
+ * This routine can be called more than once, don't do
+ * anything after the first time.
+ */
+ if (depinfo_already_read) {
+ return;
+ } else {
+ depinfo_already_read = true;
+ }
+
+ search_dir = getenv(NOCATGETS("NSE_DEP"));
+ if (search_dir == NULL) {
+ return;
+ }
+ (void) sprintf(nse_depinfo, "%s/%s", search_dir, NSE_DEPINFO);
+ fp = fopen(nse_depinfo, "r");
+ if (fp == NULL) {
+ return;
+ }
+ line_size = MAXPATHLEN;
+ line_index = line_size - 1;
+ line = ALLOC_WC(line_size);
+ Wstring rns(recursive_name);
+ wchar_t * wcb = rns.get_string();
+ while (fgetws(line, line_size, fp) != NULL) {
+ while (wslen(line) == line_index) {
+ if (line[wslen(line) - 1] == '\n') {
+ continue;
+ }
+ bigger_line = ALLOC_WC(2 * line_size);
+ wscpy(bigger_line, line);
+ retmem(line);
+ line = bigger_line;
+ if (fgetws(&line[line_index], line_size, fp) == NULL)
+ continue;
+ line_index = 2 * line_index;
+ line_size = 2 * line_size;
+ }
+
+ colon = (wchar_t *) wschr(line, (int) colon_char);
+ if (colon == NULL) {
+ continue;
+ }
+ dollar = (wchar_t *) wschr(line, (int) dollar_char);
+ line[wslen(line) - 1] = (int) nul_char;
+ if (IS_WEQUALN(&colon[2], wcb,
+ (int) recursive_name->hash.length)) {
+ /*
+ * If this entry is an old entry, ignore it
+ */
+ MBSTOWCS(wcs_buffer, DEPINFO_FMT_VERSION);
+ if (dollar == NULL ||
+ !IS_WEQUALN(wcs_buffer, (dollar+1) - VER_LEN, VER_LEN)){
+ continue;
+ }
+ rp = ALLOC(Recursive_make);
+ (void) memset((char *) rp, 0, sizeof (Recursive_make_rec));
+ /*
+ * set conditional_macro_string if string is present
+ */
+ rp->oldline = (wchar_t *) wsdup(line);
+ if ( dollar != NULL ){
+ rp->cond_macrostring =
+ (wchar_t *) wsdup(dollar - VER_LEN + 1);
+ }
+ /*
+ * get target name into recursive struct
+ */
+ *colon = (int) nul_char;
+ rp->target = (wchar_t *) wsdup(line);
+ *bpatch = rp;
+ bpatch = &rp->next;
+ }
+ }
+ (void) fclose(fp);
+}
+
+/*
+ * report_recursive_dep(target, line)
+ *
+ * Report a target as recursive.
+ *
+ * Parameters:
+ * line Dependency line reported
+ *
+ * Static variables used:
+ * bpatch Points to slot where next cell should be added
+ * changed Written if report set changed
+ */
+void
+report_recursive_dep(Name target, wchar_t *line)
+{
+ Recursive_make rp;
+ wchar_t rec_buf[STRING_BUFFER_LENGTH];
+ String_rec string;
+
+ INIT_STRING_FROM_STACK(string, rec_buf);
+ cond_macros_into_string(target, &string);
+ /*
+ * find an applicable recursive entry, if there isn't one, create it
+ */
+ rp = find_recursive_target(target);
+ if (rp == NULL) {
+ rp = ALLOC(Recursive_make);
+ (void) memset((char *) rp, 0, sizeof (Recursive_make_rec));
+ wchar_t * wcb = get_wstring(target->string_mb); // XXX Tolik: needs retmem
+ rp->target = wcb;
+ rp->newline = (wchar_t *) wsdup(line);
+ rp->cond_macrostring = (wchar_t *) wsdup(rec_buf);
+ *bpatch = rp;
+ bpatch = &rp->next;
+ changed = true;
+ } else {
+ if ((rp->oldline != NULL) && !IS_WEQUAL(rp->oldline, line)) {
+ rp->newline = (wchar_t *) wsdup(line);
+ changed = true;
+ }
+ rp->removed = false;
+ }
+}
+
+/*
+ * find_recursive_target(target)
+ *
+ * Search the list for a given target.
+ *
+ * Return value:
+ * The target cell
+ *
+ * Parameters:
+ * target The target we need
+ * top_level_target more info used to determinde the
+ * target we need
+ *
+ * Static variables used:
+ * recursive_list The list of targets
+ */
+Recursive_make
+find_recursive_target(Name target)
+{
+ Recursive_make rp;
+ String_rec string;
+ wchar_t rec_buf[STRING_BUFFER_LENGTH];
+
+ INIT_STRING_FROM_STACK(string, rec_buf);
+ cond_macros_into_string(target, &string);
+
+ Wstring tstr(target);
+ wchar_t * wcb = tstr.get_string();
+ for (rp = recursive_list; rp != NULL; rp = rp->next) {
+ /*
+ * If this entry has already been removed, ignore it.
+ */
+ if (rp->removed)
+ continue;
+ /*
+ * If this target, and the target on the list are the same
+ * and if one of them contains conditional macro info, while
+ * the other doesn't, remove this entry from the list of
+ * recursive entries. This can only happen if the Makefile
+ * has changed to no longer contain conditional macros.
+ */
+ if (IS_WEQUAL(rp->target, wcb)) {
+ if (rp->cond_macrostring[VER_LEN] == '\0' &&
+ string.buffer.start[VER_LEN] != '\0'){
+ rp->removed = true;
+ continue;
+ } else if (rp->cond_macrostring[VER_LEN] != '\0' &&
+ string.buffer.start[VER_LEN] == '\0'){
+ rp->removed = true;
+ continue;
+ }
+ }
+ /*
+ * If this is not a VERS2 entry, only need to match
+ * the target name. toptarg information from VERS1 entries
+ * are ignored.
+ */
+ MBSTOWCS(wcs_buffer, DEPINFO_FMT_VERSION);
+ if (IS_WEQUALN(wcs_buffer, string.buffer.start, VER_LEN)) {
+ if (IS_WEQUAL(rp->cond_macrostring,
+ string.buffer.start) &&
+ IS_WEQUAL(rp->target, wcb)) {
+ return rp;
+ }
+ } else {
+ if (IS_WEQUAL(rp->target, wcb)) {
+ return rp;
+ }
+ }
+ }
+ return NULL;
+}
+
+/*
+ * remove_recursive_dep(target, top_level_target)
+ *
+ * Mark a target as no longer recursive.
+ *
+ * Parameters:
+ * target The target we want to remove
+ * top_level_target target we want to remove must be built from
+ * the same top level target
+ *
+ * Static variables used:
+ * changed Written if report set changed
+ */
+void
+remove_recursive_dep(Name target)
+{
+ Recursive_make rp;
+
+ rp = find_recursive_target(target);
+
+ if ( rp != NULL ) {
+ rp->removed = true;
+ changed = true;
+ if(rp->target) {
+ retmem(rp->target);
+ rp->target = NULL;
+ }
+ if(rp->newline) {
+ retmem(rp->newline);
+ rp->newline = NULL;
+ }
+ if(rp->oldline) {
+ retmem(rp->oldline);
+ rp->oldline = NULL;
+ }
+ if(rp->cond_macrostring) {
+ retmem(rp->cond_macrostring);
+ rp->cond_macrostring = NULL;
+ }
+ }
+}
+
+#ifdef NSE
+/*
+ * report_recursive_done()
+ *
+ * Write the .nse_depinfo file.
+ *
+ * Parameters:
+ *
+ * Static variables used:
+ * recursive_list The list of targets
+ * changed Written if report set changed
+ *
+ * Global variables used:
+ * recursive_name The Name ".RECURSIVE", compared against
+ */
+void
+report_recursive_done(void)
+{
+ char *search_dir;
+ char nse_depinfo[MAXPATHLEN];
+ char tmpfile[MAXPATHLEN];
+ FILE *ofp;
+ FILE *ifp;
+ wchar_t *space;
+ wchar_t *data;
+ wchar_t *line;
+ wchar_t *bigger_line;
+ int line_size, line_index;
+ int lock_err;
+ Recursive_make rp;
+
+ if (changed == false) {
+ return;
+ }
+
+ search_dir = getenv(NOCATGETS("NSE_DEP"));
+ if (search_dir == NULL) {
+ return;
+ }
+ (void) sprintf(nse_depinfo, "%s/%s", search_dir, NSE_DEPINFO);
+ (void) sprintf(tmpfile, "%s.%d", nse_depinfo, getpid());
+ ofp = fopen(tmpfile, "w");
+ if (ofp == NULL) {
+ (void) fprintf(stderr,
+ catgets(catd, 1, 116, "Cannot open `%s' for writing\n"),
+ tmpfile);
+ return;
+ }
+ (void) sprintf(nse_depinfo_lockfile,
+ "%s/%s", search_dir, NSE_DEPINFO_LOCK);
+ if (lock_err = file_lock(nse_depinfo,
+ nse_depinfo_lockfile,
+ (int *) &nse_depinfo_locked, 0)) {
+ (void) fprintf(stderr,
+ catgets(catd, 1, 117, "writing .RECURSIVE lines to %s\n"),
+ tmpfile);
+ (void) fprintf(stderr,
+ catgets(catd, 1, 118, "To recover, merge .nse_depinfo.%d with .nse_depinfo\n"),
+ getpid(),
+ catgets(catd, 1, 119, "with .nse_depinfo"));
+ }
+
+ if (nse_depinfo_locked) {
+ ifp = fopen(nse_depinfo, "r");
+ if (ifp != NULL) {
+ /*
+ * Copy all the non-.RECURSIVE lines from
+ * the old file to the new one.
+ */
+ line_size = MAXPATHLEN;
+ line_index = line_size - 1;
+ line = ALLOC_WC(line_size);
+ while (fgetws(line, line_size, ifp) != NULL) {
+ while (wslen(line) == line_index) {
+ if (line[wslen(line) - 1] == '\n') {
+ continue;
+ }
+ bigger_line = ALLOC_WC(2 * line_size);
+ wscpy(bigger_line, line);
+ retmem(line);
+ line = bigger_line;
+ if (fgetws(&line[line_index],
+ line_size, ifp) == NULL)
+ continue;
+ line_index = 2 * line_index;
+ line_size = 2 * line_size;
+ }
+
+ space = wschr(line, (int) space_char);
+ if (space != NULL &&
+ IS_WEQUALN(&space[1],
+ recursive_name->string,
+ (int) recursive_name->hash.length)) {
+ continue;
+ }
+ WCSTOMBS(mbs_buffer, line);
+ (void) fprintf(ofp, "%s", mbs_buffer);
+ }
+ (void) fclose(ifp);
+ }
+ }
+
+ /*
+ * Write out the .RECURSIVE lines.
+ */
+ for (rp = recursive_list; rp != NULL; rp = rp->next) {
+ if (rp->removed) {
+ continue;
+ }
+ if (rp->newline != NULL) {
+ data = rp->newline;
+ } else {
+ data = rp->oldline;
+ }
+ if (data != NULL) {
+ WCSTOMBS(mbs_buffer, data);
+ (void) fprintf(ofp, "%s\n", mbs_buffer);
+ }
+ }
+ (void) fclose(ofp);
+
+ if (nse_depinfo_locked) {
+ (void) rename(tmpfile, nse_depinfo);
+ (void) unlink(nse_depinfo_lockfile);
+ nse_depinfo_locked = false;
+ nse_depinfo_lockfile[0] = '\0';
+ (void) chmod(nse_depinfo, 0666);
+ }
+}
+#endif // NSE
+
+/* gather_recursive_deps()
+ *
+ * Create or update list of recursive targets.
+ */
+void
+gather_recursive_deps(void)
+{
+ Name_set::iterator np, e;
+ String_rec rec;
+ wchar_t rec_buf[STRING_BUFFER_LENGTH];
+ register Property lines;
+ Boolean has_recursive;
+ Dependency dp;
+
+ report_recursive_init();
+
+ /* Go thru all targets and dump recursive dependencies */
+ for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
+ if (np->has_recursive_dependency){
+ has_recursive = false;
+ /*
+ * start .RECURSIVE line with target:
+ */
+ INIT_STRING_FROM_STACK(rec, rec_buf);
+ APPEND_NAME(np, &rec, FIND_LENGTH);
+ append_char((int) colon_char, &rec);
+ append_char((int) space_char, &rec);
+
+ for (lines = get_prop(np->prop,recursive_prop);
+ lines != NULL;
+ lines = get_prop(lines->next, recursive_prop)) {
+ /*
+ * if entry is already in depinfo
+ * file or entry was not built, ignore it
+ */
+ if (lines->body.recursive.in_depinfo)
+ continue;
+ if (!lines->body.recursive.has_built)
+ continue;
+ has_recursive = true;
+ lines->body.recursive.in_depinfo=true;
+
+ /*
+ * Write the remainder of the
+ * .RECURSIVE line
+ */
+ APPEND_NAME(recursive_name, &rec,
+ FIND_LENGTH);
+ append_char((int) space_char, &rec);
+ APPEND_NAME(lines->body.recursive.directory,
+ &rec, FIND_LENGTH);
+ append_char((int) space_char, &rec);
+ APPEND_NAME(lines->body.recursive.target,
+ &rec, FIND_LENGTH);
+ append_char((int) space_char, &rec);
+
+ /* Complete list of makefiles used */
+ for (dp = lines->body.recursive.makefiles;
+ dp != NULL;
+ dp = dp->next) {
+ APPEND_NAME(dp->name, &rec, FIND_LENGTH);
+ append_char((int) space_char, &rec);
+ }
+ }
+ /*
+ * dump list of conditional targets,
+ * and report recursive entry, if needed
+ */
+ cond_macros_into_string(np, &rec);
+ if (has_recursive){
+ report_recursive_dep(np, rec.buffer.start);
+ }
+
+ } else if ( np->has_built ) {
+ remove_recursive_dep(np);
+ }
+ }
+}
+
diff --git a/usr/src/make_src/Make/bin/make/common/state.cc b/usr/src/make_src/Make/bin/make/common/state.cc
new file mode 100644
index 0000000..eff066a
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/state.cc
@@ -0,0 +1,463 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)state.cc 1.27 06/12/12
+ */
+
+#pragma ident "@(#)state.cc 1.27 06/12/12"
+
+/*
+ * state.c
+ *
+ * This file contains the routines that write the .make.state file
+ */
+
+/*
+ * Included files
+ */
+#include <mk/defs.h>
+#include <mksh/misc.h> /* errmsg() */
+#include <setjmp.h> /* setjmp() */
+#include <unistd.h> /* getpid() */
+#include <errno.h> /* errno */
+#include <locale.h> /* MB_CUR_MAX */
+
+/*
+ * Defined macros
+ */
+#define LONGJUMP_VALUE 17
+#define XFWRITE(string, length, fd) {if (fwrite(string, 1, length, fd) == 0) \
+ longjmp(long_jump, LONGJUMP_VALUE);}
+#define XPUTC(ch, fd) { \
+ if (putc((int) ch, fd) == EOF) \
+ longjmp(long_jump, LONGJUMP_VALUE); \
+ }
+#define XFPUTS(string, fd) fputs(string, fd)
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+static char * escape_target_name(Name np)
+{
+ if(np->dollar) {
+ int len = strlen(np->string_mb);
+ char * buff = (char*)malloc(2 * len);
+ int pos = 0;
+ wchar_t wc;
+ int pp = 0;
+ while(pos < len) {
+ int n = mbtowc(&wc, np->string_mb + pos, MB_CUR_MAX);
+ if(n < 0) { // error - this shouldn't happen
+ (void)free(buff);
+ return strdup(np->string_mb);
+ }
+ if(wc == dollar_char) {
+ buff[pp] = '\\'; pp++;
+ buff[pp] = '$'; pp++;
+ } else {
+ for(int j=0;j<n;j++) {
+ buff[pp] = np->string_mb[pos+j]; pp++;
+ }
+ }
+ pos += n;
+ }
+ buff[pp] = '\0';
+ return buff;
+ } else {
+ return strdup(np->string_mb);
+ }
+}
+
+static void print_auto_depes(register Dependency dependency, register FILE *fd, register Boolean built_this_run, register int *line_length, register char *target_name, jmp_buf long_jump);
+
+/*
+ * write_state_file(report_recursive, exiting)
+ *
+ * Write a new version of .make.state
+ *
+ * Parameters:
+ * report_recursive Should only be done at end of run
+ * exiting true if called from the exit handler
+ *
+ * Global variables used:
+ * built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written
+ * command_changed If no command changed we do not need to write
+ * current_make_version The Name "<current version>", written
+ * do_not_exec_rule If -n is on we do not write statefile
+ * hashtab The hashtable that contains all names
+ * keep_state If .KEEP_STATE is no on we do not write file
+ * make_state The Name ".make.state", used for opening file
+ * make_version The Name ".MAKE_VERSION", written
+ * recursive_name The Name ".RECURSIVE", written
+ * rewrite_statefile Indicates that something changed
+ */
+
+void
+#ifdef NSE
+write_state_file(int report_recursive, Boolean exiting)
+#else
+write_state_file(int, Boolean exiting)
+#endif
+{
+ register FILE *fd;
+ int lock_err;
+ char buffer[MAXPATHLEN];
+ char make_state_tempfile[MAXPATHLEN];
+ jmp_buf long_jump;
+ register int attempts = 0;
+ Name_set::iterator np, e;
+ register Property lines;
+ register int m;
+ Dependency dependency;
+ register Boolean name_printed;
+ Boolean built_this_run = false;
+ char *target_name;
+ int line_length;
+ register Cmd_line cp;
+
+
+ if (!rewrite_statefile ||
+ !command_changed ||
+ !keep_state ||
+ do_not_exec_rule ||
+ (report_dependencies_level > 0)) {
+ return;
+ }
+ /* Lock the file for writing. */
+ make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(NOCATGETS(".lock")) + 1);
+ (void) sprintf(make_state_lockfile,
+ NOCATGETS("%s.lock"),
+ make_state->string_mb);
+ if (lock_err = file_lock(make_state->string_mb,
+ make_state_lockfile,
+ (int *) &make_state_locked, 0)) {
+ retmem_mb(make_state_lockfile);
+ make_state_lockfile = NULL;
+
+ /*
+ * We need to make sure that we are not being
+ * called by the exit handler so we don't call
+ * it again.
+ */
+
+ if (exiting) {
+ (void) sprintf(buffer, NOCATGETS("%s/.make.state.%d.XXXXXX"), tmpdir, getpid());
+ report_pwd = true;
+ warning(catgets(catd, 1, 60, "Writing to %s"), buffer);
+ int fdes = mkstemp(buffer);
+ if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) {
+ fprintf(stderr,
+ catgets(catd, 1, 61, "Could not open statefile `%s': %s"),
+ buffer,
+ errmsg(errno));
+ return;
+ }
+ } else {
+ report_pwd = true;
+ fatal(catgets(catd, 1, 62, "Can't lock .make.state"));
+ }
+ }
+
+ (void) sprintf(make_state_tempfile,
+ NOCATGETS("%s.tmp"),
+ make_state->string_mb);
+ /* Delete old temporary statefile (in case it exists) */
+ (void) unlink(make_state_tempfile);
+ if ((fd = fopen(make_state_tempfile, "w")) == NULL) {
+ lock_err = errno; /* Save it! unlink() can change errno */
+ (void) unlink(make_state_lockfile);
+ retmem_mb(make_state_lockfile);
+ make_state_lockfile = NULL;
+ make_state_locked = false;
+ fatal(catgets(catd, 1, 59, "Could not open temporary statefile `%s': %s"),
+ make_state_tempfile,
+ errmsg(lock_err));
+ }
+#ifdef NSE
+ if (nse) {
+ (void) fchmod(fileno(fd), 0666);
+ }
+#endif
+ /*
+ * Set a trap for failed writes. If a write fails, the routine
+ * will try saving the .make.state file under another name in /tmp.
+ */
+ if (setjmp(long_jump)) {
+ (void) fclose(fd);
+ if (attempts++ > 5) {
+ if ((make_state_lockfile != NULL) &&
+ make_state_locked) {
+ (void) unlink(make_state_lockfile);
+ retmem_mb(make_state_lockfile);
+ make_state_lockfile = NULL;
+ make_state_locked = false;
+ }
+ fatal(catgets(catd, 1, 63, "Giving up on writing statefile"));
+ }
+ sleep(10);
+ (void) sprintf(buffer, NOCATGETS("%s/.make.state.%d.XXXXXX"), tmpdir, getpid());
+ int fdes = mkstemp(buffer);
+ if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) {
+ fatal(catgets(catd, 1, 64, "Could not open statefile `%s': %s"),
+ buffer,
+ errmsg(errno));
+ }
+ warning(catgets(catd, 1, 65, "Initial write of statefile failed. Trying again on %s"),
+ buffer);
+ }
+
+ /* Write the version stamp. */
+ XFWRITE(make_version->string_mb,
+ strlen(make_version->string_mb),
+ fd);
+ XPUTC(colon_char, fd);
+ XPUTC(tab_char, fd);
+ XFWRITE(current_make_version->string_mb,
+ strlen(current_make_version->string_mb),
+ fd);
+ XPUTC(newline_char, fd);
+
+ /*
+ * Go through all the targets, dump their dependencies and
+ * command used.
+ */
+ for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
+ /*
+ * If the target has no command used nor dependencies,
+ * we can go to the next one.
+ */
+ if ((lines = get_prop(np->prop, line_prop)) == NULL) {
+ continue;
+ }
+ /* If this target is a special target, don't print. */
+ if (np->special_reader != no_special) {
+ continue;
+ }
+ /*
+ * Find out if any of the targets dependencies should
+ * be written to .make.state.
+ */
+ for (m = 0, dependency = lines->body.line.dependencies;
+ dependency != NULL;
+ dependency = dependency->next) {
+ if (m = !dependency->stale
+ && (dependency->name != force)
+#ifndef PRINT_EXPLICIT_DEPEN
+ && dependency->automatic
+#endif
+ ) {
+ break;
+ }
+ }
+ /* Only print if dependencies listed. */
+ if (m || (lines->body.line.command_used != NULL)) {
+ name_printed = false;
+ /*
+ * If this target was built during this make run,
+ * we mark it.
+ */
+ built_this_run = false;
+ if (np->has_built) {
+ built_this_run = true;
+ XFWRITE(built_last_make_run->string_mb,
+ strlen(built_last_make_run->string_mb),
+ fd);
+ XPUTC(colon_char, fd);
+ XPUTC(newline_char, fd);
+ }
+ /* If the target has dependencies, we dump them. */
+ target_name = escape_target_name(np);
+ if (np->has_long_member_name) {
+ target_name =
+ get_prop(np->prop, long_member_name_prop)
+ ->body.long_member_name.member_name->
+ string_mb;
+ }
+ if (m) {
+ XFPUTS(target_name, fd);
+ XPUTC(colon_char, fd);
+ XFPUTS("\t", fd);
+ name_printed = true;
+ line_length = 0;
+ for (dependency =
+ lines->body.line.dependencies;
+ dependency != NULL;
+ dependency = dependency->next) {
+ print_auto_depes(dependency,
+ fd,
+ built_this_run,
+ &line_length,
+ target_name,
+ long_jump);
+ }
+ XFPUTS("\n", fd);
+ }
+ /* If there is a command used, we dump it. */
+ if (lines->body.line.command_used != NULL) {
+ /*
+ * Only write the target name if it
+ * wasn't done for the dependencies.
+ */
+ if (!name_printed) {
+ XFPUTS(target_name, fd);
+ XPUTC(colon_char, fd);
+ XPUTC(newline_char, fd);
+ }
+ /*
+ * Write the command lines.
+ * Prefix each textual line with a tab.
+ */
+ for (cp = lines->body.line.command_used;
+ cp != NULL;
+ cp = cp->next) {
+ char *csp;
+ int n;
+
+ XPUTC(tab_char, fd);
+ if (cp->command_line != NULL) {
+ for (csp = cp->
+ command_line->
+ string_mb,
+ n = strlen(cp->
+ command_line->
+ string_mb);
+ n > 0;
+ n--, csp++) {
+ XPUTC(*csp, fd);
+ if (*csp ==
+ (int) newline_char) {
+ XPUTC(tab_char,
+ fd);
+ }
+ }
+ }
+ XPUTC(newline_char, fd);
+ }
+ }
+ (void)free(target_name);
+ }
+ }
+ if (fclose(fd) == EOF) {
+ longjmp(long_jump, LONGJUMP_VALUE);
+ }
+ if (attempts == 0) {
+ if (unlink(make_state->string_mb) != 0 && errno != ENOENT) {
+ lock_err = errno; /* Save it! unlink() can change errno */
+ /* Delete temporary statefile */
+ (void) unlink(make_state_tempfile);
+ (void) unlink(make_state_lockfile);
+ retmem_mb(make_state_lockfile);
+ make_state_lockfile = NULL;
+ make_state_locked = false;
+ fatal(catgets(catd, 1, 356, "Could not delete old statefile `%s': %s"),
+ make_state->string_mb,
+ errmsg(lock_err));
+ }
+ if (rename(make_state_tempfile, make_state->string_mb) != 0) {
+ lock_err = errno; /* Save it! unlink() can change errno */
+ /* Delete temporary statefile */
+ (void) unlink(make_state_tempfile);
+ (void) unlink(make_state_lockfile);
+ retmem_mb(make_state_lockfile);
+ make_state_lockfile = NULL;
+ make_state_locked = false;
+ fatal(catgets(catd, 1, 357, "Could not rename `%s' to `%s': %s"),
+ make_state_tempfile,
+ make_state->string_mb,
+ errmsg(lock_err));
+ }
+ }
+ if ((make_state_lockfile != NULL) && make_state_locked) {
+ (void) unlink(make_state_lockfile);
+ retmem_mb(make_state_lockfile);
+ make_state_lockfile = NULL;
+ make_state_locked = false;
+ }
+#ifdef NSE
+ if (report_recursive) {
+ report_recursive_done();
+ }
+#endif
+}
+
+/*
+ * print_auto_depes(dependency, fd, built_this_run,
+ * line_length, target_name, long_jump)
+ *
+ * Will print a dependency list for automatic entries.
+ *
+ * Parameters:
+ * dependency The dependency to print
+ * fd The file to print it to
+ * built_this_run If on we prefix each line with .BUILT_THIS...
+ * line_length Pointer to line length var that we update
+ * target_name We need this when we restart line
+ * long_jump setjmp/longjmp buffer used for IO error action
+ *
+ * Global variables used:
+ * built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written
+ * force The Name " FORCE", compared against
+ */
+static void
+print_auto_depes(register Dependency dependency, register FILE *fd, register Boolean built_this_run, register int *line_length, register char *target_name, jmp_buf long_jump)
+{
+ if (!dependency->automatic ||
+ dependency->stale ||
+ (dependency->name == force)) {
+ return;
+ }
+ XFWRITE(dependency->name->string_mb,
+ strlen(dependency->name->string_mb),
+ fd);
+ /*
+ * Check if the dependency line is too long.
+ * If so, break it and start a new one.
+ */
+ if ((*line_length += (int) strlen(dependency->name->string_mb) + 1) > 450) {
+ *line_length = 0;
+ XPUTC(newline_char, fd);
+ if (built_this_run) {
+ XFPUTS(built_last_make_run->string_mb, fd);
+ XPUTC(colon_char, fd);
+ XPUTC(newline_char, fd);
+ }
+ XFPUTS(target_name, fd);
+ XPUTC(colon_char, fd);
+ XPUTC(tab_char, fd);
+ } else {
+ XFPUTS(" ", fd);
+ }
+ return;
+}
+
+
diff --git a/usr/src/make_src/Make/bin/make/common/svr4.make.rules.file b/usr/src/make_src/Make/bin/make/common/svr4.make.rules.file
new file mode 100644
index 0000000..55c9a1d
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/common/svr4.make.rules.file
@@ -0,0 +1,242 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1994 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)svr4.make.rules.file 1.4 06/12/12
+#
+.SUFFIXES: .o .c .c~ .y .y~ .l .l~ .s .s~ .sh .sh~ .h .h~ .f .f~ \
+.C .C~ .Y .Y~ .L .L~
+
+MAKE=make
+BUILD=build
+AR=ar
+ARFLAGS=rv
+AS=as
+ASFLAGS=
+CC=cc
+CFLAGS=-O
+F77=f77
+FFLAGS=-O
+GET=get
+GFLAGS=
+LD=ld
+LDFLAGS=
+LEX=lex
+LFLAGS=
+YACC=yacc
+YFLAGS=
+C++C=CC
+C++FLAGS=-O
+
+
+.c:
+ $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
+.c~:
+ $(GET) $(GFLAGS) $<
+ $(CC) $(CFLAGS) $*.c -o $@ $(LDFLAGS)
+ -rm -f $*.c
+.f:
+ $(F77) $(FFLAGS) $< -o $@ $(LDFLAGS)
+.f~:
+ $(GET) $(GFLAGS) $<
+ $(F77) $(FFLAGS) $*.f -o $@ $(LDFLAGS)
+ -rm -f $*.f
+.s:
+ $(AS) $(ASFLAGS) $< -o $@ $(LDFLAGS)
+.s~:
+ $(GET) $(GFLAGS) $<
+ $(AS) $(ASFLAGS) $*.s -o $* $(LDFLAGS)
+ -rm -f $*.s
+.sh:
+ cp $< $@; chmod 0777 $@
+.sh~:
+ $(GET) $(GFLAGS) $<
+ cp $*.sh $*; chmod 0777 $@
+ -rm -f $*.sh
+.C:
+ $(C++C) $(C++FLAGS) $< -o $@ $(LDFLAGS)
+.C~:
+ $(GET) $(GFLAGS) $<
+ $(C++C) $(C++FLAGS) $*.C -o $@ $(LDFLAGS)
+ -rm -f $*.C
+
+.c.a:
+ $(CC) $(CFLAGS) -c $<
+ $(AR) $(ARFLAGS) $@ $*.o
+ -rm -f $*.o
+.c.o:
+ $(CC) $(CFLAGS) -c $<
+.c~.a:
+ $(GET) $(GFLAGS) $<
+ $(CC) $(CFLAGS) -c $*.c
+ $(AR) $(ARFLAGS) $@ $*.o
+ -rm -f $*.[co]
+.c~.c:
+ $(GET) $(GFLAGS) $<
+.c~.o:
+ $(GET) $(GFLAGS) $<
+ $(CC) $(CFLAGS) -c $*.c
+ -rm -f $*.c
+.f.a:
+ $(F77) $(FFLAGS) -c $*.f
+ $(AR) $(ARFLAGS) $@ $*.o
+ -rm -f $*.o
+.f.o:
+ $(F77) $(FFLAGS) -c $*.f
+.f~.a:
+ $(GET) $(GFLAGS) $<
+ $(F77) $(FFLAGS) -c $*.f
+ $(AR) $(ARFLAGS) $@ $*.o
+ -rm -f $*.[fo]
+.f~.f:
+ $(GET) $(GFLAGS) $<
+.f~.o:
+ $(GET) $(GFLAGS) $<
+ $(F77) $(FFLAGS) -c $*.f
+ -rm -f $*.f
+.h~.h:
+ $(GET) $(GFLAGS) $<
+.l.c:
+ $(LEX) $(LFLAGS) $<
+ mv lex.yy.c $@
+.l.o:
+ $(LEX) $(LFLAGS) $<
+ $(CC) $(CFLAGS) -c lex.yy.c
+ -rm lex.yy.c; mv lex.yy.o $@
+.l~.c:
+ $(GET) $(GFLAGS) $<
+ $(LEX) $(LFLAGS) $*.l
+ mv lex.yy.c $@
+ -rm -f $*.l
+.l~.l:
+ $(GET) $(GFLAGS) $<
+.l~.o:
+ $(GET) $(GFLAGS) $<
+ $(LEX) $(LFLAGS) $*.l
+ $(CC) $(CFLAGS) -c lex.yy.c
+ -rm -f lex.yy.c $*.l
+ mv lex.yy.o $@
+.s.a:
+ $(AS) $(ASFLAGS) -o $*.o $*.s
+ $(AR) $(ARFLAGS) $@ $*.o
+.s.o:
+ $(AS) $(ASFLAGS) -o $@ $<
+.s~.a:
+ $(GET) $(GFLAGS) $<
+ $(AS) $(ASFLAGS) -o $*.o $*.s
+ $(AR) $(ARFLAGS) $@ $*.o
+ -rm -f $*.[so]
+.s~.o:
+ $(GET) $(GFLAGS) $<
+ $(AS) $(ASFLAGS) -o $*.o $*.s
+ -rm -f $*.s
+.s~.s:
+ $(GET) $(GFLAGS) $<
+.sh~.sh:
+ $(GET) $(GFLAGS) $<
+.y.c:
+ $(YACC) $(YFLAGS) $<
+ mv y.tab.c $@
+.y.o:
+ $(YACC) $(YFLAGS) $<
+ $(CC) $(CFLAGS) -c y.tab.c
+ -rm y.tab.c
+ mv y.tab.o $@
+.y~.c:
+ $(GET) $(GFLAGS) $<
+ $(YACC) $(YFLAGS) $*.y
+ mv y.tab.c $*.c
+ -rm -f $*.y
+.y~.o:
+ $(GET) $(GFLAGS) $<
+ $(YACC) $(YFLAGS) $*.y
+ $(CC) $(CFLAGS) -c y.tab.c
+ -rm -f y.tab.c $*.y
+ mv y.tab.o $*.o
+.y~.y :
+ $(GET) $(GFLAGS) $<
+.C.a:
+ $(C++C) $(C++FLAGS) -c $<
+ $(AR) $(ARFLAGS) $@ $*.o
+ -rm -f $*.o
+.C.o:
+ $(C++C) $(C++FLAGS) -c $<
+.C~.a:
+ $(GET) $(GFLAGS) $<
+ $(C++C) $(C++FLAGS) -c $*.C
+ $(AR) $(ARFLAGS) $@ $*.o
+ -rm -f $*.[Co]
+.C~.C:
+ $(GET) $(GFLAGS) $<
+.C~.o:
+ $(GET) $(GFLAGS) $<
+ $(C++C) $(C++FLAGS) -c $*.C
+ -rm -f $*.C
+.L.C:
+ $(LEX) $(LFLAGS) $<
+ mv lex.yy.c $@
+.L.o:
+ $(LEX) $(LFLAGS) $<
+ $(C++C) $(C++FLAGS) -c lex.yy.c
+ -rm lex.yy.c; mv lex.yy.o $@
+.L~.C:
+ $(GET) $(GFLAGS) $<
+ $(LEX) $(LFLAGS) $*.L
+ mv lex.yy.c $@
+ -rm -f $*.L
+.L~.L:
+ $(GET) $(GFLAGS) $<
+.L~.o:
+ $(GET) $(GFLAGS) $<
+ $(LEX) $(LFLAGS) $*.L
+ $(C++C) $(C++FLAGS) -c lex.yy.c
+ -rm -f lex.yy.c $*.L
+ mv lex.yy.c $@
+.Y.C:
+ $(YACC) $(YFLAGS) $<
+ mv y.tab.c $@
+.Y.o:
+ $(YACC) $(YFLAGS) $<
+ $(C++C) $(C++FLAGS) -c y.tab.c
+ -rm y.tab.c
+ mv y.tab.o $@
+.Y~.C:
+ $(GET) $(GFLAGS) $<
+ $(YACC) $(YFLAGS) $*.Y
+ mv y.tab.c $*.C
+ -rm -f $*.Y
+.Y~.o:
+ $(GET) $(GFLAGS) $<
+ $(YACC) $(YFLAGS) $*.Y
+ $(C++C) $(C++FLAGS) -c y.tab.c
+ -rm -f y.tab.c $*.Y
+ mv y.tab.o $*.o
+.Y~.Y :
+ $(GET) $(GFLAGS) $<
+
+markfile.o: markfile
+ echo "static char _sccsid[] = \"`grep @'(#)' markfile`\";" > markfile.c
+ $(CC) -c markfile.c
+ -rm -f markfile.c
+
+.SCCS_GET:
+ $(GET) $(GFLAGS) s.$@
diff --git a/usr/src/make_src/Make/bin/make/make.svr4/Makefile b/usr/src/make_src/Make/bin/make/make.svr4/Makefile
new file mode 100644
index 0000000..96000a3
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/make.svr4/Makefile
@@ -0,0 +1,38 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2001 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.6 06/12/12
+#
+
+TOP=../../../..
+include $(TOP)/rules/master.mk
+
+all clean clobber l10n_install:
+
+install:
+ $(INSTALL) -d $(DESTDIR)/usr/lib
+ $(INSTALL) -d $(DESTDIR)/usr/ccs/lib
+ rm -f $(DESTDIR)/usr/lib/svr4.make
+ rm -f $(DESTDIR)/usr/ccs/lib/svr4.make
+ ln $(DESTDIR)/usr/ccs/bin/make $(DESTDIR)/usr/lib/svr4.make
+ (cd $(DESTDIR)/usr/ccs/lib; ln -s ../../lib/svr4.make svr4.make)
diff --git a/usr/src/make_src/Make/bin/make/make.xpg4/Makefile b/usr/src/make_src/Make/bin/make/make.xpg4/Makefile
new file mode 100644
index 0000000..6688c9d
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/make.xpg4/Makefile
@@ -0,0 +1,36 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.2 06/12/12
+#
+# @(#)Makefile 1.1 95/06/29 SMI
+
+TOP=../../../..
+include $(TOP)/rules/master.mk
+
+all clean clobber l10n_install:
+
+install:
+ $(INSTALL) -d $(DESTDIR)/usr/xpg4/bin
+ rm -f $(DESTDIR)/usr/xpg4/bin/make
+ ln $(DESTDIR)/usr/ccs/bin/make $(DESTDIR)/usr/xpg4/bin/make
diff --git a/usr/src/make_src/Make/bin/make/smake/Makefile b/usr/src/make_src/Make/bin/make/smake/Makefile
new file mode 100644
index 0000000..0cf0d68
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/smake/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.5 06/12/12
+#
+
+TOP = ../../../..
+include $(TOP)/rules/variant.mk
+include $(TOP)/rules/derived.mk
+
diff --git a/usr/src/make_src/Make/bin/make/smake/src/Makefile b/usr/src/make_src/Make/bin/make/smake/src/Makefile
new file mode 100644
index 0000000..bdefefc
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/smake/src/Makefile
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.3 06/12/12
+#
+
+# Generic makefile for use in src directories. Knows how to make common things
+# in the right $(VARIANT) directory.
+
+#TOP = ../../../../..
+include $(TOP)/rules/variant.mk
+
+all := TARG = all
+install := TARG = install
+clean := TARG = clean
+test := TARG = test
+l10n_install := TARG = l10n_install
+i18n_install := TARG = i18n_install
+
+SRC = ../src
+MFLAGS += SRC=$(SRC)
+
+# See $(TOP)/rules/master.mk for how these are built.
+%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC
+ @ if [ ! -d ../$(VARIANT) ]; then \
+ mkdir ../$(VARIANT) ; \
+ fi
+ cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@
+
+FRC:
diff --git a/usr/src/make_src/Make/bin/make/smake/src/Variant.mk b/usr/src/make_src/Make/bin/make/smake/src/Variant.mk
new file mode 100644
index 0000000..c2e5f64
--- /dev/null
+++ b/usr/src/make_src/Make/bin/make/smake/src/Variant.mk
@@ -0,0 +1,155 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Variant.mk 1.36 06/12/12
+#
+
+TOP = ../../../../..
+include $(TOP)/rules/master.mk
+include $(TOP)/Make/lib/Lib.mk
+
+# RELEASE_VER should be "Generic" for FCS. Otherwise it should be overridden
+# to display build number - "Build XX", patch number - "Patch XXXXXX-XX", etc.
+
+PKG_TOP = ../../../..
+PROG = make
+PACKAGE = SUNWspro
+PRODVER = 11
+PRODVER_V = SunOS 5.11
+RELEASE_VER = Generic
+DATE:sh = date '+%B %Y'
+
+VERSTRING = RELEASE VERSION $(PRODVER_V) $(RELEASE_VER) $(DATE)
+
+MORE_SRC = \
+ ar.cc \
+ depvar.cc \
+ doname.cc \
+ dosys.cc \
+ files.cc \
+ globals.cc \
+ implicit.cc \
+ macro.cc \
+ main.cc \
+ misc.cc \
+ nse_printdep.cc \
+ read.cc \
+ read2.cc \
+ rep.cc \
+ state.cc
+
+CPPFLAGS += -I$(PKG_TOP)/include
+
+LDLIB += \
+ -lnsl \
+ -lsocket \
+ -lw
+
+HDRS_DIR = $(PKG_TOP)/include/mk
+HDRS_LIST = $(HDRS_DIR)/copyright.h $(HDRS_DIR)/defs.h
+
+.INIT: $(HDRS_LIST)
+
+SRCS = $(PROG).cc $(MORE_SRC)
+OBJS = $(SRCS:%.cc=%.o)
+
+LIB += -lintl -lm
+
+all install:: $(PROG)
+
+$(PROG): $(OBJS)
+ $(CCC) $(CCFLAGS) $(LDFLAGS) -o $@ \
+ $(OBJS) $(LIB) $(I18LIB) $(LDLIB)
+ /bin/sh $(TOP)/exe/sanity-check.sh $(TOP) $(PROG)
+
+clean:
+ $(RM) $(OBJS) $(PROG)
+
+
+include $(TOP)/rules/computed-options.mk
+
+#
+# This LIB macro must be declared after the include's above
+#
+LIB = \
+ $(LIBMKSH) \
+ $(LIBMKSDMSI18N) \
+ $(LIBBSD) \
+ $(LIBVROOT)
+
+%.o: ../../common/%.cc
+ $(COMPILE.cc) $(OUTPUT_OPTION) $<
+
+depvar.o nse.o nse_printdep.o := CPPFLAGS += -DSUNOS4_AND_AFTER
+
+LDFLAGS += -xildoff -norunpath
+
+install:: install-make-hdrs install-make-bin
+
+IHDR = make.rules.file
+VIHDR = svr4.make.rules.file
+HDR = ${PKG_TOP}/bin/make/common/make.rules.file
+VHDR = ${PKG_TOP}/bin/make/common/svr4.make.rules.file
+HDRSDIR = $(DESTDIR)/usr/share/lib/make
+HDRFILE = make.rules
+VHDRFILE = svr4.make.rules
+SMAKEDIR = $(DESTDIR)/usr/ccs/bin
+
+install-make-bin: make
+ $(INSTALL) -d $(SMAKEDIR)
+ $(INSTALL) make $(SMAKEDIR)
+ mcs -d $(SMAKEDIR)/make
+ mcs -a '@(#)$(VERSTRING)' $(SMAKEDIR)/make
+
+install-make-hdrs: $(HDR) $(VHDR)
+ $(INSTALL) -d $(HDRSDIR)
+ $(INSTALL) -m 0444 $(HDR) $(HDRSDIR)
+ mv -f $(HDRSDIR)/$(IHDR) $(HDRSDIR)/$(HDRFILE)
+ $(INSTALL) -m 0444 $(VHDR) $(HDRSDIR)
+ mv -f $(HDRSDIR)/$(VIHDR) $(HDRSDIR)/$(VHDRFILE)
+
+
+#
+# i18n stuff
+#
+MAKE_MSG = SUNW_SPRO_MAKE.msg
+#I18N_DIRS = ../../common ../../../../lib/bsd/src ../../../../lib/mksh/src ../../../../lib/vroot/src
+I18N_DIRS = ../../common
+TEXTDOMAIN = SUNW_SPRO_MAKE
+APPPATH = $(PKG_TOP)/bin/make/smake/$(VARIANT)
+LIB_DESTDIR = $(DESTDIR)/usr/lib
+CAT_DESTDIR = $(LIB_DESTDIR)/locale/C/LC_MESSAGES
+
+$(CAT_DESTDIR):
+ $(INSTALL) -d $@
+
+msg_catalogs: $(CAT_DESTDIR) .WAIT MAKE_MSG
+ cp $(APPPATH)/$(TEXTDOMAIN).msg $(CAT_DESTDIR)
+
+MAKE_MSG:
+ $(GENMSG) -l $(SRC)/genmsg.project -o $(TEXTDOMAIN).msg `find $(I18N_DIRS) \( -name '*.cc' -o -name '*.c' -o -name '*.y' -o -name '*.h' \) -print | grep -v /SCCS/`
+ rm -f *.cc.new
+
+i18n_install: msg_catalogs
+
+FRC:
diff --git a/usr/src/make_src/Make/include/bsd/bsd.h b/usr/src/make_src/Make/include/bsd/bsd.h
new file mode 100644
index 0000000..c8b9cb6
--- /dev/null
+++ b/usr/src/make_src/Make/include/bsd/bsd.h
@@ -0,0 +1,58 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)bsd.h 1.6 06/12/12
+ */
+
+#pragma ident "@(#)bsd.h 1.6 06/12/12"
+
+/*
+ * bsd/bsd.h: Interface definitions to BSD compatibility functions for SVR4.
+ */
+
+#ifndef _BSD_BSD_H
+#define _BSD_BSD_H
+
+#include <signal.h>
+
+#if defined (HP_UX) || defined (linux)
+typedef void SIG_FUNC_TYP(int);
+typedef SIG_FUNC_TYP *SIG_TYP;
+#define SIG_PF SIG_TYP
+#endif
+
+#ifndef __cplusplus
+typedef void (*SIG_PF) (int);
+#endif
+
+#ifdef __cplusplus
+extern "C" SIG_PF bsd_signal(int a, SIG_PF b);
+#else
+extern void (*bsd_signal(int, void (*) (int))) (int);
+#endif
+extern void bsd_signals(void);
+
+#endif
+
diff --git a/usr/src/make_src/Make/include/mk/copyright.h b/usr/src/make_src/Make/include/mk/copyright.h
new file mode 100644
index 0000000..1d04701
--- /dev/null
+++ b/usr/src/make_src/Make/include/mk/copyright.h
@@ -0,0 +1,27 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)copyright.h 1.11 06/12/12
+ */
diff --git a/usr/src/make_src/Make/include/mk/defs.h b/usr/src/make_src/Make/include/mk/defs.h
new file mode 100644
index 0000000..53510a2
--- /dev/null
+++ b/usr/src/make_src/Make/include/mk/defs.h
@@ -0,0 +1,495 @@
+#ifndef _MK_DEFS_H
+#define _MK_DEFS_H
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)defs.h 1.61 06/12/12
+ */
+
+#pragma ident "@(#)defs.h 1.61 06/12/12"
+
+/*
+ * Included files
+ */
+#ifdef DISTRIBUTED
+# include <dm/Avo_AcknowledgeMsg.h>
+# include <dm/Avo_DoJobMsg.h>
+# include <dm/Avo_JobResultMsg.h>
+#endif
+
+#include <mksh/defs.h>
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+# include <rw/xdrstrea.h>
+#endif
+
+
+/*
+ * Defined macros
+ */
+
+#define SKIPSPACE(x) while (*x && \
+ ((*x == (int) space_char) || \
+ (*x == (int) tab_char) || \
+ (*x == (int) comma_char))) { \
+ x++; \
+ }
+
+#define SKIPWORD(x) while (*x && \
+ (*x != (int) space_char) && \
+ (*x != (int) tab_char) && \
+ (*x != (int) newline_char) && \
+ (*x != (int) comma_char) && \
+ (*x != (int) equal_char)) { \
+ x++; \
+ }
+
+#define SKIPTOEND(x) while (*x && \
+ (*x != (int) newline_char)) { \
+ x++; \
+ }
+
+#define PMAKE_DEF_MAX_JOBS 2 /* Default number of parallel jobs. */
+
+#define OUT_OF_DATE(a,b) \
+ (((a) < (b)) || (((a) == file_doesnt_exist) && ((b) == file_doesnt_exist)))
+
+#define OUT_OF_DATE_SEC(a,b) \
+ (((a).tv_sec < (b).tv_sec) || (((a).tv_sec == file_doesnt_exist.tv_sec) && ((b).tv_sec == file_doesnt_exist.tv_sec)))
+
+#define SETVAR(name, value, append) \
+ setvar_daemon(name, value, append, no_daemon, \
+ true, debug_level)
+#ifdef SUN5_0
+#define MAX(a,b) (((a)>(b))?(a):(b))
+/*
+ * New feature added to SUN5_0 make, invoke the vanilla svr4 make when
+ * the USE_SVR4_MAKE environment variable is set.
+ */
+#define SVR4_MAKE "/usr/ccs/lib/svr4.make"
+#define USE_SVR4_MAKE "USE_SVR4_MAKE"
+#endif
+/*
+ * The standard MAXHOSTNAMELEN is 64. We want 32.
+ */
+#define MAX_HOSTNAMELEN 32
+
+
+/*
+ * typedefs & structs
+ */
+typedef enum {
+ no_state,
+ scan_name_state,
+ scan_command_state,
+ enter_dependencies_state,
+ enter_conditional_state,
+ enter_equal_state,
+ illegal_bytes_state,
+ illegal_eoln_state,
+ poorly_formed_macro_state,
+ exit_state
+} Reader_state;
+
+struct _Name_vector {
+ struct _Name *names[64];
+ struct _Chain *target_group[64];
+ short used;
+ struct _Name_vector *next;
+};
+
+struct _Running {
+ struct _Running *next;
+ Doname state;
+ struct _Name *target;
+ struct _Name *true_target;
+ struct _Property *command;
+ struct _Name *sprodep_value;
+ char *sprodep_env;
+ int recursion_level;
+ Boolean do_get;
+ Boolean implicit;
+ Boolean redo;
+ int auto_count;
+ struct _Name **automatics;
+ pid_t pid;
+#ifdef TEAMWARE_MAKE_CMN
+ int job_msg_id;
+#else
+ int host;
+#endif
+ char *stdout_file;
+ char *stderr_file;
+ struct _Name *temp_file;
+ int conditional_cnt;
+ struct _Name **conditional_targets;
+#ifdef TEAMWARE_MAKE_CMN
+ Boolean make_refd;
+#endif
+};
+
+typedef enum {
+ serial_mode,
+ parallel_mode,
+ distributed_mode
+} DMake_mode;
+
+typedef enum {
+ txt1_mode,
+ txt2_mode,
+ html1_mode
+} DMake_output_mode;
+
+struct _Recursive_make {
+ struct _Recursive_make *next; /* Linked list */
+ wchar_t *target;/* Name of target */
+ wchar_t *oldline;/* Original line in .nse_depinfo */
+ wchar_t *newline;/* New line in .nse_depinfo */
+ wchar_t *cond_macrostring;
+ /* string built from value of
+ * conditional macros used by
+ * this target
+ */
+ Boolean removed;/* This target is no longer recursive*/
+};
+
+struct _Dyntarget {
+ struct _Dyntarget *next;
+ struct _Name *name;
+};
+
+
+/*
+ * Typedefs for all structs
+ */
+typedef struct _Cmd_line *Cmd_line, Cmd_line_rec;
+typedef struct _Dependency *Dependency, Dependency_rec;
+typedef struct _Macro *Macro, Macro_rec;
+typedef struct _Name_vector *Name_vector, Name_vector_rec;
+typedef struct _Percent *Percent, Percent_rec;
+typedef struct _Dyntarget *Dyntarget;
+typedef struct _Recursive_make *Recursive_make, Recursive_make_rec;
+typedef struct _Running *Running, Running_rec;
+
+
+/*
+ * extern declarations for all global variables.
+ * The actual declarations are in globals.cc
+ */
+extern Boolean allrules_read;
+extern Name posix_name;
+extern Name svr4_name;
+extern Boolean sdot_target;
+extern Boolean all_parallel;
+extern Boolean assign_done;
+extern Boolean build_failed_seen;
+#ifdef DISTRIBUTED
+extern Boolean building_serial;
+#endif
+extern Name built_last_make_run;
+extern Name c_at;
+#ifdef DISTRIBUTED
+extern Boolean called_make;
+#endif
+extern Boolean command_changed;
+extern Boolean commands_done;
+extern Chain conditional_targets;
+extern Name conditionals;
+extern Boolean continue_after_error;
+extern Property current_line;
+extern Name current_make_version;
+extern Name current_target;
+extern short debug_level;
+extern Cmd_line default_rule;
+extern Name default_rule_name;
+extern Name default_target_to_build;
+extern Boolean depinfo_already_read;
+extern Name dmake_group;
+extern Name dmake_max_jobs;
+extern Name dmake_mode;
+extern DMake_mode dmake_mode_type;
+extern Name dmake_output_mode;
+extern DMake_output_mode output_mode;
+extern Name dmake_odir;
+extern Name dmake_rcfile;
+extern Name done;
+extern Name dot;
+extern Name dot_keep_state;
+extern Name dot_keep_state_file;
+extern Name empty_name;
+extern Boolean fatal_in_progress;
+extern int file_number;
+extern Name force;
+extern Name ignore_name;
+extern Boolean ignore_errors;
+extern Boolean ignore_errors_all;
+extern Name init;
+extern int job_msg_id;
+extern Boolean keep_state;
+extern Name make_state;
+#ifdef TEAMWARE_MAKE_CMN
+extern timestruc_t make_state_before;
+#endif
+extern Boolean make_state_locked;
+extern Dependency makefiles_used;
+extern Name makeflags;
+extern Name make_version;
+extern char mbs_buffer2[];
+extern char *mbs_ptr;
+extern char *mbs_ptr2;
+extern Boolean no_action_was_taken;
+extern int mtool_msgs_fd;
+extern Boolean no_parallel;
+#ifdef SGE_SUPPORT
+extern Boolean grid;
+#endif
+extern Name no_parallel_name;
+extern Name not_auto;
+extern Boolean only_parallel;
+extern Boolean parallel;
+extern Name parallel_name;
+extern Name localhost_name;
+extern int parallel_process_cnt;
+extern Percent percent_list;
+extern Dyntarget dyntarget_list;
+extern Name plus;
+extern Name pmake_machinesfile;
+extern Name precious;
+extern Name primary_makefile;
+extern Boolean quest;
+extern short read_trace_level;
+extern Boolean reading_dependencies;
+extern int recursion_level;
+extern Name recursive_name;
+extern short report_dependencies_level;
+extern Boolean report_pwd;
+extern Boolean rewrite_statefile;
+extern Running running_list;
+extern char *sccs_dir_path;
+extern Name sccs_get_name;
+extern Name sccs_get_posix_name;
+extern Cmd_line sccs_get_rule;
+extern Cmd_line sccs_get_org_rule;
+extern Cmd_line sccs_get_posix_rule;
+extern Name get_name;
+extern Name get_posix_name;
+extern Cmd_line get_rule;
+extern Cmd_line get_posix_rule;
+extern Boolean send_mtool_msgs;
+extern Boolean all_precious;
+extern Boolean report_cwd;
+extern Boolean silent_all;
+extern Boolean silent;
+extern Name silent_name;
+extern char *stderr_file;
+extern char *stdout_file;
+#ifdef SGE_SUPPORT
+extern char script_file[];
+#endif
+extern Boolean stdout_stderr_same;
+extern Dependency suffixes;
+extern Name suffixes_name;
+extern Name sunpro_dependencies;
+extern Boolean target_variants;
+extern char *tmpdir;
+extern char *temp_file_directory;
+extern Name temp_file_name;
+extern short temp_file_number;
+extern wchar_t *top_level_target;
+extern Boolean touch;
+extern Boolean trace_reader;
+extern Boolean build_unconditional;
+extern pathpt vroot_path;
+extern Name wait_name;
+extern wchar_t wcs_buffer2[];
+extern wchar_t *wcs_ptr;
+extern wchar_t *wcs_ptr2;
+extern nl_catd catd;
+extern long int hostid;
+
+/*
+ * Declarations of system defined variables
+ */
+#if !defined(linux)
+/* On linux this variable is defined in 'signal.h' */
+extern char *sys_siglist[];
+#endif
+
+/*
+ * Declarations of system supplied functions
+ */
+extern int file_lock(char *, char *, int *, int);
+
+/*
+ * Declarations of functions declared and used by make
+ */
+extern void add_pending(Name target, int recursion_level, Boolean do_get, Boolean implicit, Boolean redo);
+extern void add_running(Name target, Name true_target, Property command, int recursion_level, int auto_count, Name *automatics, Boolean do_get, Boolean implicit);
+extern void add_serial(Name target, int recursion_level, Boolean do_get, Boolean implicit);
+extern void add_subtree(Name target, int recursion_level, Boolean do_get, Boolean implicit);
+extern void append_or_replace_macro_in_dyn_array(ASCII_Dyn_Array *Ar, char *macro);
+#ifdef DISTRIBUTED
+extern Doname await_dist(Boolean waitflg);
+#endif
+#ifdef TEAMWARE_MAKE_CMN
+extern void await_parallel(Boolean waitflg);
+#endif
+extern void build_suffix_list(Name target_suffix);
+extern Boolean check_auto_dependencies(Name target, int auto_count, Name *automatics);
+extern void check_state(Name temp_file_name);
+extern void cond_macros_into_string(Name np, String_rec *buffer);
+extern void construct_target_string();
+extern void create_xdrs_ptr(void);
+extern void depvar_add_to_list (Name name, Boolean cmdline);
+#ifdef DISTRIBUTED
+extern void distribute_rxm(Avo_DoJobMsg *dmake_job_msg);
+extern int getRxmMessage(void);
+extern Avo_JobResultMsg* getJobResultMsg(void);
+extern Avo_AcknowledgeMsg* getAcknowledgeMsg(void);
+#endif
+extern Doname doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic = false);
+extern Doname doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);
+extern Doname doname_parallel(Name target, Boolean do_get, Boolean implicit);
+extern Doname dosys(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target, Boolean redirect_out_err);
+extern void dump_make_state(void);
+extern void dump_target_list(void);
+extern void enter_conditional(register Name target, Name name, Name value, register Boolean append);
+extern void enter_dependencies(register Name target, Chain target_group, register Name_vector depes, register Cmd_line command, register Separator separator);
+extern void enter_dependency(Property line, register Name depe, Boolean automatic);
+extern void enter_equal(Name name, Name value, register Boolean append);
+extern Percent enter_percent(register Name target, Chain target_group, register Name_vector depes, Cmd_line command);
+extern Dyntarget enter_dyntarget(register Name target);
+extern Name_vector enter_name(String string, Boolean tail_present, register wchar_t *string_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names, Boolean *target_group_seen);
+extern Boolean exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error);
+extern Doname execute_parallel(Property line, Boolean waitflg, Boolean local = false);
+extern Doname execute_serial(Property line);
+extern timestruc_t& exists(register Name target);
+extern void fatal(char *, ...);
+extern void fatal_reader(char *, ...);
+extern Doname find_ar_suffix_rule(register Name target, Name true_target, Property *command, Boolean rechecking);
+extern Doname find_double_suffix_rule(register Name target, Property *command, Boolean rechecking);
+extern Doname find_percent_rule(register Name target, Property *command, Boolean rechecking);
+extern int find_run_directory (char *cmd, char *cwd, char *dir, char **pgm, char **run, char *path);
+extern Doname find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *command, Boolean rechecking);
+extern Chain find_target_groups(register Name_vector target_list, register int i, Boolean reset);
+extern void finish_children(Boolean docheck);
+extern void finish_running(void);
+extern void free_chain(Name_vector ptr);
+extern void gather_recursive_deps(void);
+extern char *get_current_path(void);
+extern int get_job_msg_id(void);
+extern FILE *get_mtool_msgs_fp(void);
+#ifdef DISTRIBUTED
+extern Boolean get_dmake_group_specified(void);
+extern Boolean get_dmake_max_jobs_specified(void);
+extern Boolean get_dmake_mode_specified(void);
+extern Boolean get_dmake_odir_specified(void);
+extern Boolean get_dmake_rcfile_specified(void);
+extern Boolean get_pmake_machinesfile_specified(void);
+#endif
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+extern XDR *get_xdrs_ptr(void);
+#endif
+extern wchar_t *getmem_wc(register int size);
+#if !defined(linux)
+/* On linux getwd(char *) is defined in 'unistd.h' */
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern char *getwd(char *);
+#ifdef __cplusplus
+}
+#endif
+#endif
+extern void handle_interrupt(int);
+extern Boolean is_running(Name target);
+extern void load_cached_names(void);
+extern Boolean parallel_ok(Name target, Boolean line_prop_must_exists);
+extern void print_dependencies(register Name target, register Property line);
+extern void send_job_start_msg(Property line);
+extern void send_rsrc_info_msg(int max_jobs, char *hostname, char *username);
+extern void print_value(register Name value, Daemon daemon);
+extern timestruc_t& read_archive(register Name target);
+extern int read_dir(Name dir, wchar_t *pattern, Property line, wchar_t *library);
+extern void read_directory_of_file(register Name file);
+extern int read_make_machines(Name make_machines_name);
+extern Boolean read_simple_file(register Name makefile_name, register Boolean chase_path, register Boolean doname_it, Boolean complain, Boolean must_exist, Boolean report_file, Boolean lock_makefile);
+extern void remove_recursive_dep(Name target);
+extern void report_recursive_dep(Name target, char *line);
+extern void report_recursive_done(void);
+extern void report_recursive_init(void);
+extern Recursive_make find_recursive_target(Name target);
+extern void reset_locals(register Name target, register Property old_locals, register Property conditional, register int index);
+extern void set_locals(register Name target, register Property old_locals);
+extern void setvar_append(register Name name, register Name value);
+#ifdef DISTRIBUTED
+extern void setvar_envvar(Avo_DoJobMsg *dmake_job_msg);
+#else
+extern void setvar_envvar(void);
+#endif
+extern void special_reader(Name target, register Name_vector depes, Cmd_line command);
+extern void startup_rxm();
+extern Doname target_can_be_built(register Name target);
+extern char *time_to_string(const timestruc_t &time);
+extern void update_target(Property line, Doname result);
+extern void warning(char *, ...);
+extern void write_state_file(int report_recursive, Boolean exiting);
+extern Name vpath_translation(register Name cmd);
+
+#define DEPINFO_FMT_VERSION "VERS2$"
+#define VER_LEN strlen(DEPINFO_FMT_VERSION)
+
+#ifdef NSE
+
+/*
+ * NSE version for depinfo format
+ */
+extern Boolean nse;
+extern Name nse_backquote_seen;
+extern Boolean nse_did_recursion;
+extern Name nse_shell_var_used;
+extern Boolean nse_watch_vars;
+extern wchar_t current_makefile[MAXPATHLEN];
+extern Boolean nse_depinfo_locked;
+extern char nse_depinfo_lockfile[MAXPATHLEN];
+extern Name derived_src;
+
+extern void depvar_dep_macro_used(Name);
+extern void depvar_rule_macro_used(Name);
+extern Boolean nse_backquotes(wchar_t *);
+extern void nse_check_cd(Property);
+extern void nse_check_derived_src(Name, wchar_t *, Cmd_line);
+extern void nse_check_file_backquotes(wchar_t *);
+extern void nse_check_no_deps_no_rule(Name, Property, Property);
+extern void nse_check_sccs(wchar_t *, wchar_t *);
+extern void nse_dep_cmdmacro(wchar_t *);
+extern int nse_exit_status(void);
+extern void nse_init_source_suffixes(void);
+extern void nse_no_makefile(Name);
+extern void nse_rule_cmdmacro(wchar_t *);
+extern void nse_wildcard(wchar_t *, wchar_t *);
+#endif
+
+#endif
diff --git a/usr/src/make_src/Make/include/mksdmsi18n/mksdmsi18n.h b/usr/src/make_src/Make/include/mksdmsi18n/mksdmsi18n.h
new file mode 100644
index 0000000..d8b55eb
--- /dev/null
+++ b/usr/src/make_src/Make/include/mksdmsi18n/mksdmsi18n.h
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)mksdmsi18n.h 1.3 06/12/12
+ */
+
+#pragma ident "@(#)mksdmsi18n.h 1.3 06/12/12"
+
+#ifndef _AVO_MKSDMSI18N_H
+#define _AVO_MKSDMSI18N_H
+
+#ifndef _AVO_INTL_H
+#include <avo/intl.h>
+#endif
+
+extern nl_catd libmksdmsi18n_catd;
+
+int libmksdmsi18n_init();
+void libmksdmsi18n_fini();
+
+#endif
+
diff --git a/usr/src/make_src/Make/include/mksh/defs.h b/usr/src/make_src/Make/include/mksh/defs.h
new file mode 100644
index 0000000..e8ae60e
--- /dev/null
+++ b/usr/src/make_src/Make/include/mksh/defs.h
@@ -0,0 +1,1042 @@
+#ifndef _MKSH_DEFS_H
+#define _MKSH_DEFS_H
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)defs.h 1.35 06/12/12
+ */
+
+#pragma ident "@(#)defs.h 1.35 06/12/12"
+
+/*
+ * This is not "#ifdef TEAMWARE_MAKE_CMN" because we're currently
+ * using the TW fake i18n headers and libraries to build both
+ * SMake and PMake on SPARC/S1 and x86/S2.
+ */
+
+#include <avo/intl.h>
+#include <limits.h> /* MB_LEN_MAX */
+#include <stdio.h>
+#include <stdlib.h> /* wchar_t */
+#include <string.h> /* strcmp() */
+#include <nl_types.h> /* catgets() */
+#include <sys/param.h> /* MAXPATHLEN */
+#include <sys/types.h> /* time_t, caddr_t */
+#include <vroot/vroot.h> /* pathpt */
+#include <sys/time.h> /* timestruc_t */
+#include <errno.h> /* errno */
+
+#if defined (HP_UX) || defined (linux)
+#define MAXNAMELEN 256
+#define RW_NO_OVERLOAD_WCHAR 1 /* Rogue Wave, belongs in <rw/compiler.h> */
+#else
+#include <wctype.h>
+#include <widec.h>
+#endif
+
+#if defined (linux)
+/*
+ * Definition of wchar functions.
+ */
+# include <wctype.h>
+# include <wchar.h>
+# define wsdup(x) wcsdup(x)
+# define wschr(x,y) wcschr(x,y)
+# define wscat(x,y) wcscat(x,y)
+# define wsrchr(x,y) wcsrchr(x,y)
+# define wslen(x) wcslen(x)
+# define wscpy(x,y) wcscpy(x,y)
+# define wsncpy(x,y,z) wcsncpy(x,y,z)
+# define wscmp(x,y) wcscmp(x,y)
+# define wsncmp(x,y,z) wcsncmp(x,y,z)
+#endif
+
+/*
+ * A type and some utilities for boolean values
+ */
+
+#define false BOOLEAN_false
+#define true BOOLEAN_true
+
+typedef enum {
+ false = 0,
+ true = 1,
+ failed = 0,
+ succeeded = 1
+} Boolean;
+#define BOOLEAN(expr) ((expr) ? true : false)
+
+/*
+ * Some random constants (in an enum so dbx knows their values)
+ */
+enum {
+ update_delay = 30, /* time between rstat checks */
+#ifdef sun386
+ ar_member_name_len = 14,
+#else
+#if defined(SUN5_0) || defined(linux)
+ ar_member_name_len = 1024,
+#else
+ ar_member_name_len = 15,
+#endif
+#endif
+
+ hashsize = 2048 /* size of hash table */
+};
+
+
+/*
+ * Symbols that defines all the different char constants make uses
+ */
+enum {
+ ampersand_char = '&',
+ asterisk_char = '*',
+ at_char = '@',
+ backquote_char = '`',
+ backslash_char = '\\',
+ bar_char = '|',
+ braceleft_char = '{',
+ braceright_char = '}',
+ bracketleft_char = '[',
+ bracketright_char = ']',
+ colon_char = ':',
+ comma_char = ',',
+ dollar_char = '$',
+ doublequote_char = '"',
+ equal_char = '=',
+ exclam_char = '!',
+ greater_char = '>',
+ hat_char = '^',
+ hyphen_char = '-',
+ less_char = '<',
+ newline_char = '\n',
+ nul_char = '\0',
+ numbersign_char = '#',
+ parenleft_char = '(',
+ parenright_char = ')',
+ percent_char = '%',
+ period_char = '.',
+ plus_char = '+',
+ question_char = '?',
+ quote_char = '\'',
+ semicolon_char = ';',
+ slash_char = '/',
+ space_char = ' ',
+ tab_char = '\t',
+ tilde_char = '~'
+};
+
+/*
+ * For make i18n. Codeset independent.
+ * Setup character semantics by identifying all the special characters
+ * of make, and assigning each an entry in the char_semantics[] vector.
+ */
+enum {
+ ampersand_char_entry = 0, /* 0 */
+ asterisk_char_entry, /* 1 */
+ at_char_entry, /* 2 */
+ backquote_char_entry, /* 3 */
+ backslash_char_entry, /* 4 */
+ bar_char_entry, /* 5 */
+ bracketleft_char_entry, /* 6 */
+ bracketright_char_entry, /* 7 */
+ colon_char_entry, /* 8 */
+ dollar_char_entry, /* 9 */
+ doublequote_char_entry, /* 10 */
+ equal_char_entry, /* 11 */
+ exclam_char_entry, /* 12 */
+ greater_char_entry, /* 13 */
+ hat_char_entry, /* 14 */
+ hyphen_char_entry, /* 15 */
+ less_char_entry, /* 16 */
+ newline_char_entry, /* 17 */
+ numbersign_char_entry, /* 18 */
+ parenleft_char_entry, /* 19 */
+ parenright_char_entry, /* 20 */
+ percent_char_entry, /* 21 */
+ plus_char_entry, /* 22 */
+ question_char_entry, /* 23 */
+ quote_char_entry, /* 24 */
+ semicolon_char_entry, /* 25 */
+#ifdef SGE_SUPPORT
+ space_char_entry, /* 26 */
+ tab_char_entry, /* 27 */
+ no_semantics_entry /* 28 */
+#else
+ no_semantics_entry /* 26 */
+#endif /* SGE_SUPPORT */
+};
+
+/*
+ * CHAR_SEMANTICS_ENTRIES should be the number of entries above.
+ * The last entry in char_semantics[] should be blank.
+ */
+#ifdef SGE_SUPPORT
+#define CHAR_SEMANTICS_ENTRIES 29
+/*
+#define CHAR_SEMANTICS_STRING "&*@`\\|[]:$=!>-\n#()%+?;^<'\" \t"
+ */
+#else
+#define CHAR_SEMANTICS_ENTRIES 27
+/*
+#define CHAR_SEMANTICS_STRING "&*@`\\|[]:$=!>-\n#()%+?;^<'\""
+ */
+#endif /* SGE_SUPPORT */
+
+/*
+ * Some utility macros
+ */
+#define ALLOC(x) ((struct _##x *)getmem(sizeof (struct _##x)))
+#define ALLOC_WC(x) ((wchar_t *)getmem((x) * SIZEOFWCHAR_T))
+#define FIND_LENGTH -1
+#define GETNAME(a,b) getname_fn((a), (b), false)
+#define IS_EQUAL(a,b) (!strcmp((a), (b)))
+#define IS_EQUALN(a,b,n) (!strncmp((a), (b), (n)))
+#define IS_WEQUAL(a,b) (!wscmp((a), (b)))
+#define IS_WEQUALN(a,b,n) (!wsncmp((a), (b), (n)))
+#define MBLEN(a) mblen((a), MB_LEN_MAX)
+#define MBSTOWCS(a,b) (void) mbstowcs_with_check((a), (b), MAXPATHLEN)
+#define MBTOWC(a,b) mbtowc((a), (b), MB_LEN_MAX)
+#define SIZEOFWCHAR_T (sizeof (wchar_t))
+#define VSIZEOF(v) (sizeof (v) / sizeof ((v)[0]))
+#define WCSTOMBS(a,b) (void) wcstombs((a), (b), (MAXPATHLEN * MB_LEN_MAX))
+#define WCTOMB(a,b) (void) wctomb((a), (b))
+#define HASH(v, c) (v = (v)*31 + (unsigned int)(c))
+
+extern void mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n);
+
+/*
+ * Bits stored in funny vector to classify chars
+ */
+enum {
+ dollar_sem = 0001,
+ meta_sem = 0002,
+ percent_sem = 0004,
+ wildcard_sem = 0010,
+ command_prefix_sem = 0020,
+ special_macro_sem = 0040,
+ colon_sem = 0100,
+ parenleft_sem = 0200
+};
+
+/*
+ * Type returned from doname class functions
+ */
+typedef enum {
+ build_dont_know = 0,
+ build_failed,
+ build_ok,
+ build_in_progress,
+ build_running, /* PARALLEL & DISTRIBUTED */
+ build_pending, /* PARALLEL & DISTRIBUTED */
+ build_serial, /* PARALLEL & DISTRIBUTED */
+ build_subtree /* PARALLEL & DISTRIBUTED */
+} Doname;
+
+/*
+ * The String struct defines a string with the following layout
+ * "xxxxxxxxxxxxxxxCxxxxxxxxxxxxxxx________"
+ * ^ ^ ^ ^
+ * | | | |
+ * buffer.start text.p text.end buffer.end
+ * text.p points to the next char to read/write.
+ */
+struct _String {
+ struct Text {
+ wchar_t *p; /* Read/Write pointer */
+ wchar_t *end; /* Read limit pointer */
+ } text;
+ struct Physical_buffer {
+ wchar_t *start; /* Points to start of buffer */
+ wchar_t *end; /* End of physical buffer */
+ } buffer;
+ Boolean free_after_use:1;
+};
+
+#define STRING_BUFFER_LENGTH 1024
+#define INIT_STRING_FROM_STACK(str, buf) { \
+ str.buffer.start = (buf); \
+ str.text.p = (buf); \
+ str.text.end = NULL; \
+ str.buffer.end = (buf) \
+ + (sizeof (buf)/SIZEOFWCHAR_T); \
+ str.free_after_use = false; \
+ }
+
+#define APPEND_NAME(np, dest, len) append_string((np)->string_mb, (dest), (len));
+
+class Wstring {
+ public:
+ struct _String string;
+ wchar_t string_buf[STRING_BUFFER_LENGTH];
+
+ public:
+ Wstring();
+ Wstring(struct _Name * name);
+ ~Wstring();
+
+ void init(struct _Name * name);
+ void init(wchar_t * name, unsigned length);
+ unsigned length() {
+ return wslen(string.buffer.start);
+ };
+ void append_to_str(struct _String * str, unsigned off, unsigned length);
+
+ wchar_t * get_string() {
+ return string.buffer.start;
+ };
+
+ wchar_t * get_string(unsigned off) {
+ return string.buffer.start + off;
+ };
+
+ Boolean equaln(wchar_t * str, unsigned length);
+ Boolean equal(wchar_t * str);
+ Boolean equal(wchar_t * str, unsigned off);
+ Boolean equal(wchar_t * str, unsigned off, unsigned length);
+
+ Boolean equaln(Wstring * str, unsigned length);
+ Boolean equal(Wstring * str);
+ Boolean equal(Wstring * str, unsigned off);
+ Boolean equal(Wstring * str, unsigned off, unsigned length);
+};
+
+
+/*
+ * Used for storing the $? list and also for the "target + target:"
+ * construct.
+ */
+struct _Chain {
+ struct _Chain *next;
+ struct _Name *name;
+ struct _Percent *percent_member;
+};
+
+/*
+ * Stores one command line for a rule
+ */
+struct _Cmd_line {
+ struct _Cmd_line *next;
+ struct _Name *command_line;
+ Boolean make_refd:1; /* $(MAKE) referenced? */
+ /*
+ * Remember any command line prefixes given
+ */
+ Boolean ignore_command_dependency:1; /* `?' */
+ Boolean assign:1; /* `=' */
+ Boolean ignore_error:1; /* `-' */
+ Boolean silent:1; /* `@' */
+ Boolean always_exec:1; /* `+' */
+};
+
+/*
+ * Linked list of targets/files
+ */
+struct _Dependency {
+ struct _Dependency *next;
+ struct _Name *name;
+ Boolean automatic:1;
+ Boolean stale:1;
+ Boolean built:1;
+};
+
+/*
+ * The specials are markers for targets that the reader should special case
+ */
+typedef enum {
+ no_special,
+ built_last_make_run_special,
+ default_special,
+#ifdef NSE
+ derived_src_special,
+#endif
+ get_posix_special,
+ get_special,
+ ignore_special,
+ keep_state_file_special,
+ keep_state_special,
+ make_version_special,
+ no_parallel_special,
+ parallel_special,
+ posix_special,
+ precious_special,
+ sccs_get_posix_special,
+ sccs_get_special,
+ silent_special,
+ suffixes_special,
+ svr4_special,
+ localhost_special
+} Special;
+
+typedef enum {
+ no_colon,
+ one_colon,
+ two_colon,
+ equal_seen,
+ conditional_seen,
+ none_seen
+} Separator;
+
+/*
+ * Magic values for the timestamp stored with each name object
+ */
+
+#if defined (linux)
+typedef struct timespec timestruc_t;
+#endif
+
+extern const timestruc_t file_no_time;
+extern const timestruc_t file_doesnt_exist;
+extern const timestruc_t file_is_dir;
+extern const timestruc_t file_min_time;
+extern const timestruc_t file_max_time;
+
+/*
+ * Each Name has a list of properties
+ * The properties are used to store information that only
+ * a subset of the Names need
+ */
+typedef enum {
+ no_prop,
+ conditional_prop,
+ line_prop,
+ macro_prop,
+ makefile_prop,
+ member_prop,
+ recursive_prop,
+ sccs_prop,
+ suffix_prop,
+ target_prop,
+ time_prop,
+ vpath_alias_prop,
+ long_member_name_prop,
+ macro_append_prop,
+ env_mem_prop
+} Property_id;
+
+typedef enum {
+ no_daemon = 0,
+ chain_daemon
+} Daemon;
+
+struct _Env_mem {
+ char *value;
+};
+
+struct _Macro_appendix {
+ struct _Name *value;
+ struct _Name *value_to_append;
+};
+
+struct _Macro {
+ /*
+ * For "ABC = xyz" constructs
+ * Name "ABC" get one macro prop
+ */
+ struct _Name *value;
+#ifdef NSE
+ Boolean imported:1;
+#endif
+ Boolean exported:1;
+ Boolean read_only:1;
+ /*
+ * This macro is defined conditionally
+ */
+ Boolean is_conditional:1;
+ /*
+ * The list for $? is stored as a structured list that
+ * is translated into a string iff it is referenced.
+ * This is why some macro values need a daemon.
+ */
+#if defined(HP_UX) || defined(linux)
+ Daemon daemon;
+#else
+ Daemon daemon:2;
+#endif
+};
+
+struct _Macro_list {
+ struct _Macro_list *next;
+ char *macro_name;
+ char *value;
+};
+
+enum sccs_stat {
+ DONT_KNOW_SCCS = 0,
+ NO_SCCS,
+ HAS_SCCS
+};
+
+struct _Name {
+ struct _Property *prop; /* List of properties */
+ char *string_mb; /* Multi-byte name string */
+ struct {
+ unsigned int length;
+ } hash;
+ struct {
+ timestruc_t time; /* Modification */
+ int stat_errno; /* error from "stat" */
+ off_t size; /* Of file */
+ mode_t mode; /* Of file */
+#if defined(HP_UX) || defined(linux)
+ Boolean is_file;
+ Boolean is_dir;
+ Boolean is_sym_link;
+ Boolean is_precious;
+ enum sccs_stat has_sccs;
+#else
+ Boolean is_file:1;
+ Boolean is_dir:1;
+ Boolean is_sym_link:1;
+ Boolean is_precious:1;
+#ifdef NSE
+ Boolean is_derived_src:1;
+#endif
+ enum sccs_stat has_sccs:2;
+#endif
+ } stat;
+ /*
+ * Count instances of :: definitions for this target
+ */
+ short colon_splits;
+ /*
+ * We only clear the automatic depes once per target per report
+ */
+ short temp_file_number;
+ /*
+ * Count how many conditional macros this target has defined
+ */
+ short conditional_cnt;
+ /*
+ * A conditional macro was used when building this target
+ */
+ Boolean depends_on_conditional:1;
+ /*
+ * Pointer to list of conditional macros which were used to build
+ * this target
+ */
+ struct _Macro_list *conditional_macro_list;
+ Boolean has_member_depe:1;
+ Boolean is_member:1;
+ /*
+ * This target is a directory that has been read
+ */
+ Boolean has_read_dir:1;
+ /*
+ * This name is a macro that is now being expanded
+ */
+ Boolean being_expanded:1;
+ /*
+ * This name is a magic name that the reader must know about
+ */
+#if defined(HP_UX) || defined(linux)
+ Special special_reader;
+ Doname state;
+ Separator colons;
+#else
+ Special special_reader:5;
+ Doname state:3;
+ Separator colons:3;
+#endif
+ Boolean has_depe_list_expanded:1;
+ Boolean suffix_scan_done:1;
+ Boolean has_complained:1; /* For sccs */
+ /*
+ * This target has been built during this make run
+ */
+ Boolean ran_command:1;
+ Boolean with_squiggle:1; /* for .SUFFIXES */
+ Boolean without_squiggle:1; /* for .SUFFIXES */
+ Boolean has_read_suffixes:1; /* Suffix list cached*/
+ Boolean has_suffixes:1;
+ Boolean has_target_prop:1;
+ Boolean has_vpath_alias_prop:1;
+ Boolean dependency_printed:1; /* For dump_make_state() */
+ Boolean dollar:1; /* In namestring */
+ Boolean meta:1; /* In namestring */
+ Boolean percent:1; /* In namestring */
+ Boolean wildcard:1; /* In namestring */
+ Boolean has_parent:1;
+ Boolean is_target:1;
+ Boolean has_built:1;
+ Boolean colon:1; /* In namestring */
+ Boolean parenleft:1; /* In namestring */
+ Boolean has_recursive_dependency:1;
+ Boolean has_regular_dependency:1;
+ Boolean is_double_colon:1;
+ Boolean is_double_colon_parent:1;
+ Boolean has_long_member_name:1;
+ /*
+ * allowed to run in parallel
+ */
+ Boolean parallel:1;
+ /*
+ * not allowed to run in parallel
+ */
+ Boolean no_parallel:1;
+ /*
+ * used in dependency_conflict
+ */
+ Boolean checking_subtree:1;
+ Boolean added_pattern_conditionals:1;
+ /*
+ * rechecking target for possible rebuild
+ */
+ Boolean rechecking_target:1;
+ /*
+ * build this target in silent mode
+ */
+ Boolean silent_mode:1;
+ /*
+ * build this target in ignore error mode
+ */
+ Boolean ignore_error_mode:1;
+ Boolean dont_activate_cond_values:1;
+ /*
+ * allowed to run serially on local host
+ */
+ Boolean localhost:1;
+};
+
+/*
+ * Stores the % matched default rules
+ */
+struct _Percent {
+ struct _Percent *next;
+ struct _Name **patterns;
+ struct _Name *name;
+ struct _Percent *dependencies;
+ struct _Cmd_line *command_template;
+ struct _Chain *target_group;
+ int patterns_total;
+ Boolean being_expanded;
+};
+
+struct Conditional {
+ /*
+ * For "foo := ABC [+]= xyz" constructs
+ * Name "foo" gets one conditional prop
+ */
+ struct _Name *target;
+ struct _Name *name;
+ struct _Name *value;
+ int sequence;
+ Boolean append:1;
+};
+
+struct Line {
+ /*
+ * For "target : dependencies" constructs
+ * Name "target" gets one line prop
+ */
+ struct _Cmd_line *command_template;
+ struct _Cmd_line *command_used;
+ struct _Dependency *dependencies;
+ timestruc_t dependency_time;
+ struct _Chain *target_group;
+ Boolean is_out_of_date:1;
+ Boolean sccs_command:1;
+ Boolean command_template_redefined:1;
+ Boolean dont_rebuild_command_used:1;
+ /*
+ * Values for the dynamic macros
+ */
+ struct _Name *target;
+ struct _Name *star;
+ struct _Name *less;
+ struct _Name *percent;
+ struct _Chain *query;
+};
+
+struct Makefile {
+ /*
+ * Names that reference makefiles gets one prop
+ */
+ wchar_t *contents;
+ off_t size;
+};
+
+struct Member {
+ /*
+ * For "lib(member)" and "lib((entry))" constructs
+ * Name "lib(member)" gets one member prop
+ * Name "lib((entry))" gets one member prop
+ * The member field is filled in when the prop is refd
+ */
+ struct _Name *library;
+ struct _Name *entry;
+ struct _Name *member;
+};
+
+struct Recursive {
+ /*
+ * For "target: .RECURSIVE dir makefiles" constructs
+ * Used to keep track of recursive calls to make
+ * Name "target" gets one recursive prop
+ */
+ struct _Name *directory;
+ struct _Name *target;
+ struct _Dependency *makefiles;
+ Boolean has_built;
+ Boolean in_depinfo;
+};
+
+struct Sccs {
+ /*
+ * Each file that has a SCCS s. file gets one prop
+ */
+ struct _Name *file;
+};
+
+struct Suffix {
+ /*
+ * Cached list of suffixes that can build this target
+ * suffix is built from .SUFFIXES
+ */
+ struct _Name *suffix;
+ struct _Cmd_line *command_template;
+};
+
+struct Target {
+ /*
+ * For "target:: dependencies" constructs
+ * The "::" construct is handled by converting it to
+ * "foo: 1@foo" + "1@foo: dependecies"
+ * "1@foo" gets one target prop
+ * This target prop cause $@ to be bound to "foo"
+ * not "1@foo" when the rule is evaluated
+ */
+ struct _Name *target;
+};
+
+struct STime {
+ /*
+ * Save the original time for :: targets
+ */
+ timestruc_t time;
+};
+
+struct Vpath_alias {
+ /*
+ * If a file was found using the VPATH it gets
+ * a vpath_alias prop
+ */
+ struct _Name *alias;
+};
+
+struct Long_member_name {
+ /*
+ * Targets with a truncated member name carries
+ * the full lib(member) name for the state file
+ */
+ struct _Name *member_name;
+};
+
+union Body {
+ struct _Macro macro;
+ struct Conditional conditional;
+ struct Line line;
+ struct Makefile makefile;
+ struct Member member;
+ struct Recursive recursive;
+ struct Sccs sccs;
+ struct Suffix suffix;
+ struct Target target;
+ struct STime time;
+ struct Vpath_alias vpath_alias;
+ struct Long_member_name long_member_name;
+ struct _Macro_appendix macro_appendix;
+ struct _Env_mem env_mem;
+};
+
+#define PROPERTY_HEAD_SIZE (sizeof (struct _Property)-sizeof (union Body))
+struct _Property {
+ struct _Property *next;
+#if defined(HP_UX) || defined(linux)
+ Property_id type;
+#else
+ Property_id type:4;
+#endif
+ union Body body;
+};
+
+/* Structure for dynamic "ascii" arrays */
+struct ASCII_Dyn_Array {
+ char *start;
+ size_t size;
+};
+
+struct _Envvar {
+ struct _Name *name;
+ struct _Name *value;
+ struct _Envvar *next;
+ char *env_string;
+ Boolean already_put:1;
+};
+
+/*
+ * Macros for the reader
+ */
+#define GOTO_STATE(new_state) { \
+ SET_STATE(new_state); \
+ goto enter_state; \
+ }
+#define SET_STATE(new_state) state = (new_state)
+
+#define UNCACHE_SOURCE() if (source != NULL) { \
+ source->string.text.p = source_p; \
+ }
+#define CACHE_SOURCE(comp) if (source != NULL) { \
+ source_p = source->string.text.p - \
+ (comp); \
+ source_end = source->string.text.end; \
+ }
+#define GET_NEXT_BLOCK_NOCHK(source) { UNCACHE_SOURCE(); \
+ source = get_next_block_fn(source); \
+ CACHE_SOURCE(0) \
+ }
+#define GET_NEXT_BLOCK(source) { GET_NEXT_BLOCK_NOCHK(source); \
+ if (source != NULL && source->error_converting) { \
+ GOTO_STATE(illegal_bytes_state); \
+ } \
+ }
+#define GET_CHAR() ((source == NULL) || \
+ (source_p >= source_end) ? 0 : *source_p)
+
+struct _Source {
+ struct _String string;
+ struct _Source *previous;
+ off_t bytes_left_in_file;
+ short fd;
+ Boolean already_expanded:1;
+ Boolean error_converting:1;
+ char *inp_buf;
+ char *inp_buf_end;
+ char *inp_buf_ptr;
+};
+
+typedef enum {
+ reading_nothing,
+ reading_makefile,
+ reading_statefile,
+ rereading_statefile,
+ reading_cpp_file
+} Makefile_type;
+
+/*
+ * Typedefs for all structs
+ */
+typedef struct _Chain *Chain, Chain_rec;
+typedef struct _Envvar *Envvar, Envvar_rec;
+typedef struct _Macro_list *Macro_list, Macro_list_rec;
+typedef struct _Name *Name, Name_rec;
+typedef struct _Property *Property, Property_rec;
+typedef struct _Source *Source, Source_rec;
+typedef struct _String *String, String_rec;
+
+/*
+ * name records hash table.
+ */
+struct Name_set {
+private:
+ // single node in a tree
+ struct entry {
+ entry(Name name_, entry *parent_) :
+ name(name_),
+ parent(parent_),
+ left(0),
+ right(0),
+ depth(1)
+ {}
+
+ Name name;
+
+ entry *parent;
+ entry *left;
+ entry *right;
+ unsigned depth;
+
+ void setup_depth() {
+ unsigned rdepth = (right != 0) ? right->depth : 0;
+ unsigned ldepth = (left != 0) ? left->depth : 0;
+ depth = 1 + ((ldepth > rdepth) ? ldepth : rdepth);
+ }
+ };
+
+public:
+ // make iterator a friend of Name_set to have access to struct entry
+ struct iterator;
+ friend struct Name_set::iterator;
+
+ // iterator over tree nodes
+ struct iterator {
+ public:
+ // constructors
+ iterator() : node(0) {}
+ iterator(entry *node_) : node(node_) {}
+
+ // dereference operator
+ Name operator->() const { return node->name; }
+
+ // conversion operator
+ operator Name() { return node->name; }
+
+ // assignment operator
+ iterator& operator=(const iterator &o) { node = o.node; return *this; }
+
+ // equality/inequality operators
+ int operator==(const iterator &o) const { return (node == o.node); }
+ int operator!=(const iterator &o) const { return (node != o.node); }
+
+ // pre/post increment operators
+ iterator& operator++();
+ iterator operator++(int) { iterator it = *this; ++*this; return it; }
+
+ private:
+ // the node iterator points to
+ entry *node;
+ };
+
+public:
+ // constructor
+ Name_set() : root(0) {}
+
+ // lookup, insert and remove operations
+ Name lookup(const char *key);
+ Name insert(const char *key, Boolean &found);
+ void insert(Name name);
+
+ // begin/end iterators
+ iterator begin() const;
+ iterator end() const { return iterator(); }
+
+private:
+ // rebalance given node
+ void rebalance(entry *node);
+
+private:
+ // tree root
+ entry *root;
+};
+
+/*
+ * extern declarations for all global variables.
+ * The actual declarations are in globals.cc
+ */
+extern char char_semantics[];
+extern wchar_t char_semantics_char[];
+extern Macro_list cond_macro_list;
+extern Boolean conditional_macro_used;
+extern Boolean do_not_exec_rule; /* `-n' */
+extern Boolean dollarget_seen;
+extern Boolean dollarless_flag;
+extern Name dollarless_value;
+extern char **environ;
+extern Envvar envvar;
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+extern int exit_status;
+#endif
+extern wchar_t *file_being_read;
+/* Variable gnu_style=true if env. var. SUN_MAKE_COMPAT_MODE=GNU (RFE 4866328) */
+extern Boolean gnu_style;
+extern Name_set hashtab;
+extern Name host_arch;
+extern Name host_mach;
+extern int line_number;
+extern char *make_state_lockfile;
+extern Boolean make_word_mentioned;
+extern Makefile_type makefile_type;
+extern char mbs_buffer[];
+extern Name path_name;
+extern Boolean posix;
+extern Name query;
+extern Boolean query_mentioned;
+extern Name hat;
+extern Boolean reading_environment;
+extern Name shell_name;
+extern Boolean svr4;
+extern Name target_arch;
+extern Name target_mach;
+extern Boolean tilde_rule;
+extern wchar_t wcs_buffer[];
+extern Boolean working_on_targets;
+extern Name virtual_root;
+extern Boolean vpath_defined;
+extern Name vpath_name;
+extern Boolean make_state_locked;
+#if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR)
+extern Boolean out_err_same;
+#endif
+extern pid_t childPid;
+extern nl_catd libmksh_catd;
+
+/*
+ * RFE 1257407: make does not use fine granularity time info available from stat.
+ * High resolution time comparison.
+ */
+
+inline int
+operator==(const timestruc_t &t1, const timestruc_t &t2) {
+ return ((t1.tv_sec == t2.tv_sec) && (t1.tv_nsec == t2.tv_nsec));
+}
+
+inline int
+operator!=(const timestruc_t &t1, const timestruc_t &t2) {
+ return ((t1.tv_sec != t2.tv_sec) || (t1.tv_nsec != t2.tv_nsec));
+}
+
+inline int
+operator>(const timestruc_t &t1, const timestruc_t &t2) {
+ if (t1.tv_sec == t2.tv_sec) {
+ return (t1.tv_nsec > t2.tv_nsec);
+ }
+ return (t1.tv_sec > t2.tv_sec);
+}
+
+inline int
+operator>=(const timestruc_t &t1, const timestruc_t &t2) {
+ if (t1.tv_sec == t2.tv_sec) {
+ return (t1.tv_nsec >= t2.tv_nsec);
+ }
+ return (t1.tv_sec > t2.tv_sec);
+}
+
+inline int
+operator<(const timestruc_t &t1, const timestruc_t &t2) {
+ if (t1.tv_sec == t2.tv_sec) {
+ return (t1.tv_nsec < t2.tv_nsec);
+ }
+ return (t1.tv_sec < t2.tv_sec);
+}
+
+inline int
+operator<=(const timestruc_t &t1, const timestruc_t &t2) {
+ if (t1.tv_sec == t2.tv_sec) {
+ return (t1.tv_nsec <= t2.tv_nsec);
+ }
+ return (t1.tv_sec < t2.tv_sec);
+}
+
+#endif
diff --git a/usr/src/make_src/Make/include/mksh/dosys.h b/usr/src/make_src/Make/include/mksh/dosys.h
new file mode 100644
index 0000000..daab07b
--- /dev/null
+++ b/usr/src/make_src/Make/include/mksh/dosys.h
@@ -0,0 +1,50 @@
+#ifndef _MKSH_DOSYS_H
+#define _MKSH_DOSYS_H
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)dosys.h 1.9 06/12/12
+ */
+
+#pragma ident "@(#)dosys.h 1.9 06/12/12"
+
+#include <mksh/defs.h>
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+# include <rw/xdrstrea.h>
+#endif
+#include <vroot/vroot.h>
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+extern Boolean await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, Boolean send_mtool_msgs, XDR *xdrs, int job_msg_id);
+#else
+extern Boolean await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, Boolean send_mtool_msgs, void *xdrs, int job_msg_id);
+#endif
+extern int doexec(register wchar_t *command, register Boolean ignore_error, Boolean redirect_out_err, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio);
+extern int doshell(wchar_t *command, register Boolean ignore_error, Boolean redirect_out_err, char *stdout_file, char *stderr_file, int nice_prio);
+extern Doname dosys_mksh(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target, Boolean redirect_out_err, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio);
+extern void redirect_io(char *stdout_file, char *stderr_file);
+extern void sh_command2string(register String command, register String destination);
+
+#endif
diff --git a/usr/src/make_src/Make/include/mksh/globals.h b/usr/src/make_src/Make/include/mksh/globals.h
new file mode 100644
index 0000000..129dbee
--- /dev/null
+++ b/usr/src/make_src/Make/include/mksh/globals.h
@@ -0,0 +1,35 @@
+#ifndef _MKSH_GLOBALS_H
+#define _MKSH_GLOBALS_H
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1994 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)globals.h 1.2 06/12/12
+ */
+
+#pragma ident "@(#)globals.h 1.2 06/12/12"
+
+#include <mksh/defs.h>
+
+#endif
diff --git a/usr/src/make_src/Make/include/mksh/i18n.h b/usr/src/make_src/Make/include/mksh/i18n.h
new file mode 100644
index 0000000..7c9e3c4
--- /dev/null
+++ b/usr/src/make_src/Make/include/mksh/i18n.h
@@ -0,0 +1,38 @@
+#ifndef _MKSH_I18N_H
+#define _MKSH_I18N_H
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1994 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)i18n.h 1.2 06/12/12
+ */
+
+#pragma ident "@(#)i18n.h 1.2 06/12/12"
+
+#include <mksh/defs.h>
+
+extern int get_char_semantics_entry(wchar_t ch);
+extern char get_char_semantics_value(wchar_t ch);
+
+#endif
diff --git a/usr/src/make_src/Make/include/mksh/libmksh_init.h b/usr/src/make_src/Make/include/mksh/libmksh_init.h
new file mode 100644
index 0000000..7190b06
--- /dev/null
+++ b/usr/src/make_src/Make/include/mksh/libmksh_init.h
@@ -0,0 +1,36 @@
+#ifndef _MKSH_INIT_H
+#define _MKSH_INIT_H
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1995 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)libmksh_init.h 1.2 06/12/12
+ */
+
+#pragma ident "@(#)libmksh_init.h 1.2 06/12/12"
+
+int libmksh_init()
+void libmksh_fini();
+
+#endif
diff --git a/usr/src/make_src/Make/include/mksh/macro.h b/usr/src/make_src/Make/include/mksh/macro.h
new file mode 100644
index 0000000..5989c9e
--- /dev/null
+++ b/usr/src/make_src/Make/include/mksh/macro.h
@@ -0,0 +1,41 @@
+#ifndef _MKSH_MACRO_H
+#define _MKSH_MACRO_H
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)macro.h 1.3 06/12/12
+ */
+
+#pragma ident "@(#)macro.h 1.3 06/12/12"
+
+#include <mksh/defs.h>
+
+extern void expand_macro(register Source source, register String destination, wchar_t *current_string, Boolean cmd);
+extern void expand_value(Name value, register String destination, Boolean cmd);
+extern Name getvar(register Name name);
+
+extern Property setvar_daemon(register Name name, register Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level);
+
+#endif
diff --git a/usr/src/make_src/Make/include/mksh/misc.h b/usr/src/make_src/Make/include/mksh/misc.h
new file mode 100644
index 0000000..bb397fc
--- /dev/null
+++ b/usr/src/make_src/Make/include/mksh/misc.h
@@ -0,0 +1,60 @@
+#ifndef _MKSH_MISC_H
+#define _MKSH_MISC_H
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)misc.h 1.4 06/12/12
+ */
+
+#pragma ident "@(#)misc.h 1.4 06/12/12"
+
+#include <mksh/defs.h>
+
+extern void append_char(wchar_t from, register String to);
+extern Property append_prop(register Name target, register Property_id type);
+extern void append_string(register wchar_t *from, register String to, register int length);
+extern void enable_interrupt(register void (*handler) (int));
+extern char *errmsg(int errnum);
+extern void fatal_mksh(char * message, ...);
+extern void fatal_reader_mksh(char * pattern, ...);
+extern char *get_current_path_mksh(void);
+extern Property get_prop(register Property start, register Property_id type);
+extern char *getmem(register int size);
+extern Name getname_fn(wchar_t *name, register int len, register Boolean dont_enter, register Boolean * foundp = NULL);
+extern void store_name(Name name);
+extern void free_name(Name name);
+extern void handle_interrupt_mksh(int);
+extern Property maybe_append_prop(register Name target, register Property_id type);
+extern void retmem(wchar_t *p);
+extern void retmem_mb(caddr_t p);
+extern void setup_char_semantics(void);
+extern void setup_interrupt(register void (*handler) (int));
+extern void warning_mksh(char * message, ...);
+
+extern void append_string(register char *from, register String to, register int length);
+extern wchar_t *get_wstring(char * from);
+
+
+#endif
diff --git a/usr/src/make_src/Make/include/mksh/mksh.h b/usr/src/make_src/Make/include/mksh/mksh.h
new file mode 100644
index 0000000..2b555e0
--- /dev/null
+++ b/usr/src/make_src/Make/include/mksh/mksh.h
@@ -0,0 +1,49 @@
+#ifndef _MKSH_MKSH_H
+#define _MKSH_MKSH_H
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)mksh.h 1.7 06/12/12
+ */
+
+#pragma ident "@(#)mksh.h 1.7 06/12/12"
+
+/*
+ * Included files
+ */
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+# include <dm/Avo_DmakeCommand.h>
+#endif
+
+#include <mksh/defs.h>
+#include <unistd.h>
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+
+extern int do_job(Avo_DmakeCommand *cmd_list[], char *env_list[], char *stdout_file, char *stderr_file, char *cwd, char *cnwd, int ignore, int silent, pathpt vroot_path, char *shell, int nice_prio);
+
+#endif /* TEAMWARE_MAKE_CMN */
+
+#endif
diff --git a/usr/src/make_src/Make/include/mksh/read.h b/usr/src/make_src/Make/include/mksh/read.h
new file mode 100644
index 0000000..5afffd2
--- /dev/null
+++ b/usr/src/make_src/Make/include/mksh/read.h
@@ -0,0 +1,37 @@
+#ifndef _MKSH_READ_H
+#define _MKSH_READ_H
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1994 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)read.h 1.2 06/12/12
+ */
+
+#pragma ident "@(#)read.h 1.2 06/12/12"
+
+#include <mksh/defs.h>
+
+extern Source get_next_block_fn(register Source source);
+
+#endif
diff --git a/usr/src/make_src/Make/include/vroot/args.h b/usr/src/make_src/Make/include/vroot/args.h
new file mode 100644
index 0000000..96795ad
--- /dev/null
+++ b/usr/src/make_src/Make/include/vroot/args.h
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1999 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)args.h 1.7 06/12/12
+ */
+
+#pragma ident "@(#)args.h 1.7 06/12/12"
+
+#ifndef _ARGS_H_
+#define _ARGS_H_
+
+#include <sys/syscall.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+
+typedef enum { rw_read, rw_write} rwt, *rwpt;
+
+extern void translate_with_thunk(register char *filename, int (*thunk) (char *), pathpt path_vector, pathpt vroot_vector, rwt rw);
+
+union Args {
+ struct { int mode;} access;
+ struct { int mode;} chmod;
+ struct { int user; int group;} chown;
+ struct { int mode;} creat;
+ struct { char **argv; char **environ;} execve;
+ struct { struct stat *buffer;} lstat;
+ struct { int mode;} mkdir;
+ struct { char *name; int mode;} mount;
+ struct { int flags; int mode;} open;
+ struct { char *buffer; int buffer_size;} readlink;
+ struct { struct stat *buffer;} stat;
+#ifndef SUN5_0
+ struct { struct statfs *buffer;} statfs;
+#endif
+ struct { int length;} truncate;
+ struct { struct timeval *time;} utimes;
+};
+
+extern union Args vroot_args;
+extern int vroot_result;
+
+#endif
diff --git a/usr/src/make_src/Make/include/vroot/report.h b/usr/src/make_src/Make/include/vroot/report.h
new file mode 100644
index 0000000..15babab
--- /dev/null
+++ b/usr/src/make_src/Make/include/vroot/report.h
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1994 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)report.h 1.6 06/12/12
+ */
+
+#pragma ident "@(#)report.h 1.6 06/12/12"
+
+#ifndef _REPORT_H_
+#define _REPORT_H_
+
+#include <stdio.h>
+
+extern FILE *get_report_file(void);
+extern char *get_target_being_reported_for(void);
+extern void report_dependency(register char *name);
+extern int file_lock(char *name, char *lockname, int *file_locked, int timeout);
+#ifdef NSE
+extern char *setenv(char *name, char *value);
+#endif
+
+#define SUNPRO_DEPENDENCIES "SUNPRO_DEPENDENCIES"
+#define LD "LD"
+#define COMP "COMP"
+
+/* the following definitions define the interface between make and
+ * NSE - the two systems must track each other.
+ */
+#define NSE_DEPINFO ".nse_depinfo"
+#define NSE_DEPINFO_LOCK ".nse_depinfo.lock"
+#define NSE_DEP_ENV "NSE_DEP"
+#define NSE_TFS_PUSH "/usr/nse/bin/tfs_push"
+#define NSE_TFS_PUSH_LEN 8
+#define NSE_VARIANT_ENV "NSE_VARIANT"
+#define NSE_RT_SOURCE_NAME "Shared_Source"
+
+#endif
diff --git a/usr/src/make_src/Make/include/vroot/vroot.h b/usr/src/make_src/Make/include/vroot/vroot.h
new file mode 100644
index 0000000..faeb011
--- /dev/null
+++ b/usr/src/make_src/Make/include/vroot/vroot.h
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)vroot.h 1.10 06/12/12
+ */
+
+#pragma ident "@(#)vroot.h 1.10 06/12/12"
+
+#ifndef _VROOT_H_
+#define _VROOT_H_
+
+#include <stdio.h>
+#include <nl_types.h>
+
+#define VROOT_DEFAULT ((pathpt)-1)
+
+typedef struct {
+ char *path;
+ short length;
+} pathcellt, *pathcellpt, patht;
+typedef patht *pathpt;
+
+extern void add_dir_to_path(register char *path, register pathpt *pointer, register int position);
+extern void flush_path_cache(void);
+extern void flush_vroot_cache(void);
+extern char *get_path_name(void);
+extern char *get_vroot_path(register char **vroot, register char **path, register char **filename);
+extern char *get_vroot_name(void);
+extern int open_vroot(char *path, int flags, int mode, pathpt vroot_path, pathpt vroot_vroot);
+extern pathpt parse_path_string(register char *string, register int remove_slash);
+extern void scan_path_first(void);
+extern void scan_vroot_first(void);
+extern void set_path_style(int style);
+
+extern int access_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot);
+
+extern int execve_vroot(char *path, char **argv, char **environ, pathpt vroot_path, pathpt vroot_vroot);
+
+extern int lstat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot);
+extern int stat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot);
+extern int readlink_vroot(char *path, char *buffer, int buffer_size, pathpt vroot_path, pathpt vroot_vroot);
+
+
+extern nl_catd libvroot_catd;
+#endif
diff --git a/usr/src/make_src/Make/lib/Lib.mk b/usr/src/make_src/Make/lib/Lib.mk
new file mode 100644
index 0000000..2bf2147
--- /dev/null
+++ b/usr/src/make_src/Make/lib/Lib.mk
@@ -0,0 +1,67 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2001 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Lib.mk 1.13 06/12/12
+#
+
+# Definitions of the libraries supplied by make/dmake.
+# You must correctly define TOP before including this file!
+
+MAKE_TOP = $(TOP)/Make
+
+LIBBSD_DIR = $(MAKE_TOP)/lib/bsd
+LIBBSD = $(LIBBSD_DIR)/$(VARIANT)/libbsd.a
+
+LIBDMRXM_DIR = $(MAKE_TOP)/lib/dmrxm
+LIBDMRXM = $(LIBDMRXM_DIR)/$(VARIANT)/libdmrxm.a
+
+LIBDMRXS_DIR = $(MAKE_TOP)/lib/dmrxs
+LIBDMRXS = $(LIBDMRXS_DIR)/$(VARIANT)/libdmrxs.a
+
+LIBMAKESTATE_DIR = $(MAKE_TOP)/lib/makestate
+LIBMAKESTATE = $(LIBMAKESTATE_DIR)/$(VARIANT)/libmakestate.a
+
+LIBMKSDMSI18N_DIR = $(MAKE_TOP)/lib/mksdmsi18n
+LIBMKSDMSI18N = $(LIBMKSDMSI18N_DIR)/$(VARIANT)/libmksdmsi18n.a
+
+LIBMKSH_DIR = $(MAKE_TOP)/lib/mksh
+LIBMKSH = $(LIBMKSH_DIR)/$(VARIANT)/libmksh.a
+
+LIBVROOT_DIR = $(MAKE_TOP)/lib/vroot
+LIBVROOT = $(LIBVROOT_DIR)/$(VARIANT)/libvroot.a
+
+LIBDM_DIR = $(MAKE_TOP)/lib/dm
+LIBDM = $(LIBDM_DIR)/$(VARIANT)/libdm.a
+
+LIBDMCONF_DIR = $(MAKE_TOP)/lib/dmconf
+LIBDMCONF = $(LIBDMCONF_DIR)/$(VARIANT)/libdmconf.a
+
+LIBDMRC_DIR = $(MAKE_TOP)/lib/dmrc
+LIBDMRC = $(LIBDMRC_DIR)/$(VARIANT)/libdmrc.a
+
+LIBDMTHREAD_DIR = $(MAKE_TOP)/lib/dmthread
+LIBDMTHREAD = $(LIBDMTHREAD_DIR)/$(VARIANT)/libdmthread.a
+
+LIBRX_DIR = $(MAKE_TOP)/lib/rx
+LIBRX = $(LIBRX_DIR)/$(VARIANT)/librx.a
+
diff --git a/usr/src/make_src/Make/lib/Makefile b/usr/src/make_src/Make/lib/Makefile
new file mode 100644
index 0000000..0e0d489
--- /dev/null
+++ b/usr/src/make_src/Make/lib/Makefile
@@ -0,0 +1,39 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.8 06/12/12
+#
+# @(#)Makefile 1.4 96/03/16 SMI
+
+TOP = ../..
+
+SUBDIRS = \
+ makestate \
+ bsd \
+ dmrxm \
+ dmrxs \
+ mksdmsi18n \
+ mksh \
+ vroot
+
+include $(TOP)/rules/recurse.mk
diff --git a/usr/src/make_src/Make/lib/bsd/Makefile b/usr/src/make_src/Make/lib/bsd/Makefile
new file mode 100644
index 0000000..fd663cd
--- /dev/null
+++ b/usr/src/make_src/Make/lib/bsd/Makefile
@@ -0,0 +1,29 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.5 06/12/12
+#
+
+TOP = ../../..
+include $(TOP)/rules/variant.mk
+include $(TOP)/rules/derived.mk
diff --git a/usr/src/make_src/Make/lib/bsd/src/Makefile b/usr/src/make_src/Make/lib/bsd/src/Makefile
new file mode 100644
index 0000000..299c46d
--- /dev/null
+++ b/usr/src/make_src/Make/lib/bsd/src/Makefile
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.3 06/12/12
+#
+
+# Generic makefile for use in src directories. Knows how to make common things
+# in the right $(VARIANT) directory.
+
+include $(TOP)/rules/variant.mk
+
+all := TARG = all
+install := TARG = install
+clean := TARG = clean
+test := TARG = test
+l10n_install := TARG = l10n_install
+i18n_install := TARG = i18n_install
+
+SRC = ../src
+MFLAGS += SRC=$(SRC)
+
+# See $(TOP)/rules/master.mk for how these are built.
+%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC
+ @ if [ ! -d ../$(VARIANT) ]; then \
+ mkdir ../$(VARIANT) ; \
+ fi
+ cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@
+
+FRC:
diff --git a/usr/src/make_src/Make/lib/bsd/src/Variant.mk b/usr/src/make_src/Make/lib/bsd/src/Variant.mk
new file mode 100644
index 0000000..650ee3e
--- /dev/null
+++ b/usr/src/make_src/Make/lib/bsd/src/Variant.mk
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Variant.mk 1.13 06/12/12
+#
+
+TOP = ../../../..
+include ${TOP}/rules/master.mk
+
+PKG_TOP = $(TOP)/Make
+CPPFLAGS += -I${PKG_TOP}/include
+MSG_FILE = libbsd.msg
+I18N_DIRS = $(SRC)
+
+CCSRCS = bsd.cc
+CSRCS =
+
+HDRS_DIR = ${PKG_TOP}/include/bsd
+
+.INIT: ${HDRS_DIR}/bsd.h
+
+LIBNAME = libbsd.a
+
+include ${TOP}/rules/lib.mk
+
diff --git a/usr/src/make_src/Make/lib/bsd/src/bsd.cc b/usr/src/make_src/Make/lib/bsd/src/bsd.cc
new file mode 100644
index 0000000..c61bca2
--- /dev/null
+++ b/usr/src/make_src/Make/lib/bsd/src/bsd.cc
@@ -0,0 +1,182 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)bsd.cc 1.6 06/12/12
+ */
+
+#pragma ident "@(#)bsd.cc 1.6 06/12/12"
+
+#include <signal.h>
+
+#include <bsd/bsd.h>
+
+/* External references.
+ */
+
+/* Forward references.
+ */
+
+/* Static data.
+ */
+
+extern SIG_PF
+bsd_signal (int Signal, SIG_PF Handler)
+{
+ auto SIG_PF previous_handler;
+#ifdef SUN5_0
+#ifdef sun
+ previous_handler = sigset (Signal, Handler);
+#else
+ auto struct sigaction new_action;
+ auto struct sigaction old_action;
+
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_handler = (void (*) ()) Handler;
+ (void) sigemptyset (&new_action.sa_mask);
+ (void) sigaddset (&new_action.sa_mask, Signal);
+
+ (void) sigaction (Signal, &new_action, &old_action);
+
+ previous_handler = (SIG_PF) old_action.sa_handler;
+#endif
+#elif defined(linux)
+ previous_handler = sigset (Signal, Handler);
+#else
+ previous_handler = signal (Signal, Handler);
+#endif
+ return previous_handler;
+}
+
+extern void
+bsd_signals (void)
+{
+ static int initialized = 0;
+
+ if (initialized == 0)
+ {
+ initialized = 1;
+#if !defined(SUN5_0) && !defined(linux)
+#if defined(SIGHUP)
+ (void) bsd_signal (SIGHUP, SIG_DFL);
+#endif
+#if defined(SIGINT)
+ (void) bsd_signal (SIGINT, SIG_DFL);
+#endif
+#if defined(SIGQUIT)
+ (void) bsd_signal (SIGQUIT, SIG_DFL);
+#endif
+#if defined(SIGILL)
+ (void) bsd_signal (SIGILL, SIG_DFL);
+#endif
+#if defined(SIGTRAP)
+ (void) bsd_signal (SIGTRAP, SIG_DFL);
+#endif
+#if defined(SIGIOT)
+ (void) bsd_signal (SIGIOT, SIG_DFL);
+#endif
+#if defined(SIGABRT)
+ (void) bsd_signal (SIGABRT, SIG_DFL);
+#endif
+#if defined(SIGEMT)
+ (void) bsd_signal (SIGEMT, SIG_DFL);
+#endif
+#if defined(SIGFPE)
+ (void) bsd_signal (SIGFPE, SIG_DFL);
+#endif
+#if defined(SIGBUS)
+ (void) bsd_signal (SIGBUS, SIG_DFL);
+#endif
+#if defined(SIGSEGV)
+ (void) bsd_signal (SIGSEGV, SIG_DFL);
+#endif
+#if defined(SIGSYS)
+ (void) bsd_signal (SIGSYS, SIG_DFL);
+#endif
+#if defined(SIGPIPE)
+ (void) bsd_signal (SIGPIPE, SIG_DFL);
+#endif
+#if defined(SIGALRM)
+ (void) bsd_signal (SIGALRM, SIG_DFL);
+#endif
+#if defined(SIGTERM)
+ (void) bsd_signal (SIGTERM, SIG_DFL);
+#endif
+#if defined(SIGUSR1)
+ (void) bsd_signal (SIGUSR1, SIG_DFL);
+#endif
+#if defined(SIGUSR2)
+ (void) bsd_signal (SIGUSR2, SIG_DFL);
+#endif
+#if defined(SIGCLD)
+ (void) bsd_signal (SIGCLD, SIG_DFL);
+#endif
+#if defined(SIGCHLD)
+ (void) bsd_signal (SIGCHLD, SIG_DFL);
+#endif
+#if defined(SIGPWR)
+ (void) bsd_signal (SIGPWR, SIG_DFL);
+#endif
+#if defined(SIGWINCH)
+ (void) bsd_signal (SIGWINCH, SIG_DFL);
+#endif
+#if defined(SIGURG)
+ (void) bsd_signal (SIGURG, SIG_DFL);
+#endif
+#if defined(SIGIO)
+ (void) bsd_signal (SIGIO, SIG_DFL);
+#else
+#if defined(SIGPOLL)
+ (void) bsd_signal (SIGPOLL, SIG_DFL);
+#endif
+#endif
+#if defined(SIGTSTP)
+ (void) bsd_signal (SIGTSTP, SIG_DFL);
+#endif
+#if defined(SIGCONT)
+ (void) bsd_signal (SIGCONT, SIG_DFL);
+#endif
+#if defined(SIGTTIN)
+ (void) bsd_signal (SIGTTIN, SIG_DFL);
+#endif
+#if defined(SIGTTOU)
+ (void) bsd_signal (SIGTTOU, SIG_DFL);
+#endif
+#if defined(SIGVTALRM)
+ (void) bsd_signal (SIGVTALRM, SIG_DFL);
+#endif
+#if defined(SIGPROF)
+ (void) bsd_signal (SIGPROF, SIG_DFL);
+#endif
+#if defined(SIGXCPU)
+ (void) bsd_signal (SIGXCPU, SIG_DFL);
+#endif
+#if defined(SIGXFSZ)
+ (void) bsd_signal (SIGXFSZ, SIG_DFL);
+#endif
+#endif
+ }
+
+ return;
+}
diff --git a/usr/src/make_src/Make/lib/makestate/Makefile b/usr/src/make_src/Make/lib/makestate/Makefile
new file mode 100644
index 0000000..9c1ddf0
--- /dev/null
+++ b/usr/src/make_src/Make/lib/makestate/Makefile
@@ -0,0 +1,48 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.7 06/12/12
+#
+
+TOP = ../../..
+include $(TOP)/rules/variant.mk
+
+V9_VARIANT :sh= \
+if [ -x /usr/bin/isalist ] ; \
+then \
+ for f in `/usr/bin/isalist` ; \
+ do \
+ if [ "$f" = sparcv9 ] ; \
+ then \
+ echo sparcv9 ; \
+ break ; \
+ fi ; \
+ if [ "$f" = amd64 ] ; \
+ then \
+ echo amd64-S2 ; \
+ break ; \
+ fi ; \
+ done ; \
+fi
+
+include $(TOP)/rules/derived.mk
diff --git a/usr/src/make_src/Make/lib/makestate/src/Makefile b/usr/src/make_src/Make/lib/makestate/src/Makefile
new file mode 100644
index 0000000..21e239d
--- /dev/null
+++ b/usr/src/make_src/Make/lib/makestate/src/Makefile
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.5 06/12/12
+#
+# @(#)Makefile 1.1 96/03/11 SMI
+
+# Generic makefile for use in src directories. Knows how to make common things
+# in the right $(VARIANT) directory.
+
+include $(TOP)/rules/variant.mk
+
+all := TARG = all
+install := TARG = install
+clean := TARG = clean
+test := TARG = test
+l10n_install := TARG = l10n_install
+i18n_install := TARG = i18n_install
+
+SRC = ../src
+MFLAGS += SRC=$(SRC)
+
+# See $(TOP)/rules/master.mk for how these are built.
+%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC
+ @ if [ ! -d ../$(VARIANT) ]; then \
+ mkdir ../$(VARIANT) ; \
+ fi
+ cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@
+
+FRC:
diff --git a/usr/src/make_src/Make/lib/makestate/src/Variant.mk b/usr/src/make_src/Make/lib/makestate/src/Variant.mk
new file mode 100644
index 0000000..26971d5
--- /dev/null
+++ b/usr/src/make_src/Make/lib/makestate/src/Variant.mk
@@ -0,0 +1,73 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Variant.mk 1.12 06/12/12
+#
+
+TOP = ../../../..
+
+%.o: $(SRC)/%.c
+ $(COMPILE.c) $(OUTPUT_OPTION) $<
+
+include $(TOP)/rules/master.mk
+
+PKG_TOP = $(TOP)/Make
+
+CSRCS = \
+ ld_file.c \
+ lock.c
+
+LIBNAME = libmakestate.a
+DLIBNAME = libmakestate.so.1
+MSG_FILE = libmakestate.msg
+I18N_DIRS = $(SRC)
+
+CFLAGS += $(V9FLAGS) -KPIC -DTEXT_DOMAIN=\"SUNW_OST_OSLIB\"
+CPPFLAGS=
+
+#include $(TOP)/Make/lib/Lib.mk
+include $(TOP)/rules/lib.mk
+
+POUND_SIGN:sh= echo \#
+RELEASE= 5.11
+VERSION= $(RELEASE_VER)
+PATCHID= $(VERSION)
+DATE:sh = date '+%B %Y'
+RELEASE_DATE= $(DATE)
+PATCH_DATE= $(RELEASE_DATE)
+RELEASE_CM= "@($(POUND_SIGN))RELEASE VERSION SunOS $(RELEASE) $(PATCHID) $(PATCH_DATE)"
+
+PROCESS_COMMENT= mcs -a $(RELEASE_CM)
+POST_PROCESS_SO= $(PROCESS_COMMENT) $@
+
+$(DLIBNAME) : $(LIBNAME)
+ $(CC) $(V9FLAGS) -o $@ -dy -G -ztext -h $@ ld_file.o lock.o -lelf
+ mcs -d $@
+ ${POST_PROCESS_SO}
+
+all: $(DLIBNAME)
+
+install: all
+ ${INSTALL} -d ${DESTDIR}/usr/lib$(VAR_DIR)
+ ${RM} ${DESTDIR}/usr/lib$(VAR_DIR)/$(DLIBNAME)
+ ${INSTALL} $(DLIBNAME) ${DESTDIR}/usr/lib$(VAR_DIR)
diff --git a/usr/src/make_src/Make/lib/makestate/src/ld_file.c b/usr/src/make_src/Make/lib/makestate/src/ld_file.c
new file mode 100644
index 0000000..b80ea68
--- /dev/null
+++ b/usr/src/make_src/Make/lib/makestate/src/ld_file.c
@@ -0,0 +1,192 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1998 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)ld_file.c 1.7 06/12/12
+ */
+#pragma ident "@(#)ld_file.c 1.7 06/12/12"
+
+#pragma init(ld_support_init)
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libelf.h>
+#include <sys/param.h>
+#include <link.h>
+
+#define SUNPRO_DEPENDENCIES "SUNPRO_DEPENDENCIES"
+
+/*
+ * Linked list of strings - used to keep lists of names
+ * of directories or files.
+ */
+
+struct Stritem {
+ char * str;
+ void * next;
+};
+
+typedef struct Stritem Stritem;
+
+static char * depend_file = NULL;
+static Stritem * list = NULL;
+
+
+void mk_state_init()
+{
+ depend_file = getenv(SUNPRO_DEPENDENCIES);
+} /* mk_state_init() */
+
+
+
+static void
+prepend_str(Stritem **list, const char * str)
+{
+ Stritem * new;
+ char * newstr;
+
+ if (!(new = calloc(1, sizeof (Stritem)))) {
+ perror("libmakestate.so");
+ return;
+ } /* if */
+
+ if (!(newstr = malloc(strlen(str) + 1))) {
+ perror("libmakestate.so");
+ return;
+ } /* if */
+
+ new->str = strcpy(newstr, str);
+ new->next = *list;
+ *list = new;
+
+} /* prepend_str() */
+
+
+void
+mk_state_collect_dep(const char * file)
+{
+ /*
+ * SUNPRO_DEPENDENCIES wasn't set, we don't collect .make.state
+ * information.
+ */
+ if (!depend_file)
+ return;
+
+ prepend_str(&list, file);
+
+} /* mk_state_collect_dep() */
+
+
+void
+mk_state_update_exit()
+{
+ Stritem * cur;
+ char lockfile[MAXPATHLEN], * err, * space, * target;
+ FILE * ofp;
+ extern char * file_lock(char *, char *, int);
+
+ if (!depend_file)
+ return;
+
+ if ((space = strchr(depend_file, ' ')) == NULL)
+ return;
+ *space = '\0';
+ target = &space[1];
+
+ (void) sprintf(lockfile, "%s.lock", depend_file);
+ if ((err = file_lock(depend_file, lockfile, 0))) {
+ (void) fprintf(stderr, "%s\n", err);
+ return;
+ } /* if */
+
+ if (!(ofp = fopen(depend_file, "a")))
+ return;
+
+ if (list)
+ (void) fprintf(ofp, "%s: ", target);
+
+ for (cur = list; cur; cur = cur->next)
+ (void) fprintf(ofp, " %s", cur->str);
+
+ (void) fputc('\n', ofp);
+
+ (void) fclose(ofp);
+ (void) unlink(lockfile);
+ *space = ' ';
+
+} /* mk_state_update_exit() */
+
+static void
+/* LINTED static unused */
+ld_support_init()
+{
+ mk_state_init();
+
+} /* ld_support_init() */
+
+/* ARGSUSED */
+void
+ld_file(const char * file, const Elf_Kind ekind, int flags, Elf *elf)
+{
+ if(! ((flags & LD_SUP_DERIVED) && !(flags & LD_SUP_EXTRACTED)))
+ return;
+
+ mk_state_collect_dep(file);
+
+} /* ld_file */
+
+void
+ld_atexit(int exit_code)
+{
+ if (exit_code)
+ return;
+
+ mk_state_update_exit();
+
+} /* ld_atexit() */
+
+/*
+ * Supporting 64-bit objects
+ */
+void
+ld_file64(const char * file, const Elf_Kind ekind, int flags, Elf *elf)
+{
+ if(! ((flags & LD_SUP_DERIVED) && !(flags & LD_SUP_EXTRACTED)))
+ return;
+
+ mk_state_collect_dep(file);
+
+} /* ld_file64 */
+
+void
+ld_atexit64(int exit_code)
+{
+ if (exit_code)
+ return;
+
+ mk_state_update_exit();
+
+} /* ld_atexit64() */
diff --git a/usr/src/make_src/Make/lib/makestate/src/lock.c b/usr/src/make_src/Make/lib/makestate/src/lock.c
new file mode 100644
index 0000000..7646059
--- /dev/null
+++ b/usr/src/make_src/Make/lib/makestate/src/lock.c
@@ -0,0 +1,175 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)lock.c 1.5 06/12/12
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <errno.h> /* errno */
+
+#if defined(_LP64)
+/*
+ * The symbols _sys_errlist and _sys_nerr are not visible in the
+ * LP64 libc. Use strerror(3C) instead.
+ */
+#else /* #_LP64 */
+extern char * sys_errlist[];
+extern int sys_nerr;
+#endif /* #_LP64 */
+
+static void file_lock_error();
+
+/*
+ * This code stolen from the NSE library and changed to not depend
+ * upon any NSE routines or header files.
+ *
+ * Simple file locking.
+ * Create a symlink to a file. The "test and set" will be
+ * atomic as creating the symlink provides both functions.
+ *
+ * The timeout value specifies how long to wait for stale locks
+ * to disappear. If the lock is more than 'timeout' seconds old
+ * then it is ok to blow it away. This part has a small window
+ * of vunerability as the operations of testing the time,
+ * removing the lock and creating a new one are not atomic.
+ * It would be possible for two processes to both decide to blow
+ * away the lock and then have process A remove the lock and establish
+ * its own, and then then have process B remove the lock which accidentily
+ * removes A's lock rather than the stale one.
+ *
+ * A further complication is with the NFS. If the file in question is
+ * being served by an NFS server, then its time is set by that server.
+ * We can not use the time on the client machine to check for a stale
+ * lock. Therefore, a temp file on the server is created to get
+ * the servers current time.
+ *
+ * Returns an error message. NULL return means the lock was obtained.
+ *
+ */
+char *
+file_lock(char * name, char * lockname, int timeout)
+{
+ int r;
+ int fd;
+ struct stat statb;
+ struct stat fs_statb;
+ char tmpname[MAXPATHLEN];
+ static char msg[MAXPATHLEN];
+
+ if (timeout <= 0) {
+ timeout = 15;
+ }
+ for (;;) {
+ r = symlink(name, lockname);
+ if (r == 0) {
+ return (NULL);
+ }
+ if (errno != EEXIST) {
+ file_lock_error(msg, name,
+ (const char *)"symlink(%s, %s)", name, lockname);
+ return (msg);
+ }
+ for (;;) {
+ (void) sleep(1);
+ r = lstat(lockname, &statb);
+ if (r == -1) {
+ /*
+ * The lock must have just gone away - try
+ * again.
+ */
+ break;
+ }
+
+ /*
+ * With the NFS the time given a file is the time on
+ * the file server. This time may vary from the
+ * client's time. Therefore, we create a tmpfile in
+ * the same directory to establish the time on the
+ * server and use this time to see if the lock has
+ * expired.
+ */
+ (void) sprintf(tmpname, "%s.XXXXXX", lockname);
+ (void) mktemp(tmpname);
+ fd = creat(tmpname, 0666);
+ if (fd != -1) {
+ (void) close(fd);
+ } else {
+ file_lock_error(msg, name,
+ (const char *)"creat(%s)", tmpname);
+ return (msg);
+ }
+ if (stat(tmpname, &fs_statb) == -1) {
+ file_lock_error(msg, name,
+ (const char *)"stat(%s)", tmpname);
+ return (msg);
+ }
+ (void) unlink(tmpname);
+ if (statb.st_mtime + timeout < fs_statb.st_mtime) {
+ /*
+ * The lock has expired - blow it away.
+ */
+ (void) unlink(lockname);
+ break;
+ }
+ }
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * Format a message telling why the lock could not be created.
+ */
+/* VARARGS4 */
+static void
+file_lock_error(char * msg, char * file, const char * str, char * arg1,
+ char * arg2)
+{
+ int len;
+
+ (void) sprintf(msg, "Could not lock file `%s'; ", file);
+ len = strlen(msg);
+ (void) sprintf(&msg[len], str, arg1, arg2);
+ (void) strcat(msg, " failed - ");
+#if defined(_LP64)
+ /* Needs to be changed to use strerror(3C) instead. */
+ len = strlen(msg);
+ (void) sprintf(&msg[len], "errno %d", errno);
+#else /* #_LP64 */
+ if (errno < sys_nerr) {
+ (void) strcat(msg, sys_errlist[errno]);
+ } else {
+ len = strlen(msg);
+ (void) sprintf(&msg[len], "errno %d", errno);
+ }
+#endif /* #_LP64 */
+}
diff --git a/usr/src/make_src/Make/lib/mksdmsi18n/Makefile b/usr/src/make_src/Make/lib/mksdmsi18n/Makefile
new file mode 100644
index 0000000..c9d8161
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksdmsi18n/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.5 06/12/12
+#
+
+TOP = ../../..
+include $(TOP)/rules/variant.mk
+include $(TOP)/rules/derived.mk
+
diff --git a/usr/src/make_src/Make/lib/mksdmsi18n/src/Makefile b/usr/src/make_src/Make/lib/mksdmsi18n/src/Makefile
new file mode 100644
index 0000000..f27801b
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksdmsi18n/src/Makefile
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.10 06/12/12
+#
+
+TOP = ../../../..
+include $(TOP)/rules/master.mk
+
+SUBDIRS = lib
+include $(TOP)/rules/recurse.mk
+include $(SRC)/lib/version.mk
+
+PKG_TOP = $(TOP)/Make
+CPPFLAGS += -I$(PKG_TOP)/include
+
+CCSRCS = libmksdmsi18n_init.cc
+
+LIBNAME = libmksdmsi18n.a
+
+#
+# Pass in the version number for the i18n message catalog.
+#
+libmksdmsi18n_init.o := CPPFLAGS += -DI18N_VERSION=$(VERSION)
+
+include $(TOP)/rules/lib.mk
diff --git a/usr/src/make_src/Make/lib/mksdmsi18n/src/Variant.mk b/usr/src/make_src/Make/lib/mksdmsi18n/src/Variant.mk
new file mode 100644
index 0000000..1faef99
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksdmsi18n/src/Variant.mk
@@ -0,0 +1,52 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1997 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Variant.mk 1.4 06/12/12
+#
+
+TOP = ../../../..
+include $(TOP)/rules/master.mk
+#include $(TOP)/rules/dmake.mk
+
+#SUBDIRS = $(SRC)/lib
+#include $(TOP)/rules/recurse.mk
+
+CCSRCS = \
+ libmksdmsi18n_init.cc
+
+CSRCS =
+
+include $(SRC)/lib/version.mk
+
+libmksdmsi18n_init.o := CPPFLAGS += -DI18N_VERSION=$(VERSION)
+
+#PKG_TOP = $(TOP)/Make
+#CPPFLAGS += -I$(PKG_TOP)/include
+
+LIBNAME = libmksdmsi18n.a
+MSG_FILE = libmksdmsi18n.msg
+I18N_DIRS = $(SRC)
+
+include $(TOP)/Make/lib/Lib.mk
+include $(TOP)/rules/lib.mk
+
diff --git a/usr/src/make_src/Make/lib/mksdmsi18n/src/lib/Makefile b/usr/src/make_src/Make/lib/mksdmsi18n/src/lib/Makefile
new file mode 100644
index 0000000..73399b1
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksdmsi18n/src/lib/Makefile
@@ -0,0 +1,54 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.7 06/12/12
+#
+
+include version.mk
+
+TOP = ../../../../..
+PKG_TOP = $(TOP)/Make
+PKG_LIB_TOP = $(PKG_TOP)/lib
+I18N_LIBS = bsd dmrxm dmrxs mksh vroot
+I18N_DIRS = $(I18N_LIBS:%=$(PKG_LIB_TOP)/%/src)
+SRC = .
+APPPATH = .
+LIBNAME = libmksdmsi18n
+TEXTDOMAIN = $(LIBNAME)_$(VERSION)
+MSG_FILE = $(TEXTDOMAIN).msg
+
+all clean:
+install: catalogs .WAIT i18n_install
+
+#
+# This is a hack until the top level makefiles for i18n/l10n message catalogs
+# are better organized and written.
+# This "catalogs" target was cp'ed from $(TOP)/rules/lib.mk
+#
+catalogs:
+ $(GENMSG) -l $(SRC)/genmsg.project -o $(MSG_FILE) `find $(I18N_DIRS) \( -name '*.cc' -o -name '*.c' -o -name '*.y' \) -print | grep -v /SCCS/`
+ rm -f *.cc.new
+
+include $(PKG_TOP)/prodver.mk
+include $(TOP)/rules/i18n-install.mk
+
diff --git a/usr/src/make_src/Make/lib/mksdmsi18n/src/lib/version.mk b/usr/src/make_src/Make/lib/mksdmsi18n/src/lib/version.mk
new file mode 100644
index 0000000..aaad8d8
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksdmsi18n/src/lib/version.mk
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1995 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)version.mk 1.2 06/12/12
+#
+
+# A version number is needed to version the i18n catalog file
+
+VERSION = 1
+
diff --git a/usr/src/make_src/Make/lib/mksdmsi18n/src/libmksdmsi18n_init.cc b/usr/src/make_src/Make/lib/mksdmsi18n/src/libmksdmsi18n_init.cc
new file mode 100644
index 0000000..e234125
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksdmsi18n/src/libmksdmsi18n_init.cc
@@ -0,0 +1,63 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)libmksdmsi18n_init.cc 1.5 06/12/12
+ */
+
+#pragma ident "@(#)libmksdmsi18n_init.cc 1.5 06/12/12"
+
+#include <avo/intl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+nl_catd libmksdmsi18n_catd;
+
+/*
+ * Open the catalog file for libmksdmsi18n. Users of this library must set
+ * NSLPATH first. See avo_18n_init().
+ */
+int
+libmksdmsi18n_init()
+{
+ char name[20];
+
+ if (getenv(NOCATGETS("NLSPATH")) == NULL) {
+ fprintf(stderr, NOCATGETS("Internal error: Set NLSPATH before opening catalogue file\n"));
+ return 1;
+ }
+ sprintf(name, NOCATGETS("libmksdmsi18n_%d"), I18N_VERSION);
+ libmksdmsi18n_catd = catopen(name, NL_CAT_LOCALE);
+ return 0;
+}
+
+/*
+ * Close the catalog file for libmksdmsi18n
+ */
+void
+libmksdmsi18n_fini()
+{
+ catclose(libmksdmsi18n_catd);
+}
+
diff --git a/usr/src/make_src/Make/lib/mksh/Makefile b/usr/src/make_src/Make/lib/mksh/Makefile
new file mode 100644
index 0000000..fd663cd
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksh/Makefile
@@ -0,0 +1,29 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.5 06/12/12
+#
+
+TOP = ../../..
+include $(TOP)/rules/variant.mk
+include $(TOP)/rules/derived.mk
diff --git a/usr/src/make_src/Make/lib/mksh/src/Makefile b/usr/src/make_src/Make/lib/mksh/src/Makefile
new file mode 100644
index 0000000..ebed78f
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksh/src/Makefile
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.3 06/12/12
+#
+
+# Generic makefile for use in src directories. Knows how to make common things
+# in the right $(VARIANT) directory.
+
+#TOP = ../../../..
+include $(TOP)/rules/variant.mk
+
+all := TARG = all
+install := TARG = install
+clean := TARG = clean
+test := TARG = test
+l10n_install := TARG = l10n_install
+i18n_install := TARG = i18n_install
+
+SRC = ../src
+MFLAGS += SRC=$(SRC)
+
+# See $(TOP)/rules/master.mk for how these are built.
+%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC
+ @ if [ ! -d ../$(VARIANT) ]; then \
+ mkdir ../$(VARIANT) ; \
+ fi
+ cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@
+
+FRC:
diff --git a/usr/src/make_src/Make/lib/mksh/src/Variant.mk b/usr/src/make_src/Make/lib/mksh/src/Variant.mk
new file mode 100644
index 0000000..427ba54
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksh/src/Variant.mk
@@ -0,0 +1,58 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Variant.mk 1.19 06/12/12
+#
+
+TOP = ../../../..
+include $(TOP)/rules/master.mk
+include $(TOP)/rules/dmake.mk
+
+PKG_TOP = $(TOP)/Make
+CPPFLAGS += -I$(PKG_TOP)/include
+
+CCSRCS = \
+ dosys.cc \
+ globals.cc \
+ i18n.cc \
+ macro.cc \
+ misc.cc \
+ mksh.cc \
+ read.cc
+
+HDRS_DIR = $(PKG_TOP)/include/mksh
+HDRS_LIST = $(HDRS_DIR)/defs.h \
+ $(CCSRCS:%.cc=$(HDRS_DIR)/%.h) \
+ $(CSRCS:%.c=$(HDRS_DIR)/%.h)
+
+.INIT: $(HDRS_LIST)
+
+LIBNAME = libmksh.a
+MSG_FILE = libmksh.msg
+I18N_DIRS = $(SRC)
+
+#CPPFLAGS += -DTEAMWARE_MAKE_CMN -DDISTRIBUTED
+
+include $(TOP)/Make/lib/Lib.mk
+include $(TOP)/rules/lib.mk
+
diff --git a/usr/src/make_src/Make/lib/mksh/src/dosys.cc b/usr/src/make_src/Make/lib/mksh/src/dosys.cc
new file mode 100644
index 0000000..fc4306b
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksh/src/dosys.cc
@@ -0,0 +1,851 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)dosys.cc 1.38 06/12/12
+ */
+
+#pragma ident "@(#)dosys.cc 1.38 06/12/12"
+
+/*
+ * dosys.cc
+ *
+ * Execute one commandline
+ */
+
+/*
+ * Included files
+ */
+#include <sys/wait.h> /* WIFEXITED(status) */
+#include <avo/avo_alloca.h> /* alloca() */
+
+#if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL) /* tolik */
+# include <avo/strings.h> /* AVO_STRDUP() */
+#if defined(DISTRIBUTED)
+# include <dm/Avo_CmdOutput.h>
+# include <rw/xdrstrea.h>
+#endif
+#endif
+
+#include <stdio.h> /* errno */
+#include <errno.h> /* errno */
+#include <fcntl.h> /* open() */
+#include <mksh/dosys.h>
+#include <mksh/macro.h> /* getvar() */
+#include <mksh/misc.h> /* getmem(), fatal_mksh(), errmsg() */
+#include <mksdmsi18n/mksdmsi18n.h> /* libmksdmsi18n_init() */
+#include <sys/signal.h> /* SIG_DFL */
+#include <sys/stat.h> /* open() */
+#include <sys/wait.h> /* wait() */
+#include <ulimit.h> /* ulimit() */
+#include <unistd.h> /* close(), dup2() */
+
+#if defined (HP_UX) || defined (linux)
+# include <sys/param.h>
+# include <wctype.h>
+# include <wchar.h>
+#endif
+
+#if defined (linux)
+# define wslen(x) wcslen(x)
+# define wscpy(x,y) wcscpy(x,y)
+#endif
+
+/*
+ * Defined macros
+ */
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+#define SEND_MTOOL_MSG(cmds) \
+ if (send_mtool_msgs) { \
+ cmds \
+ }
+#else
+#define SEND_MTOOL_MSG(cmds)
+#endif
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+
+/*
+ * File table of contents
+ */
+static Boolean exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error, pathpt vroot_path);
+
+/*
+ * Workaround for NFS bug. Sometimes, when running 'open' on a remote
+ * dmake server, it fails with "Stale NFS file handle" error.
+ * The second attempt seems to work.
+ */
+int
+my_open(const char *path, int oflag, mode_t mode) {
+ int res = open(path, oflag, mode);
+#ifdef linux
+// Workaround for NFS problem: even when all directories in 'path'
+// exist, 'open' (file creation) fails with ENOENT.
+ int nattempt = 0;
+ while (res < 0 && (errno == ESTALE || errno == EAGAIN || errno == ENOENT)) {
+ nattempt++;
+ if(nattempt > 30) {
+ break;
+ }
+ sleep(1);
+#else
+ if (res < 0 && (errno == ESTALE || errno == EAGAIN)) {
+#endif
+ /* Stale NFS file handle. Try again */
+ res = open(path, oflag, mode);
+ }
+ return res;
+}
+
+/*
+ * void
+ * redirect_io(char *stdout_file, char *stderr_file)
+ *
+ * Redirects stdout and stderr for a child mksh process.
+ */
+void
+redirect_io(char *stdout_file, char *stderr_file)
+{
+ long descriptor_limit;
+ int i;
+
+#if defined (HP_UX) || defined (linux)
+ /*
+ * HP-UX does not support the UL_GDESLIM command for ulimit().
+ * NOFILE == max num open files per process (from <sys/param.h>)
+ */
+ descriptor_limit = NOFILE;
+#else
+ if ((descriptor_limit = ulimit(UL_GDESLIM)) < 0) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 89, "ulimit() failed: %s"), errmsg(errno));
+ }
+#endif
+ for (i = 3; i < descriptor_limit; i++) {
+ (void) close(i);
+ }
+ if ((i = my_open(stdout_file,
+ O_WRONLY | O_CREAT | O_TRUNC | O_DSYNC,
+ S_IREAD | S_IWRITE)) < 0) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 90, "Couldn't open standard out temp file `%s': %s"),
+ stdout_file,
+ errmsg(errno));
+ } else {
+ if (dup2(i, 1) == -1) {
+ fatal_mksh(NOCATGETS("*** Error: dup2(3, 1) failed: %s"),
+ errmsg(errno));
+ }
+ close(i);
+ }
+ if (stderr_file == NULL) {
+ if (dup2(1, 2) == -1) {
+ fatal_mksh(NOCATGETS("*** Error: dup2(1, 2) failed: %s"),
+ errmsg(errno));
+ }
+ } else if ((i = my_open(stderr_file,
+ O_WRONLY | O_CREAT | O_TRUNC | O_DSYNC,
+ S_IREAD | S_IWRITE)) < 0) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 91, "Couldn't open standard error temp file `%s': %s"),
+ stderr_file,
+ errmsg(errno));
+ } else {
+ if (dup2(i, 2) == -1) {
+ fatal_mksh(NOCATGETS("*** Error: dup2(3, 2) failed: %s"),
+ errmsg(errno));
+ }
+ close(i);
+ }
+}
+
+/*
+ * dosys_mksh(command, ignore_error, call_make, silent_error, target)
+ *
+ * Check if command string contains meta chars and dispatch to
+ * the proper routine for executing one command line.
+ *
+ * Return value:
+ * Indicates if the command execution failed
+ *
+ * Parameters:
+ * command The command to run
+ * ignore_error Should we abort when an error is seen?
+ * call_make Did command reference $(MAKE) ?
+ * silent_error Should error messages be suppressed for dmake?
+ * target Target we are building
+ *
+ * Global variables used:
+ * do_not_exec_rule Is -n on?
+ * working_on_targets We started processing real targets
+ */
+Doname
+dosys_mksh(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target, Boolean redirect_out_err, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio)
+{
+ register int length = command->hash.length;
+ register wchar_t *p;
+ register wchar_t *q;
+ register wchar_t *cmd_string;
+ struct stat before;
+ Doname result;
+ Boolean working_on_targets_mksh = true;
+ Wstring wcb(command);
+ p = wcb.get_string();
+ cmd_string = p;
+
+ /* Strip spaces from head of command string */
+ while (iswspace(*p)) {
+ p++, length--;
+ }
+ if (*p == (int) nul_char) {
+ return build_failed;
+ }
+ /* If we are faking it we just return */
+ if (do_not_exec_rule &&
+ working_on_targets_mksh &&
+ !call_make &&
+ !always_exec) {
+ return build_ok;
+ }
+
+ /* Copy string to make it OK to write it. */
+ q = ALLOC_WC(length + 1);
+ (void) wscpy(q, p);
+ /* Write the state file iff this command uses make. */
+/* XXX - currently does not support recursive make's, $(MAKE)'s
+ if (call_make && command_changed) {
+ write_state_file(0, false);
+ }
+ (void) stat(make_state->string_mb, &before);
+ */
+ /*
+ * Run command directly if it contains no shell meta chars,
+ * else run it using the shell.
+ */
+ /* XXX - command->meta *may* not be set correctly */
+ if (await(ignore_error,
+ silent_error,
+ target,
+ cmd_string,
+ command->meta ?
+ doshell(q, ignore_error, redirect_out_err, stdout_file, stderr_file, nice_prio) :
+ doexec(q, ignore_error, redirect_out_err, stdout_file, stderr_file, vroot_path, nice_prio),
+ false,
+ NULL,
+ -1)) {
+
+#ifdef PRINT_EXIT_STATUS
+ warning_mksh(NOCATGETS("I'm in dosys_mksh(), and await() returned result of build_ok."));
+#endif
+
+ result = build_ok;
+ } else {
+
+#ifdef PRINT_EXIT_STATUS
+ warning_mksh(NOCATGETS("I'm in dosys_mksh(), and await() returned result of build_failed."));
+#endif
+
+ result = build_failed;
+ }
+ retmem(q);
+
+/* XXX - currently does not support recursive make's, $(MAKE)'s
+ if ((report_dependencies_level == 0) &&
+ call_make) {
+ make_state->stat.time = (time_t)file_no_time;
+ (void)exists(make_state);
+ if (before.st_mtime == make_state->stat.time) {
+ return result;
+ }
+ makefile_type = reading_statefile;
+ if (read_trace_level > 1) {
+ trace_reader = true;
+ }
+ (void) read_simple_file(make_state,
+ false,
+ false,
+ false,
+ false,
+ false,
+ true);
+ trace_reader = false;
+ }
+ */
+ return result;
+}
+
+/*
+ * doshell(command, ignore_error)
+ *
+ * Used to run command lines that include shell meta-characters.
+ * The make macro SHELL is supposed to contain a path to the shell.
+ *
+ * Return value:
+ * The pid of the process we started
+ *
+ * Parameters:
+ * command The command to run
+ * ignore_error Should we abort on error?
+ *
+ * Global variables used:
+ * filter_stderr If -X is on we redirect stderr
+ * shell_name The Name "SHELL", used to get the path to shell
+ */
+int
+doshell(wchar_t *command, register Boolean ignore_error, Boolean redirect_out_err, char *stdout_file, char *stderr_file, int nice_prio)
+{
+ char *argv[6];
+ int argv_index = 0;
+ int cmd_argv_index;
+ int length;
+ char nice_prio_buf[MAXPATHLEN];
+ register Name shell = getvar(shell_name);
+ register char *shellname;
+ char *tmp_mbs_buffer;
+
+
+ if (IS_EQUAL(shell->string_mb, "")) {
+ shell = shell_name;
+ }
+ if ((shellname = strrchr(shell->string_mb, (int) slash_char)) == NULL) {
+ shellname = shell->string_mb;
+ } else {
+ shellname++;
+ }
+
+ /*
+ * Only prepend the /usr/bin/nice command to the original command
+ * if the nice priority, nice_prio, is NOT zero (0).
+ * Nice priorities can be a positive or a negative number.
+ */
+ if (nice_prio != 0) {
+ argv[argv_index++] = NOCATGETS("nice");
+ (void) sprintf(nice_prio_buf, NOCATGETS("-%d"), nice_prio);
+ argv[argv_index++] = strdup(nice_prio_buf);
+ }
+ argv[argv_index++] = shellname;
+#if defined(linux)
+ if(0 == strcmp(shell->string_mb, (char*)NOCATGETS("/bin/sh"))) {
+ argv[argv_index++] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce"));
+ } else {
+ argv[argv_index++] = (char*)NOCATGETS("-c");
+ }
+#else
+ argv[argv_index++] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce"));
+#endif
+ if ((length = wslen(command)) >= MAXPATHLEN) {
+ tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
+ (void) wcstombs(tmp_mbs_buffer, command, (length * MB_LEN_MAX) + 1);
+ cmd_argv_index = argv_index;
+ argv[argv_index++] = strdup(tmp_mbs_buffer);
+ retmem_mb(tmp_mbs_buffer);
+ } else {
+ WCSTOMBS(mbs_buffer, command);
+ cmd_argv_index = argv_index;
+#if defined(linux)
+ int mbl = strlen(mbs_buffer);
+ if(mbl > 2) {
+ if(mbs_buffer[mbl-1] == '\n' && mbs_buffer[mbl-2] == '\\') {
+ mbs_buffer[mbl] = '\n';
+ mbs_buffer[mbl+1] = 0;
+ }
+ }
+#endif
+ argv[argv_index++] = strdup(mbs_buffer);
+ }
+ argv[argv_index] = NULL;
+ (void) fflush(stdout);
+ if ((childPid = fork()) == 0) {
+ enable_interrupt((void (*) (int)) SIG_DFL);
+ if (redirect_out_err) {
+ redirect_io(stdout_file, stderr_file);
+ }
+#if 0
+ if (filter_stderr) {
+ redirect_stderr();
+ }
+#endif
+ if (nice_prio != 0) {
+ (void) execve(NOCATGETS("/usr/bin/nice"), argv, environ);
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 92, "Could not load `/usr/bin/nice': %s"),
+ errmsg(errno));
+ } else {
+ (void) execve(shell->string_mb, argv, environ);
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 93, "Could not load Shell from `%s': %s"),
+ shell->string_mb,
+ errmsg(errno));
+ }
+ }
+ if (childPid == -1) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 94, "fork failed: %s"),
+ errmsg(errno));
+ }
+ retmem_mb(argv[cmd_argv_index]);
+ return childPid;
+}
+
+/*
+ * exec_vp(name, argv, envp, ignore_error)
+ *
+ * Like execve, but does path search.
+ * This starts command when make invokes it directly (without a shell).
+ *
+ * Return value:
+ * Returns false if the exec failed
+ *
+ * Parameters:
+ * name The name of the command to run
+ * argv Arguments for the command
+ * envp The environment for it
+ * ignore_error Should we abort on error?
+ *
+ * Global variables used:
+ * shell_name The Name "SHELL", used to get the path to shell
+ * vroot_path The path used by the vroot package
+ */
+static Boolean
+exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error, pathpt vroot_path)
+{
+ register Name shell = getvar(shell_name);
+ register char *shellname;
+ char *shargv[4];
+ Name tmp_shell;
+
+ if (IS_EQUAL(shell->string_mb, "")) {
+ shell = shell_name;
+ }
+
+ for (int i = 0; i < 5; i++) {
+ (void) execve_vroot(name,
+ argv + 1,
+ envp,
+ vroot_path,
+ VROOT_DEFAULT);
+ switch (errno) {
+ case ENOEXEC:
+ case ENOENT:
+ /* That failed. Let the shell handle it */
+ shellname = strrchr(shell->string_mb, (int) slash_char);
+ if (shellname == NULL) {
+ shellname = shell->string_mb;
+ } else {
+ shellname++;
+ }
+ shargv[0] = shellname;
+ shargv[1] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce"));
+ shargv[2] = argv[0];
+ shargv[3] = NULL;
+ tmp_shell = getvar(shell_name);
+ if (IS_EQUAL(tmp_shell->string_mb, "")) {
+ tmp_shell = shell_name;
+ }
+ (void) execve_vroot(tmp_shell->string_mb,
+ shargv,
+ envp,
+ vroot_path,
+ VROOT_DEFAULT);
+ return failed;
+ case ETXTBSY:
+ /*
+ * The program is busy (debugged?).
+ * Wait and then try again.
+ */
+ (void) sleep((unsigned) i);
+ case EAGAIN:
+ break;
+ default:
+ return failed;
+ }
+ }
+ return failed;
+}
+
+/*
+ * doexec(command, ignore_error)
+ *
+ * Will scan an argument string and split it into words
+ * thus building an argument list that can be passed to exec_ve()
+ *
+ * Return value:
+ * The pid of the process started here
+ *
+ * Parameters:
+ * command The command to run
+ * ignore_error Should we abort on error?
+ *
+ * Global variables used:
+ * filter_stderr If -X is on we redirect stderr
+ */
+int
+doexec(register wchar_t *command, register Boolean ignore_error, Boolean redirect_out_err, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio)
+{
+ int arg_count = 5;
+ char **argv;
+ int length;
+ char nice_prio_buf[MAXPATHLEN];
+ register char **p;
+ wchar_t *q;
+ register wchar_t *t;
+ char *tmp_mbs_buffer;
+
+ /*
+ * Only prepend the /usr/bin/nice command to the original command
+ * if the nice priority, nice_prio, is NOT zero (0).
+ * Nice priorities can be a positive or a negative number.
+ */
+ if (nice_prio != 0) {
+ arg_count += 2;
+ }
+ for (t = command; *t != (int) nul_char; t++) {
+ if (iswspace(*t)) {
+ arg_count++;
+ }
+ }
+ argv = (char **)alloca(arg_count * (sizeof(char *)));
+ /*
+ * Reserve argv[0] for sh in case of exec_vp failure.
+ * Don't worry about prepending /usr/bin/nice command to argv[0].
+ * In fact, doing it may cause the sh command to fail!
+ */
+ p = &argv[1];
+ if ((length = wslen(command)) >= MAXPATHLEN) {
+ tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
+ (void) wcstombs(tmp_mbs_buffer, command, (length * MB_LEN_MAX) + 1);
+ argv[0] = strdup(tmp_mbs_buffer);
+ retmem_mb(tmp_mbs_buffer);
+ } else {
+ WCSTOMBS(mbs_buffer, command);
+ argv[0] = strdup(mbs_buffer);
+ }
+
+ if (nice_prio != 0) {
+ *p++ = strdup(NOCATGETS("/usr/bin/nice"));
+ (void) sprintf(nice_prio_buf, NOCATGETS("-%d"), nice_prio);
+ *p++ = strdup(nice_prio_buf);
+ }
+ /* Build list of argument words. */
+ for (t = command; *t;) {
+ if (p >= &argv[arg_count]) {
+ /* This should never happen, right? */
+ WCSTOMBS(mbs_buffer, command);
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 95, "Command `%s' has more than %d arguments"),
+ mbs_buffer,
+ arg_count);
+ }
+ q = t;
+ while (!iswspace(*t) && (*t != (int) nul_char)) {
+ t++;
+ }
+ if (*t) {
+ for (*t++ = (int) nul_char; iswspace(*t); t++);
+ }
+ if ((length = wslen(q)) >= MAXPATHLEN) {
+ tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
+ (void) wcstombs(tmp_mbs_buffer, q, (length * MB_LEN_MAX) + 1);
+ *p++ = strdup(tmp_mbs_buffer);
+ retmem_mb(tmp_mbs_buffer);
+ } else {
+ WCSTOMBS(mbs_buffer, q);
+ *p++ = strdup(mbs_buffer);
+ }
+ }
+ *p = NULL;
+
+ /* Then exec the command with that argument list. */
+ (void) fflush(stdout);
+ if ((childPid = fork()) == 0) {
+ enable_interrupt((void (*) (int)) SIG_DFL);
+ if (redirect_out_err) {
+ redirect_io(stdout_file, stderr_file);
+ }
+#if 0
+ if (filter_stderr) {
+ redirect_stderr();
+ }
+#endif
+ (void) exec_vp(argv[1], argv, environ, ignore_error, vroot_path);
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 96, "Cannot load command `%s': %s"), argv[1], errmsg(errno));
+ }
+ if (childPid == -1) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 97, "fork failed: %s"),
+ errmsg(errno));
+ }
+ for (int i = 0; argv[i] != NULL; i++) {
+ retmem_mb(argv[i]);
+ }
+ return childPid;
+}
+
+/*
+ * await(ignore_error, silent_error, target, command, running_pid)
+ *
+ * Wait for one child process and analyzes
+ * the returned status when the child process terminates.
+ *
+ * Return value:
+ * Returns true if commands ran OK
+ *
+ * Parameters:
+ * ignore_error Should we abort on error?
+ * silent_error Should error messages be suppressed for dmake?
+ * target The target we are building, for error msgs
+ * command The command we ran, for error msgs
+ * running_pid The pid of the process we are waiting for
+ *
+ * Static variables used:
+ * filter_file The fd for the filter file
+ * filter_file_name The name of the filter file
+ *
+ * Global variables used:
+ * filter_stderr Set if -X is on
+ */
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+Boolean
+await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, Boolean send_mtool_msgs, XDR *xdrs_p, int job_msg_id)
+#else
+Boolean
+await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, Boolean send_mtool_msgs, void *xdrs_p, int job_msg_id)
+#endif
+{
+#ifdef SUN5_0
+ int status;
+#else
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat) stat.w_T.w_Retcode
+#endif
+#ifndef WTERMSIG
+#define WTERMSIG(stat) stat.w_T.w_Termsig
+#endif
+#ifndef WCOREDUMP
+#define WCOREDUMP(stat) stat.w_T.w_Coredump
+#endif
+#if defined (HP_UX) || defined (linux)
+ int status;
+#else
+ union wait status;
+#endif
+#endif
+ char *buffer;
+ int core_dumped;
+ int exit_status;
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+ Avo_CmdOutput *make_output_msg;
+#endif
+ FILE *outfp;
+ register pid_t pid;
+ struct stat stat_buff;
+ int termination_signal;
+ char tmp_buf[MAXPATHLEN];
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+ RWCollectable *xdr_msg;
+#endif
+
+ while ((pid = wait(&status)) != running_pid) {
+ if (pid == -1) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 98, "wait() failed: %s"), errmsg(errno));
+ }
+ }
+ (void) fflush(stdout);
+ (void) fflush(stderr);
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ if (status == 0) {
+
+#ifdef PRINT_EXIT_STATUS
+ warning_mksh(NOCATGETS("I'm in await(), and status is 0."));
+#endif
+
+ return succeeded;
+ }
+
+#ifdef PRINT_EXIT_STATUS
+ warning_mksh(NOCATGETS("I'm in await(), and status is *NOT* 0."));
+#endif
+
+#else
+ if (status.w_status == 0) {
+ return succeeded;
+ }
+#endif
+
+ exit_status = WEXITSTATUS(status);
+
+#ifdef PRINT_EXIT_STATUS
+ warning_mksh(NOCATGETS("I'm in await(), and exit_status is %d."), exit_status);
+#endif
+
+ termination_signal = WTERMSIG(status);
+ core_dumped = WCOREDUMP(status);
+
+ /*
+ * If the child returned an error, we now try to print a
+ * nice message about it.
+ */
+ SEND_MTOOL_MSG(
+ make_output_msg = new Avo_CmdOutput();
+ (void) sprintf(tmp_buf, "%d", job_msg_id);
+ make_output_msg->appendOutput(AVO_STRDUP(tmp_buf));
+ );
+
+ tmp_buf[0] = (int) nul_char;
+ if (!silent_error) {
+ if (exit_status != 0) {
+ (void) fprintf(stdout,
+ catgets(libmksdmsi18n_catd, 1, 103, "*** Error code %d"),
+ exit_status);
+ SEND_MTOOL_MSG(
+ (void) sprintf(&tmp_buf[strlen(tmp_buf)],
+ catgets(libmksdmsi18n_catd, 1, 104, "*** Error code %d"),
+ exit_status);
+ );
+ } else {
+#if ! defined(SUN5_0) && ! defined(HP_UX) && ! defined(linux)
+ if (termination_signal > NSIG) {
+#endif
+ (void) fprintf(stdout,
+ catgets(libmksdmsi18n_catd, 1, 105, "*** Signal %d"),
+ termination_signal);
+ SEND_MTOOL_MSG(
+ (void) sprintf(&tmp_buf[strlen(tmp_buf)],
+ catgets(libmksdmsi18n_catd, 1, 106, "*** Signal %d"),
+ termination_signal);
+ );
+#if ! defined(SUN5_0) && ! defined(HP_UX) && ! defined(linux)
+ } else {
+ (void) fprintf(stdout,
+ "*** %s",
+ sys_siglist[termination_signal]);
+ SEND_MTOOL_MSG(
+ (void) sprintf(&tmp_buf[strlen(tmp_buf)],
+ "*** %s",
+ sys_siglist[termination_signal]);
+ );
+ }
+#endif
+ if (core_dumped) {
+ (void) fprintf(stdout,
+ catgets(libmksdmsi18n_catd, 1, 107, " - core dumped"));
+ SEND_MTOOL_MSG(
+ (void) sprintf(&tmp_buf[strlen(tmp_buf)],
+ catgets(libmksdmsi18n_catd, 1, 108, " - core dumped"));
+ );
+ }
+ }
+ if (ignore_error) {
+ (void) fprintf(stdout,
+ catgets(libmksdmsi18n_catd, 1, 109, " (ignored)"));
+ SEND_MTOOL_MSG(
+ (void) sprintf(&tmp_buf[strlen(tmp_buf)],
+ catgets(libmksdmsi18n_catd, 1, 110, " (ignored)"));
+ );
+ }
+ (void) fprintf(stdout, "\n");
+ (void) fflush(stdout);
+ SEND_MTOOL_MSG(
+ make_output_msg->appendOutput(AVO_STRDUP(tmp_buf));
+ );
+ }
+ SEND_MTOOL_MSG(
+ xdr_msg = (RWCollectable*) make_output_msg;
+ xdr(xdrs_p, xdr_msg);
+ delete make_output_msg;
+ );
+
+#ifdef PRINT_EXIT_STATUS
+ warning_mksh(NOCATGETS("I'm in await(), returning failed."));
+#endif
+
+ return failed;
+}
+
+/*
+ * sh_command2string(command, destination)
+ *
+ * Run one sh command and capture the output from it.
+ *
+ * Return value:
+ *
+ * Parameters:
+ * command The command to run
+ * destination Where to deposit the output from the command
+ *
+ * Static variables used:
+ *
+ * Global variables used:
+ */
+void
+sh_command2string(register String command, register String destination)
+{
+ register FILE *fd;
+ register int chr;
+ int status;
+ Boolean command_generated_output = false;
+
+ command->text.p = (int) nul_char;
+ WCSTOMBS(mbs_buffer, command->buffer.start);
+ if ((fd = popen(mbs_buffer, "r")) == NULL) {
+ WCSTOMBS(mbs_buffer, command->buffer.start);
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 111, "Could not run command `%s' for :sh transformation"),
+ mbs_buffer);
+ }
+ while ((chr = getc(fd)) != EOF) {
+ if (chr == (int) newline_char) {
+ chr = (int) space_char;
+ }
+ command_generated_output = true;
+ append_char(chr, destination);
+ }
+
+ /*
+ * We don't want to keep the last LINE_FEED since usually
+ * the output of the 'sh:' command is used to evaluate
+ * some MACRO. ( /bin/sh and other shell add a line feed
+ * to the output so that the prompt appear in the right place.
+ * We don't need that
+ */
+ if (command_generated_output){
+ if ( *(destination->text.p-1) == (int) space_char) {
+ * (-- destination->text.p) = '\0';
+ }
+ } else {
+ /*
+ * If the command didn't generate any output,
+ * set the buffer to a null string.
+ */
+ *(destination->text.p) = '\0';
+ }
+
+ status = pclose(fd);
+ if (status != 0) {
+ WCSTOMBS(mbs_buffer, command->buffer.start);
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 112, "The command `%s' returned status `%d'"),
+ mbs_buffer,
+ WEXITSTATUS(status));
+ }
+}
+
+
diff --git a/usr/src/make_src/Make/lib/mksh/src/globals.cc b/usr/src/make_src/Make/lib/mksh/src/globals.cc
new file mode 100644
index 0000000..2d36d24
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksh/src/globals.cc
@@ -0,0 +1,140 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)globals.cc 1.16 06/12/12
+ */
+
+#pragma ident "@(#)globals.cc 1.16 06/12/12"
+
+/*
+ * globals.cc
+ *
+ * This declares all global variables
+ */
+
+/*
+ * Included files
+ */
+#include <mksh/globals.h>
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Global variables
+ */
+char char_semantics[CHAR_SEMANTICS_ENTRIES];
+wchar_t char_semantics_char[] = {
+ ampersand_char,
+ asterisk_char,
+ at_char,
+ backquote_char,
+ backslash_char,
+ bar_char,
+ bracketleft_char,
+ bracketright_char,
+ colon_char,
+ dollar_char,
+ doublequote_char,
+ equal_char,
+ exclam_char,
+ greater_char,
+ hat_char,
+ hyphen_char,
+ less_char,
+ newline_char,
+ numbersign_char,
+ parenleft_char,
+ parenright_char,
+ percent_char,
+ plus_char,
+ question_char,
+ quote_char,
+ semicolon_char,
+#ifdef SGE_SUPPORT
+ space_char,
+ tab_char,
+#endif
+ nul_char
+};
+Macro_list cond_macro_list;
+Boolean conditional_macro_used;
+Boolean do_not_exec_rule; /* `-n' */
+Boolean dollarget_seen;
+Boolean dollarless_flag;
+Name dollarless_value;
+Envvar envvar;
+#ifdef lint
+char **environ;
+#endif
+#ifdef SUN5_0
+int exit_status;
+#endif
+wchar_t *file_being_read;
+/* Variable gnu_style=true if env. var. SUN_MAKE_COMPAT_MODE=GNU (RFE 4866328) */
+Boolean gnu_style = false;
+Name_set hashtab;
+Name host_arch;
+Name host_mach;
+int line_number;
+char *make_state_lockfile;
+Boolean make_word_mentioned;
+Makefile_type makefile_type = reading_nothing;
+char mbs_buffer[(MAXPATHLEN * MB_LEN_MAX)];
+Name path_name;
+Boolean posix = true;
+Name hat;
+Name query;
+Boolean query_mentioned;
+Boolean reading_environment;
+Name shell_name;
+Boolean svr4 = false;
+Name target_arch;
+Name target_mach;
+Boolean tilde_rule;
+Name virtual_root;
+Boolean vpath_defined;
+Name vpath_name;
+wchar_t wcs_buffer[MAXPATHLEN];
+Boolean working_on_targets;
+#if defined (TEAMWARE_MAKE_CMN) && defined(REDIRECT_ERR)
+Boolean out_err_same;
+#endif
+pid_t childPid = -1; // This variable is used for killing child's process
+ // Such as qrsh, running command, etc.
+
+/*
+ * timestamps defined in defs.h
+ */
+const timestruc_t file_no_time = { -1, 0 };
+const timestruc_t file_doesnt_exist = { 0, 0 };
+const timestruc_t file_is_dir = { 1, 0 };
+const timestruc_t file_min_time = { 2, 0 };
+const timestruc_t file_max_time = { INT_MAX, 0 };
diff --git a/usr/src/make_src/Make/lib/mksh/src/i18n.cc b/usr/src/make_src/Make/lib/mksh/src/i18n.cc
new file mode 100644
index 0000000..f12341e
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksh/src/i18n.cc
@@ -0,0 +1,100 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)i18n.cc 1.3 06/12/12
+ */
+
+#pragma ident "@(#)i18n.cc 1.3 06/12/12"
+
+/*
+ * i18n.cc
+ *
+ * Deal with internationalization conversions
+ */
+
+/*
+ * Included files
+ */
+#include <mksh/i18n.h>
+#include <mksh/misc.h> /* setup_char_semantics() */
+#if defined (linux)
+# include <wctype.h>
+# include <wchar.h>
+# define wschr(x,y) wcschr(x,y)
+#endif
+
+/*
+ * get_char_semantics_value(ch)
+ *
+ * Return value:
+ * The character semantics of ch.
+ *
+ * Parameters:
+ * ch character we want semantics for.
+ *
+ */
+char
+get_char_semantics_value(wchar_t ch)
+{
+ static Boolean char_semantics_setup;
+
+ if (!char_semantics_setup) {
+ setup_char_semantics();
+ char_semantics_setup = true;
+ }
+ return char_semantics[get_char_semantics_entry(ch)];
+}
+
+/*
+ * get_char_semantics_entry(ch)
+ *
+ * Return value:
+ * The slot number in the array for special make chars,
+ * else the slot number of the last array entry.
+ *
+ * Parameters:
+ * ch The wide character
+ *
+ * Global variables used:
+ * char_semantics_char[] array of special wchar_t chars
+ * "&*@`\\|[]:$=!>-\n#()%?;^<'\""
+ */
+int
+get_char_semantics_entry(wchar_t ch)
+{
+ wchar_t *char_sem_char;
+
+ char_sem_char = (wchar_t *) wschr(char_semantics_char, ch);
+ if (char_sem_char == NULL) {
+ /*
+ * Return the integer entry for the last slot,
+ * whose content is empty.
+ */
+ return (CHAR_SEMANTICS_ENTRIES - 1);
+ } else {
+ return (char_sem_char - char_semantics_char);
+ }
+}
+
diff --git a/usr/src/make_src/Make/lib/mksh/src/libmksh.msg b/usr/src/make_src/Make/lib/mksh/src/libmksh.msg
new file mode 100644
index 0000000..d1994aa
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksh/src/libmksh.msg
@@ -0,0 +1,81 @@
+
+$quote "
+
+
+$set 1
+$
+$ CDDL HEADER START
+$
+$ The contents of this file are subject to the terms of the
+$ Common Development and Distribution License (the "License").
+$ You may not use this file except in compliance with the License.
+$
+$ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+$ or http://www.opensolaris.org/os/licensing.
+$ See the License for the specific language governing permissions
+$ and limitations under the License.
+$
+$ When distributing Covered Code, include this CDDL HEADER in each
+$ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+$ If applicable, add the following below this CDDL HEADER, with the
+$ fields enclosed by brackets "[]" replaced with your own identifying
+$ information: Portions Copyright [yyyy] [name of copyright owner]
+$
+$ CDDL HEADER END
+$
+$ Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+$ Use is subject to license terms.
+$
+$ @(#)libmksh.msg 1.2 06/12/12
+$
+89 "ulimit() failed: %s"
+90 "Couldn't open standard out temp file `%s': %s"
+91 "Couldn't open standard error temp file `%s': %s"
+92 "Could not load `/usr/bin/nice': %s"
+93 "Could not load Shell from `%s': %s"
+94 "fork failed: %s"
+95 "Command `%s' has more than %d arguments"
+96 "Cannot load command `%s': %s"
+97 "fork failed: %s"
+98 "wait() failed: %s"
+99 "Could not open filter file for -X"
+100 "Could not stat filter file for -X"
+101 "\n**** Error: Directory %s Target %s:\n%s\n"
+102 "**** Error: Directory %s Target %s\n"
+103 "*** Error code %d"
+104 "*** Error code %d"
+105 "*** Signal %d"
+106 "*** Signal %d"
+107 " - core dumped"
+108 " - core dumped"
+109 " (ignored)"
+110 " (ignored)"
+111 "Could not run command `%s' for :sh transformation"
+112 "The command `%s' returned status `%d'"
+113 "Loop detected when expanding macro value `%s'"
+114 "'$' at end of string `%s'"
+115 "'$' at end of line"
+116 "Unmatched `%c' in string `%s'"
+117 "Premature EOF"
+118 "Unmatched `%c' on line"
+119 "Illegal macro reference `%s'"
+120 "= missing from replacement macro reference"
+121 "= missing from replacement macro reference"
+122 "%% missing from replacement macro reference"
+123 "%% missing from replacement macro reference"
+124 "Too many %% in pattern"
+125 "Conditional macro `%s' referenced on line %d"
+126 "Out of memory"
+127 "Error %d"
+128 "mksh: Fatal error: "
+129 "Current working directory %s\n"
+131 "mksh: Fatal error in reader: "
+133 "Current working directory %s\n"
+134 "mksh: Warning: "
+135 "Current working directory %s\n"
+136 "Internal error. Unknown prop type %d"
+137 "`cd %s' failed, and conversion of %s to automounter pathname also failed"
+138 "`cd %s' and `cd %s' both failed"
+139 "The following command caused the error:\n%s\n"
+140 "Error reading `%s': Premature EOF"
+141 "Error reading `%s': %s"
diff --git a/usr/src/make_src/Make/lib/mksh/src/macro.cc b/usr/src/make_src/Make/lib/mksh/src/macro.cc
new file mode 100644
index 0000000..43d7603
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksh/src/macro.cc
@@ -0,0 +1,1414 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)macro.cc 1.22 06/12/12
+ */
+
+#pragma ident "@(#)macro.cc 1.22 06/12/12"
+
+/*
+ * macro.cc
+ *
+ * Handle expansion of make macros
+ */
+
+/*
+ * Included files
+ */
+#include <mksh/dosys.h> /* sh_command2string() */
+#include <mksh/i18n.h> /* get_char_semantics_value() */
+#include <mksh/macro.h>
+#include <mksh/misc.h> /* retmem() */
+#include <mksh/read.h> /* get_next_block_fn() */
+#include <mksdmsi18n/mksdmsi18n.h> /* libmksdmsi18n_init() */
+
+/*
+ * File table of contents
+ */
+static void add_macro_to_global_list(Name macro_to_add);
+#ifdef NSE
+static void expand_value_with_daemon(Name name, register Property macro, register String destination, Boolean cmd);
+#else
+static void expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd);
+#endif
+
+static void init_arch_macros(void);
+static void init_mach_macros(void);
+static Boolean init_arch_done = false;
+static Boolean init_mach_done = false;
+
+
+long env_alloc_num = 0;
+long env_alloc_bytes = 0;
+
+/*
+ * getvar(name)
+ *
+ * Return expanded value of macro.
+ *
+ * Return value:
+ * The expanded value of the macro
+ *
+ * Parameters:
+ * name The name of the macro we want the value for
+ *
+ * Global variables used:
+ */
+Name
+getvar(register Name name)
+{
+ String_rec destination;
+ wchar_t buffer[STRING_BUFFER_LENGTH];
+ register Name result;
+
+ if ((name == host_arch) || (name == target_arch)) {
+ if (!init_arch_done) {
+ init_arch_done = true;
+ init_arch_macros();
+ }
+ }
+ if ((name == host_mach) || (name == target_mach)) {
+ if (!init_mach_done) {
+ init_mach_done = true;
+ init_mach_macros();
+ }
+ }
+
+ INIT_STRING_FROM_STACK(destination, buffer);
+ expand_value(maybe_append_prop(name, macro_prop)->body.macro.value,
+ &destination,
+ false);
+ result = GETNAME(destination.buffer.start, FIND_LENGTH);
+ if (destination.free_after_use) {
+ retmem(destination.buffer.start);
+ }
+ return result;
+}
+
+/*
+ * expand_value(value, destination, cmd)
+ *
+ * Recursively expands all macros in the string value.
+ * destination is where the expanded value should be appended.
+ *
+ * Parameters:
+ * value The value we are expanding
+ * destination Where to deposit the expansion
+ * cmd If we are evaluating a command line we
+ * turn \ quoting off
+ *
+ * Global variables used:
+ */
+void
+expand_value(Name value, register String destination, Boolean cmd)
+{
+ Source_rec sourceb;
+ register Source source = &sourceb;
+ register wchar_t *source_p = NULL;
+ register wchar_t *source_end = NULL;
+ wchar_t *block_start = NULL;
+ int quote_seen = 0;
+
+ if (value == NULL) {
+ /*
+ * Make sure to get a string allocated even if it
+ * will be empty.
+ */
+ MBSTOWCS(wcs_buffer, "");
+ append_string(wcs_buffer, destination, FIND_LENGTH);
+ destination->text.end = destination->text.p;
+ return;
+ }
+ if (!value->dollar) {
+ /*
+ * If the value we are expanding does not contain
+ * any $, we don't have to parse it.
+ */
+ APPEND_NAME(value,
+ destination,
+ (int) value->hash.length
+ );
+ destination->text.end = destination->text.p;
+ return;
+ }
+
+ if (value->being_expanded) {
+ fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 113, "Loop detected when expanding macro value `%s'"),
+ value->string_mb);
+ }
+ value->being_expanded = true;
+ /* Setup the structure we read from */
+ Wstring vals(value);
+ sourceb.string.text.p = sourceb.string.buffer.start = wsdup(vals.get_string());
+ sourceb.string.free_after_use = true;
+ sourceb.string.text.end =
+ sourceb.string.buffer.end =
+ sourceb.string.text.p + value->hash.length;
+ sourceb.previous = NULL;
+ sourceb.fd = -1;
+ sourceb.inp_buf =
+ sourceb.inp_buf_ptr =
+ sourceb.inp_buf_end = NULL;
+ sourceb.error_converting = false;
+ /* Lift some pointers from the struct to local register variables */
+ CACHE_SOURCE(0);
+/* We parse the string in segments */
+/* We read chars until we find a $, then we append what we have read so far */
+/* (since last $ processing) to the destination. When we find a $ we call */
+/* expand_macro() and let it expand that particular $ reference into dest */
+ block_start = source_p;
+ quote_seen = 0;
+ for (; 1; source_p++) {
+ switch (GET_CHAR()) {
+ case backslash_char:
+ /* Quote $ in macro value */
+ if (!cmd) {
+ quote_seen = ~quote_seen;
+ }
+ continue;
+ case dollar_char:
+ /* Save the plain string we found since */
+ /* start of string or previous $ */
+ if (quote_seen) {
+ append_string(block_start,
+ destination,
+ source_p - block_start - 1);
+ block_start = source_p;
+ break;
+ }
+ append_string(block_start,
+ destination,
+ source_p - block_start);
+ source->string.text.p = ++source_p;
+ UNCACHE_SOURCE();
+ /* Go expand the macro reference */
+ expand_macro(source, destination, sourceb.string.buffer.start, cmd);
+ CACHE_SOURCE(1);
+ block_start = source_p + 1;
+ break;
+ case nul_char:
+ /* The string ran out. Get some more */
+ append_string(block_start,
+ destination,
+ source_p - block_start);
+ GET_NEXT_BLOCK_NOCHK(source);
+ if (source == NULL) {
+ destination->text.end = destination->text.p;
+ value->being_expanded = false;
+ return;
+ }
+ if (source->error_converting) {
+ fatal_reader_mksh(NOCATGETS("Internal error: Invalid byte sequence in expand_value()"));
+ }
+ block_start = source_p;
+ source_p--;
+ continue;
+ }
+ quote_seen = 0;
+ }
+ retmem(sourceb.string.buffer.start);
+}
+
+/*
+ * expand_macro(source, destination, current_string, cmd)
+ *
+ * Should be called with source->string.text.p pointing to
+ * the first char after the $ that starts a macro reference.
+ * source->string.text.p is returned pointing to the first char after
+ * the macro name.
+ * It will read the macro name, expanding any macros in it,
+ * and get the value. The value is then expanded.
+ * destination is a String that is filled in with the expanded macro.
+ * It may be passed in referencing a buffer to expand the macro into.
+ * Note that most expansions are done on demand, e.g. right
+ * before the command is executed and not while the file is
+ * being parsed.
+ *
+ * Parameters:
+ * source The source block that references the string
+ * to expand
+ * destination Where to put the result
+ * current_string The string we are expanding, for error msg
+ * cmd If we are evaluating a command line we
+ * turn \ quoting off
+ *
+ * Global variables used:
+ * funny Vector of semantic tags for characters
+ * is_conditional Set if a conditional macro is refd
+ * make_word_mentioned Set if the word "MAKE" is mentioned
+ * makefile_type We deliver extra msg when reading makefiles
+ * query The Name "?", compared against
+ * query_mentioned Set if the word "?" is mentioned
+ */
+void
+expand_macro(register Source source, register String destination, wchar_t *current_string, Boolean cmd)
+{
+ static Name make = (Name)NULL;
+ static wchar_t colon_sh[4];
+ static wchar_t colon_shell[7];
+ String_rec string;
+ wchar_t buffer[STRING_BUFFER_LENGTH];
+ register wchar_t *source_p = source->string.text.p;
+ register wchar_t *source_end = source->string.text.end;
+ register int closer = 0;
+ wchar_t *block_start = (wchar_t *)NULL;
+ int quote_seen = 0;
+ register int closer_level = 1;
+ Name name = (Name)NULL;
+ wchar_t *colon = (wchar_t *)NULL;
+ wchar_t *percent = (wchar_t *)NULL;
+ wchar_t *eq = (wchar_t *) NULL;
+ Property macro = NULL;
+ wchar_t *p = (wchar_t*)NULL;
+ String_rec extracted;
+ wchar_t extracted_string[MAXPATHLEN];
+ wchar_t *left_head = NULL;
+ wchar_t *left_tail = NULL;
+ wchar_t *right_tail = NULL;
+ int left_head_len = 0;
+ int left_tail_len = 0;
+ int tmp_len = 0;
+ wchar_t *right_hand[128];
+ int i = 0;
+ enum {
+ no_extract,
+ dir_extract,
+ file_extract
+ } extraction = no_extract;
+ enum {
+ no_replace,
+ suffix_replace,
+ pattern_replace,
+ sh_replace
+ } replacement = no_replace;
+
+ if (make == NULL) {
+ MBSTOWCS(wcs_buffer, NOCATGETS("MAKE"));
+ make = GETNAME(wcs_buffer, FIND_LENGTH);
+
+ MBSTOWCS(colon_sh, NOCATGETS(":sh"));
+ MBSTOWCS(colon_shell, NOCATGETS(":shell"));
+ }
+
+ right_hand[0] = NULL;
+
+ /* First copy the (macro-expanded) macro name into string. */
+ INIT_STRING_FROM_STACK(string, buffer);
+recheck_first_char:
+ /* Check the first char of the macro name to figure out what to do. */
+ switch (GET_CHAR()) {
+ case nul_char:
+ GET_NEXT_BLOCK_NOCHK(source);
+ if (source == NULL) {
+ WCSTOMBS(mbs_buffer, current_string);
+ fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 114, "'$' at end of string `%s'"),
+ mbs_buffer);
+ }
+ if (source->error_converting) {
+ fatal_reader_mksh(NOCATGETS("Internal error: Invalid byte sequence in expand_macro()"));
+ }
+ goto recheck_first_char;
+ case parenleft_char:
+ /* Multi char name. */
+ closer = (int) parenright_char;
+ break;
+ case braceleft_char:
+ /* Multi char name. */
+ closer = (int) braceright_char;
+ break;
+ case newline_char:
+ fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 115, "'$' at end of line"));
+ default:
+ /* Single char macro name. Just suck it up */
+ append_char(*source_p, &string);
+ source->string.text.p = source_p + 1;
+ goto get_macro_value;
+ }
+
+ /* Handle multi-char macro names */
+ block_start = ++source_p;
+ quote_seen = 0;
+ for (; 1; source_p++) {
+ switch (GET_CHAR()) {
+ case nul_char:
+ append_string(block_start,
+ &string,
+ source_p - block_start);
+ GET_NEXT_BLOCK_NOCHK(source);
+ if (source == NULL) {
+ if (current_string != NULL) {
+ WCSTOMBS(mbs_buffer, current_string);
+ fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 116, "Unmatched `%c' in string `%s'"),
+ closer ==
+ (int) braceright_char ?
+ (int) braceleft_char :
+ (int) parenleft_char,
+ mbs_buffer);
+ } else {
+ fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 117, "Premature EOF"));
+ }
+ }
+ if (source->error_converting) {
+ fatal_reader_mksh(NOCATGETS("Internal error: Invalid byte sequence in expand_macro()"));
+ }
+ block_start = source_p;
+ source_p--;
+ continue;
+ case newline_char:
+ fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 118, "Unmatched `%c' on line"),
+ closer == (int) braceright_char ?
+ (int) braceleft_char :
+ (int) parenleft_char);
+ case backslash_char:
+ /* Quote dollar in macro value. */
+ if (!cmd) {
+ quote_seen = ~quote_seen;
+ }
+ continue;
+ case dollar_char:
+ /*
+ * Macro names may reference macros.
+ * This expands the value of such macros into the
+ * macro name string.
+ */
+ if (quote_seen) {
+ append_string(block_start,
+ &string,
+ source_p - block_start - 1);
+ block_start = source_p;
+ break;
+ }
+ append_string(block_start,
+ &string,
+ source_p - block_start);
+ source->string.text.p = ++source_p;
+ UNCACHE_SOURCE();
+ expand_macro(source, &string, current_string, cmd);
+ CACHE_SOURCE(0);
+ block_start = source_p;
+ source_p--;
+ break;
+ case parenleft_char:
+ /* Allow nested pairs of () in the macro name. */
+ if (closer == (int) parenright_char) {
+ closer_level++;
+ }
+ break;
+ case braceleft_char:
+ /* Allow nested pairs of {} in the macro name. */
+ if (closer == (int) braceright_char) {
+ closer_level++;
+ }
+ break;
+ case parenright_char:
+ case braceright_char:
+ /*
+ * End of the name. Save the string in the macro
+ * name string.
+ */
+ if ((*source_p == closer) && (--closer_level <= 0)) {
+ source->string.text.p = source_p + 1;
+ append_string(block_start,
+ &string,
+ source_p - block_start);
+ goto get_macro_value;
+ }
+ break;
+ }
+ quote_seen = 0;
+ }
+ /*
+ * We got the macro name. We now inspect it to see if it
+ * specifies any translations of the value.
+ */
+get_macro_value:
+ name = NULL;
+ /* First check if we have a $(@D) type translation. */
+ if ((get_char_semantics_value(string.buffer.start[0]) &
+ (int) special_macro_sem) &&
+ (string.text.p - string.buffer.start >= 2) &&
+ ((string.buffer.start[1] == 'D') ||
+ (string.buffer.start[1] == 'F'))) {
+ switch (string.buffer.start[1]) {
+ case 'D':
+ extraction = dir_extract;
+ break;
+ case 'F':
+ extraction = file_extract;
+ break;
+ default:
+ WCSTOMBS(mbs_buffer, string.buffer.start);
+ fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 119, "Illegal macro reference `%s'"),
+ mbs_buffer);
+ }
+ /* Internalize the macro name using the first char only. */
+ name = GETNAME(string.buffer.start, 1);
+ (void) wscpy(string.buffer.start, string.buffer.start + 2);
+ }
+ /* Check for other kinds of translations. */
+ if ((colon = (wchar_t *) wschr(string.buffer.start,
+ (int) colon_char)) != NULL) {
+ /*
+ * We have a $(FOO:.c=.o) type translation.
+ * Get the name of the macro proper.
+ */
+ if (name == NULL) {
+ name = GETNAME(string.buffer.start,
+ colon - string.buffer.start);
+ }
+ /* Pickup all the translations. */
+ if (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell)) {
+ replacement = sh_replace;
+ } else if ((svr4) ||
+ ((percent = (wchar_t *) wschr(colon + 1,
+ (int) percent_char)) == NULL)) {
+ while (colon != NULL) {
+ if ((eq = (wchar_t *) wschr(colon + 1,
+ (int) equal_char)) == NULL) {
+ fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 120, "= missing from replacement macro reference"));
+ }
+ left_tail_len = eq - colon - 1;
+ if(left_tail) {
+ retmem(left_tail);
+ }
+ left_tail = ALLOC_WC(left_tail_len + 1);
+ (void) wsncpy(left_tail,
+ colon + 1,
+ eq - colon - 1);
+ left_tail[eq - colon - 1] = (int) nul_char;
+ replacement = suffix_replace;
+ if ((colon = (wchar_t *) wschr(eq + 1,
+ (int) colon_char)) != NULL) {
+ tmp_len = colon - eq;
+ if(right_tail) {
+ retmem(right_tail);
+ }
+ right_tail = ALLOC_WC(tmp_len);
+ (void) wsncpy(right_tail,
+ eq + 1,
+ colon - eq - 1);
+ right_tail[colon - eq - 1] =
+ (int) nul_char;
+ } else {
+ if(right_tail) {
+ retmem(right_tail);
+ }
+ right_tail = ALLOC_WC(wslen(eq) + 1);
+ (void) wscpy(right_tail, eq + 1);
+ }
+ }
+ } else {
+ if ((eq = (wchar_t *) wschr(colon + 1,
+ (int) equal_char)) == NULL) {
+ fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 121, "= missing from replacement macro reference"));
+ }
+ if ((percent = (wchar_t *) wschr(colon + 1,
+ (int) percent_char)) == NULL) {
+ fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 122, "%% missing from replacement macro reference"));
+ }
+ if (eq < percent) {
+ fatal_reader_mksh(catgets(libmksdmsi18n_catd, 1, 123, "%% missing from replacement macro reference"));
+ }
+
+ if (percent > (colon + 1)) {
+ tmp_len = percent - colon;
+ if(left_head) {
+ retmem(left_head);
+ }
+ left_head = ALLOC_WC(tmp_len);
+ (void) wsncpy(left_head,
+ colon + 1,
+ percent - colon - 1);
+ left_head[percent-colon-1] = (int) nul_char;
+ left_head_len = percent-colon-1;
+ } else {
+ left_head = NULL;
+ left_head_len = 0;
+ }
+
+ if (eq > percent+1) {
+ tmp_len = eq - percent;
+ if(left_tail) {
+ retmem(left_tail);
+ }
+ left_tail = ALLOC_WC(tmp_len);
+ (void) wsncpy(left_tail,
+ percent + 1,
+ eq - percent - 1);
+ left_tail[eq-percent-1] = (int) nul_char;
+ left_tail_len = eq-percent-1;
+ } else {
+ left_tail = NULL;
+ left_tail_len = 0;
+ }
+
+ if ((percent = (wchar_t *) wschr(++eq,
+ (int) percent_char)) == NULL) {
+
+ right_hand[0] = ALLOC_WC(wslen(eq) + 1);
+ right_hand[1] = NULL;
+ (void) wscpy(right_hand[0], eq);
+ } else {
+ i = 0;
+ do {
+ right_hand[i] = ALLOC_WC(percent-eq+1);
+ (void) wsncpy(right_hand[i],
+ eq,
+ percent - eq);
+ right_hand[i][percent-eq] =
+ (int) nul_char;
+ if (i++ >= VSIZEOF(right_hand)) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 124, "Too many %% in pattern"));
+ }
+ eq = percent + 1;
+ if (eq[0] == (int) nul_char) {
+ MBSTOWCS(wcs_buffer, "");
+ right_hand[i] = (wchar_t *) wsdup(wcs_buffer);
+ i++;
+ break;
+ }
+ } while ((percent = (wchar_t *) wschr(eq, (int) percent_char)) != NULL);
+ if (eq[0] != (int) nul_char) {
+ right_hand[i] = ALLOC_WC(wslen(eq) + 1);
+ (void) wscpy(right_hand[i], eq);
+ i++;
+ }
+ right_hand[i] = NULL;
+ }
+ replacement = pattern_replace;
+ }
+ }
+ if (name == NULL) {
+ /*
+ * No translations found.
+ * Use the whole string as the macro name.
+ */
+ name = GETNAME(string.buffer.start,
+ string.text.p - string.buffer.start);
+ }
+ if (string.free_after_use) {
+ retmem(string.buffer.start);
+ }
+ if (name == make) {
+ make_word_mentioned = true;
+ }
+ if (name == query) {
+ query_mentioned = true;
+ }
+ if ((name == host_arch) || (name == target_arch)) {
+ if (!init_arch_done) {
+ init_arch_done = true;
+ init_arch_macros();
+ }
+ }
+ if ((name == host_mach) || (name == target_mach)) {
+ if (!init_mach_done) {
+ init_mach_done = true;
+ init_mach_macros();
+ }
+ }
+ /* Get the macro value. */
+ macro = get_prop(name->prop, macro_prop);
+#ifdef NSE
+ if (nse_watch_vars && nse && macro != NULL) {
+ if (macro->body.macro.imported) {
+ nse_shell_var_used= name;
+ }
+ if (macro->body.macro.value != NULL){
+ if (nse_backquotes(macro->body.macro.value->string)) {
+ nse_backquote_seen= name;
+ }
+ }
+ }
+#endif
+ if ((macro != NULL) && macro->body.macro.is_conditional) {
+ conditional_macro_used = true;
+ /*
+ * Add this conditional macro to the beginning of the
+ * global list.
+ */
+ add_macro_to_global_list(name);
+ if (makefile_type == reading_makefile) {
+ warning_mksh(catgets(libmksdmsi18n_catd, 1, 164, "Conditional macro `%s' referenced in file `%ws', line %d"),
+ name->string_mb, file_being_read, line_number);
+ }
+ }
+ /* Macro name read and parsed. Expand the value. */
+ if ((macro == NULL) || (macro->body.macro.value == NULL)) {
+ /* If the value is empty, we just get out of here. */
+ goto exit;
+ }
+ if (replacement == sh_replace) {
+ /* If we should do a :sh transform, we expand the command
+ * and process it.
+ */
+ INIT_STRING_FROM_STACK(string, buffer);
+ /* Expand the value into a local string buffer and run cmd. */
+ expand_value_with_daemon(name, macro, &string, cmd);
+ sh_command2string(&string, destination);
+ } else if ((replacement != no_replace) || (extraction != no_extract)) {
+ /*
+ * If there were any transforms specified in the macro
+ * name, we deal with them here.
+ */
+ INIT_STRING_FROM_STACK(string, buffer);
+ /* Expand the value into a local string buffer. */
+ expand_value_with_daemon(name, macro, &string, cmd);
+ /* Scan the expanded string. */
+ p = string.buffer.start;
+ while (*p != (int) nul_char) {
+ wchar_t chr;
+
+ /*
+ * First skip over any white space and append
+ * that to the destination string.
+ */
+ block_start = p;
+ while ((*p != (int) nul_char) && iswspace(*p)) {
+ p++;
+ }
+ append_string(block_start,
+ destination,
+ p - block_start);
+ /* Then find the end of the next word. */
+ block_start = p;
+ while ((*p != (int) nul_char) && !iswspace(*p)) {
+ p++;
+ }
+ /* If we cant find another word we are done */
+ if (block_start == p) {
+ break;
+ }
+ /* Then apply the transforms to the word */
+ INIT_STRING_FROM_STACK(extracted, extracted_string);
+ switch (extraction) {
+ case dir_extract:
+ /*
+ * $(@D) type transform. Extract the
+ * path from the word. Deliver "." if
+ * none is found.
+ */
+ if (p != NULL) {
+ chr = *p;
+ *p = (int) nul_char;
+ }
+ eq = (wchar_t *) wsrchr(block_start, (int) slash_char);
+ if (p != NULL) {
+ *p = chr;
+ }
+ if ((eq == NULL) || (eq > p)) {
+ MBSTOWCS(wcs_buffer, ".");
+ append_string(wcs_buffer, &extracted, 1);
+ } else {
+ append_string(block_start,
+ &extracted,
+ eq - block_start);
+ }
+ break;
+ case file_extract:
+ /*
+ * $(@F) type transform. Remove the path
+ * from the word if any.
+ */
+ if (p != NULL) {
+ chr = *p;
+ *p = (int) nul_char;
+ }
+ eq = (wchar_t *) wsrchr(block_start, (int) slash_char);
+ if (p != NULL) {
+ *p = chr;
+ }
+ if ((eq == NULL) || (eq > p)) {
+ append_string(block_start,
+ &extracted,
+ p - block_start);
+ } else {
+ append_string(eq + 1,
+ &extracted,
+ p - eq - 1);
+ }
+ break;
+ case no_extract:
+ append_string(block_start,
+ &extracted,
+ p - block_start);
+ break;
+ }
+ switch (replacement) {
+ case suffix_replace:
+ /*
+ * $(FOO:.o=.c) type transform.
+ * Maybe replace the tail of the word.
+ */
+ if (((extracted.text.p -
+ extracted.buffer.start) >=
+ left_tail_len) &&
+ IS_WEQUALN(extracted.text.p - left_tail_len,
+ left_tail,
+ left_tail_len)) {
+ append_string(extracted.buffer.start,
+ destination,
+ (extracted.text.p -
+ extracted.buffer.start)
+ - left_tail_len);
+ append_string(right_tail,
+ destination,
+ FIND_LENGTH);
+ } else {
+ append_string(extracted.buffer.start,
+ destination,
+ FIND_LENGTH);
+ }
+ break;
+ case pattern_replace:
+ /* $(X:a%b=c%d) type transform. */
+ if (((extracted.text.p -
+ extracted.buffer.start) >=
+ left_head_len+left_tail_len) &&
+ IS_WEQUALN(left_head,
+ extracted.buffer.start,
+ left_head_len) &&
+ IS_WEQUALN(left_tail,
+ extracted.text.p - left_tail_len,
+ left_tail_len)) {
+ i = 0;
+ while (right_hand[i] != NULL) {
+ append_string(right_hand[i],
+ destination,
+ FIND_LENGTH);
+ i++;
+ if (right_hand[i] != NULL) {
+ append_string(extracted.buffer.
+ start +
+ left_head_len,
+ destination,
+ (extracted.text.p - extracted.buffer.start)-left_head_len-left_tail_len);
+ }
+ }
+ } else {
+ append_string(extracted.buffer.start,
+ destination,
+ FIND_LENGTH);
+ }
+ break;
+ case no_replace:
+ append_string(extracted.buffer.start,
+ destination,
+ FIND_LENGTH);
+ break;
+ case sh_replace:
+ break;
+ }
+ }
+ if (string.free_after_use) {
+ retmem(string.buffer.start);
+ }
+ } else {
+ /*
+ * This is for the case when the macro name did not
+ * specify transforms.
+ */
+ if (!strncmp(name->string_mb, NOCATGETS("GET"), 3)) {
+ dollarget_seen = true;
+ }
+ dollarless_flag = false;
+ if (!strncmp(name->string_mb, "<", 1) &&
+ dollarget_seen) {
+ dollarless_flag = true;
+ dollarget_seen = false;
+ }
+ expand_value_with_daemon(name, macro, destination, cmd);
+ }
+exit:
+ if(left_tail) {
+ retmem(left_tail);
+ }
+ if(right_tail) {
+ retmem(right_tail);
+ }
+ if(left_head) {
+ retmem(left_head);
+ }
+ i = 0;
+ while (right_hand[i] != NULL) {
+ retmem(right_hand[i]);
+ i++;
+ }
+ *destination->text.p = (int) nul_char;
+ destination->text.end = destination->text.p;
+}
+
+static void
+add_macro_to_global_list(Name macro_to_add)
+{
+ Macro_list new_macro;
+ Macro_list macro_on_list;
+ char *name_on_list = (char*)NULL;
+ char *name_to_add = macro_to_add->string_mb;
+ char *value_on_list = (char*)NULL;
+ char *value_to_add = (char*)NULL;
+
+ if (macro_to_add->prop->body.macro.value != NULL) {
+ value_to_add = macro_to_add->prop->body.macro.value->string_mb;
+ } else {
+ value_to_add = "";
+ }
+
+ /*
+ * Check if this macro is already on list, if so, do nothing
+ */
+ for (macro_on_list = cond_macro_list;
+ macro_on_list != NULL;
+ macro_on_list = macro_on_list->next) {
+
+ name_on_list = macro_on_list->macro_name;
+ value_on_list = macro_on_list->value;
+
+ if (IS_EQUAL(name_on_list, name_to_add)) {
+ if (IS_EQUAL(value_on_list, value_to_add)) {
+ return;
+ }
+ }
+ }
+ new_macro = (Macro_list) malloc(sizeof(Macro_list_rec));
+ new_macro->macro_name = strdup(name_to_add);
+ new_macro->value = strdup(value_to_add);
+ new_macro->next = cond_macro_list;
+ cond_macro_list = new_macro;
+}
+
+/*
+ * init_arch_macros(void)
+ *
+ * Set the magic macros TARGET_ARCH, HOST_ARCH,
+ *
+ * Parameters:
+ *
+ * Global variables used:
+ * host_arch Property for magic macro HOST_ARCH
+ * target_arch Property for magic macro TARGET_ARCH
+ *
+ * Return value:
+ * The function does not return a value, but can
+ * call fatal() in case of error.
+ */
+static void
+init_arch_macros(void)
+{
+ String_rec result_string;
+ wchar_t wc_buf[STRING_BUFFER_LENGTH];
+ char mb_buf[STRING_BUFFER_LENGTH];
+ FILE *pipe;
+ Name value;
+ int set_host, set_target;
+#ifdef NSE
+ Property macro;
+#endif
+#if defined(linux)
+ const char *mach_command = NOCATGETS("/bin/uname -p");
+#else
+ const char *mach_command = NOCATGETS("/bin/mach");
+#endif
+
+ set_host = (get_prop(host_arch->prop, macro_prop) == NULL);
+ set_target = (get_prop(target_arch->prop, macro_prop) == NULL);
+
+ if (set_host || set_target) {
+ INIT_STRING_FROM_STACK(result_string, wc_buf);
+ append_char((int) hyphen_char, &result_string);
+
+ if ((pipe = popen(mach_command, "r")) == NULL) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 185, "Execute of %s failed"), mach_command);
+ }
+ while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
+ MBSTOWCS(wcs_buffer, mb_buf);
+ append_string(wcs_buffer, &result_string, wslen(wcs_buffer));
+ }
+ if (pclose(pipe) != 0) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 186, "Execute of %s failed"), mach_command);
+ }
+
+ value = GETNAME(result_string.buffer.start, wslen(result_string.buffer.start));
+
+#ifdef NSE
+ macro = setvar_daemon(host_arch, value, false, no_daemon, true, 0);
+ macro->body.macro.imported= true;
+ macro = setvar_daemon(target_arch, value, false, no_daemon, true, 0);
+ macro->body.macro.imported= true;
+#else
+ if (set_host) {
+ (void) setvar_daemon(host_arch, value, false, no_daemon, true, 0);
+ }
+ if (set_target) {
+ (void) setvar_daemon(target_arch, value, false, no_daemon, true, 0);
+ }
+#endif
+ }
+}
+
+/*
+ * init_mach_macros(void)
+ *
+ * Set the magic macros TARGET_MACH, HOST_MACH,
+ *
+ * Parameters:
+ *
+ * Global variables used:
+ * host_mach Property for magic macro HOST_MACH
+ * target_mach Property for magic macro TARGET_MACH
+ *
+ * Return value:
+ * The function does not return a value, but can
+ * call fatal() in case of error.
+ */
+static void
+init_mach_macros(void)
+{
+ String_rec result_string;
+ wchar_t wc_buf[STRING_BUFFER_LENGTH];
+ char mb_buf[STRING_BUFFER_LENGTH];
+ FILE *pipe;
+ Name value;
+ int set_host, set_target;
+ const char *arch_command = NOCATGETS("/bin/arch");
+
+ set_host = (get_prop(host_mach->prop, macro_prop) == NULL);
+ set_target = (get_prop(target_mach->prop, macro_prop) == NULL);
+
+ if (set_host || set_target) {
+ INIT_STRING_FROM_STACK(result_string, wc_buf);
+ append_char((int) hyphen_char, &result_string);
+
+ if ((pipe = popen(arch_command, "r")) == NULL) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 183, "Execute of %s failed"), arch_command);
+ }
+ while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
+ MBSTOWCS(wcs_buffer, mb_buf);
+ append_string(wcs_buffer, &result_string, wslen(wcs_buffer));
+ }
+ if (pclose(pipe) != 0) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 184, "Execute of %s failed"), arch_command);
+ }
+
+ value = GETNAME(result_string.buffer.start, wslen(result_string.buffer.start));
+
+ if (set_host) {
+ (void) setvar_daemon(host_mach, value, false, no_daemon, true, 0);
+ }
+ if (set_target) {
+ (void) setvar_daemon(target_mach, value, false, no_daemon, true, 0);
+ }
+ }
+}
+
+/*
+ * expand_value_with_daemon(name, macro, destination, cmd)
+ *
+ * Checks for daemons and then maybe calls expand_value().
+ *
+ * Parameters:
+ * name Name of the macro (Added by the NSE)
+ * macro The property block with the value to expand
+ * destination Where the result should be deposited
+ * cmd If we are evaluating a command line we
+ * turn \ quoting off
+ *
+ * Global variables used:
+ */
+static void
+#ifdef NSE
+expand_value_with_daemon(Name name, register Property macro, register String destination, Boolean cmd)
+#else
+expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd)
+#endif
+{
+ register Chain chain;
+
+#ifdef NSE
+ if (reading_dependencies) {
+ /*
+ * Processing the dependencies themselves
+ */
+ depvar_dep_macro_used(name);
+ } else {
+ /*
+ * Processing the rules for the targets
+ * the nse_watch_vars flags chokes off most
+ * checks. it is true only when processing
+ * the output from a recursive make run
+ * which is all we are interested in here.
+ */
+ if (nse_watch_vars) {
+ depvar_rule_macro_used(name);
+ }
+ }
+#endif
+
+ switch (macro->body.macro.daemon) {
+ case no_daemon:
+ if (!svr4 && !posix) {
+ expand_value(macro->body.macro.value, destination, cmd);
+ } else {
+ if (dollarless_flag && tilde_rule) {
+ expand_value(dollarless_value, destination, cmd);
+ dollarless_flag = false;
+ tilde_rule = false;
+ } else {
+ expand_value(macro->body.macro.value, destination, cmd);
+ }
+ }
+ return;
+ case chain_daemon:
+ /* If this is a $? value we call the daemon to translate the */
+ /* list of names to a string */
+ for (chain = (Chain) macro->body.macro.value;
+ chain != NULL;
+ chain = chain->next) {
+ APPEND_NAME(chain->name,
+ destination,
+ (int) chain->name->hash.length);
+ if (chain->next != NULL) {
+ append_char((int) space_char, destination);
+ }
+ }
+ return;
+ }
+}
+
+/*
+ * We use a permanent buffer to reset SUNPRO_DEPENDENCIES value.
+ */
+char *sunpro_dependencies_buf = NULL;
+char *sunpro_dependencies_oldbuf = NULL;
+int sunpro_dependencies_buf_size = 0;
+
+/*
+ * setvar_daemon(name, value, append, daemon, strip_trailing_spaces)
+ *
+ * Set a macro value, possibly supplying a daemon to be used
+ * when referencing the value.
+ *
+ * Return value:
+ * The property block with the new value
+ *
+ * Parameters:
+ * name Name of the macro to set
+ * value The value to set
+ * append Should we reset or append to the current value?
+ * daemon Special treatment when reading the value
+ * strip_trailing_spaces from the end of value->string
+ * debug_level Indicates how much tracing we should do
+ *
+ * Global variables used:
+ * makefile_type Used to check if we should enforce read only
+ * path_name The Name "PATH", compared against
+ * virtual_root The Name "VIRTUAL_ROOT", compared against
+ * vpath_defined Set if the macro VPATH is set
+ * vpath_name The Name "VPATH", compared against
+ * envvar A list of environment vars with $ in value
+ */
+Property
+setvar_daemon(register Name name, register Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level)
+{
+ register Property macro = maybe_append_prop(name, macro_prop);
+ register Property macro_apx = get_prop(name->prop, macro_append_prop);
+ int length = 0;
+ String_rec destination;
+ wchar_t buffer[STRING_BUFFER_LENGTH];
+ register Chain chain;
+ Name val;
+ wchar_t *val_string = (wchar_t*)NULL;
+ Wstring wcb;
+
+#ifdef NSE
+ macro->body.macro.imported = false;
+#endif
+
+ if ((makefile_type != reading_nothing) &&
+ macro->body.macro.read_only) {
+ return macro;
+ }
+ /* Strip spaces from the end of the value */
+ if (daemon == no_daemon) {
+ if(value != NULL) {
+ wcb.init(value);
+ length = wcb.length();
+ val_string = wcb.get_string();
+ }
+ if ((length > 0) && iswspace(val_string[length-1])) {
+ INIT_STRING_FROM_STACK(destination, buffer);
+ buffer[0] = 0;
+ append_string(val_string, &destination, length);
+ if (strip_trailing_spaces) {
+ while ((length > 0) &&
+ iswspace(destination.buffer.start[length-1])) {
+ destination.buffer.start[--length] = 0;
+ }
+ }
+ value = GETNAME(destination.buffer.start, FIND_LENGTH);
+ }
+ }
+
+ if(macro_apx != NULL) {
+ val = macro_apx->body.macro_appendix.value;
+ } else {
+ val = macro->body.macro.value;
+ }
+
+ if (append) {
+ /*
+ * If we are appending, we just tack the new value after
+ * the old one with a space in between.
+ */
+ INIT_STRING_FROM_STACK(destination, buffer);
+ buffer[0] = 0;
+ if ((macro != NULL) && (val != NULL)) {
+ APPEND_NAME(val,
+ &destination,
+ (int) val->hash.length);
+ if (value != NULL) {
+ wcb.init(value);
+ if(wcb.length() > 0) {
+ MBTOWC(wcs_buffer, " ");
+ append_char(wcs_buffer[0], &destination);
+ }
+ }
+ }
+ if (value != NULL) {
+ APPEND_NAME(value,
+ &destination,
+ (int) value->hash.length);
+ }
+ value = GETNAME(destination.buffer.start, FIND_LENGTH);
+ wcb.init(value);
+ if (destination.free_after_use) {
+ retmem(destination.buffer.start);
+ }
+ }
+
+ /* Debugging trace */
+ if (debug_level > 1) {
+ if (value != NULL) {
+ switch (daemon) {
+ case chain_daemon:
+ (void) printf("%s =", name->string_mb);
+ for (chain = (Chain) value;
+ chain != NULL;
+ chain = chain->next) {
+ (void) printf(" %s", chain->name->string_mb);
+ }
+ (void) printf("\n");
+ break;
+ case no_daemon:
+ (void) printf("%s= %s\n",
+ name->string_mb,
+ value->string_mb);
+ break;
+ }
+ } else {
+ (void) printf("%s =\n", name->string_mb);
+ }
+ }
+ /* Set the new values in the macro property block */
+/**/
+ if(macro_apx != NULL) {
+ macro_apx->body.macro_appendix.value = value;
+ INIT_STRING_FROM_STACK(destination, buffer);
+ buffer[0] = 0;
+ if (value != NULL) {
+ APPEND_NAME(value,
+ &destination,
+ (int) value->hash.length);
+ if (macro_apx->body.macro_appendix.value_to_append != NULL) {
+ MBTOWC(wcs_buffer, " ");
+ append_char(wcs_buffer[0], &destination);
+ }
+ }
+ if (macro_apx->body.macro_appendix.value_to_append != NULL) {
+ APPEND_NAME(macro_apx->body.macro_appendix.value_to_append,
+ &destination,
+ (int) macro_apx->body.macro_appendix.value_to_append->hash.length);
+ }
+ value = GETNAME(destination.buffer.start, FIND_LENGTH);
+ if (destination.free_after_use) {
+ retmem(destination.buffer.start);
+ }
+ }
+/**/
+ macro->body.macro.value = value;
+ macro->body.macro.daemon = daemon;
+ /*
+ * If the user changes the VIRTUAL_ROOT, we need to flush
+ * the vroot package cache.
+ */
+ if (name == path_name) {
+ flush_path_cache();
+ }
+ if (name == virtual_root) {
+ flush_vroot_cache();
+ }
+ /* If this sets the VPATH we remember that */
+ if ((name == vpath_name) &&
+ (value != NULL) &&
+ (value->hash.length > 0)) {
+ vpath_defined = true;
+ }
+ /*
+ * For environment variables we also set the
+ * environment value each time.
+ */
+ if (macro->body.macro.exported) {
+ static char *env;
+
+#ifdef DISTRIBUTED
+ if (!reading_environment && (value != NULL)) {
+#else
+ if (!reading_environment && (value != NULL) && value->dollar) {
+#endif
+ Envvar p;
+
+ for (p = envvar; p != NULL; p = p->next) {
+ if (p->name == name) {
+ p->value = value;
+ p->already_put = false;
+ goto found_it;
+ }
+ }
+ p = ALLOC(Envvar);
+ p->name = name;
+ p->value = value;
+ p->next = envvar;
+ p->env_string = NULL;
+ p->already_put = false;
+ envvar = p;
+found_it:;
+#ifdef DISTRIBUTED
+ }
+ if (reading_environment || (value == NULL) || !value->dollar) {
+#else
+ } else {
+#endif
+ length = 2 + strlen(name->string_mb);
+ if (value != NULL) {
+ length += strlen(value->string_mb);
+ }
+ Property env_prop = maybe_append_prop(name, env_mem_prop);
+ /*
+ * We use a permanent buffer to reset SUNPRO_DEPENDENCIES value.
+ */
+ if (!strncmp(name->string_mb, NOCATGETS("SUNPRO_DEPENDENCIES"), 19)) {
+ if (length >= sunpro_dependencies_buf_size) {
+ sunpro_dependencies_buf_size=length*2;
+ if (sunpro_dependencies_buf_size < 4096)
+ sunpro_dependencies_buf_size = 4096; // Default minimum size
+ if (sunpro_dependencies_buf)
+ sunpro_dependencies_oldbuf = sunpro_dependencies_buf;
+ sunpro_dependencies_buf=getmem(sunpro_dependencies_buf_size);
+ }
+ env = sunpro_dependencies_buf;
+ } else {
+ env = getmem(length);
+ }
+ env_alloc_num++;
+ env_alloc_bytes += length;
+ (void) sprintf(env,
+ "%s=%s",
+ name->string_mb,
+ value == NULL ?
+ "" : value->string_mb);
+ (void) putenv(env);
+ env_prop->body.env_mem.value = env;
+ if (sunpro_dependencies_oldbuf) {
+ /* Return old buffer */
+ retmem_mb(sunpro_dependencies_oldbuf);
+ sunpro_dependencies_oldbuf = NULL;
+ }
+ }
+ }
+ if (name == target_arch) {
+ Name ha = getvar(host_arch);
+ Name ta = getvar(target_arch);
+ Name vr = getvar(virtual_root);
+ int length;
+ wchar_t *new_value;
+ wchar_t *old_vr;
+ Boolean new_value_allocated = false;
+
+ Wstring ha_str(ha);
+ Wstring ta_str(ta);
+ Wstring vr_str(vr);
+
+ wchar_t * wcb_ha = ha_str.get_string();
+ wchar_t * wcb_ta = ta_str.get_string();
+ wchar_t * wcb_vr = vr_str.get_string();
+
+ length = 32 +
+ wslen(wcb_ha) +
+ wslen(wcb_ta) +
+ wslen(wcb_vr);
+ old_vr = wcb_vr;
+ MBSTOWCS(wcs_buffer, NOCATGETS("/usr/arch/"));
+ if (IS_WEQUALN(old_vr,
+ wcs_buffer,
+ wslen(wcs_buffer))) {
+ old_vr = (wchar_t *) wschr(old_vr, (int) colon_char) + 1;
+ }
+ if ( (ha == ta) || (wslen(wcb_ta) == 0) ) {
+ new_value = old_vr;
+ } else {
+ new_value = ALLOC_WC(length);
+ new_value_allocated = true;
+ WCSTOMBS(mbs_buffer, old_vr);
+#if !defined(linux)
+ (void) wsprintf(new_value,
+ NOCATGETS("/usr/arch/%s/%s:%s"),
+ ha->string_mb + 1,
+ ta->string_mb + 1,
+ mbs_buffer);
+#else
+ char * mbs_new_value = (char *)getmem(length);
+ (void) sprintf(mbs_new_value,
+ NOCATGETS("/usr/arch/%s/%s:%s"),
+ ha->string_mb + 1,
+ ta->string_mb + 1,
+ mbs_buffer);
+ MBSTOWCS(new_value, mbs_new_value);
+ retmem_mb(mbs_new_value);
+#endif
+ }
+ if (new_value[0] != 0) {
+ (void) setvar_daemon(virtual_root,
+ GETNAME(new_value, FIND_LENGTH),
+ false,
+ no_daemon,
+ true,
+ debug_level);
+ }
+ if (new_value_allocated) {
+ retmem(new_value);
+ }
+ }
+ return macro;
+}
diff --git a/usr/src/make_src/Make/lib/mksh/src/misc.cc b/usr/src/make_src/Make/lib/mksh/src/misc.cc
new file mode 100644
index 0000000..17a878b
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksh/src/misc.cc
@@ -0,0 +1,1178 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)misc.cc 1.31 06/12/12
+ */
+
+#pragma ident "@(#)misc.cc 1.31 06/12/12"
+
+/*
+ * misc.cc
+ *
+ * This file contains various unclassified routines. Some main groups:
+ * getname
+ * Memory allocation
+ * String handling
+ * Property handling
+ * Error message handling
+ * Make internal state dumping
+ * main routine support
+ */
+
+/*
+ * Included files
+ */
+#include <bsd/bsd.h> /* bsd_signal() */
+#include <mksh/i18n.h> /* get_char_semantics_value() */
+#include <mksh/misc.h>
+#include <mksdmsi18n/mksdmsi18n.h>
+#include <stdarg.h> /* va_list, va_start(), va_end() */
+#include <stdlib.h> /* mbstowcs() */
+#include <sys/signal.h> /* SIG_DFL */
+#include <sys/wait.h> /* wait() */
+
+#ifdef SUN5_0
+#include <string.h> /* strerror() */
+#endif
+
+#if defined (HP_UX) || defined (linux)
+#include <unistd.h>
+#endif
+
+/*
+ * Defined macros
+ */
+
+/*
+ * typedefs & structs
+ */
+
+/*
+ * Static variables
+ */
+#ifdef SUN5_0
+extern "C" void (*sigivalue)(int) = SIG_DFL;
+extern "C" void (*sigqvalue)(int) = SIG_DFL;
+extern "C" void (*sigtvalue)(int) = SIG_DFL;
+extern "C" void (*sighvalue)(int) = SIG_DFL;
+#else
+static void (*sigivalue)(int) = (void (*) (int)) SIG_DFL;
+static void (*sigqvalue)(int) = (void (*) (int)) SIG_DFL;
+static void (*sigtvalue)(int) = (void (*) (int)) SIG_DFL;
+static void (*sighvalue)(int) = (void (*) (int)) SIG_DFL;
+#endif
+
+long getname_bytes_count = 0;
+long getname_names_count = 0;
+long getname_struct_count = 0;
+
+long freename_bytes_count = 0;
+long freename_names_count = 0;
+long freename_struct_count = 0;
+
+long expandstring_count = 0;
+long getwstring_count = 0;
+
+/*
+ * File table of contents
+ */
+static void expand_string(register String string, register int length);
+
+#define FATAL_ERROR_MSG_SIZE 200
+
+/*
+ * getmem(size)
+ *
+ * malloc() version that checks the returned value.
+ *
+ * Return value:
+ * The memory chunk we allocated
+ *
+ * Parameters:
+ * size The size of the chunk we need
+ *
+ * Global variables used:
+ */
+char *
+getmem(register int size)
+{
+ register char *result = (char *) malloc((unsigned) size);
+ if (result == NULL) {
+ char buf[FATAL_ERROR_MSG_SIZE];
+ sprintf(buf, NOCATGETS("*** Error: malloc(%d) failed: %s\n"), size, strerror(errno));
+ strcat(buf, catgets(libmksdmsi18n_catd, 1, 126, "mksh: Fatal error: Out of memory\n"));
+ fputs(buf, stderr);
+#ifdef SUN5_0
+ exit_status = 1;
+#endif
+ exit(1);
+ }
+ return result;
+}
+
+/*
+ * retmem(p)
+ *
+ * Cover funtion for free() to make it possible to insert advises.
+ *
+ * Parameters:
+ * p The memory block to free
+ *
+ * Global variables used:
+ */
+void
+retmem(wchar_t *p)
+{
+ (void) free((char *) p);
+}
+
+void
+retmem_mb(caddr_t p)
+{
+ (void) free(p);
+}
+
+/*
+ * getname_fn(name, len, dont_enter)
+ *
+ * Hash a name string to the corresponding nameblock.
+ *
+ * Return value:
+ * The Name block for the string
+ *
+ * Parameters:
+ * name The string we want to internalize
+ * len The length of that string
+ * dont_enter Don't enter the name if it does not exist
+ *
+ * Global variables used:
+ * funny The vector of semantic tags for characters
+ * hashtab The hashtable used for the nametable
+ */
+Name
+getname_fn(wchar_t *name, register int len, register Boolean dont_enter, register Boolean * foundp)
+{
+ register int length;
+ register wchar_t *cap = name;
+ register Name np;
+ static Name_rec empty_Name;
+ char *tmp_mbs_buffer = NULL;
+ char *mbs_name = mbs_buffer;
+
+ /*
+ * First figure out how long the string is.
+ * If the len argument is -1 we count the chars here.
+ */
+ if (len == FIND_LENGTH) {
+ length = wslen(name);
+ } else {
+ length = len;
+ }
+
+ Wstring ws;
+ ws.init(name, length);
+ if (length >= MAXPATHLEN) {
+ mbs_name = tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
+ }
+ (void) wcstombs(mbs_name, ws.get_string(), (length * MB_LEN_MAX) + 1);
+
+ /* Look for the string */
+ if (dont_enter || (foundp != 0)) {
+ np = hashtab.lookup(mbs_name);
+ if (foundp != 0) {
+ *foundp = (np != 0) ? true : false;
+ }
+ if ((np != 0) || dont_enter) {
+ if(tmp_mbs_buffer != NULL) {
+ retmem_mb(tmp_mbs_buffer);
+ }
+ return np;
+ } else {
+ np = ALLOC(Name);
+ }
+ } else {
+ Boolean found;
+ np = hashtab.insert(mbs_name, found);
+ if (found) {
+ if(tmp_mbs_buffer != NULL) {
+ retmem_mb(tmp_mbs_buffer);
+ }
+ return np;
+ }
+ }
+ getname_struct_count += sizeof(struct _Name);
+ *np = empty_Name;
+
+ np->string_mb = strdup(mbs_name);
+ if(tmp_mbs_buffer != NULL) {
+ retmem_mb(tmp_mbs_buffer);
+ mbs_name = tmp_mbs_buffer = NULL;
+ }
+ getname_bytes_count += strlen(np->string_mb) + 1;
+ /* Fill in the new Name */
+ np->stat.time = file_no_time;
+ np->hash.length = length;
+ /* Scan the namestring to classify it */
+ for (cap = name, len = 0; --length >= 0;) {
+ len |= get_char_semantics_value(*cap++);
+ }
+ np->dollar = BOOLEAN((len & (int) dollar_sem) != 0);
+ np->meta = BOOLEAN((len & (int) meta_sem) != 0);
+ np->percent = BOOLEAN((len & (int) percent_sem) != 0);
+ np->wildcard = BOOLEAN((len & (int) wildcard_sem) != 0);
+ np->colon = BOOLEAN((len & (int) colon_sem) != 0);
+ np->parenleft = BOOLEAN((len & (int) parenleft_sem) != 0);
+ getname_names_count++;
+ return np;
+}
+
+void
+store_name(Name name)
+{
+ hashtab.insert(name);
+}
+
+void
+free_name(Name name)
+{
+ freename_names_count++;
+ freename_struct_count += sizeof(struct _Name);
+ freename_bytes_count += strlen(name->string_mb) + 1;
+ retmem_mb(name->string_mb);
+ for (Property next, p = name->prop; p != NULL; p = next) {
+ next = p->next;
+ free(p);
+ }
+ free(name);
+}
+
+/*
+ * enable_interrupt(handler)
+ *
+ * This routine sets a new interrupt handler for the signals make
+ * wants to deal with.
+ *
+ * Parameters:
+ * handler The function installed as interrupt handler
+ *
+ * Static variables used:
+ * sigivalue The original signal handler
+ * sigqvalue The original signal handler
+ * sigtvalue The original signal handler
+ * sighvalue The original signal handler
+ */
+void
+enable_interrupt(register void (*handler) (int))
+{
+#ifdef SUN5_0
+ if (sigivalue != SIG_IGN) {
+#else
+ if (sigivalue != (void (*) (int)) SIG_IGN) {
+#endif
+ (void) bsd_signal(SIGINT, (SIG_PF) handler);
+ }
+#ifdef SUN5_0
+ if (sigqvalue != SIG_IGN) {
+#else
+ if (sigqvalue != (void (*) (int)) SIG_IGN) {
+#endif
+ (void) bsd_signal(SIGQUIT, (SIG_PF) handler);
+ }
+#ifdef SUN5_0
+ if (sigtvalue != SIG_IGN) {
+#else
+ if (sigtvalue != (void (*) (int)) SIG_IGN) {
+#endif
+ (void) bsd_signal(SIGTERM, (SIG_PF) handler);
+ }
+#ifdef SUN5_0
+ if (sighvalue != SIG_IGN) {
+#else
+ if (sighvalue != (void (*) (int)) SIG_IGN) {
+#endif
+ (void) bsd_signal(SIGHUP, (SIG_PF) handler);
+ }
+}
+
+/*
+ * setup_char_semantics()
+ *
+ * Load the vector char_semantics[] with lexical markers
+ *
+ * Parameters:
+ *
+ * Global variables used:
+ * char_semantics The vector of character semantics that we set
+ */
+void
+setup_char_semantics(void)
+{
+ char *s;
+ wchar_t wc_buffer[1];
+ int entry;
+
+ if (svr4) {
+ s = "@-";
+ } else {
+ s = "=@-?!+";
+ }
+ for (s; MBTOWC(wc_buffer, s); s++) {
+ entry = get_char_semantics_entry(*wc_buffer);
+ char_semantics[entry] |= (int) command_prefix_sem;
+ }
+ char_semantics[dollar_char_entry] |= (int) dollar_sem;
+ for (s = "#|=^();&<>*?[]:$`'\"\\\n"; MBTOWC(wc_buffer, s); s++) {
+ entry = get_char_semantics_entry(*wc_buffer);
+ char_semantics[entry] |= (int) meta_sem;
+ }
+ char_semantics[percent_char_entry] |= (int) percent_sem;
+ for (s = "@*<%?^"; MBTOWC(wc_buffer, s); s++) {
+ entry = get_char_semantics_entry(*wc_buffer);
+ char_semantics[entry] |= (int) special_macro_sem;
+ }
+ for (s = "?[*"; MBTOWC(wc_buffer, s); s++) {
+ entry = get_char_semantics_entry(*wc_buffer);
+ char_semantics[entry] |= (int) wildcard_sem;
+ }
+ char_semantics[colon_char_entry] |= (int) colon_sem;
+ char_semantics[parenleft_char_entry] |= (int) parenleft_sem;
+}
+
+/*
+ * errmsg(errnum)
+ *
+ * Return the error message for a system call error
+ *
+ * Return value:
+ * An error message string
+ *
+ * Parameters:
+ * errnum The number of the error we want to describe
+ *
+ * Global variables used:
+ * sys_errlist A vector of error messages
+ * sys_nerr The size of sys_errlist
+ */
+char *
+errmsg(int errnum)
+{
+#ifdef linux
+ return strerror(errnum);
+#else // linux
+
+ extern int sys_nerr;
+#ifdef SUN4_x
+ extern char *sys_errlist[];
+#endif
+ char *errbuf;
+
+ if ((errnum < 0) || (errnum > sys_nerr)) {
+ errbuf = getmem(6+1+11+1);
+ (void) sprintf(errbuf, catgets(libmksdmsi18n_catd, 1, 127, "Error %d"), errnum);
+ return errbuf;
+ } else {
+#ifdef SUN4_x
+ return(sys_errlist[errnum]);
+#endif
+#ifdef SUN5_0
+ return strerror(errnum);
+#endif
+
+ }
+#endif // linux
+}
+
+static char static_buf[MAXPATHLEN*3];
+
+/*
+ * fatal_mksh(format, args...)
+ *
+ * Print a message and die
+ *
+ * Parameters:
+ * format printf type format string
+ * args Arguments to match the format
+ */
+/*VARARGS*/
+void
+fatal_mksh(char * message, ...)
+{
+ va_list args;
+ char *buf = static_buf;
+ char *mksh_fat_err = catgets(libmksdmsi18n_catd, 1, 128, "mksh: Fatal error: ");
+ char *cur_wrk_dir = catgets(libmksdmsi18n_catd, 1, 129, "Current working directory: ");
+ int mksh_fat_err_len = strlen(mksh_fat_err);
+
+ va_start(args, message);
+ (void) fflush(stdout);
+ (void) strcpy(buf, mksh_fat_err);
+ size_t buf_len = vsnprintf(static_buf + mksh_fat_err_len,
+ sizeof(static_buf) - mksh_fat_err_len,
+ message, args)
+ + mksh_fat_err_len
+ + strlen(cur_wrk_dir)
+ + strlen(get_current_path_mksh())
+ + 3; // "\n\n"
+ va_end(args);
+ if (buf_len >= sizeof(static_buf)) {
+ buf = getmem(buf_len);
+ (void) strcpy(buf, mksh_fat_err);
+ va_start(args, message);
+ (void) vsprintf(buf + mksh_fat_err_len, message, args);
+ va_end(args);
+ }
+ (void) strcat(buf, "\n");
+/*
+ if (report_pwd) {
+ */
+ if (1) {
+ (void) strcat(buf, cur_wrk_dir);
+ (void) strcat(buf, get_current_path_mksh());
+ (void) strcat(buf, "\n");
+ }
+ (void) fputs(buf, stderr);
+ (void) fflush(stderr);
+ if (buf != static_buf) {
+ retmem_mb(buf);
+ }
+#ifdef SUN5_0
+ exit_status = 1;
+#endif
+ exit(1);
+}
+
+/*
+ * fatal_reader_mksh(format, args...)
+ *
+ * Parameters:
+ * format printf style format string
+ * args arguments to match the format
+ */
+/*VARARGS*/
+void
+fatal_reader_mksh(char * pattern, ...)
+{
+ va_list args;
+ char message[1000];
+
+ va_start(args, pattern);
+/*
+ if (file_being_read != NULL) {
+ WCSTOMBS(mbs_buffer, file_being_read);
+ if (line_number != 0) {
+ (void) sprintf(message,
+ catgets(libmksdmsi18n_catd, 1, 130, "%s, line %d: %s"),
+ mbs_buffer,
+ line_number,
+ pattern);
+ } else {
+ (void) sprintf(message,
+ "%s: %s",
+ mbs_buffer,
+ pattern);
+ }
+ pattern = message;
+ }
+ */
+
+ (void) fflush(stdout);
+ (void) fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 131, "mksh: Fatal error in reader: "));
+ (void) vfprintf(stderr, pattern, args);
+ (void) fprintf(stderr, "\n");
+ va_end(args);
+
+/*
+ if (temp_file_name != NULL) {
+ (void) fprintf(stderr,
+ catgets(libmksdmsi18n_catd, 1, 132, "mksh: Temp-file %s not removed\n"),
+ temp_file_name->string_mb);
+ temp_file_name = NULL;
+ }
+ */
+
+/*
+ if (report_pwd) {
+ */
+ if (1) {
+ (void) fprintf(stderr,
+ catgets(libmksdmsi18n_catd, 1, 133, "Current working directory %s\n"),
+ get_current_path_mksh());
+ }
+ (void) fflush(stderr);
+#ifdef SUN5_0
+ exit_status = 1;
+#endif
+ exit(1);
+}
+
+/*
+ * warning_mksh(format, args...)
+ *
+ * Print a message and continue.
+ *
+ * Parameters:
+ * format printf type format string
+ * args Arguments to match the format
+ */
+/*VARARGS*/
+void
+warning_mksh(char * message, ...)
+{
+ va_list args;
+
+ va_start(args, message);
+ (void) fflush(stdout);
+ (void) fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 134, "mksh: Warning: "));
+ (void) vfprintf(stderr, message, args);
+ (void) fprintf(stderr, "\n");
+ va_end(args);
+/*
+ if (report_pwd) {
+ */
+ if (1) {
+ (void) fprintf(stderr,
+ catgets(libmksdmsi18n_catd, 1, 135, "Current working directory %s\n"),
+ get_current_path_mksh());
+ }
+ (void) fflush(stderr);
+}
+
+/*
+ * get_current_path_mksh()
+ *
+ * Stuff current_path with the current path if it isnt there already.
+ *
+ * Parameters:
+ *
+ * Global variables used:
+ */
+char *
+get_current_path_mksh(void)
+{
+ char pwd[(MAXPATHLEN * MB_LEN_MAX)];
+ static char *current_path;
+
+ if (current_path == NULL) {
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ getcwd(pwd, sizeof(pwd));
+#else
+ (void) getwd(pwd);
+#endif
+ if (pwd[0] == (int) nul_char) {
+ pwd[0] = (int) slash_char;
+ pwd[1] = (int) nul_char;
+ }
+ current_path = strdup(pwd);
+ }
+ return current_path;
+}
+
+/*
+ * append_prop(target, type)
+ *
+ * Create a new property and append it to the property list of a Name.
+ *
+ * Return value:
+ * A new property block for the target
+ *
+ * Parameters:
+ * target The target that wants a new property
+ * type The type of property being requested
+ *
+ * Global variables used:
+ */
+Property
+append_prop(register Name target, register Property_id type)
+{
+ register Property *insert = &target->prop;
+ register Property prop = *insert;
+ register int size;
+
+ switch (type) {
+ case conditional_prop:
+ size = sizeof (struct Conditional);
+ break;
+ case line_prop:
+ size = sizeof (struct Line);
+ break;
+ case macro_prop:
+ size = sizeof (struct _Macro);
+ break;
+ case makefile_prop:
+ size = sizeof (struct Makefile);
+ break;
+ case member_prop:
+ size = sizeof (struct Member);
+ break;
+ case recursive_prop:
+ size = sizeof (struct Recursive);
+ break;
+ case sccs_prop:
+ size = sizeof (struct Sccs);
+ break;
+ case suffix_prop:
+ size = sizeof (struct Suffix);
+ break;
+ case target_prop:
+ size = sizeof (struct Target);
+ break;
+ case time_prop:
+ size = sizeof (struct STime);
+ break;
+ case vpath_alias_prop:
+ size = sizeof (struct Vpath_alias);
+ break;
+ case long_member_name_prop:
+ size = sizeof (struct Long_member_name);
+ break;
+ case macro_append_prop:
+ size = sizeof (struct _Macro_appendix);
+ break;
+ case env_mem_prop:
+ size = sizeof (struct _Env_mem);
+ break;
+ default:
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 136, "Internal error. Unknown prop type %d"), type);
+ }
+ for (; prop != NULL; insert = &prop->next, prop = *insert);
+ size += PROPERTY_HEAD_SIZE;
+ *insert = prop = (Property) getmem(size);
+ memset((char *) prop, 0, size);
+ prop->type = type;
+ prop->next = NULL;
+ return prop;
+}
+
+/*
+ * maybe_append_prop(target, type)
+ *
+ * Append a property to the Name if none of this type exists
+ * else return the one already there
+ *
+ * Return value:
+ * A property of the requested type for the target
+ *
+ * Parameters:
+ * target The target that wants a new property
+ * type The type of property being requested
+ *
+ * Global variables used:
+ */
+Property
+maybe_append_prop(register Name target, register Property_id type)
+{
+ register Property prop;
+
+ if ((prop = get_prop(target->prop, type)) != NULL) {
+ return prop;
+ }
+ return append_prop(target, type);
+}
+
+/*
+ * get_prop(start, type)
+ *
+ * Scan the property list of a Name to find the next property
+ * of a given type.
+ *
+ * Return value:
+ * The first property of the type, if any left
+ *
+ * Parameters:
+ * start The first property block to check for type
+ * type The type of property block we need
+ *
+ * Global variables used:
+ */
+Property
+get_prop(register Property start, register Property_id type)
+{
+ for (; start != NULL; start = start->next) {
+ if (start->type == type) {
+ return start;
+ }
+ }
+ return NULL;
+}
+
+/*
+ * append_string(from, to, length)
+ *
+ * Append a C string to a make string expanding it if nessecary
+ *
+ * Parameters:
+ * from The source (C style) string
+ * to The destination (make style) string
+ * length The length of the from string
+ *
+ * Global variables used:
+ */
+void
+append_string(register wchar_t *from, register String to, register int length)
+{
+ if (length == FIND_LENGTH) {
+ length = wslen(from);
+ }
+ if (to->buffer.start == NULL) {
+ expand_string(to, 32 + length);
+ }
+ if (to->buffer.end - to->text.p <= length) {
+ expand_string(to,
+ (to->buffer.end - to->buffer.start) * 2 +
+ length);
+ }
+ if (length > 0) {
+ (void) wsncpy(to->text.p, from, length);
+ to->text.p += length;
+ }
+ *(to->text.p) = (int) nul_char;
+}
+
+wchar_t * get_wstring(char *from) {
+ if(from == NULL) {
+ return NULL;
+ }
+ getwstring_count++;
+ wchar_t * wcbuf = ALLOC_WC(strlen(from) + 1);
+ mbstowcs(wcbuf, from, strlen(from)+1);
+ return wcbuf;
+}
+
+void
+append_string(register char *from, register String to, register int length)
+{
+ if (length == FIND_LENGTH) {
+ length = strlen(from);
+ }
+ if (to->buffer.start == NULL) {
+ expand_string(to, 32 + length);
+ }
+ if (to->buffer.end - to->text.p <= length) {
+ expand_string(to,
+ (to->buffer.end - to->buffer.start) * 2 +
+ length);
+ }
+ if (length > 0) {
+ (void) mbstowcs(to->text.p, from, length);
+ to->text.p += length;
+ }
+ *(to->text.p) = (int) nul_char;
+}
+
+/*
+ * expand_string(string, length)
+ *
+ * Allocate more memory for strings that run out of space.
+ *
+ * Parameters:
+ * string The make style string we want to expand
+ * length The new length we need
+ *
+ * Global variables used:
+ */
+static void
+expand_string(register String string, register int length)
+{
+ register wchar_t *p;
+
+ if (string->buffer.start == NULL) {
+ /* For strings that have no memory allocated */
+ string->buffer.start =
+ string->text.p =
+ string->text.end =
+ ALLOC_WC(length);
+ string->buffer.end = string->buffer.start + length;
+ string->text.p[0] = (int) nul_char;
+ string->free_after_use = true;
+ expandstring_count++;
+ return;
+ }
+ if (string->buffer.end - string->buffer.start >= length) {
+ /* If we really don't need more memory. */
+ return;
+ }
+ /*
+ * Get more memory, copy the string and free the old buffer if
+ * it is was malloc()'ed.
+ */
+ expandstring_count++;
+ p = ALLOC_WC(length);
+ (void) wscpy(p, string->buffer.start);
+ string->text.p = p + (string->text.p - string->buffer.start);
+ string->text.end = p + (string->text.end - string->buffer.start);
+ string->buffer.end = p + length;
+ if (string->free_after_use) {
+ retmem(string->buffer.start);
+ }
+ string->buffer.start = p;
+ string->free_after_use = true;
+}
+
+/*
+ * append_char(from, to)
+ *
+ * Append one char to a make string expanding it if nessecary
+ *
+ * Parameters:
+ * from Single character to append to string
+ * to The destination (make style) string
+ *
+ * Global variables used:
+ */
+void
+append_char(wchar_t from, register String to)
+{
+ if (to->buffer.start == NULL) {
+ expand_string(to, 32);
+ }
+ if (to->buffer.end - to->text.p <= 2) {
+ expand_string(to, to->buffer.end - to->buffer.start + 32);
+ }
+ *(to->text.p)++ = from;
+ *(to->text.p) = (int) nul_char;
+}
+
+/*
+ * handle_interrupt_mksh()
+ *
+ * This is where C-C traps are caught.
+ */
+void
+handle_interrupt_mksh(int)
+{
+ (void) fflush(stdout);
+ /* Make sure the processes running under us terminate first. */
+ if (childPid > 0) {
+ kill(childPid, SIGTERM);
+ childPid = -1;
+ }
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ while (wait((int *) NULL) != -1);
+#if defined(SUN5_0)
+ exit_status = 2;
+#endif
+#else
+ while (wait((union wait *) NULL) != -1);
+#endif
+ exit(2);
+}
+
+/*
+ * setup_interrupt()
+ *
+ * This routine saves the original interrupt handler pointers
+ *
+ * Parameters:
+ *
+ * Static variables used:
+ * sigivalue The original signal handler
+ * sigqvalue The original signal handler
+ * sigtvalue The original signal handler
+ * sighvalue The original signal handler
+ */
+void
+setup_interrupt(register void (*handler) (int))
+{
+#ifdef SUN5_0
+ sigivalue = bsd_signal(SIGINT, SIG_IGN);
+ sigqvalue = bsd_signal(SIGQUIT, SIG_IGN);
+ sigtvalue = bsd_signal(SIGTERM, SIG_IGN);
+ sighvalue = bsd_signal(SIGHUP, SIG_IGN);
+#else
+ sigivalue = (void (*) (int)) bsd_signal(SIGINT, SIG_IGN);
+ sigqvalue = (void (*) (int)) bsd_signal(SIGQUIT, SIG_IGN);
+ sigtvalue = (void (*) (int)) bsd_signal(SIGTERM, SIG_IGN);
+ sighvalue = (void (*) (int)) bsd_signal(SIGHUP, SIG_IGN);
+#endif
+ enable_interrupt(handler);
+}
+
+
+void
+mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n)
+{
+ if(mbstowcs(pwcs, s, n) == -1) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 143, "The string `%s' is not valid in current locale"), s);
+ }
+}
+
+
+
+Wstring::Wstring()
+{
+ INIT_STRING_FROM_STACK(string, string_buf);
+}
+
+Wstring::Wstring(struct _Name * name)
+{
+ INIT_STRING_FROM_STACK(string, string_buf);
+ append_string(name->string_mb, &string, name->hash.length);
+}
+
+Wstring::~Wstring()
+{
+ if(string.free_after_use) {
+ retmem(string.buffer.start);
+ }
+}
+
+void
+Wstring::init(struct _Name * name)
+{
+ if(string.free_after_use) {
+ retmem(string.buffer.start);
+ }
+ INIT_STRING_FROM_STACK(string, string_buf);
+ append_string(name->string_mb, &string, name->hash.length);
+}
+
+void
+Wstring::init(wchar_t * name, unsigned length)
+{
+ INIT_STRING_FROM_STACK(string, string_buf);
+ append_string(name, &string, length);
+ string.buffer.start[length] = 0;
+}
+
+Boolean
+Wstring::equaln(wchar_t * str, unsigned length)
+{
+ return (Boolean)IS_WEQUALN(string.buffer.start, str, length);
+}
+
+Boolean
+Wstring::equaln(Wstring * str, unsigned length)
+{
+ return (Boolean)IS_WEQUALN(string.buffer.start, str->string.buffer.start, length);
+}
+
+Boolean
+Wstring::equal(wchar_t * str, unsigned off, unsigned length)
+{
+ return (Boolean)IS_WEQUALN(string.buffer.start + off, str, length);
+}
+
+Boolean
+Wstring::equal(wchar_t * str, unsigned off)
+{
+ return (Boolean)IS_WEQUAL(string.buffer.start + off, str);
+}
+
+Boolean
+Wstring::equal(wchar_t * str)
+{
+ return equal(str, 0);
+}
+
+Boolean
+Wstring::equal(Wstring * str, unsigned off, unsigned length)
+{
+ return (Boolean)IS_WEQUALN(string.buffer.start + off, str->string.buffer.start, length);
+}
+
+Boolean
+Wstring::equal(Wstring * str)
+{
+ return equal(str, 0);
+}
+
+Boolean
+Wstring::equal(Wstring * str, unsigned off)
+{
+ return (Boolean)IS_WEQUAL(string.buffer.start + off, str->string.buffer.start);
+}
+
+void
+Wstring::append_to_str(struct _String * str, unsigned off, unsigned length)
+{
+ append_string(string.buffer.start + off, str, length);
+}
+
+Name
+Name_set::lookup(const char *key)
+{
+ for (entry *node = root; node != 0;) {
+ int res = strcmp(key, node->name->string_mb);
+ if (res < 0) {
+ node = node->left;
+ } else if (res > 0) {
+ node = node->right;
+ } else {
+ return node->name;
+ }
+ }
+ return 0;
+}
+
+Name
+Name_set::insert(const char *key, Boolean &found)
+{
+ Name name = 0;
+
+ if (root != 0) {
+ for (entry *node = root; name == 0;) {
+ int res = strcmp(key, node->name->string_mb);
+ if (res < 0) {
+ if (node->left != 0) {
+ node = node->left;
+ } else {
+ found = false;
+ name = ALLOC(Name);
+
+ node->left = new entry(name, node);
+ rebalance(node);
+ }
+ } else if (res > 0) {
+ if (node->right != 0) {
+ node = node->right;
+ } else {
+ found = false;
+ name = ALLOC(Name);
+
+ node->right = new entry(name, node);
+ rebalance(node);
+ }
+ } else {
+ found = true;
+ name = node->name;
+ }
+ }
+ } else {
+ found = false;
+ name = ALLOC(Name);
+
+ root = new entry(name, 0);
+ }
+ return name;
+}
+
+void
+Name_set::insert(Name name) {
+ if (root != 0) {
+ for (entry *node = root;;) {
+ int res = strcmp(name->string_mb, node->name->string_mb);
+ if (res < 0) {
+ if (node->left != 0) {
+ node = node->left;
+ } else {
+ node->left = new entry(name, node);
+ rebalance(node);
+ break;
+ }
+ } else if (res > 0) {
+ if (node->right != 0) {
+ node = node->right;
+ } else {
+ node->right = new entry(name, node);
+ rebalance(node);
+ break;
+ }
+ } else {
+ // should be an error: inserting already existing name
+ break;
+ }
+ }
+ } else {
+ root = new entry(name, 0);
+ }
+}
+
+void
+Name_set::rebalance(Name_set::entry *node) {
+ for (; node != 0; node = node->parent) {
+ entry *right = node->right;
+ entry *left = node->left;
+
+ unsigned rdepth = (right != 0) ? right->depth : 0;
+ unsigned ldepth = (left != 0) ? left->depth : 0;
+
+ if (ldepth > rdepth + 1) {
+ if ((node->left = left->right) != 0) {
+ left->right->parent = node;
+ }
+ if ((left->parent = node->parent) != 0) {
+ if (node == node->parent->right) {
+ node->parent->right = left;
+ } else {
+ node->parent->left = left;
+ }
+ } else {
+ root = left;
+ }
+ left->right = node;
+ node->parent = left;
+
+ node->setup_depth();
+ node = left;
+ } else if (rdepth > ldepth + 1) {
+ if ((node->right = right->left) != 0) {
+ right->left->parent = node;
+ }
+ if ((right->parent = node->parent) != 0) {
+ if (node == node->parent->right) {
+ node->parent->right = right;
+ } else {
+ node->parent->left = right;
+ }
+ } else {
+ root = right;
+ }
+ right->left = node;
+ node->parent = right;
+
+ node->setup_depth();
+ node = right;
+ }
+ node->setup_depth();
+ }
+}
+
+Name_set::iterator
+Name_set::begin() const {
+ for (entry *node = root; node != 0; node = node->left) {
+ if (node->left == 0) {
+ return iterator(node);
+ }
+ }
+ return iterator();
+}
+
+Name_set::iterator&
+Name_set::iterator::operator++() {
+ if (node != 0) {
+ if (node->right != 0) {
+ node = node->right;
+ while (node->left != 0) {
+ node = node->left;
+ }
+ } else {
+ while ((node->parent != 0) && (node->parent->right == node)) {
+ node = node->parent;
+ }
+ node = node->parent;
+ }
+ }
+ return *this;
+}
diff --git a/usr/src/make_src/Make/lib/mksh/src/mksh.cc b/usr/src/make_src/Make/lib/mksh/src/mksh.cc
new file mode 100644
index 0000000..98c9601
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksh/src/mksh.cc
@@ -0,0 +1,286 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)mksh.cc 1.22 06/12/12
+ */
+
+#pragma ident "@(#)mksh.cc 1.22 06/12/12"
+
+/*
+ * mksh.cc
+ *
+ * Execute the command(s) of one Make or DMake rule
+ */
+
+/*
+ * Included files
+ */
+#if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL) /* tolik */
+# include <avo/util.h>
+#endif
+
+#include <mksh/dosys.h> /* redirect_io() */
+#include <mksh/misc.h> /* retmem() */
+#include <mksh/mksh.h>
+#include <mksdmsi18n/mksdmsi18n.h>
+#include <errno.h>
+#include <signal.h>
+
+#ifdef HP_UX
+ extern void (*sigset(int, void (*)(__harg)))(__harg);
+#endif
+
+/*
+ * Workaround for NFS bug. Sometimes, when running 'chdir' on a remote
+ * dmake server, it fails with "Stale NFS file handle" error.
+ * The second attempt seems to work.
+ */
+int
+my_chdir(char * dir) {
+ int res = chdir(dir);
+ if (res != 0 && (errno == ESTALE || errno == EAGAIN)) {
+ /* Stale NFS file handle. Try again */
+ res = chdir(dir);
+ }
+ return res;
+}
+
+
+/*
+ * File table of contents
+ */
+static void change_sunpro_dependencies_value(char *oldpath, char *newpath);
+static void init_mksh_globals(char *shell);
+static void set_env_vars(char *env_list[]);
+
+#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
+/*
+ * Execute the command(s) of one Make or DMake rule
+ */
+int
+do_job(Avo_DmakeCommand *cmd_list[], char *env_list[], char *stdout_file, char *stderr_file, char *cwd, char *cnwd, int ignore, int silent, pathpt vroot_path, char *shell, int nice_prio)
+{
+ Boolean always_exec_flag;
+ char *cmd;
+ Avo_DmakeCommand **cmd_list_p;
+ Name command;
+ Boolean do_not_exec_flag;
+ Boolean ignore_flag;
+ int length;
+ Boolean make_refd_flag;
+ Boolean meta_flag;
+ char pathname[MAXPATHLEN];
+ Doname result;
+ Boolean silent_flag;
+ wchar_t *tmp_wcs_buffer;
+
+ if ((childPid = fork()) < 0) { /* error */
+ ;
+ } else if (childPid > 0) { /* parent */
+ ;
+ } else { /* child, mksh */
+ (void) sigset(SIGCHLD, SIG_DFL);
+ enable_interrupt(handle_interrupt_mksh);
+ /* set environment variables */
+ set_env_vars(env_list);
+ /* redirect stdout and stderr to temp files */
+ dup2(1, 2); // Because fatal_mksh() prints error messages into
+ // stderr but dmake uses stderr for XDR communications
+ // and stdout for errors messages.
+ redirect_io(stdout_file, stderr_file);
+ /* try cd'ing to cwd */
+ if (my_chdir(cwd) != 0) {
+ /* try the netpath machine:pathname */
+ if (!avo_netpath_to_path(cnwd, pathname)) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 137, "`cd %s' failed, and conversion of %s to automounter pathname also failed: %s"), cwd, cnwd, strerror(errno));
+ } else if (my_chdir(pathname) != 0) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 138, "`cd %s' and `cd %s' both failed: %s"), cwd, pathname, strerror(errno));
+ }
+ /*
+ * change the value of SUNPRO_DEPENDENCIES
+ * to the new path.
+ */
+ change_sunpro_dependencies_value(cwd, pathname);
+ }
+ init_mksh_globals(shell);
+ for (cmd_list_p = cmd_list;
+ *cmd_list_p != (Avo_DmakeCommand *) NULL;
+ cmd_list_p++) {
+ if ((*cmd_list_p)->ignore()) {
+ ignore_flag = true;
+ } else {
+ ignore_flag = false;
+ }
+ if ((*cmd_list_p)->silent()) {
+ silent_flag = true;
+ } else {
+ silent_flag = false;
+ }
+/*
+ if ((*cmd_list_p)->always_exec()) {
+ always_exec_flag = true;
+ } else {
+ always_exec_flag = false;
+ }
+ */
+ always_exec_flag = false;
+ if ((*cmd_list_p)->meta()) {
+ meta_flag = true;
+ } else {
+ meta_flag = false;
+ }
+ if ((*cmd_list_p)->make_refd()) {
+ make_refd_flag = true;
+ } else {
+ make_refd_flag = false;
+ }
+ if ((*cmd_list_p)->do_not_exec()) {
+ do_not_exec_flag = true;
+ } else {
+ do_not_exec_flag = false;
+ }
+ do_not_exec_rule = do_not_exec_flag;
+ cmd = (*cmd_list_p)->getCmd();
+ if ((length = strlen(cmd)) >= MAXPATHLEN) {
+ tmp_wcs_buffer = ALLOC_WC(length + 1);
+ (void) mbstowcs(tmp_wcs_buffer, cmd, length + 1);
+ command = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
+ retmem(tmp_wcs_buffer);
+ } else {
+ MBSTOWCS(wcs_buffer, cmd);
+ command = GETNAME(wcs_buffer, FIND_LENGTH);
+ }
+ if ((command->hash.length > 0) &&
+ (!silent_flag || do_not_exec_flag)) {
+ (void) printf("%s\n", command->string_mb);
+ }
+ result = dosys_mksh(command,
+ ignore_flag,
+ make_refd_flag,
+ false, /* bugs #4085164 & #4990057 */
+ /* BOOLEAN(silent_flag && ignore_flag), */
+ always_exec_flag,
+ (Name) NULL,
+ false,
+ NULL,
+ NULL,
+ vroot_path,
+ nice_prio);
+ if (result == build_failed) {
+
+#ifdef PRINT_EXIT_STATUS
+ warning_mksh(NOCATGETS("I'm in do_job(), and dosys_mksh() returned result of build_failed."));
+#endif
+
+ if (silent_flag) {
+ (void) printf(catgets(libmksdmsi18n_catd, 1, 139, "The following command caused the error:\n%s\n"),
+ command->string_mb);
+ }
+ if (!ignore_flag && !ignore) {
+
+#ifdef PRINT_EXIT_STATUS
+ warning_mksh(NOCATGETS("I'm in do_job(), and dosys_mksh() returned result of build_failed, exiting 1."));
+#endif
+
+ exit(1);
+ }
+ }
+ }
+
+#ifdef PRINT_EXIT_STATUS
+ warning_mksh(NOCATGETS("I'm in do_job(), exiting 0."));
+#endif
+
+ exit(0);
+ }
+ return childPid;
+}
+#endif /* TEAMWARE_MAKE_CMN */
+
+static void
+set_env_vars(char *env_list[])
+{
+ char **env_list_p;
+
+ for (env_list_p = env_list;
+ *env_list_p != (char *) NULL;
+ env_list_p++) {
+ putenv(*env_list_p);
+ }
+}
+
+static void
+init_mksh_globals(char *shell)
+{
+/*
+ MBSTOWCS(wcs_buffer, NOCATGETS("SHELL"));
+ shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
+ MBSTOWCS(wcs_buffer, shell);
+ (void) SETVAR(shell_name, GETNAME(wcs_buffer, FIND_LENGTH), false);
+ */
+ char * dmake_shell;
+ if ((dmake_shell = getenv(NOCATGETS("DMAKE_SHELL"))) == NULL) {
+ dmake_shell = shell;
+ }
+ MBSTOWCS(wcs_buffer, dmake_shell);
+ shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
+}
+
+/*
+ * Change the pathname in the value of the SUNPRO_DEPENDENCIES env variable
+ * from oldpath to newpath.
+ */
+static void
+change_sunpro_dependencies_value(char *oldpath, char *newpath)
+{
+ char buf[MAXPATHLEN];
+ static char *env;
+ int length;
+ int oldpathlen;
+ char *sp_dep_value;
+
+ /* check if SUNPRO_DEPENDENCIES is set in the environment */
+ if ((sp_dep_value = getenv(NOCATGETS("SUNPRO_DEPENDENCIES"))) != NULL) {
+ oldpathlen = strlen(oldpath);
+ /* check if oldpath is indeed in the value of SUNPRO_DEPENDENCIES */
+ if (strncmp(oldpath, sp_dep_value, oldpathlen) == 0) {
+ (void) sprintf(buf,
+ "%s%s",
+ newpath,
+ sp_dep_value + oldpathlen);
+ length = 2 +
+ strlen(NOCATGETS("SUNPRO_DEPENDENCIES")) +
+ strlen(buf);
+ env = getmem(length);
+ (void) sprintf(env,
+ "%s=%s",
+ NOCATGETS("SUNPRO_DEPENDENCIES"),
+ buf);
+ (void) putenv(env);
+ }
+ }
+}
+
+
diff --git a/usr/src/make_src/Make/lib/mksh/src/read.cc b/usr/src/make_src/Make/lib/mksh/src/read.cc
new file mode 100644
index 0000000..53cd524
--- /dev/null
+++ b/usr/src/make_src/Make/lib/mksh/src/read.cc
@@ -0,0 +1,174 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)read.cc 1.11 06/12/12
+ */
+
+#pragma ident "@(#)read.cc 1.11 06/12/12"
+
+/*
+ * read.c
+ *
+ * This file contains the makefile reader.
+ */
+
+/*
+ * Included files
+ */
+#include <mksh/misc.h> /* retmem() */
+#include <mksh/read.h>
+#include <mksdmsi18n/mksdmsi18n.h>
+#include <sys/uio.h> /* read() */
+#include <unistd.h> /* close(), unlink(), read() */
+
+#define STRING_LEN_TO_CONVERT (8*1024)
+
+/*
+ * get_next_block_fn(source)
+ *
+ * Will get the next block of text to read either
+ * by popping one source bVSIZEOFlock of the stack of Sources
+ * or by reading some more from the makefile.
+ *
+ * Return value:
+ * The new source block to read from
+ *
+ * Parameters:
+ * source The old source block
+ *
+ * Global variables used:
+ * file_being_read The name of the current file, error msg
+ */
+Boolean make_state_locked;
+Source
+get_next_block_fn(register Source source)
+{
+ register off_t to_read;
+ register int length;
+ register size_t num_wc_chars;
+ char ch_save;
+ char *ptr;
+
+ if (source == NULL) {
+ return NULL;
+ }
+ if ((source->fd < 0) ||
+ ((source->bytes_left_in_file <= 0) &&
+ (source->inp_buf_ptr >= source->inp_buf_end))) {
+ /* We can't read from the makefile, so pop the source block */
+ if (source->fd > 2) {
+ (void) close(source->fd);
+ if (make_state_lockfile != NULL) {
+ (void) unlink(make_state_lockfile);
+ retmem_mb(make_state_lockfile);
+ make_state_lockfile = NULL;
+ make_state_locked = false;
+ }
+ }
+ if (source->string.free_after_use &&
+ (source->string.buffer.start != NULL)) {
+ retmem(source->string.buffer.start);
+ source->string.buffer.start = NULL;
+ }
+ if (source->inp_buf != NULL) {
+ retmem_mb(source->inp_buf);
+ source->inp_buf = NULL;
+ }
+ source = source->previous;
+ if (source != NULL) {
+ source->error_converting = false;
+ }
+ return source;
+ }
+ if (source->bytes_left_in_file > 0) {
+ /*
+ * Read the whole makefile.
+ * Hopefully the kernel managed to prefetch the stuff.
+ */
+ to_read = source->bytes_left_in_file;
+ source->inp_buf_ptr = source->inp_buf = getmem(to_read + 1);
+ source->inp_buf_end = source->inp_buf + to_read;
+ length = read(source->fd, source->inp_buf, (unsigned int) to_read);
+ if (length != to_read) {
+ WCSTOMBS(mbs_buffer, file_being_read);
+ if (length == 0) {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 140, "Error reading `%s': Premature EOF"),
+ mbs_buffer);
+ } else {
+ fatal_mksh(catgets(libmksdmsi18n_catd, 1, 141, "Error reading `%s': %s"),
+ mbs_buffer,
+ errmsg(errno));
+ }
+ }
+ *source->inp_buf_end = nul_char;
+ source->bytes_left_in_file = 0;
+ }
+ /*
+ * Try to convert the next piece.
+ */
+ ptr = source->inp_buf_ptr + STRING_LEN_TO_CONVERT;
+ if (ptr > source->inp_buf_end) {
+ ptr = source->inp_buf_end;
+ }
+ for (num_wc_chars = 0; ptr > source->inp_buf_ptr; ptr--) {
+ ch_save = *ptr;
+ *ptr = nul_char;
+ num_wc_chars = mbstowcs(source->string.text.end,
+ source->inp_buf_ptr,
+ STRING_LEN_TO_CONVERT);
+ *ptr = ch_save;
+ if (num_wc_chars != (size_t)-1) {
+ break;
+ }
+ }
+
+ if ((int) num_wc_chars == (size_t)-1) {
+ source->error_converting = true;
+ return source;
+ }
+
+ source->error_converting = false;
+ source->inp_buf_ptr = ptr;
+ source->string.text.end += num_wc_chars;
+ *source->string.text.end = 0;
+
+ if (source->inp_buf_ptr >= source->inp_buf_end) {
+ if (*(source->string.text.end - 1) != (int) newline_char) {
+ WCSTOMBS(mbs_buffer, file_being_read);
+ warning_mksh(catgets(libmksdmsi18n_catd, 1, 142, "newline is not last character in file %s"),
+ mbs_buffer);
+ *source->string.text.end++ = (int) newline_char;
+ *source->string.text.end = (int) nul_char;
+ *source->string.buffer.end++;
+ }
+ if (source->inp_buf != NULL) {
+ retmem_mb(source->inp_buf);
+ source->inp_buf = NULL;
+ }
+ }
+ return source;
+}
+
+
diff --git a/usr/src/make_src/Make/lib/vroot/Makefile b/usr/src/make_src/Make/lib/vroot/Makefile
new file mode 100644
index 0000000..fd663cd
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/Makefile
@@ -0,0 +1,29 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.5 06/12/12
+#
+
+TOP = ../../..
+include $(TOP)/rules/variant.mk
+include $(TOP)/rules/derived.mk
diff --git a/usr/src/make_src/Make/lib/vroot/src/Makefile b/usr/src/make_src/Make/lib/vroot/src/Makefile
new file mode 100644
index 0000000..299c46d
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/Makefile
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.3 06/12/12
+#
+
+# Generic makefile for use in src directories. Knows how to make common things
+# in the right $(VARIANT) directory.
+
+include $(TOP)/rules/variant.mk
+
+all := TARG = all
+install := TARG = install
+clean := TARG = clean
+test := TARG = test
+l10n_install := TARG = l10n_install
+i18n_install := TARG = i18n_install
+
+SRC = ../src
+MFLAGS += SRC=$(SRC)
+
+# See $(TOP)/rules/master.mk for how these are built.
+%.h %.cc %.C %.E %.o all install clean test l10n_install i18n_install: FRC
+ @ if [ ! -d ../$(VARIANT) ]; then \
+ mkdir ../$(VARIANT) ; \
+ fi
+ cd ../$(VARIANT); $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk DESTDIR=$(DESTDIR) $@
+
+FRC:
diff --git a/usr/src/make_src/Make/lib/vroot/src/Variant.mk b/usr/src/make_src/Make/lib/vroot/src/Variant.mk
new file mode 100644
index 0000000..b276156
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/Variant.mk
@@ -0,0 +1,71 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Variant.mk 1.28 06/12/12
+#
+
+TOP = ../../../..
+include $(TOP)/rules/master.mk
+include $(TOP)/rules/dmake.mk
+
+PKG_TOP = $(TOP)/Make
+CPPFLAGS += -I$(PKG_TOP)/include
+
+CCSRCS = \
+ access.cc \
+ args.cc \
+ chdir.cc \
+ chmod.cc \
+ chown.cc \
+ chroot.cc \
+ creat.cc \
+ execve.cc \
+ lock.cc \
+ lstat.cc \
+ mkdir.cc \
+ mount.cc \
+ open.cc \
+ readlink.cc \
+ report.cc \
+ rmdir.cc \
+ stat.cc \
+ statfs.cc \
+ truncate.cc \
+ unlink.cc \
+ unmount.cc \
+ utimes.cc \
+ vroot.cc \
+ setenv.cc
+
+
+HDRS_DIR = $(PKG_TOP)/include/vroot
+
+.INIT: $(HDRS_DIR)/args.h $(HDRS_DIR)/report.h $(HDRS_DIR)/vroot.h
+
+LIBNAME = libvroot.a
+MSG_FILE = libvroot.msg
+I18N_DIRS = $(SRC)
+
+include $(TOP)/Make/lib/Lib.mk
+include $(TOP)/rules/lib.mk
+
diff --git a/usr/src/make_src/Make/lib/vroot/src/access.cc b/usr/src/make_src/Make/lib/vroot/src/access.cc
new file mode 100644
index 0000000..83141cc
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/access.cc
@@ -0,0 +1,46 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)access.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)access.cc 1.4 06/12/12"
+
+#include <unistd.h>
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int access_thunk(char *path)
+{
+ vroot_result= access(path, vroot_args.access.mode);
+ return((vroot_result == 0) || (errno != ENOENT));
+}
+
+int access_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.access.mode= mode;
+ translate_with_thunk(path, access_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/args.cc b/usr/src/make_src/Make/lib/vroot/src/args.cc
new file mode 100644
index 0000000..de4ad9b
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/args.cc
@@ -0,0 +1,35 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)args.cc 1.3 06/12/12
+ */
+
+#pragma ident "@(#)args.cc 1.3 06/12/12"
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+union Args vroot_args;
+int vroot_result;
diff --git a/usr/src/make_src/Make/lib/vroot/src/chdir.cc b/usr/src/make_src/Make/lib/vroot/src/chdir.cc
new file mode 100644
index 0000000..c5aa0ac
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/chdir.cc
@@ -0,0 +1,45 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)chdir.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)chdir.cc 1.4 06/12/12"
+
+#include <unistd.h>
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int chdir_thunk(char *path)
+{
+ vroot_result= chdir(path);
+ return(vroot_result == 0);
+}
+
+int chdir_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
+{
+ translate_with_thunk(path, chdir_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/chmod.cc b/usr/src/make_src/Make/lib/vroot/src/chmod.cc
new file mode 100644
index 0000000..64cda72
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/chmod.cc
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)chmod.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)chmod.cc 1.4 06/12/12"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+extern int chmod(const char *path, mode_t mode);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int chmod_thunk(char *path)
+{
+ vroot_result= chmod(path, vroot_args.chmod.mode);
+ return(vroot_result == 0);
+}
+
+int chmod_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.chmod.mode= mode;
+ translate_with_thunk(path, chmod_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/chown.cc b/usr/src/make_src/Make/lib/vroot/src/chown.cc
new file mode 100644
index 0000000..eeeb2ef
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/chown.cc
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)chown.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)chown.cc 1.4 06/12/12"
+
+#include <unistd.h>
+#include <sys/types.h>
+
+extern int chown(const char *path, uid_t owner, gid_t group);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int chown_thunk(char *path)
+{
+ vroot_result= chown(path, vroot_args.chown.user, vroot_args.chown.group);
+ return(vroot_result == 0);
+}
+
+int chown_vroot(char *path, int user, int group, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.chown.user= user;
+ vroot_args.chown.group= group;
+ translate_with_thunk(path, chown_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/chroot.cc b/usr/src/make_src/Make/lib/vroot/src/chroot.cc
new file mode 100644
index 0000000..8586a8c
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/chroot.cc
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)chroot.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)chroot.cc 1.4 06/12/12"
+
+#include <unistd.h>
+
+extern int chroot(const char *path);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int chroot_thunk(char *path)
+{
+ vroot_result= chroot(path);
+ return(vroot_result == 0);
+}
+
+int chroot_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
+{
+ translate_with_thunk(path, chroot_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/creat.cc b/usr/src/make_src/Make/lib/vroot/src/creat.cc
new file mode 100644
index 0000000..27aa694
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/creat.cc
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)creat.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)creat.cc 1.4 06/12/12"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+extern int creat(const char *path, mode_t mode);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int creat_thunk(char *path)
+{
+ vroot_result= creat(path, vroot_args.creat.mode);
+ return(vroot_result >= 0);
+}
+
+int creat_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.creat.mode= mode;
+ translate_with_thunk(path, creat_thunk, vroot_path, vroot_vroot, rw_write);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/execve.cc b/usr/src/make_src/Make/lib/vroot/src/execve.cc
new file mode 100644
index 0000000..ec2a268
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/execve.cc
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)execve.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)execve.cc 1.4 06/12/12"
+
+#include <unistd.h>
+
+extern int execve (const char *path, char *const argv[], char *const envp[]);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int execve_thunk(char *path)
+{
+ execve(path, vroot_args.execve.argv, vroot_args.execve.environ);
+ switch (errno) {
+ case ETXTBSY:
+ case ENOEXEC: return 1;
+ default: return 0;
+ }
+}
+
+int execve_vroot(char *path, char **argv, char **environ, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.execve.argv= argv;
+ vroot_args.execve.environ= environ;
+ translate_with_thunk(path, execve_thunk, vroot_path, vroot_vroot, rw_read);
+ return(-1);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/libvroot.msg b/usr/src/make_src/Make/lib/vroot/src/libvroot.msg
new file mode 100644
index 0000000..f3a805f
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/libvroot.msg
@@ -0,0 +1,38 @@
+
+$quote "
+
+
+$set 1
+$
+$ CDDL HEADER START
+$
+$ The contents of this file are subject to the terms of the
+$ Common Development and Distribution License (the "License").
+$ You may not use this file except in compliance with the License.
+$
+$ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+$ or http://www.opensolaris.org/os/licensing.
+$ See the License for the specific language governing permissions
+$ and limitations under the License.
+$
+$ When distributing Covered Code, include this CDDL HEADER in each
+$ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+$ If applicable, add the following below this CDDL HEADER, with the
+$ fields enclosed by brackets "[]" replaced with your own identifying
+$ information: Portions Copyright [yyyy] [name of copyright owner]
+$
+$ CDDL HEADER END
+$
+$ Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+$ Use is subject to license terms.
+$
+$ @(#)libvroot.msg 1.2 06/12/12
+$
+142 "file_lock: file %s is already locked.\n"
+143 "file_lock: will periodically check the lockfile %s for two minutes.\n"
+144 "Current working directory %s\n"
+145 "Could not lock file `%s'; "
+146 " failed - "
+147 "Couldn't write to %s"
+148 "Cannot open `%s' for writing\n"
+149 "Cannot open %s for writing\n"
diff --git a/usr/src/make_src/Make/lib/vroot/src/lock.cc b/usr/src/make_src/Make/lib/vroot/src/lock.cc
new file mode 100644
index 0000000..ca5a9a5
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/lock.cc
@@ -0,0 +1,196 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)lock.cc 1.17 06/12/12
+ */
+
+#pragma ident "@(#)lock.cc 1.17 06/12/12"
+
+#include <avo/intl.h> /* for NOCATGETS */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/errno.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <vroot/vroot.h>
+#include <mksdmsi18n/mksdmsi18n.h>
+#include <signal.h>
+#include <errno.h> /* errno */
+
+#if !defined(linux)
+extern char *sys_errlist[];
+extern int sys_nerr;
+#endif
+
+static void file_lock_error(char *msg, char *file, char *str, int arg1, int arg2);
+
+#define BLOCK_INTERUPTS sigfillset(&newset) ; \
+ sigprocmask(SIG_SETMASK, &newset, &oldset)
+
+#define UNBLOCK_INTERUPTS \
+ sigprocmask(SIG_SETMASK, &oldset, &newset)
+
+/*
+ * This code stolen from the NSE library and changed to not depend
+ * upon any NSE routines or header files.
+ *
+ * Simple file locking.
+ * Create a symlink to a file. The "test and set" will be
+ * atomic as creating the symlink provides both functions.
+ *
+ * The timeout value specifies how long to wait for stale locks
+ * to disappear. If the lock is more than 'timeout' seconds old
+ * then it is ok to blow it away. This part has a small window
+ * of vunerability as the operations of testing the time,
+ * removing the lock and creating a new one are not atomic.
+ * It would be possible for two processes to both decide to blow
+ * away the lock and then have process A remove the lock and establish
+ * its own, and then then have process B remove the lock which accidentily
+ * removes A's lock rather than the stale one.
+ *
+ * A further complication is with the NFS. If the file in question is
+ * being served by an NFS server, then its time is set by that server.
+ * We can not use the time on the client machine to check for a stale
+ * lock. Therefore, a temp file on the server is created to get
+ * the servers current time.
+ *
+ * Returns an error message. NULL return means the lock was obtained.
+ *
+ * 12/6/91 Added the parameter "file_locked". Before this parameter
+ * was added, the calling procedure would have to wait for file_lock()
+ * to return before it sets the flag. If the user interrupted "make"
+ * between the time the lock was acquired and the time file_lock()
+ * returns, make wouldn't know that the file has been locked, and therefore
+ * it wouldn' remove the lock. Setting the flag right after locking the file
+ * makes this window much smaller.
+ */
+
+int
+file_lock(char *name, char *lockname, int *file_locked, int timeout)
+{
+ int counter = 0;
+ static char msg[MAXPATHLEN+1];
+ int printed_warning = 0;
+ int r;
+ struct stat statb;
+ sigset_t newset;
+ sigset_t oldset;
+
+ *file_locked = 0;
+ if (timeout <= 0) {
+ timeout = 120;
+ }
+ for (;;) {
+ BLOCK_INTERUPTS;
+ r = symlink(name, lockname);
+ if (r == 0) {
+ *file_locked = 1;
+ UNBLOCK_INTERUPTS;
+ return 0; /* success */
+ }
+ UNBLOCK_INTERUPTS;
+
+ if (errno != EEXIST) {
+ file_lock_error(msg, name, NOCATGETS("symlink(%s, %s)"),
+ (int) name, (int) lockname);
+ fprintf(stderr, "%s", msg);
+ return errno;
+ }
+
+ counter = 0;
+ for (;;) {
+ sleep(1);
+ r = lstat(lockname, &statb);
+ if (r == -1) {
+ /*
+ * The lock must have just gone away - try
+ * again.
+ */
+ break;
+ }
+
+ if ((counter > 5) && (!printed_warning)) {
+ /* Print waiting message after 5 secs */
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ (void) getcwd(msg, MAXPATHLEN);
+#else
+ (void) getwd(msg);
+#endif
+ fprintf(stderr,
+ catgets(libmksdmsi18n_catd, 1, 162, "file_lock: file %s is already locked.\n"),
+ name);
+ fprintf(stderr,
+ catgets(libmksdmsi18n_catd, 1, 163, "file_lock: will periodically check the lockfile %s for two minutes.\n"),
+ lockname);
+ fprintf(stderr,
+ catgets(libmksdmsi18n_catd, 1, 144, "Current working directory %s\n"),
+ msg);
+
+ printed_warning = 1;
+ }
+
+ if (++counter > timeout ) {
+ /*
+ * Waited enough - return an error..
+ */
+ return EEXIST;
+ }
+ }
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * Format a message telling why the lock could not be created.
+ */
+static void
+file_lock_error(char *msg, char *file, char *str, int arg1, int arg2)
+{
+ int len;
+
+ sprintf(msg, catgets(libmksdmsi18n_catd, 1, 145, "Could not lock file `%s'; "), file);
+ len = strlen(msg);
+ sprintf(&msg[len], str, arg1, arg2);
+ strcat(msg, catgets(libmksdmsi18n_catd, 1, 146, " failed - "));
+#if !defined(linux)
+ if (errno < sys_nerr) {
+#ifdef SUN4_x
+ strcat(msg, sys_errlist[errno]);
+#endif
+#ifdef SUN5_0
+ strcat(msg, strerror(errno));
+#endif
+ } else {
+ len = strlen(msg);
+ sprintf(&msg[len], NOCATGETS("errno %d"), errno);
+ }
+#else
+ strcat(msg, strerror(errno));
+#endif
+}
+
diff --git a/usr/src/make_src/Make/lib/vroot/src/lstat.cc b/usr/src/make_src/Make/lib/vroot/src/lstat.cc
new file mode 100644
index 0000000..ba938aa
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/lstat.cc
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1998 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)lstat.cc 1.6 06/12/12
+ */
+
+#pragma ident "@(#)lstat.cc 1.6 06/12/12"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+extern int lstat(const char *path, struct stat *buf);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int lstat_thunk(char *path)
+{
+ vroot_result= lstat(path, vroot_args.lstat.buffer);
+ return(vroot_result == 0);
+}
+
+int lstat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.lstat.buffer= buffer;
+ translate_with_thunk(path, lstat_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/mkdir.cc b/usr/src/make_src/Make/lib/vroot/src/mkdir.cc
new file mode 100644
index 0000000..7180039
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/mkdir.cc
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)mkdir.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)mkdir.cc 1.4 06/12/12"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+extern int mkdir(const char *path, mode_t mode);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int mkdir_thunk(char *path)
+{
+ vroot_result= mkdir(path, vroot_args.mkdir.mode);
+ return(vroot_result == 0);
+}
+
+int mkdir_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.mkdir.mode= mode;
+ translate_with_thunk(path, mkdir_thunk, vroot_path, vroot_vroot, rw_write);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/mount.cc b/usr/src/make_src/Make/lib/vroot/src/mount.cc
new file mode 100644
index 0000000..2769a55
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/mount.cc
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1995 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)mount.cc 1.5 06/12/12
+ */
+
+#pragma ident "@(#)mount.cc 1.5 06/12/12"
+
+#include <sys/types.h>
+#include <sys/mount.h>
+
+#ifndef HP_UX
+extern int mount(const char *spec, const char *dir, int mflag, ...);
+#endif
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int mount_thunk(char *path)
+{
+ vroot_result= mount(path, vroot_args.mount.name, vroot_args.mount.mode);
+ return(vroot_result == 0);
+}
+
+int mount_vroot(char *target, char *name, int mode, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.mount.name= name;
+ vroot_args.mount.mode= mode;
+ translate_with_thunk(target, mount_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/open.cc b/usr/src/make_src/Make/lib/vroot/src/open.cc
new file mode 100644
index 0000000..30b44e6
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/open.cc
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)open.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)open.cc 1.4 06/12/12"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+extern int open(const char *path, int oflag, ...);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int open_thunk(char *path)
+{
+ vroot_result= open(path, vroot_args.open.flags, vroot_args.open.mode);
+ return(vroot_result >= 0);
+}
+
+int open_vroot(char *path, int flags, int mode, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.open.flags= flags;
+ vroot_args.open.mode= mode;
+ translate_with_thunk(path, open_thunk, vroot_path, vroot_vroot,
+ ((flags & (O_CREAT|O_APPEND)) != 0) ? rw_write : rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/readlink.cc b/usr/src/make_src/Make/lib/vroot/src/readlink.cc
new file mode 100644
index 0000000..e0efe5b
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/readlink.cc
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)readlink.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)readlink.cc 1.4 06/12/12"
+
+#include <unistd.h>
+
+extern int readlink(const char *path, void *buf, size_t bufsiz);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int readlink_thunk(char *path)
+{
+ vroot_result= readlink(path, vroot_args.readlink.buffer, vroot_args.readlink.buffer_size);
+ return(vroot_result >= 0);
+}
+
+int readlink_vroot(char *path, char *buffer, int buffer_size, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.readlink.buffer= buffer;
+ vroot_args.readlink.buffer_size= buffer_size;
+ translate_with_thunk(path, readlink_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/report.cc b/usr/src/make_src/Make/lib/vroot/src/report.cc
new file mode 100644
index 0000000..192eb13
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/report.cc
@@ -0,0 +1,396 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)report.cc 1.17 06/12/12
+ */
+
+#pragma ident "@(#)report.cc 1.17 06/12/12"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <vroot/report.h>
+#include <vroot/vroot.h>
+#include <mksdmsi18n/mksdmsi18n.h>
+#include <avo/intl.h> /* for NOCATGETS */
+#include <mk/defs.h> /* for tmpdir */
+
+static FILE *report_file;
+static FILE *command_output_fp;
+static char *target_being_reported_for;
+static char *search_dir;
+static char command_output_tmpfile[30];
+static int is_path = 0;
+static char sfile[MAXPATHLEN];
+extern "C" {
+static void (*warning_ptr) (char *, ...) = (void (*) (char *, ...)) NULL;
+}
+
+FILE *
+get_report_file(void)
+{
+ return(report_file);
+}
+
+char *
+get_target_being_reported_for(void)
+{
+ return(target_being_reported_for);
+}
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+extern "C" {
+static void
+close_report_file(void)
+{
+ (void)fputs("\n", report_file);
+ (void)fclose(report_file);
+}
+} // extern "C"
+#else
+static void
+close_report_file(int, ...)
+{
+ (void)fputs("\n", report_file);
+ (void)fclose(report_file);
+}
+#endif
+
+static void
+clean_up(FILE *nse_depinfo_fp, FILE *merge_fp, char *nse_depinfo_file, char *merge_file, int unlinkf)
+{
+ fclose(nse_depinfo_fp);
+ fclose(merge_fp);
+ fclose(command_output_fp);
+ unlink(command_output_tmpfile);
+ if (unlinkf)
+ unlink(merge_file);
+ else
+ rename(merge_file, nse_depinfo_file);
+}
+
+
+/*
+ * Update the file, if necessary. We don't want to rewrite
+ * the file if we don't have to because we don't want the time of the file
+ * to change in that case.
+ */
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+extern "C" {
+static void
+close_file(void)
+#else
+static void
+close_file(int, ...)
+#endif
+{
+ char line[MAXPATHLEN+2];
+ char buf[MAXPATHLEN+2];
+ FILE *nse_depinfo_fp;
+ FILE *merge_fp;
+ char nse_depinfo_file[MAXPATHLEN];
+ char merge_file[MAXPATHLEN];
+ char lock_file[MAXPATHLEN];
+ int err;
+ int len;
+ int changed = 0;
+ int file_locked;
+
+ fprintf(command_output_fp, "\n");
+ fclose(command_output_fp);
+ if ((command_output_fp = fopen(command_output_tmpfile, "r")) == NULL) {
+ return;
+ }
+ sprintf(nse_depinfo_file, "%s/%s", search_dir, NSE_DEPINFO);
+ sprintf(merge_file, NOCATGETS("%s/.tmp%s.%d"), search_dir, NSE_DEPINFO, getpid());
+ sprintf(lock_file, "%s/%s", search_dir, NSE_DEPINFO_LOCK);
+ err = file_lock(nse_depinfo_file, lock_file, &file_locked, 0);
+ if (err) {
+ if (warning_ptr != (void (*) (char *, ...)) NULL) {
+ (*warning_ptr)(catgets(libmksdmsi18n_catd, 1, 147, "Couldn't write to %s"), nse_depinfo_file);
+ }
+ unlink(command_output_tmpfile);
+ return;
+ }
+ /* If .nse_depinfo file doesn't exist */
+ if ((nse_depinfo_fp = fopen(nse_depinfo_file, "r+")) == NULL) {
+ if (is_path) {
+ if ((nse_depinfo_fp =
+ fopen(nse_depinfo_file, "w")) == NULL) {
+ fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 148, "Cannot open `%s' for writing\n"),
+ nse_depinfo_file);
+ unlink(command_output_tmpfile);
+
+ unlink(lock_file);
+ return;
+ }
+ while (fgets(line, MAXPATHLEN+2, command_output_fp)
+ != NULL) {
+ fprintf(nse_depinfo_fp, "%s", line);
+ }
+ fclose(command_output_fp);
+ }
+ fclose(nse_depinfo_fp);
+ if (file_locked) {
+ unlink(lock_file);
+ }
+ unlink(command_output_tmpfile);
+ return;
+ }
+ if ((merge_fp = fopen(merge_file, "w")) == NULL) {
+ fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 149, "Cannot open %s for writing\n"), merge_file);
+ if (file_locked) {
+ unlink(lock_file);
+ }
+ unlink(command_output_tmpfile);
+ return;
+ }
+ len = strlen(sfile);
+ while (fgets(line, MAXPATHLEN+2, nse_depinfo_fp) != NULL) {
+ if (strncmp(line, sfile, len) == 0 && line[len] == ':') {
+ while (fgets(buf, MAXPATHLEN+2, command_output_fp)
+ != NULL) {
+ if (is_path) {
+ fprintf(merge_fp, "%s", buf);
+ if (strcmp(line, buf)) {
+ /* changed */
+ changed = 1;
+ }
+ }
+ if (buf[strlen(buf)-1] == '\n') {
+ break;
+ }
+ }
+ if (changed || !is_path) {
+ while (fgets(line, MAXPATHLEN, nse_depinfo_fp)
+ != NULL) {
+ fputs(line, merge_fp);
+ }
+ clean_up(nse_depinfo_fp, merge_fp,
+ nse_depinfo_file, merge_file, 0);
+ } else {
+ clean_up(nse_depinfo_fp, merge_fp,
+ nse_depinfo_file, merge_file, 1);
+ }
+ if (file_locked) {
+ unlink(lock_file);
+ }
+ unlink(command_output_tmpfile);
+ return;
+ } /* entry found */
+ fputs(line, merge_fp);
+ }
+ /* Entry never found. Add it if there is a search path */
+ if (is_path) {
+ while (fgets(line, MAXPATHLEN+2, command_output_fp) != NULL) {
+ fprintf(nse_depinfo_fp, "%s", line);
+ }
+ }
+ clean_up(nse_depinfo_fp, merge_fp, nse_depinfo_file, merge_file, 1);
+ if (file_locked) {
+ unlink(lock_file);
+ }
+}
+
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+} // extern "C"
+#endif
+
+static void
+report_dep(char *iflag, char *filename)
+{
+
+ if (command_output_fp == NULL) {
+ sprintf(command_output_tmpfile,
+ NOCATGETS("%s/%s.%d.XXXXXX"), tmpdir, NSE_DEPINFO, getpid());
+ int fd = mkstemp(command_output_tmpfile);
+ if ((fd < 0) || (command_output_fp = fdopen(fd, "w")) == NULL) {
+ return;
+ }
+ if ((search_dir = getenv(NOCATGETS("NSE_DEP"))) == NULL) {
+ return;
+ }
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ atexit(close_file);
+#else
+ on_exit(close_file, 0);
+#endif
+ strcpy(sfile, filename);
+ if (iflag == NULL || *iflag == '\0') {
+ return;
+ }
+ fprintf(command_output_fp, "%s:", sfile);
+ }
+ fprintf(command_output_fp, " ");
+ fprintf(command_output_fp, iflag);
+ if (iflag != NULL) {
+ is_path = 1;
+ }
+}
+
+void
+report_libdep(char *lib, char *flag)
+{
+ char *ptr;
+ char filename[MAXPATHLEN];
+ char *p;
+
+ if ((p= getenv(SUNPRO_DEPENDENCIES)) == NULL) {
+ return;
+ }
+ ptr = strchr(p, ' ');
+ if(ptr) {
+ sprintf(filename, "%s-%s", ptr+1, flag);
+ is_path = 1;
+ report_dep(lib, filename);
+ }
+}
+
+void
+report_search_path(char *iflag)
+{
+ char curdir[MAXPATHLEN];
+ char *sdir;
+ char *newiflag;
+ char filename[MAXPATHLEN];
+ char *p, *ptr;
+
+ if ((sdir = getenv(NOCATGETS("NSE_DEP"))) == NULL) {
+ return;
+ }
+ if ((p= getenv(SUNPRO_DEPENDENCIES)) == NULL) {
+ return;
+ }
+ ptr = strchr(p, ' ');
+ if( ! ptr ) {
+ return;
+ }
+ sprintf(filename, NOCATGETS("%s-CPP"), ptr+1);
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ getcwd(curdir, sizeof(curdir));
+#else
+ getwd(curdir);
+#endif
+ if (strcmp(curdir, sdir) != 0 && strlen(iflag) > 2 &&
+ iflag[2] != '/') {
+ /* Makefile must have had an "cd xx; cc ..." */
+ /* Modify the -I path to be relative to the cd */
+ newiflag = (char *)malloc(strlen(iflag) + strlen(curdir) + 2);
+ sprintf(newiflag, "-%c%s/%s", iflag[1], curdir, &iflag[2]);
+ report_dep(newiflag, filename);
+ } else {
+ report_dep(iflag, filename);
+ }
+}
+
+void
+report_dependency(register char *name)
+{
+ register char *filename;
+ char buffer[MAXPATHLEN+1];
+ register char *p;
+ register char *p2;
+ char nse_depinfo_file[MAXPATHLEN];
+
+ if (report_file == NULL) {
+ if ((filename= getenv(SUNPRO_DEPENDENCIES)) == NULL) {
+ report_file = (FILE *)-1;
+ return;
+ }
+ if (strlen(filename) == 0) {
+ report_file = (FILE *)-1;
+ return;
+ }
+ (void)strcpy(buffer, name);
+ name = buffer;
+ p = strchr(filename, ' ');
+ if(p) {
+ *p= 0;
+ } else {
+ report_file = (FILE *)-1;
+ return;
+ }
+ if ((report_file= fopen(filename, "a")) == NULL) {
+ if ((report_file= fopen(filename, "w")) == NULL) {
+ report_file= (FILE *)-1;
+ return;
+ }
+ }
+#if defined(SUN5_0) || defined(HP_UX) || defined(linux)
+ atexit(close_report_file);
+#else
+ (void)on_exit(close_report_file, (char *)report_file);
+#endif
+ if ((p2= strchr(p+1, ' ')) != NULL)
+ *p2= 0;
+ target_being_reported_for= (char *)malloc((unsigned)(strlen(p+1)+1));
+ (void)strcpy(target_being_reported_for, p+1);
+ (void)fputs(p+1, report_file);
+ (void)fputs(":", report_file);
+ *p= ' ';
+ if (p2 != NULL)
+ *p2= ' ';
+ }
+ if (report_file == (FILE *)-1)
+ return;
+ (void)fputs(name, report_file);
+ (void)fputs(" ", report_file);
+}
+
+#ifdef MAKE_IT
+void
+make_it(filename)
+ register char *filename;
+{
+ register char *command;
+ register char *argv[6];
+ register int pid;
+ union wait foo;
+
+ if (getenv(SUNPRO_DEPENDENCIES) == NULL) return;
+ command= alloca(strlen(filename)+32);
+ (void)sprintf(command, NOCATGETS("make %s\n"), filename);
+ switch (pid= fork()) {
+ case 0: /* child */
+ argv[0]= NOCATGETS("csh");
+ argv[1]= NOCATGETS("-c");
+ argv[2]= command;
+ argv[3]= 0;
+ (void)dup2(2, 1);
+ execve(NOCATGETS("/bin/sh"), argv, environ);
+ perror(NOCATGETS("execve error"));
+ exit(1);
+ case -1: /* error */
+ perror(NOCATGETS("fork error"));
+ default: /* parent */
+ while (wait(&foo) != pid);};
+}
+#endif
+
diff --git a/usr/src/make_src/Make/lib/vroot/src/rmdir.cc b/usr/src/make_src/Make/lib/vroot/src/rmdir.cc
new file mode 100644
index 0000000..48a9a6b
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/rmdir.cc
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)rmdir.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)rmdir.cc 1.4 06/12/12"
+
+#include <unistd.h>
+
+extern int rmdir(const char *path);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int rmdir_thunk(char *path)
+{
+ vroot_result= rmdir(path);
+ return(vroot_result == 0);
+}
+
+int rmdir_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
+{
+ translate_with_thunk(path, rmdir_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/setenv.cc b/usr/src/make_src/Make/lib/vroot/src/setenv.cc
new file mode 100644
index 0000000..dc135e7
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/setenv.cc
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1994 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)setenv.cc 1.6 06/12/12
+ */
+
+#pragma ident "@(#)setenv.cc 1.6 06/12/12"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+extern char **environ;
+
+static short setenv_made_new_vector= 0;
+
+char *setenv(char *name, char *value)
+{ char *p= NULL, **q;
+ int length= 0, vl;
+
+ if ((p= getenv(name)) == NULL) { /* Allocate new vector */
+ for (q= environ; *q != NULL; q++, length++);
+ q= (char **)malloc((unsigned)(sizeof(char *)*(length+2)));
+ memcpy(((char *)q)+sizeof(char *), (char *)environ, sizeof(char *)*(length+1));
+ if (setenv_made_new_vector++)
+ free((char *)environ);
+ length= strlen(name);
+ environ= q;}
+ else { /* Find old slot */
+ length= strlen(name);
+ for (q= environ; *q != NULL; q++)
+ if (!strncmp(*q, name, length))
+ break;};
+ vl= strlen(value);
+ if (!p || (length+vl+1 > strlen(p)))
+ *q= p= (char *) malloc((unsigned)(length+vl+2));
+ else
+ p= *q;
+ (void)strcpy(p, name); p+= length;
+ *p++= '=';
+ (void)strcpy(p, value);
+ return(value);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/stat.cc b/usr/src/make_src/Make/lib/vroot/src/stat.cc
new file mode 100644
index 0000000..475a851
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/stat.cc
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1998 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)stat.cc 1.6 06/12/12
+ */
+
+#pragma ident "@(#)stat.cc 1.6 06/12/12"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+extern int stat(const char *path, struct stat *buf);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int stat_thunk(char *path)
+{
+ vroot_result= stat(path, vroot_args.stat.buffer);
+ return(vroot_result == 0);
+}
+
+int stat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.stat.buffer= buffer;
+ translate_with_thunk(path, stat_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/statfs.cc b/usr/src/make_src/Make/lib/vroot/src/statfs.cc
new file mode 100644
index 0000000..ff8ac36
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/statfs.cc
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)statfs.cc 1.5 06/12/12
+ */
+
+#pragma ident "@(#)statfs.cc 1.5 06/12/12"
+
+#ifndef SUN5_0
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+#include <sys/vfs.h>
+
+static int statfs_thunk(char *path)
+{
+ vroot_result= statfs(path, vroot_args.statfs.buffer);
+ return(vroot_result == 0);
+}
+
+int statfs_vroot(char *path, struct statfs *buffer, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.statfs.buffer= buffer;
+ translate_with_thunk(path, statfs_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
+#endif
diff --git a/usr/src/make_src/Make/lib/vroot/src/truncate.cc b/usr/src/make_src/Make/lib/vroot/src/truncate.cc
new file mode 100644
index 0000000..d38aa37
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/truncate.cc
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)truncate.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)truncate.cc 1.4 06/12/12"
+
+#include <unistd.h>
+
+extern int truncate(const char *path, off_t length);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int truncate_thunk(char *path)
+{
+ vroot_result= truncate(path, vroot_args.truncate.length);
+ return(vroot_result == 0);
+}
+
+int truncate_vroot(char *path, int length, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.truncate.length= length;
+ translate_with_thunk(path, truncate_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/unlink.cc b/usr/src/make_src/Make/lib/vroot/src/unlink.cc
new file mode 100644
index 0000000..71ae091
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/unlink.cc
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)unlink.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)unlink.cc 1.4 06/12/12"
+
+#include <unistd.h>
+
+extern int unlink(const char *path);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int unlink_thunk(char *path)
+{
+ vroot_result= unlink(path);
+ return(vroot_result == 0);
+}
+
+int unlink_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
+{
+ translate_with_thunk(path, unlink_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/unmount.cc b/usr/src/make_src/Make/lib/vroot/src/unmount.cc
new file mode 100644
index 0000000..e90d321
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/unmount.cc
@@ -0,0 +1,48 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)unmount.cc 1.5 06/12/12
+ */
+
+#pragma ident "@(#)unmount.cc 1.5 06/12/12"
+
+#ifndef SUN5_0
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+extern int unmount(char *name);
+
+static int unmount_thunk(char *path)
+{
+ vroot_result= unmount(path);
+ return(vroot_result == 0);
+}
+
+int unmount_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot)
+{
+ translate_with_thunk(path, unmount_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
+#endif
diff --git a/usr/src/make_src/Make/lib/vroot/src/utimes.cc b/usr/src/make_src/Make/lib/vroot/src/utimes.cc
new file mode 100644
index 0000000..4f670b7
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/utimes.cc
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)utimes.cc 1.4 06/12/12
+ */
+
+#pragma ident "@(#)utimes.cc 1.4 06/12/12"
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+extern int utimes(char *file, struct timeval *tvp);
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+static int utimes_thunk(char *path)
+{
+ vroot_result= utimes(path, vroot_args.utimes.time);
+ return(vroot_result == 0);
+}
+
+int utimes_vroot(char *path, struct timeval *time, pathpt vroot_path, pathpt vroot_vroot)
+{
+ vroot_args.utimes.time= time;
+ translate_with_thunk(path, utimes_thunk, vroot_path, vroot_vroot, rw_read);
+ return(vroot_result);
+}
diff --git a/usr/src/make_src/Make/lib/vroot/src/vroot.cc b/usr/src/make_src/Make/lib/vroot/src/vroot.cc
new file mode 100644
index 0000000..1a41c03
--- /dev/null
+++ b/usr/src/make_src/Make/lib/vroot/src/vroot.cc
@@ -0,0 +1,344 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)vroot.cc 1.11 06/12/12
+ */
+
+#pragma ident "@(#)vroot.cc 1.11 06/12/12"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <vroot/vroot.h>
+#include <vroot/args.h>
+
+#include <string.h>
+#include <sys/param.h>
+#include <sys/file.h>
+
+#include <avo/intl.h> /* for NOCATGETS */
+
+typedef struct {
+ short init;
+ pathpt vector;
+ char *env_var;
+} vroot_patht;
+
+typedef struct {
+ vroot_patht vroot;
+ vroot_patht path;
+ char full_path[MAXPATHLEN+1];
+ char *vroot_start;
+ char *path_start;
+ char *filename_start;
+ int scan_vroot_first;
+ int cpp_style_path;
+} vroot_datat, *vroot_datapt;
+
+static vroot_datat vroot_data= {
+ { 0, NULL, NOCATGETS("VIRTUAL_ROOT")},
+ { 0, NULL, NOCATGETS("PATH")},
+ "", NULL, NULL, NULL, 0, 1};
+
+void
+add_dir_to_path(register char *path, register pathpt *pointer, register int position)
+{
+ register int size= 0;
+ register int length;
+ register char *name;
+ register pathcellpt p;
+ pathpt new_path;
+
+ if (*pointer != NULL) {
+ for (p= &((*pointer)[0]); p->path != NULL; p++, size++);
+ if (position < 0)
+ position= size;}
+ else
+ if (position < 0)
+ position= 0;
+ if (position >= size) {
+ new_path= (pathpt)calloc((unsigned)(position+2), sizeof(pathcellt));
+ if (*pointer != NULL) {
+ memcpy((char *)new_path,(char *)(*pointer), size*sizeof(pathcellt));
+ free((char *)(*pointer));};
+ *pointer= new_path;};
+ length= strlen(path);
+ name= (char *)malloc((unsigned)(length+1));
+ (void)strcpy(name, path);
+ if ((*pointer)[position].path != NULL)
+ free((*pointer)[position].path);
+ (*pointer)[position].path= name;
+ (*pointer)[position].length= length;
+}
+
+pathpt
+parse_path_string(register char *string, register int remove_slash)
+{
+ register char *p;
+ pathpt result= NULL;
+
+ if (string != NULL)
+ for (; 1; string= p+1) {
+ if (p= strchr(string, ':')) *p= 0;
+ if ((remove_slash == 1) && !strcmp(string, "/"))
+ add_dir_to_path("", &result, -1);
+ else
+ add_dir_to_path(string, &result, -1);
+ if (p) *p= ':';
+ else return(result);};
+ return((pathpt)NULL);
+}
+
+char *
+get_vroot_name(void)
+{
+ return(vroot_data.vroot.env_var);
+}
+
+char *
+get_path_name(void)
+{
+ return(vroot_data.path.env_var);
+}
+
+void
+flush_path_cache(void)
+{
+ vroot_data.path.init= 0;
+}
+
+void
+flush_vroot_cache(void)
+{
+ vroot_data.vroot.init= 0;
+}
+
+void
+scan_path_first(void)
+{
+ vroot_data.scan_vroot_first= 0;
+}
+
+void
+scan_vroot_first(void)
+{
+ vroot_data.scan_vroot_first= 1;
+}
+
+void
+set_path_style(int style)
+{
+ vroot_data.cpp_style_path= style;
+}
+
+char *
+get_vroot_path(register char **vroot, register char **path, register char **filename)
+{
+ if (vroot != NULL) {
+ if ((*vroot= vroot_data.vroot_start) == NULL)
+ if ((*vroot= vroot_data.path_start) == NULL)
+ *vroot= vroot_data.filename_start;};
+ if (path != NULL) {
+ if ((*path= vroot_data.path_start) == NULL)
+ *path= vroot_data.filename_start;};
+ if (filename != NULL)
+ *filename= vroot_data.filename_start;
+ return(vroot_data.full_path);
+}
+
+void
+translate_with_thunk(register char *filename, int (*thunk) (char *), pathpt path_vector, pathpt vroot_vector, rwt rw)
+{
+ register pathcellt *vp;
+ pathcellt *pp;
+ register pathcellt *pp1;
+ register char *p;
+ int flags[256];
+
+/* Setup path to use */
+ if (rw == rw_write)
+ pp1= NULL; /* Do not use path when writing */
+ else {
+ if (path_vector == VROOT_DEFAULT) {
+ if (!vroot_data.path.init) {
+ vroot_data.path.init= 1;
+ vroot_data.path.vector= parse_path_string(getenv(vroot_data.path.env_var), 0);};
+ path_vector= vroot_data.path.vector;};
+ pp1= path_vector == NULL ? NULL : &(path_vector)[0];};
+
+/* Setup vroot to use */
+ if (vroot_vector == VROOT_DEFAULT) {
+ if (!vroot_data.vroot.init) {
+ vroot_data.vroot.init= 1;
+ vroot_data.vroot.vector= parse_path_string(getenv(vroot_data.vroot.env_var), 1);};
+ vroot_vector= vroot_data.vroot.vector;};
+ vp= vroot_vector == NULL ? NULL : &(vroot_vector)[0];
+
+/* Setup to remember pieces */
+ vroot_data.vroot_start= NULL;
+ vroot_data.path_start= NULL;
+ vroot_data.filename_start= NULL;
+
+ int flen = strlen(filename);
+ if(flen >= MAXPATHLEN) {
+ errno = ENAMETOOLONG;
+ return;
+ }
+
+ switch ((vp ?1:0) + (pp1 ? 2:0)) {
+ case 0: /* No path. No vroot. */
+ use_name:
+ (void)strcpy(vroot_data.full_path, filename);
+ vroot_data.filename_start= vroot_data.full_path;
+ (void)(*thunk)(vroot_data.full_path);
+ return;
+ case 1: /* No path. Vroot */
+ if (filename[0] != '/') goto use_name;
+ for (; vp->path != NULL; vp++) {
+ if((1 + flen + vp->length) >= MAXPATHLEN) {
+ errno = ENAMETOOLONG;
+ continue;
+ }
+ p= vroot_data.full_path;
+ (void)strcpy(vroot_data.vroot_start= p, vp->path);
+ p+= vp->length;
+ (void)strcpy(vroot_data.filename_start= p, filename);
+ if ((*thunk)(vroot_data.full_path)) return;};
+ (void)strcpy(vroot_data.full_path, filename);
+ return;
+ case 2: /* Path. No vroot. */
+ if (vroot_data.cpp_style_path) {
+ if (filename[0] == '/') goto use_name;
+ } else {
+ if (strchr(filename, '/') != NULL) goto use_name;
+ };
+ for (; pp1->path != NULL; pp1++) {
+ p= vroot_data.full_path;
+ if((1 + flen + pp1->length) >= MAXPATHLEN) {
+ errno = ENAMETOOLONG;
+ continue;
+ }
+ if (vroot_data.cpp_style_path) {
+ (void)strcpy(vroot_data.path_start= p, pp1->path);
+ p+= pp1->length;
+ *p++= '/';
+ } else {
+ if (pp1->length != 0) {
+ (void)strcpy(vroot_data.path_start= p,
+ pp1->path);
+ p+= pp1->length;
+ *p++= '/';
+ };
+ };
+ (void)strcpy(vroot_data.filename_start= p, filename);
+ if ((*thunk)(vroot_data.full_path)) return;};
+ (void)strcpy(vroot_data.full_path, filename);
+ return;
+ case 3: { /* Path. Vroot. */
+ int *rel_path, path_len= 1;
+ if (vroot_data.scan_vroot_first == 0) {
+ for (pp= pp1; pp->path != NULL; pp++) path_len++;
+ rel_path= flags;
+ for (path_len-= 2; path_len >= 0; path_len--) rel_path[path_len]= 0;
+ for (; vp->path != NULL; vp++)
+ for (pp= pp1, path_len= 0; pp->path != NULL; pp++, path_len++) {
+ int len = 0;
+ if (rel_path[path_len] == 1) continue;
+ if (pp->path[0] != '/') rel_path[path_len]= 1;
+ p= vroot_data.full_path;
+ if ((filename[0] == '/') || (pp->path[0] == '/')) {
+ if(vp->length >= MAXPATHLEN) {
+ errno = ENAMETOOLONG;
+ continue;
+ }
+ (void)strcpy(vroot_data.vroot_start= p, vp->path); p+= vp->length;
+ len += vp->length;
+ };
+ if (vroot_data.cpp_style_path) {
+ if (filename[0] != '/') {
+ if(1 + len + pp->length >= MAXPATHLEN) {
+ errno = ENAMETOOLONG;
+ continue;
+ }
+ (void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length;
+ *p++= '/';
+ len += 1 + pp->length;
+ };
+ } else {
+ if (strchr(filename, '/') == NULL) {
+ if (pp->length != 0) {
+ if(1 + len + pp->length >= MAXPATHLEN) {
+ errno = ENAMETOOLONG;
+ continue;
+ }
+ (void)strcpy(vroot_data.path_start= p,
+ pp->path);
+ p+= pp->length;
+ *p++= '/';
+ len += 1 + pp->length;
+ }
+ }
+ };
+ (void)strcpy(vroot_data.filename_start= p, filename);
+ if ((*thunk)(vroot_data.full_path)) return;};}
+ else { pathcellt *vp1= vp;
+ for (pp= pp1, path_len= 0; pp->path != NULL; pp++, path_len++)
+ for (vp= vp1; vp->path != NULL; vp++) {
+ int len = 0;
+ p= vroot_data.full_path;
+ if ((filename[0] == '/') || (pp->path[0] == '/')) {
+ if(vp->length >= MAXPATHLEN) {
+ errno = ENAMETOOLONG;
+ continue;
+ }
+ (void)strcpy(vroot_data.vroot_start= p, vp->path); p+= vp->length;
+ len += vp->length;
+ }
+ if (vroot_data.cpp_style_path) {
+ if (filename[0] != '/') {
+ if(1 + len + pp->length >= MAXPATHLEN) {
+ errno = ENAMETOOLONG;
+ continue;
+ }
+ (void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length;
+ *p++= '/';
+ len += 1 + pp->length;
+ }
+ } else {
+ if (strchr(filename, '/') == NULL) {
+ if(1 + len + pp->length >= MAXPATHLEN) {
+ errno = ENAMETOOLONG;
+ continue;
+ }
+ (void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length;
+ *p++= '/';
+ len += 1 + pp->length;
+ }
+ }
+ (void)strcpy(vroot_data.filename_start= p, filename);
+ if ((*thunk)(vroot_data.full_path)) return;};};
+ (void)strcpy(vroot_data.full_path, filename);
+ return;};};
+}
diff --git a/usr/src/make_src/Makefile b/usr/src/make_src/Makefile
new file mode 100644
index 0000000..f12aeac
--- /dev/null
+++ b/usr/src/make_src/Makefile
@@ -0,0 +1,38 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.65 06/12/12
+#
+
+TOP = .
+include $(TOP)/rules/master.mk
+
+# Default build variables
+CC=cc
+CCC=CC
+CC64=$(CC)
+CCC64=$(CCC)
+
+SUBDIRS = Make
+
+include $(TOP)/rules/recurse.mk
diff --git a/usr/src/make_src/exe/options.sh b/usr/src/make_src/exe/options.sh
new file mode 100644
index 0000000..738e6c2
--- /dev/null
+++ b/usr/src/make_src/exe/options.sh
@@ -0,0 +1,105 @@
+#! /bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)options.sh 1.27 06/12/12
+#
+
+##-----------------------------------------------------------------
+## Build options
+## TeamWare can be built with different options:
+## OPTION DEFAULT SWITCH
+## -g debugging OFF debug-$variant.opt
+## -g & -DDEBUG debugging OFF DEBUG-$variant.opt
+## licensing enabled ON no_license.opt
+## build source browser info OFF sb-$variant.opt
+## usage tracking enabled OFF usage_tracking.opt
+##
+## Note that those with $variant in their names are variant-specific.
+##
+## To change the default value of any option, create a file in $(TOP) with the
+## name of the switch. E.g., to create a workspace with debugging enabled,
+## create the file
+## $(TOP)/debug.opt
+## before doing a make. The make need not be done for the entire workspace.
+##
+## Switches are set in places where they are needed.
+##
+## Note that the ability to disable licensing is commented out in the places
+## where it is (currently, Jan 24 1996, used): lib/{cli,mgui}/src/Makefile
+## so that we don't accidentally ship with licensing disabled. You also will have
+## to manually make the switch in $(TOP)/exe executable.
+
+
+echo '# This file is generated by $(TOP)/exe/options.sh'
+echo "# *** DO NOT EDIT THIS FILE DIRECTLY ***"
+
+TOP=$1
+VARIANT=$2
+
+echo " "
+echo "# Debug options"
+echo "#"
+if [ -f $TOP/DEBUG-$VARIANT.opt ]; then
+ echo CFLAGS +=-g
+ echo CCFLAGS +=-g
+ echo CPPFLAGS += -DDEBUG
+ echo DEBUGLIB = -g
+ echo 'MOTIF_LD_RUN_PATH += -R$(CCR_ROOT_AUX)/$(VARIANT)/lib:$(CCR_ROOT)/$(VARIANT)/lib'
+elif [ -f $TOP/debug-$VARIANT.opt ]; then
+ echo CFLAGS +=-g
+ echo CCFLAGS +=-g
+ echo DEBUGLIB = -g
+ echo 'MOTIF_LD_RUN_PATH += -R$(CCR_ROOT_AUX)/$(VARIANT)/lib:$(CCR_ROOT)/$(VARIANT)/lib'
+else
+ echo CFLAGS +=-O
+ echo CCFLAGS +=-O
+ echo CPPFLAGS += -DNDEBUG
+ echo LDFLAGS += -norunpath -i -s
+ echo BDYNAMIC = -Bdynamic
+ echo BSTATIC = -Bstatic
+fi
+
+if [ -f $TOP/no_license.opt ]; then
+ echo " "
+ echo "# Licensing options"
+ echo "#"
+ echo -DTW_LICENSE
+fi
+
+if [ -f $TOP/sb-$VARIANT.opt ]; then
+ echo " "
+ echo "# Source Browser options"
+ echo "#"
+ echo CFLAGS += -sb
+ echo CCFLAGS += -sb
+fi
+
+if [ -f $TOP/usage_tracking.opt ]; then
+ echo " "
+ echo "# Usage tracking options"
+ echo "#"
+ echo CPPFLAGS += -DUSAGE_TRACKING
+fi
+
+echo CCFLAGS += -D_FILE_OFFSET_BITS=64
diff --git a/usr/src/make_src/exe/sanity-check.sh b/usr/src/make_src/exe/sanity-check.sh
new file mode 100644
index 0000000..f59def8
--- /dev/null
+++ b/usr/src/make_src/exe/sanity-check.sh
@@ -0,0 +1,60 @@
+#! /bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)sanity-check.sh 1.6 06/12/12
+#
+
+# Run a sanity check on $1. Sanity is loosely defined as "ok to ship to a customer".
+# Currently checks for the following:
+# no forbidden RPATH
+# no forbidden shared libraries
+# Since sanity is only important for those things we ship to customers, don't
+# check it on debugging builds.
+
+top=$1
+variant=`/bin/sh $top/exe/variant.sh`
+if [ -f $top/debug-$variant.opt ]; then
+ exit 0
+fi
+
+prog=$2
+status=0
+
+/usr/ccs/bin/dump -Lv $prog \
+ | /bin/grep RPATH | \
+ /bin/egrep 'net|export|set' > /dev/null
+if [ $? -eq 0 ]; then
+ echo Error: $prog has forbidden RPATH
+ /usr/ccs/bin/dump -Lv $prog | /bin/grep RPATH
+ status=1
+fi
+
+/bin/ldd $prog |/bin/egrep 'libC|libsunmath|net|export|set' > /dev/null
+if [ $? -eq 0 ]; then
+ echo Error: $prog has forbidden libraries
+ /bin/ldd $prog |/bin/egrep 'libC|libsunmath|net|export|set'
+ status=2
+fi
+
+exit $status
diff --git a/usr/src/make_src/exe/variant.sh b/usr/src/make_src/exe/variant.sh
new file mode 100644
index 0000000..d2fdaa1
--- /dev/null
+++ b/usr/src/make_src/exe/variant.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)variant.sh 1.3 06/12/12
+#
+
+
+
+# Author: Achut Reddy
+# Date: Fri Nov 4 12:00:24 PST 1994
+
+# Handle HP-UX separately
+sys=`uname -s`
+case $sys in
+HP-UX)
+ echo hp-ux
+ exit 0;
+ ;;
+esac
+
+mach=`(mach || uname -p) 2> /dev/null`
+case $mach in
+i?86)
+ mach=intel ;;
+esac
+
+rel=`uname -r`
+case $rel in
+5*) os=S2;;
+4*) os=S1;;
+*) os=UNKNOWN;;
+esac
+
+echo ${mach}-${os}
diff --git a/usr/src/make_src/include/Makefile b/usr/src/make_src/include/Makefile
new file mode 100644
index 0000000..94af94e
--- /dev/null
+++ b/usr/src/make_src/include/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)Makefile 1.4 06/12/12
+#
+
+TOP = ../..
+SUBDIRS = avo
+
+include $(TOP)/rules/recurse.mk
diff --git a/usr/src/make_src/include/avo/avo_alloca.h b/usr/src/make_src/include/avo/avo_alloca.h
new file mode 100644
index 0000000..3852f4c
--- /dev/null
+++ b/usr/src/make_src/include/avo/avo_alloca.h
@@ -0,0 +1,49 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1998 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)avo_alloca.h 1.4 06/12/12
+ */
+
+#pragma ident "@(#)avo_alloca.h 1.4 06/12/12"
+
+#ifndef _AVO_ALLOCA_H
+#define _AVO_ALLOCA_H
+
+#include <alloca.h>
+
+#ifdef __SunOS_5_4
+// The following prototype declaration is necessary when compiling on Solaris
+// 2.4 using 5.0 compilers. On Solaris 2.4 the necessary prototypes are not
+// included in alloca.h. The 4.x compilers provide a workaround by declaring the
+// prototype as a pre-defined type. The 5.0 compilers do not implement this workaround.
+// This can be removed when support for 2.4 is dropped
+
+#include <stdlib.h> // for size_t
+extern "C" void *__builtin_alloca(size_t);
+
+#endif // ifdef __SunOS_5_4
+
+#endif // ifdef _AVO_ALLOCA_H
+
diff --git a/usr/src/make_src/include/avo/intl.h b/usr/src/make_src/include/avo/intl.h
new file mode 100644
index 0000000..a689533
--- /dev/null
+++ b/usr/src/make_src/include/avo/intl.h
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * @(#)intl.h 1.19 06/12/12
+ */
+
+#pragma ident "@(#)intl.h 1.19 06/12/12"
+
+#ifndef _AVO_INTL_H
+#define _AVO_INTL_H
+
+#if defined(SUN4_x) || defined(HP_UX)
+#include <avo/widefake.h>
+#endif
+
+/*
+ * For catgets
+ */
+#include <nl_types.h>
+
+#ifdef HP_UX
+#ifdef __cplusplus
+#ifndef _STDLIB_INCLUDED
+#include <stdlib.h> /* for wchar_t definition and HP-UX - */
+#endif /* wide character function prototypes. */
+extern "C" {
+char *gettext(char *msg);
+char *dgettext(const char *, const char *);
+char *bindtextdomain(const char *, const char *);
+char *textdomain(char *);
+}
+#endif /* __cplusplus */
+#endif
+
+/*
+ * NOCATGETS is a dummy macro that returns it argument.
+ * It is used to identify strings that we consciously do not
+ * want to apply catgets() to. We have tools that check the
+ * sources for strings that are not catgets'd and the tools
+ * ignore strings that are NOCATGETS'd.
+ */
+#define NOCATGETS(str) (str)
+
+/*
+ * Define the various text domains
+ */
+#define AVO_DOMAIN_CODEMGR "codemgr"
+#define AVO_DOMAIN_VERTOOL "vertool"
+#define AVO_DOMAIN_FILEMERGE "filemerge"
+#define AVO_DOMAIN_DMAKE "dmake"
+#define AVO_DOMAIN_PMAKE "pmake"
+#define AVO_DOMAIN_FREEZEPOINT "freezept"
+#define AVO_DOMAIN_MAKETOOL "maketool"
+
+#endif
diff --git a/usr/src/make_src/rules/computed-options.mk b/usr/src/make_src/rules/computed-options.mk
new file mode 100644
index 0000000..3c7d1ba
--- /dev/null
+++ b/usr/src/make_src/rules/computed-options.mk
@@ -0,0 +1,37 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)computed-options.mk 1.3 06/12/12
+#
+
+#
+# Including this file causes re-computation of the options used during a build
+#
+
+$(TOP)/rules/options-$(VARIANT).mk: $(TOP)/exe/options.sh FORCE
+ /bin/rm -f $(TOP)/rules/options-$(VARIANT).mk
+ /bin/sh $(TOP)/exe/options.sh $(TOP) $(VARIANT) > $(TOP)/rules/options-$(VARIANT).mk
+
+FORCE:
+
+include $(TOP)/rules/options-$(VARIANT).mk
diff --git a/usr/src/make_src/rules/derived.mk b/usr/src/make_src/rules/derived.mk
new file mode 100644
index 0000000..89fd719
--- /dev/null
+++ b/usr/src/make_src/rules/derived.mk
@@ -0,0 +1,66 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)derived.mk 1.15 06/12/12
+#
+
+# Include this makefile in directories which contain source whose derived
+# files are to be built in ../<variant>.
+
+# The source directory must contain a makefile with these contents:
+#
+# TOP = <as appropriate>
+# include $(TOP)/rules/master.mk
+# SRC = <as appripriate>
+# include $(TOP)/rules/variant.mk
+#
+# The source directory must also contain a makefile named "Derived.mk"
+# which is used to build the derived files.
+#
+# TOP is defined as a relative path to the root of the workspace
+# SRC is defined as a relative path from the derived files' directory to the
+# source files' directory, and is typically ../src.
+
+include $(TOP)/rules/$(VARIANT).mk
+
+all := TARG = all
+install := TARG = install
+clean := TARG = clean
+test := TARG = test
+l10n_install := TARG = l10n_install
+i18n_install := TARG = i18n_install
+
+all install clean test l10n_install i18n_install: $(VARIANT) $(V9_VARIANT)
+
+SRC = ../src
+MFLAGS += SRC=$(SRC)
+
+# Conditional is in place so a "make" from the top level will work on partial
+# source heirarchies.
+$(VARIANT) $(V9_VARIANT): FRC
+ if [ ! -d $@ ]; then \
+ mkdir $@ ; \
+ fi
+ cd $@; $(MAKE) $(MFLAGS) -f $(SRC)/Variant.mk RELEASE_VER="$(RELEASE_VER)" DESTDIR=$(DESTDIR) V9FLAGS="$(V9FLAGS)" VAR_DIR=$(VAR_DIR) CC=$(CC) CCC=$(CCC) $(TARG);
+
+FRC:
diff --git a/usr/src/make_src/rules/dmake.mk b/usr/src/make_src/rules/dmake.mk
new file mode 100644
index 0000000..7ca8548
--- /dev/null
+++ b/usr/src/make_src/rules/dmake.mk
@@ -0,0 +1,33 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)dmake.mk 1.8 06/12/12
+#
+
+AVO_DM_LIBS = $(LIBDM)
+AVO_DMCONF_LIBS = $(LIBDMCONF)
+AVO_DMRC_LIBS = $(LIBDMRC)
+AVO_DMTHREAD_LIBS = $(LIBDMTHREAD)
+AVO_PUBDMSI18N_LIBS = $(LIBPUBDMSI18N)
+AVO_RX_LIBS = $(LIBRX)
+
diff --git a/usr/src/make_src/rules/i18n-install.mk b/usr/src/make_src/rules/i18n-install.mk
new file mode 100644
index 0000000..06e90fb
--- /dev/null
+++ b/usr/src/make_src/rules/i18n-install.mk
@@ -0,0 +1,73 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1997 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)i18n-install.mk 1.23 06/12/12
+#
+
+include $(TOP)/rules/master.mk
+
+#
+# Included Makefile that installs i18n message catalogs.
+#
+# Before including this Makefile the following variables should be set:
+# PACKAGE name of the package being installed
+# replaced by PRODVER in order to install multiple pkgs in
+# a single path. --emk 2/96
+#
+# TEXTDOMAIN name of default textdomain used by gettext() calls
+# APPPATH location to find the msg file
+#
+
+PRODVER = usr
+
+LIB_DESTDIR = $(DESTDIR)/$(PRODVER)/lib
+CAT_DESTDIR = $(LIB_DESTDIR)/locale/C/LC_MESSAGES
+HELP_DIR = help
+HELP_SYML_INST_DIR = $(LIB_DESTDIR)
+HELP_SYML_PTS_TO_DIR = ./locale/C
+LANG_DIR = $(LIB_DESTDIR)/local/C
+
+#i18n_install: $(CAT_DESTDIR) .WAIT msg_catalogs help_symlink
+i18n_install:
+i18n_gui_install: $(CAT_DESTDIR) .WAIT gui_msg_catalogs help_symlink
+
+$(CAT_DESTDIR):
+ $(INSTALL) -d $@
+
+#
+# Find the message catalog in the $VAriant dir
+# install the files into the package's destination.
+#
+
+msg_catalogs: FRC
+ cp $(APPPATH)/$(TEXTDOMAIN).msg $(CAT_DESTDIR)
+
+gui_msg_catalogs: FRC
+ cp $(APPPATH)/$(TEXTDOMAIN).po $(CAT_DESTDIR)
+
+help_symlink: FRC
+# @ if [! -d $(LANG_DIR)/$(HELP_DIR) ]; then \
+# cd $(LANG_DIR); ln -s LC_MESSAGES $(HELP_DIR) \
+# fi \
+
+FRC:
diff --git a/usr/src/make_src/rules/import.mk b/usr/src/make_src/rules/import.mk
new file mode 100644
index 0000000..6c3a6de
--- /dev/null
+++ b/usr/src/make_src/rules/import.mk
@@ -0,0 +1,28 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)import.mk 1.25 06/12/12
+#
+# @(#)import.mk 1.8 96/04/16 SMI
+
+VIDEO_VER = 1.0
diff --git a/usr/src/make_src/rules/install.mk b/usr/src/make_src/rules/install.mk
new file mode 100644
index 0000000..aa28359
--- /dev/null
+++ b/usr/src/make_src/rules/install.mk
@@ -0,0 +1,240 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1998 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)install.mk 1.53 06/12/12
+#
+
+#
+# This is an included Makefile that contains the standard
+# install lines for a program.
+#
+# INCLUDE THIS ONLY AFTER INCLUDING $(TOP)/rules/master.mk
+#
+# Before including this Makefile the following variables should be set:
+# PROG the name of the program
+# PROG_DIR bin || etc, lowest level directory for executables
+# LIB_DIR usually just lib; destination for libraries,
+# non-localized bitmaps, etc.
+# LICENSE_DIR_SRC where LICENSE_DIR will link to
+# DESTDIR destination directory for the install
+# PACKAGE name of the package containing the program
+#
+# PACKAGE is now being overridden by PRODVER for installation
+# purposes since multiple packages are being installed
+# into a single install path below PRODVER 2/96 --emk
+#
+# HELP_INFO optionally set to a list of .info files to install
+# HELP_INFO is initially set in gui.Makefile
+# RES_FILE optionally set name by which resource file is
+# known to the app itself (e.g. XCodeManager).
+# CDE_RES_FILE optionally set name of resource file for CDE guis
+# (e.g. XCodeManager.cde).
+# NCDE_RES_FILE optionally set name of resource file for motif guis
+# PWI_FILE optionally set name of PWI configuration file for guis
+# Installed in RES_DIR
+#
+# This install technique uses make's dependencies to decide whether
+# or not to install something. If the installed file is more recent
+# than the one in the source heirarchy, then no install will occur.
+#
+# The INST_PROG definition makes this install rule work for makefiles
+# that build more than one program, e.g. several scripts that share
+# the same source directory. To work, this install.Makefile must be
+# included after the "all" target has been defined but before the
+# rules used to build the programs to be installed. (see trans/scripts)
+#
+# For makefiles that build only one program, this install.Makefile can
+# be included at the end, after the rules used to build the program.
+# (see bin.cc.Makefile).
+
+#
+# The references to PROG_DIR below must be $$ references because
+# PROG_DIR is conditionally set in the CodeManager/etc/diff3_merge
+# Makefile. But, if it is conditional, the implicit target for
+# $(DESTDIR)/$(PROG_DIR) doesn't work. Make returns that it doesn't
+# know how to build that target.
+#
+# I made changes to add PROG_DIR=<value> in all the makefiles which include
+# install.mk. This is needed because of the assignment to
+# PGK_DIR_PROG_DIR. SYML_DIR is still conditional and set according to
+# to which target is being built. it would be nice to set PROG_DIR by
+# default, but to do this, the reference in the PKG_DIR_PROG_DIR assignment
+# must be re-done... LK
+#
+
+PKG_DIR = $(DESTDIR)/$(PRODVER)
+LOCALE_PATH = lib/locale/C
+HELP_DIR = $(PKG_DIR)/$(LOCALE_PATH)/LC_MESSAGES
+PWI_PATH = $(LOCALE_PATH)/pwi_config
+PWI_DIR = $(PKG_DIR)/$(PWI_PATH)
+LICENSE_DIR = $(DESTDIR)/license_dir
+PKG_DIR_PROG_DIR = $(DESTDIR)/$(PRODVER)/$(PROG_DIR)
+PKG_DIR_LIB_DIR = $(DESTDIR)/$(PRODVER)/$(LIB_DIR)
+CDE_RES_DIR = $(DESTDIR)/$(PRODVER)/$(LOCALE_PATH)/app-defaults/CDE
+NCDE_RES_DIR = $(DESTDIR)/$(PRODVER)/$(LOCALE_PATH)/app-defaults/non-CDE
+INST_PROG = $(PROG:%=$(PKG_DIR_PROG_DIR)/%)
+INST_LIB = $(LIBSS:%=$(PKG_DIR_LIB_DIR)/%)
+#
+# INST_HELP is the list of .info files to be installed
+#
+INST_HELP = $(HELP_INFO:%=$(HELP_DIR)/%)
+
+#
+INST_SYMLINK = /bin/csh $(TOOLS_PATH)/inst_symlink
+
+# INSTALLING PERSISTENT PROCESSES:
+#
+# If the macro INST_PERSIST is set to TRUE, move a copy of $(PROG) out of
+# the way into a unique name so it doesn't clobber the last version moved.
+#
+# A way to make this conditional in the individual Makefiles is to include
+# something like this in the Makefile which needs to install a persistent
+# process:
+#
+# INST_PERSIST = $(SWTEAM_PERSIST)
+#
+# Where SWTEAM_PERSIST is set in your .cshrc or .login to TRUE. This allows
+# it to be turned off and on on a global scale, and still only apply to those
+# executables which have INST_PERSIST set in their Makefiles.
+#
+
+#install:: \
+# $(PKG_DIR_PROG_DIR) \
+# .WAIT \
+# $(PKG_DIR_LIB_DIR) \
+# .WAIT \
+# $(HELP_DIR) \
+# .WAIT \
+# $(PWI_DIR) \
+# .WAIT \
+# $(PWI_DIR)/$(PWI_FILE) \
+# .WAIT \
+# symlinks \
+# $(LICENSE_DIR) \
+# $(CDE_RES_DIR) \
+# $(NCDE_RES_DIR) \
+# .WAIT \
+# $(INST_PROG) \
+# $(INST_LIB) \
+# $(INST_HELP) \
+# $$(INST_ABOX_ABOX) \
+# $$(INST_ABOX_ADDR) \
+# $(CDE_RES_DIR)/$(RES_FILE) \
+# $(NCDE_RES_DIR)/$(RES_FILE) \
+# .WAIT \
+# post-install
+
+#
+# Empty rule here; packages can add their own functionality.
+#
+post-install:: FRC
+
+#
+# Number of earlier versions to save.
+#
+SAVE_NUM = 1
+
+$(PKG_DIR_PROG_DIR)/%: %
+ @if [ "$(INST_PERSIST)" = "TRUE" -a -f $@ ]; then \
+ while [ `ls $@.* | wc -l` -gt $(SAVE_NUM) ]; do \
+ echo "rm -f `ls $@.* | head -1`";\
+ rm -f `ls $@.* | head -1`;\
+ done; \
+ echo "mv -f $@ $@.`date +%m.%d.%H.%M`"; \
+ mv -f $@ $@.`date +%m.%d.%H.%M`; \
+ fi
+ echo "$(INSTALL) $< $@"
+ $(INSTALL) $< $@
+
+
+#
+# Don't put the dependency upon $(PKG_DIR_PROG_DIR) on the
+# $(PKG_DIR_PROG_DIR)/% target line because it causes the executables to be
+# installed twice regardless of their relation to the current executable
+#
+$(PKG_DIR_PROG_DIR):
+ @if [ ! -d $@ ]; then \
+ $(INSTALL) -d $@; \
+ fi; \
+
+$(PKG_DIR_LIB_DIR):
+ @if [ ! -d $@ ]; then \
+ $(INSTALL) -d $@; \
+ fi; \
+
+#
+# Install the help files listed in $(INST_HELP). Each of the files
+# listed in $(INST_HELP) lives in directory $(HELP_DIR).
+#
+# Needs to be able to support HELP_INFO with values in current directory
+# as well as info files from other directories.
+#
+$(HELP_DIR)/%.info: %.info
+ $(INSTALL) $< $@
+
+$(HELP_DIR)/%.info: $(TOP)/libgui/%.info
+ $(INSTALL) $< $(HELP_DIR)/$(@F)
+
+$(HELP_DIR):
+ @if [ ! -d $(HELP_DIR) ]; then \
+ $(INSTALL) -d $@; \
+ fi
+
+$(PWI_DIR):
+ @if [ ! -d $(PWI_DIR) ]; then \
+ $(INSTALL) -d $@; \
+ fi
+
+#
+# hack in license_dir link -- probably outta be in symlinks section
+#
+$(LICENSE_DIR):
+ echo "$(INST_SYMLINK) $(LICENSE_DIR_SRC) $(DESTDIR) license_dir"
+ $(INST_SYMLINK) $(LICENSE_DIR_SRC) $(DESTDIR) license_dir
+
+$(PWI_DIR)/$(PWI_FILE): $(SRC)/$(PWI_FILE)
+ @if [ "$(PWI_FILE)" != "" ]; then \
+ $(INSTALL) -m 0444 $(SRC)/$(PWI_FILE) $@; \
+ fi
+
+$(CDE_RES_DIR)/$(RES_FILE): $(CDE_RES_FILE)
+ @if [ "$(CDE_RES_FILE)" != "" ]; then \
+ $(INSTALL) -m0444 $(CDE_RES_FILE) $(CDE_RES_DIR)/$(RES_FILE); \
+ fi
+
+$(NCDE_RES_DIR)/$(RES_FILE): $(NCDE_RES_FILE)
+ @if [ "$(NCDE_RES_FILE)" != "" ]; then \
+ $(INSTALL) -m0444 $(NCDE_RES_FILE) $(NCDE_RES_DIR)/$(RES_FILE); \
+ fi
+
+$(CDE_RES_DIR):
+ @if [ "$(CDE_RES_FILE)" != "" ]; then \
+ $(INSTALL) -d $@; \
+ fi
+
+$(NCDE_RES_DIR):
+ @if [ "$(NCDE_RES_FILE)" != "" ]; then \
+ $(INSTALL) -d $@; \
+ fi
+
+FRC:
diff --git a/usr/src/make_src/rules/intel-S2.mk b/usr/src/make_src/rules/intel-S2.mk
new file mode 100644
index 0000000..daa77cc
--- /dev/null
+++ b/usr/src/make_src/rules/intel-S2.mk
@@ -0,0 +1,60 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)intel-S2.mk 1.16 06/12/12
+#
+
+include $(TOP)/rules/solaris.mk
+
+# Please keep each list alphabetically sorted.
+
+#
+# Make variables
+#
+
+#
+# Paths
+#
+TOOLS_PATH = $(TOP)/exe
+
+#
+# Programs
+#
+
+#
+# Flags
+#
+CPPFLAGS += -DSUN5_0 -DSYSV -Dx86
+
+#
+# amd64-S2 Flags
+#
+amd64-S2 := V9FLAGS = -O -xarch=amd64
+amd64-S2 := VAR_DIR = /amd64
+
+#
+# This is temporary until both 32- and 64-bit stuff are to be compiled
+# with the same compiler.
+#
+amd64-S2 := CC = $(CC64)
+amd64-S2 := CCC = $(CCC64)
diff --git a/usr/src/make_src/rules/l10n-install.mk b/usr/src/make_src/rules/l10n-install.mk
new file mode 100644
index 0000000..9050cf2
--- /dev/null
+++ b/usr/src/make_src/rules/l10n-install.mk
@@ -0,0 +1,70 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1998 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)l10n-install.mk 1.7 06/12/12
+#
+
+# READ-THIS-PART:
+# Since L10N_SRCS are derived sources files, the make target
+# "make_l10n_install" script MUST be executed after a
+# complete build of the integration workspace. The make_l10n_install
+# scripts resides in the TOOLS_PATH directory.
+#
+
+L10N_SCRIPT = /bin/csh $(TOOLS_PATH)/inst_l10n
+
+
+# Before including this Makefile the following variables should be set:
+#
+#
+# DESTDIR the destination workspace where the L10N_SRCS will
+# be installed.
+# SOURCE_WS the source workspace from which the files will be
+# installed.
+# L10N_SRCS sources that need to be installed in the above
+# DESTDIR.
+# L10N_SCRIPT the script that will install the files under
+# sccs control in the destination directory
+# workspace.
+# TOOLS_PATH location for the L10N_SCRIPT
+#
+#
+
+ALL_USAGE = "Usage: make DESTDIR=<value> SOURCE_WS=<value> l10n_install"
+CWD:sh = pwd
+
+l10n_install:: l10n_install_usage FRC
+ @$(L10N_SCRIPT) $(DESTDIR) $(SOURCE_WS) $(CWD) \
+ $(L10N_SRCS)
+FRC:
+
+l10n_install_usage: FRC
+ @if [ "$(DESTDIR)" = "" -o "$(SOURCE_WS)" = "" ]; then \
+ echo $(ALL_USAGE); \
+ exit 1; \
+ fi;
+ @if [ "$(CWD)" = "" ]; then \
+ echo $(ALL_USAGE); \
+ exit 1; \
+ fi
+FRC:
diff --git a/usr/src/make_src/rules/lib.mk b/usr/src/make_src/rules/lib.mk
new file mode 100644
index 0000000..f38f9aa
--- /dev/null
+++ b/usr/src/make_src/rules/lib.mk
@@ -0,0 +1,131 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)lib.mk 1.33 06/12/12
+#
+
+#
+# This Makefile contains common rules for building libraries.
+# It expects the following variables to be defined:
+#
+# LIBNAME the name of the library being built
+# CCSRCS C++ source files
+# CSRCS C source files
+# BIGCSRCS C++ source files with .C suffix (so checkgettext isn't run)
+#
+
+CCOBJS = $(CCSRCS:%.cc=%.o)
+COBJS = $(CSRCS:%.c=%.o)
+BIGCOBJS = $(BIGCSRCS:%.C=%.o)
+
+OBJS += $(CCOBJS) $(COBJS) $(BIGCOBJS)
+
+L10N_SRCS = $(LIBNAME)_srrcat.po messages.po
+
+#
+# Is this '[d]make' connected to a terminal?
+#
+TTY :sh= if test -t 2; then echo true; else echo false; fi
+
+#
+# This complicated set of commands determine if there are
+# any .o files in the library that no longer belong there.
+# If so, the library must be removed and rebuilt from scratch.
+# If the old .o files are left in the library, then a program that
+# references a routine in one of these .o files will still build
+# until the library gets completely rebuilt, in which case it will
+# no longer build.
+# In addition, because $? macro is used in the command that builds
+# this library, command dependency checking is disabled. Even if
+# this command changes, the library won't be rebuilt. The library's
+# list of dependencies appear in a separate command, which is subject
+# to command dependency checking (echo to /dev/null), to ensure that
+# the library rebuilt when its list of dependencies change.
+#
+
+# XD_INCLS is defined in rules/motif-lib.mk and will
+# be empty if not called from motif-lib.mk
+
+$(LIBNAME): $(OBJS)
+ @echo "Building $(LIBNAME)" > \
+ `$(TTY) && test -t 0 && tty || echo /dev/null`
+ @echo $(OBJS) > /dev/null
+ @?ar t $(LIBNAME) | sed -e /__.SYMDEF/d | sort > ar.t.$$$$; \
+ for i in $(OBJS); do \
+ echo $$i; \
+ done | sort | comm -23 ar.t.$$$$ - > extras.$$$$; \
+ if [ -s extras.$$$$ ]; then \
+ echo rm -f $(LIBNAME); \
+ rm -f $(LIBNAME); \
+ echo ar rv $(LIBNAME) $(OBJS); \
+ ar rv $(LIBNAME) $(OBJS); \
+ else \
+ echo ar crv $(LIBNAME) $?; \
+ ar crv $(LIBNAME) $?; \
+ fi; \
+ rm -f ar.t.$$$$ extras.$$$$
+ @if [ -f $(RANLIB) ]; then \
+ echo $(RANLIB) $(LIBNAME); \
+ $(RANLIB) $(LIBNAME); \
+ fi
+
+#all install:: $(LIBNAME) catalogs
+###all install:: $(LIBNAME)
+all: $(LIBNAME)
+
+install: $(LIBNAME)
+
+#all:: $(LIBNAME)
+#
+#install:: all catalogs
+
+clean::
+ $(RM) $(OBJS) $(LIBNAME) $(CLEANFILES) $(CATALOG)
+
+# temporarily install catalogs here - will move to l10n-install later
+# when mesg files are versioned
+LIB_DESTDIR = $(DESTDIR)/$(PRODVER)/lib
+CAT_DESTDIR = $(LIB_DESTDIR)/locale/C/LC_MESSAGES
+
+#also temporary, until I find a variant specific place to find this tool
+COMPMSG =
+
+catalogs::
+ $(GENMSG) -l $(SRC)/genmsg.project -o $(MSG_FILE) `find $(I18N_DIRS) \( -name '*.cc' -o -name '*.c' -o -name '*.y' -o -name '*.h' \) -print | grep -v /SCCS/`
+ rm -f *.cc.new
+# @ if [ -f $(SRC)/$(MSG_FILE) ]; then \
+# echo "running compmsg on $(MSG_FILE)"; \
+# $(COMPMSG) -n $(SRC)/$(MSG_FILE) $(MSG_FILE); \
+# fi
+
+
+# @ if [ ! -d $(CAT_DESTDIR) ]; then \
+# $(INSTALL) -d $@ \
+# fi
+# cp $(MSG_FILE) $(CAT_DESTDIR)
+
+FRC:
+
+include $(TOP)/rules/l10n-install.mk
+
+include $(TOP)/rules/computed-options.mk
diff --git a/usr/src/make_src/rules/libraries.mk b/usr/src/make_src/rules/libraries.mk
new file mode 100644
index 0000000..b2d4c46
--- /dev/null
+++ b/usr/src/make_src/rules/libraries.mk
@@ -0,0 +1,62 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)libraries.mk 1.9 06/12/12
+#
+
+# This file defines make variables for libraries libraries which
+# are provided in both debuggable (-g) and optimized (-O) forms.
+#
+# See $(TOP)/exe/build-debuglib, rules/{singleton, motif-app}.mk,
+
+# Please keep both of the following lists alphabetized.
+
+# These libraries exist in both -g and non-g forms.
+#
+LIBDM = -ldm$(DEBUGLIB)
+LIBDMCONF = -ldmconf$(DEBUGLIB)
+LIBDMRC = -ldmrc$(DEBUGLIB)
+LIBDMTHREAD = -ldmthread$(DEBUGLIB)
+LIBLICMOTIF = -llicmotif$(DEBUGLIB)
+LIBLICTXT = -llictxt$(DEBUGLIB)
+LIBMGUI = -lmgui$(DEBUGLIB)
+LIBPSDEFS = -lpsdefs$(DEBUGLIB)
+LIBPSWIDGETS = -lPsWidgets$(DEBUGLIB)
+LIBPSUTILS = -lPsUtils$(DEBUGLIB)
+LIBPUBDMSI18N = -lpubdmsi18n$(DEBUGLIB)
+LIBPWICLIENT = -lpwiclient$(DEBUGLIB)
+LIBPWITOOLBOX = -lpwitoolbox$(DEBUGLIB)
+LIBRX = -lrx$(DEBUGLIB)
+LIBUTIL = -lutil$(DEBUGLIB)
+LIBXDCLASS = -lxdclass$(DEBUGLIB)
+
+# These libraries exist only in non-g form. That does *not* mean that they are
+# not *compiled* without -g., only that they don't exist in a libXXX-g.a form.
+#
+LIBLOG = -llog
+LIBMSSPKG = -lmsspkg
+LIBPATHUTILS = -lpathutils
+LIBPSCCHART = -lpscchart
+LIBPSCHART = -lpschart
+LIBTIMELINE = -ltimeline
+LIBXPM = $(BSTATIC) -lXpm $(BDYNAMIC)
diff --git a/usr/src/make_src/rules/master.mk b/usr/src/make_src/rules/master.mk
new file mode 100644
index 0000000..eae7f19
--- /dev/null
+++ b/usr/src/make_src/rules/master.mk
@@ -0,0 +1,109 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)master.mk 1.142 06/12/12
+#
+
+include $(TOP)/rules/variant.mk
+
+.KEEP_STATE_FILE: .make.state_${VARIANT}
+
+include $(TOP)/rules/$(VARIANT).mk
+#include $(TOP)/lib/Lib.mk
+
+#include $(TOP)/rules/libraries.mk
+
+DESTDIR =
+
+#
+# Default target to build if no target is specified.
+# All Makefiles should either define an "all" target, or set
+# DEFAULT_TARGET to the default target
+#
+DEFAULT_TARGET = all
+default_target: $$(DEFAULT_TARGET)
+
+#Tools needed for i18n
+GENMSG = genmsg
+
+##-----------------------------------------------------------------
+
+CHMOD = /bin/chmod
+LEX = /usr/ccs/bin/lex
+MV = /bin/mv
+RANLIB = /bin/ranlib
+YACC = /usr/ccs/bin/yacc
+
+##-----------------------------------------------------------------
+
+CPPFLAGS += -DINTER \
+ -I$(TOP)/include
+
+LINTFLAGS += -buxz
+
+
+#LIB += $(LIBCMM) $(LIBSCCS) $(LIBUTIL) -lw
+
+##-----------------------------------------------------------------
+## Rules for building derived files from $(SRC)
+##
+## Run check_catgets before compiling to see if there are any strings that need
+## i18n attention.
+##
+## Use .C extension for derrived source files (e.g., yacc output) and on any
+## others on which you don't want to first run check_catgets.
+
+%.o: $(SRC)/%.cc
+ $(COMPILE.cc) $(OUTPUT_OPTION) $<
+
+%.o:$(SRC)/%.C
+ $(COMPILE.cc) $(OUTPUT_OPTION) $<
+
+%.o:$(SRC)/%.c
+ $(COMPILE.c) $(OUTPUT_OPTION) $<
+
+### Generate preprocessor output
+CPP.c = $(CC) $(CFLAGS) $(CINCLS) -E
+CPP.cc = $(CCC) $(CCFLAGS) $(CCINCLS) -E
+
+%.E: $(SRC)/%.cc
+ $(CPP.cc) $(CPPFLAGS) $(SRC)/$(@:%.E=%.cc) > $*.E
+
+%.E:$(SRC)/%.C
+ $(CPP.cc) $(CPPFLAGS) $(SRC)/$(@:%.E=%.C) > $*.E
+
+%.E:$(SRC)/%.c
+ $(CPP.c) $(CPPFLAGS) $(SRC)/$(@:%.E=%.c) > $*.E
+
+### Lex and yacc
+%.cc: $(SRC)/%.y
+ $(RM) $*.cc $*.h
+ $(YACC) $(YFLAGS) $(SRC)/$*.y
+ $(MV) y.tab.c $*.cc
+ $(MV) y.tab.h $*.h
+ $(CHMOD) a-w $*.cc $*.h
+
+%.C: $(SRC)/%.l
+ $(RM) $*.C
+ $(LEX) $(LEXOPT) $(SRC)/$*.l > $*.C
+ $(CHMOD) a-w $@
diff --git a/usr/src/make_src/rules/recurse.mk b/usr/src/make_src/rules/recurse.mk
new file mode 100644
index 0000000..d0963ad
--- /dev/null
+++ b/usr/src/make_src/rules/recurse.mk
@@ -0,0 +1,58 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)recurse.mk 1.15 06/12/12
+#
+
+# Include this Makefile in directories which simply cd down a level
+# and continue the build.
+#
+# The SUBDIRS macro must be set before including recurse.Makefile
+# The OTHER_TARGS macro can be set to process targets other than
+# directories.
+
+all := TARG = all
+install := TARG = install
+clean := TARG = clean
+l10n_install := TARG = l10n_install
+i18n_install := TARG = i18n_install
+
+# Are we _really_ using OTHER_TARGS???
+#all install clean l10n_install: $(SUBDIRS) $(OTHER_TARGS)
+all install clean l10n_install i18n_install:: $(SUBDIRS) $(OTHER_TARGS)
+
+# Conditional is in place so a "make" from the top level will work on partial
+# source heirarchies.
+#
+# "MAKEFILE" can be set by makes driving this one to cause a particular
+# makefile to be used. E.g., MAKEFILE=-f foo.mk
+#
+$(SUBDIRS): FRC
+ @if [ -d $@ ]; then \
+ echo "cd $@; $(MAKE) $(MAKEFILE) $(MFLAGS) CC=$(CC) CCC=$(CCC) DESTDIR=$(DESTDIR) $(TARG)"; \
+ cd $@; $(MAKE) $(MAKEFILE) $(MFLAGS) CC=$(CC) CCC=$(CCC) DESTDIR=$(DESTDIR) $(TARG); \
+ fi
+
+FRC:
+
+
diff --git a/usr/src/make_src/rules/singleton.mk b/usr/src/make_src/rules/singleton.mk
new file mode 100644
index 0000000..3dda8b6
--- /dev/null
+++ b/usr/src/make_src/rules/singleton.mk
@@ -0,0 +1,63 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)singleton.mk 1.64 06/12/12
+#
+
+# This is an included Makefile for a program that consists of a single C++
+# source file and is built with the standard Avocet library.
+
+# Before including this Makefile the following variables should be set:
+# TOP the path from the including Makefile to this one
+# PROG the name of the program
+# DESTDIR destination directory for the install
+#
+# All other information is derived from PROG.
+
+SRCS = $(PROG).cc $(MORE_SRC)
+OBJS = $(SRCS:%.cc=%.o)
+
+LIB += $(LIBCLI) $(LIBLICTXT) -lintl -lm
+
+##-----------------------------------------------------------------
+
+all install:: $(PROG)
+
+include $(TOP)/rules/verstring.mk
+
+$(PROG): $(OBJS)
+ @echo "#pragma ident \"@(#)$(VERSTRING1)\"" > timestamp.c
+ @echo $(VERSTRING2) >> timestamp.c
+ cc -w -c timestamp.c
+ $(CCC) $(CCFLAGS) $(LDFLAGS) timestamp.o -o $@ \
+ $(OBJS) $(LIB) $(I18LIB) $(LDLIB)
+ /bin/sh $(TOP)/exe/sanity-check.sh $(TOP) $(PROG)
+
+clean:
+ $(RM) $(OBJS) $(PROG)
+
+PROG_DIR = bin
+
+include $(TOP)/rules/install.mk
+
+include $(TOP)/rules/computed-options.mk
diff --git a/usr/src/make_src/rules/solaris.mk b/usr/src/make_src/rules/solaris.mk
new file mode 100644
index 0000000..d5ef1a4
--- /dev/null
+++ b/usr/src/make_src/rules/solaris.mk
@@ -0,0 +1,55 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)solaris.mk 1.19 06/12/12
+#
+
+# Please keep each list alphabetically sorted.
+
+#
+# Make variables
+#
+OPENWINHOME = /usr/openwin
+
+#
+# Paths
+#
+#LD_LIBRARY_PATH = /usr/dt/lib:$(OPENWINHOME)/lib
+#
+SWHOME =
+
+#
+# Programs
+#
+#CC = cc
+INSTALL = /usr/ucb/install
+RPCGEN = /usr/5bin/rpcgen
+
+#
+# Flags
+#
+CPPFLAGS += -compat=4
+I18LIB = -lintl
+LDFLAGS += -compat=4 -staticlib=libC
+LEXOPT = -tw
+MOTIF_LD_RUN_PATH = /usr/dt/lib:/usr/openwin/lib
diff --git a/usr/src/make_src/rules/sparc-S2.mk b/usr/src/make_src/rules/sparc-S2.mk
new file mode 100644
index 0000000..d1fb437
--- /dev/null
+++ b/usr/src/make_src/rules/sparc-S2.mk
@@ -0,0 +1,61 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1998 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)sparc-S2.mk 1.13 06/12/12
+#
+
+include $(TOP)/rules/solaris.mk
+
+# Please keep each list alphabetically sorted.
+
+#
+# Make variables
+#
+
+#
+# Paths
+#
+TOOLS_PATH = $(TOP)/exe
+
+#
+# Programs
+#
+
+#
+# Flags
+#
+CPPFLAGS += -DSUN5_0 -DSYSV
+
+#
+# v9 Flags
+#
+sparcv9 := V9FLAGS = -xarch=v9
+sparcv9 := VAR_DIR = /sparcv9
+
+#
+# This is temporary until both 32- and 64-bit stuff are to be compiled
+# with the same compiler. Currently 32-bit should use 4.2 compiler
+# but 64-bit should use 5.0 compiler.
+#
+sparcv9 := CC = $(CC64)
+sparcv9 := CCC = $(CCC64)
diff --git a/usr/src/make_src/rules/variant.mk b/usr/src/make_src/rules/variant.mk
new file mode 100644
index 0000000..d5fa217
--- /dev/null
+++ b/usr/src/make_src/rules/variant.mk
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# @(#)variant.mk 1.2 06/12/12
+#
+VARIANT:sh=if [ `uname -r | cut -d . -f1` = 4 ] ; \
+then echo sparc-S1 ; \
+elif [ `uname -s` = HP-UX ] ; \
+then echo hp-ux ; \
+else if [ `uname -p` = sparc ] ; \
+ then \
+ echo sparc-S2 ; \
+ elif [ `uname -p` = i386 ] ; \
+ then \
+ echo intel-S2 ; \
+ elif [ `uname -p` = ppc ] ; \
+ then \
+ echo ppc-S2 ; \
+ else \
+ echo "UNKNOWN OS" ; \
+ exit 1 ; \
+ fi ; \
+fi
+
+