[Pkg-virtualbox-commits] [kbuild] 07/10: New upstream version 0.1.9998svn3098+dfsg
Gianfranco Costamagna
locutusofborg at moszumanska.debian.org
Thu Oct 19 15:44:40 UTC 2017
This is an automated email from the git hooks/post-receive script.
locutusofborg pushed a commit to branch experimental
in repository kbuild.
commit fb9427207780db27824338c43a7f8c9c959c935b
Author: Gianfranco Costamagna <locutusofborg at debian.org>
Date: Thu Oct 19 17:29:23 2017 +0200
New upstream version 0.1.9998svn3098+dfsg
---
Config.kmk | 185 +++---
SlickEdit/kdev.e | 48 +-
bootstrap.gmk | 4 +-
kBuild/env.sh | 51 +-
kBuild/header.kmk | 106 ++-
kBuild/tools/GCC32.kmk | 4 +-
kBuild/tools/GCC64.kmk | 4 +-
kBuild/tools/GXX32.kmk | 4 +-
kBuild/tools/GXX64.kmk | 4 +-
kBuild/tools/VAC308.kmk | 20 +-
kBuild/tools/VCC120.kmk | 432 +++++++++++++
kBuild/tools/VCC120AMD64.kmk | 465 +++++++++++++
kBuild/tools/VCC120X86.kmk | 465 +++++++++++++
src/kDepPre/kDepPre.c | 12 +-
src/kObjCache/kObjCache.c | 27 +-
src/kWorker/Makefile.kmk | 21 +-
src/kWorker/kWorker.c | 616 +++++++++++++++++-
src/kWorker/kWorkerTlsXxxK.c | 110 ++++
src/kash/Makefile.kmk | 21 +-
src/kash/eval.c | 6 +-
src/kash/exec.c | 50 +-
src/kash/input.c | 6 +
src/kash/mystring.h | 2 +-
src/kash/parser.c | 27 +-
src/kash/shell.h | 2 +
src/kmk/Makefile.am | 16 +-
src/kmk/Makefile.kmk | 21 +-
src/kmk/config.h.netbsd | 459 +++++++++++++
src/kmk/dir.c | 10 +-
src/kmk/expreval.c | 6 +-
src/kmk/glob/glob.h | 1 +
src/kmk/job.c | 50 +-
src/kmk/kbuild-object.c | 10 +-
src/kmk/kbuild.c | 40 +-
src/kmk/kmkbuiltin.c | 210 +++---
src/kmk/kmkbuiltin.h | 7 +-
src/kmk/kmkbuiltin/cmp.c | 4 +-
src/kmk/kmkbuiltin/cmp_util.c | 6 +-
src/kmk/kmkbuiltin/common-env-and-cwd-opt.c | 200 ++++--
src/kmk/kmkbuiltin/echo.c | 20 +-
src/kmk/kmkbuiltin/err.c | 22 +-
src/kmk/kmkbuiltin/install.c | 4 +
src/kmk/kmkbuiltin/kDepObj.c | 24 +-
src/kmk/kmkbuiltin/kSubmit.c | 54 +-
src/kmk/kmkbuiltin/mscfakes.c | 76 ++-
src/kmk/kmkbuiltin/mscfakes.h | 26 +-
src/kmk/kmkbuiltin/redirect.c | 212 +++---
src/kmk/kmkbuiltin/rm.c | 4 +
src/kmk/kmkbuiltin/test.c | 4 +-
src/kmk/kmkbuiltin/touch.c | 967 ++++++++++++++++++++++++++++
src/kmk/main.c | 24 +-
src/kmk/misc.c | 4 +-
src/kmk/strcache.c | 2 +-
src/kmk/strcache2.c | 63 +-
src/kmk/variable.c | 2 +-
src/kmk/variable.h | 8 +-
src/kmk/w32/pathstuff.c | 1 -
src/kmk/w32/subproc/sub_proc.c | 19 +
src/lib/Makefile.kmk | 3 +-
src/lib/kDep.c | 4 +-
src/lib/kStuff/include/k/kDefs.h | 60 +-
src/lib/kStuff/include/k/kHlpAssert.h | 125 +++-
src/lib/kStuff/kLdr/kLdrModLX.c | 16 +-
src/lib/kStuff/kLdr/kLdrModMachO.c | 50 +-
src/lib/maybe_con_write.c | 4 +-
src/lib/md5.c | 2 +-
src/lib/nt/kFsCache.c | 37 +-
src/lib/nt/nthlp.h | 19 +-
src/lib/nt/nttypes.h | 12 +-
src/lib/nt/ntunlink.c | 8 +-
src/lib/nt/ntunlink.h | 3 +-
src/lib/nt/ntutimes.c | 99 +++
src/lib/nt/{nttypes.h => ntutimes.h} | 28 +-
src/sed/Makefile.kmk | 6 +-
src/sed/config.h.netbsd | 471 ++++++++++++++
75 files changed, 5552 insertions(+), 663 deletions(-)
diff --git a/Config.kmk b/Config.kmk
index 176a1b6..816f948 100644
--- a/Config.kmk
+++ b/Config.kmk
@@ -1,4 +1,4 @@
-# $Id: Config.kmk 2870 2016-09-04 13:52:39Z bird $
+# $Id: Config.kmk 3087 2017-10-03 13:31:19Z bird $
## @file
# Build Configuration.
#
@@ -223,61 +223,13 @@ endif
ifeq ($(KBUILD_TARGET),os2)
-TEMPLATE_BIN_TOOL = GCC3OMF
-TEMPLATE_BIN_CFLAGS = -g
-TEMPLATE_BIN_CFLAGS.profile = -pg
-TEMPLATE_BIN_CFLAGS.release = -O3
-TEMPLATE_BIN_LDFLAGS = -Zhigh-mem -Zstack=1024 -g
-endif
-
-ifeq ($(KBUILD_TARGET),darwin)
- ifndef KBUILD_MACOSX_VERSION
- export KBUILD_MACOSX_VERSION := $(expr $(firstword $(subst ., ,$(shell uname -r))) - 4)
- endif
- #ifndef KBUILD_XCODE_VERSION
- # export KBUILD_XCODE_VERSION := $(shell xcodebuild -version | kmk_sed -e '/Xcode/!d' -e 's/Xcode *//')
- #endif
- ifndef KBUILD_MACOSX_TARGET_VERSION
- if $(KBUILD_TARGET_ARCH) == amd64
- KBUILD_MACOSX_TARGET_VERSION = 6
- else
- KBUILD_MACOSX_TARGET_VERSION = 4
- endif
- endif
- ifndef KBUILD_MACOSX_WHATEVER_MODE
- if $(KBUILD_MACOSX_TARGET_VERSION) == 4
- TOOL_GCC4MACHO_SUFFIX = -4.0
- TOOL_GXX4MACHO_SUFFIX = -4.0
- else if $(KBUILD_MACOSX_TARGET_VERSION) >= 5
- TOOL_GCC4MACHO_SUFFIX = -4.2
- TOOL_GXX4MACHO_SUFFIX = -4.2
- endif
- ifndef KBUILD_MACOSX_SDK
- KBUILD_MACOSX_SDK := /Developer/SDKs/MacOSX10.$(KBUILD_MACOSX_TARGET_VERSION)$(if-expr $(KBUILD_MACOSX_TARGET_VERSION)==4,u,).sdk
- ifeq ($(wildcard $(KBUILD_MACOSX_SDK)),)
- KBUILD_MACOSX_SDK := /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform$(KBUILD_MACOSX_SDK)
- endif
- endif
- ifeq ($(wildcard $(KBUILD_MACOSX_SDK)),)
- $(error SDK not found ($(KBUILD_MACOSX_SDK)), please adjust KBUILD_MACOSX_TARGET_VERSION or/and KBUILD_MACOSX_SDK in LocalConfig.kmk or simply use KBUILD_MACOSX_WHATEVER_MODE=1.)
- endif
- endif # !KBUILD_MACOSX_WHATEVER_MODE
- TEMPLATE_BIN_TOOL = GCC4MACHO
- TEMPLATE_BIN_CFLAGS = -g -mmacosx-version-min=10.$(KBUILD_MACOSX_TARGET_VERSION) $(if $(KBUILD_MACOSX_WHATEVER_MODE),,-isysroot $(KBUILD_MACOSX_SDK))
- ifeq ($(USER),bird)
- TEMPLATE_BIN_CFLAGS += -Wall $(GCC_Wextra) -pedantic -Wno-unused-parameter -Wno-long-long -Wshadow
- TEMPLATE_BIN_DEFS += NO_ENUM_BITFIELDS
- endif
- TEMPLATE_BIN_CFLAGS.profile = -O3 -pg
+ TEMPLATE_BIN_TOOL = GCC3OMF
+ TEMPLATE_BIN_CFLAGS = -g
+ TEMPLATE_BIN_CFLAGS.profile = -pg
TEMPLATE_BIN_CFLAGS.release = -O3
- TEMPLATE_BIN_LDFLAGS = -g -mmacosx-version-min=10.$(KBUILD_MACOSX_TARGET_VERSION) $(if $(KBUILD_MACOSX_WHATEVER_MODE),,-Wl,-syslibroot,$(KBUILD_MACOSX_SDK))
- if $(KBUILD_MACOSX_TARGET_VERSION) == 4 && $(KBUILD_MACOSX_VERSION) >= 5
- TEMPLATE_BIN_LDFLAGS += -classic_ld
- endif
- TEMPLATE_BIN_LDFLAGS.profile = -pg
-endif
+ TEMPLATE_BIN_LDFLAGS = -Zhigh-mem -Zstack=1024 -g
-ifeq ($(filter-out win nt,$(KBUILD_TARGET)),)
+else if1of ($(KBUILD_TARGET), win nt)
TEMPLATE_BIN_TOOL = VCC100
TEMPLATE_BIN_TOOL.x86 = VCC100X86
TEMPLATE_BIN_TOOL.amd64 = VCC100AMD64
@@ -319,49 +271,104 @@ ifeq ($(filter-out win nt,$(KBUILD_TARGET)),)
$(PATH_TOOL_$(TEMPLATE_BIN_TOOL)_LIB)/msvcrt.lib
endif
endif
-endif
-ifndef TEMPLATE_BIN_TOOL
- # Use GCC3 when we're certain that the system is using GNU ld and ar.
- ifeq ($(filter-out linux freebsd openbsd netbsd,$(KBUILD_TARGET)),)
- TEMPLATE_BIN_TOOL = GCC3
- else
- TEMPLATE_BIN_TOOL = GCC3PLAIN
- endif
- TEMPLATE_BIN_CFLAGS = -g
- ifeq ($(USER),bird)
- TEMPLATE_BIN_CFLAGS += -Wall $(GCC_Wextra) -pedantic -Wno-unused-parameter -Wshadow
- TEMPLATE_BIN_DEFS += NO_ENUM_BITFIELDS
- endif
- TEMPLATE_BIN_LDFLAGS = -g
- TEMPLATE_BIN_LDFLAGS.profile = -pg -p
- TEMPLATE_BIN_CFLAGS.release = -O3
- TEMPLATE_BIN_CFLAGS.profile = -O3 -pg -p
- ifeq ($(KBUILD_TARGET),freebsd)
- TEMPLATE_BIN_INCS += $(PATH_GNUMAKE_SRC)/glob /usr/local/include
- endif
- ifeq ($(KBUILD_TARGET),linux)
- TEMPLATE_BIN_LIBS += rt
+else # !os2, !win, !nt
+
+ ifeq ($(KBUILD_TARGET),darwin)
+ ifndef KBUILD_MACOSX_VERSION
+ export KBUILD_MACOSX_VERSION := $(expr $(firstword $(subst ., ,$(shell uname -r))) - 4)
+ endif
+ #ifndef KBUILD_XCODE_VERSION
+ # export KBUILD_XCODE_VERSION := $(shell xcodebuild -version | kmk_sed -e '/Xcode/!d' -e 's/Xcode *//')
+ #endif
+ ifndef KBUILD_MACOSX_TARGET_VERSION
+ if $(KBUILD_TARGET_ARCH) == amd64
+ KBUILD_MACOSX_TARGET_VERSION = 6
+ else
+ KBUILD_MACOSX_TARGET_VERSION = 5
+ endif
+ endif
+ ifndef KBUILD_MACOSX_WHATEVER_MODE
+ if $(KBUILD_MACOSX_TARGET_VERSION) == 4
+ TOOL_GCC4MACHO_SUFFIX = -4.0
+ TOOL_GXX4MACHO_SUFFIX = -4.0
+ else if $(KBUILD_MACOSX_TARGET_VERSION) >= 5
+ TOOL_GCC4MACHO_SUFFIX = -4.2
+ TOOL_GXX4MACHO_SUFFIX = -4.2
+ endif
+ ifndef KBUILD_MACOSX_SDK
+ KBUILD_MACOSX_SDK := /Developer/SDKs/MacOSX10.$(KBUILD_MACOSX_TARGET_VERSION)$(if-expr $(KBUILD_MACOSX_TARGET_VERSION)==4,u,).sdk
+ ifeq ($(wildcard $(KBUILD_MACOSX_SDK)),)
+ KBUILD_MACOSX_SDK := /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform$(KBUILD_MACOSX_SDK)
+ endif
+ endif
+ ifeq ($(wildcard $(KBUILD_MACOSX_SDK)),)
+ $(error SDK not found ($(KBUILD_MACOSX_SDK)), please adjust KBUILD_MACOSX_TARGET_VERSION or/and KBUILD_MACOSX_SDK in LocalConfig.kmk or simply use KBUILD_MACOSX_WHATEVER_MODE=1.)
+ endif
+ endif # !KBUILD_MACOSX_WHATEVER_MODE
+ TEMPLATE_BIN_TOOL = GCC4MACHO
+ TEMPLATE_BIN_CFLAGS = -g -mmacosx-version-min=10.$(KBUILD_MACOSX_TARGET_VERSION) $(if $(KBUILD_MACOSX_WHATEVER_MODE),,-isysroot $(KBUILD_MACOSX_SDK))
+ ifeq ($(USER),bird)
+ TEMPLATE_BIN_CFLAGS += -Wall $(GCC_Wextra) -pedantic -Wno-unused-parameter -Wno-long-long -Wshadow
+ TEMPLATE_BIN_DEFS += NO_ENUM_BITFIELDS
+ endif
+ TEMPLATE_BIN_CFLAGS.profile = -O3 -pg
+ TEMPLATE_BIN_CFLAGS.release = -O3
+ TEMPLATE_BIN_LDFLAGS = -g -mmacosx-version-min=10.$(KBUILD_MACOSX_TARGET_VERSION) $(if $(KBUILD_MACOSX_WHATEVER_MODE),,-Wl,-syslibroot,$(KBUILD_MACOSX_SDK))
+ if $(KBUILD_MACOSX_TARGET_VERSION) == 4 && $(KBUILD_MACOSX_VERSION) >= 5
+ TEMPLATE_BIN_LDFLAGS += -classic_ld
+ endif
+ TEMPLATE_BIN_LDFLAGS.profile = -pg
+
+ else # !darwin
+ # Use GCC3 when we're certain that the system is using GNU ld and ar.
+ ifeq ($(filter-out linux freebsd openbsd netbsd,$(KBUILD_TARGET)),)
+ TEMPLATE_BIN_TOOL = GCC3
+ else
+ TEMPLATE_BIN_TOOL = GCC3PLAIN
+ endif
+ TEMPLATE_BIN_CFLAGS = -g
+ ifeq ($(USER),bird)
+ TEMPLATE_BIN_CFLAGS += -Wall $(GCC_Wextra) -pedantic -Wno-unused-parameter -Wshadow
+ TEMPLATE_BIN_DEFS += NO_ENUM_BITFIELDS
+ endif
+ TEMPLATE_BIN_LDFLAGS = -g
+ TEMPLATE_BIN_LDFLAGS.profile = -pg -p
+ TEMPLATE_BIN_CFLAGS.release = -O3
+ TEMPLATE_BIN_CFLAGS.profile = -O3 -pg -p
+ ifeq ($(KBUILD_TARGET),freebsd)
+ TEMPLATE_BIN_INCS += $(PATH_GNUMAKE_SRC)/glob /usr/local/include
+ endif
+ ifeq ($(KBUILD_TARGET),linux)
+ TEMPLATE_BIN_LIBS += rt
+ endif
endif
- TEMPLATE_BIN_CFLAGS.x86 += -m32
- TEMPLATE_BIN_CFLAGS.sparc32 += -m32
- TEMPLATE_BIN_CFLAGS.amd64 += -m64
- TEMPLATE_BIN_CFLAGS.sparc64 += -m64
- TEMPLATE_BIN_CXXFLAGS.x86 += -m32
- TEMPLATE_BIN_CXXFLAGS.sparc32+= -m32
- TEMPLATE_BIN_CXXFLAGS.amd64 += -m64
- TEMPLATE_BIN_CXXFLAGS.sparc64+= -m64
- TEMPLATE_BIN_LDFLAGS.x86 += -m32
- TEMPLATE_BIN_LDFLAGS.sparc32 += -m32
- TEMPLATE_BIN_LDFLAGS.amd64 += -m64
- TEMPLATE_BIN_LDFLAGS.sparc64 += -m64
+
+ # Make sure we get the right bit count in the output.
+ TEMPLATE_BIN_CFLAGS.x86 += -m32
+ TEMPLATE_BIN_CFLAGS.sparc32 += -m32
+ TEMPLATE_BIN_CFLAGS.amd64 += -m64
+ TEMPLATE_BIN_CFLAGS.sparc64 += -m64
+ TEMPLATE_BIN_CXXFLAGS.x86 += -m32
+ TEMPLATE_BIN_CXXFLAGS.sparc32 += -m32
+ TEMPLATE_BIN_CXXFLAGS.amd64 += -m64
+ TEMPLATE_BIN_CXXFLAGS.sparc64 += -m64
+ TEMPLATE_BIN_LDFLAGS.x86 += -m32
+ TEMPLATE_BIN_LDFLAGS.sparc32 += -m32
+ TEMPLATE_BIN_LDFLAGS.amd64 += -m64
+ TEMPLATE_BIN_LDFLAGS.sparc64 += -m64
ifeq ($(KBUILD_TARGET),solaris)
TEMPLATE_BIN_LIBS += rt dl
TEMPLATE_BIN_LDFLAGS += -Wl,-i
TEMPLATE_BIN_DEFS.x86 += _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE
TEMPLATE_BIN_DEFS.sparc32 += _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE
endif
+ ifeq ($(KBUILD_TARGET),netbsd)
+ TEMPLATE_BIN_LIBS += util
+ endif
endif
+
+# On systems where it's possible, do split out the debug info from the binaries.
if1of ($(KBUILD_TARGET), darwin win)
TEMPLATE_BIN_LD_DEBUG = split
endif
@@ -372,7 +379,7 @@ endif
TEMPLATE_BIN-THREADED = Threaded command line binary
TEMPLATE_BIN-THREADED_EXTENDS = BIN
TEMPLATE_BIN-THREADED_EXTENDS_BY = appending
-if1of ($(KBUILD_TARGET), dragonfly freebsd linux openbsd)
+if1of ($(KBUILD_TARGET), dragonfly freebsd gnukfbsd gnuknbsd linux netbsd openbsd)
TEMPLATE_BIN-THREADED_LIBS = pthread
endif
diff --git a/SlickEdit/kdev.e b/SlickEdit/kdev.e
index 46d7940..476d437 100644
--- a/SlickEdit/kdev.e
+++ b/SlickEdit/kdev.e
@@ -1,4 +1,4 @@
-/* $Id: kdev.e 3018 2017-01-07 00:06:39Z bird $ -*- tab-width: 4 c-indent-level: 4 -*- */
+/* $Id: kdev.e 3069 2017-10-02 06:28:54Z bird $ -*- tab-width: 4 c-indent-level: 4 -*- */
/** @file
* Visual SlickEdit Documentation Macros.
*/
@@ -66,6 +66,7 @@ def 'C-S-G' = k_box_globals
def 'C-S-H' = k_box_headers
def 'C-S-I' = k_box_intfuncs
def 'C-S-K' = k_box_consts
+def 'C-S-N' = k_noref
def 'C-S-M' = k_javadoc_moduleheader
def 'C-S-O' = k_oneliner
def 'C-S-P' = k_mark_modified_line
@@ -1561,8 +1562,6 @@ void k_box_exported()
k_box_end();
}
-
-
/** oneliner comment */
void k_oneliner()
{
@@ -1600,7 +1599,6 @@ void k_mark_modified_line()
down();
}
-
/**
* Inserts a signature. Form: "//Initials ISO-date:"
* @remark defeventtab
@@ -1616,6 +1614,48 @@ void k_signature()
k_insert_comment(sSig, KIC_CURSOR_AT_END);
}
+/* Insert a list of NOREF() macro invocations. */
+void k_noref()
+{
+ typeless org_pos;
+ _save_pos2(org_pos);
+
+ _str sNoRefs = '';
+ boolean fFoundFn = !k_func_goto_nearest_function();
+ if (fFoundFn)
+ {
+ _str sArgs = k_func_getparams();
+ int cArgs = k_func_countparams(sArgs);
+ int i;
+ int offLine = 4;
+ for (i = 0; i < cArgs; i++)
+ {
+ _str sName, sType, sDefault;
+ if (!k_func_enumparams(sArgs, i, sType, sName, sDefault))
+ {
+ sThis = 'NOREF(' sName ');';
+ if (length(sNoRefs) == 0)
+ {
+ sNoRefs = sThis;
+ offLine += length(sThis);
+ }
+ else if (offLine + length(sThis) < 130)
+ {
+ sNoRefs = sNoRefs ' ' sThis;
+ offLine += 1 + length(sThis);
+ }
+ else
+ {
+ sNoRefs = sNoRefs "\n " sThis;
+ offLine = 4 + length(sThis);
+ }
+ }
+ }
+ }
+
+ _restore_pos2(org_pos);
+ _insert_text(sNoRefs);
+}
/*******************************************************************************
* kLIB Logging *
diff --git a/bootstrap.gmk b/bootstrap.gmk
index 8cbb233..7f4b1cb 100644
--- a/bootstrap.gmk
+++ b/bootstrap.gmk
@@ -1,4 +1,4 @@
-# $Id: bootstrap.gmk 2421 2010-10-17 21:27:53Z bird $
+# $Id: bootstrap.gmk 3028 2017-04-13 13:31:34Z bird $
## @file
# GNU Make Compatible bootstrap Makefile.
#
@@ -36,7 +36,7 @@
# - echo done > some-file works.
# - Recent GNU make that implements CURDIR, $(error) and ifdef.
#
-# Tip: kBuild/env.sh --full (g(nu))make -f bootstrap.kmk
+# Tip: kBuild/env.sh --full (g(nu))make -f bootstrap.gmk
#
# Note to self on bootstrapping solaris.sparc64:
# SED_MAKE_DEFS="SED=gsed" AUTOPOINT=true ACLOCAL=aclocal-1.10 AUTOMAKE=automake-1.10 nice ./kBuild/env.sh --full gmake -f bootstrap.gmk
diff --git a/kBuild/env.sh b/kBuild/env.sh
index b832cf2..7be6315 100755
--- a/kBuild/env.sh
+++ b/kBuild/env.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: env.sh 2546 2011-10-01 19:49:54Z bird $
+# $Id: env.sh 3062 2017-09-30 11:26:21Z bird $
## @file
# Environment setup script.
#
@@ -329,22 +329,28 @@ if test -z "$KBUILD_HOST_ARCH"; then
x86|i86pc|ia32|i[3456789]86|BePC)
KBUILD_HOST_ARCH='x86'
;;
- sparc32|sparc|sparcv8|sparcv7|sparcv8e)
- KBUILD_HOST_ARCH='sparc32'
+ alpha)
+ KBUILD_HOST_ARCH='alpha'
;;
- sparc64|sparcv9)
- KBUILD_HOST_ARCH='sparc64'
+ aarch32|arm|arm1|arm2|arm3|arm6|armv1|armv2|armv3*|armv4*|armv5*|armv6*|armv7*)
+ KBUILD_HOST_ARCH='arm32'
;;
- s390)
- KBUILD_HOST_ARCH='s390'
+ aarch64*)
+ KBUILD_HOST_ARCH='arm64'
;;
- s390x)
- KBUILD_HOST_ARCH='s390x'
+ hppa32|parisc32|parisc)
+ KBUILD_HOST_ARCH='hppa32'
+ ;;
+ hppa64|parisc64)
+ KBUILD_HOST_ARCH='hppa64'
+ ;;
+ ia64)
+ KBUILD_HOST_ARCH='ia64'
;;
ppc32|ppc|powerpc)
KBUILD_HOST_ARCH='ppc32'
;;
- ppc64|powerpc64)
+ ppc64|ppc64le|powerpc64|powerpc64le)
KBUILD_HOST_ARCH='ppc64'
;;
mips32|mips)
@@ -353,20 +359,23 @@ if test -z "$KBUILD_HOST_ARCH"; then
mips64)
KBUILD_HOST_ARCH='mips64'
;;
- ia64)
- KBUILD_HOST_ARCH='ia64'
- ;;
- hppa32|parisc32|parisc)
- KBUILD_HOST_ARCH='hppa32'
+ s390)
+ KBUILD_HOST_ARCH='s390'
;;
- hppa64|parisc64)
- KBUILD_HOST_ARCH='hppa64'
+ s390x)
+ KBUILD_HOST_ARCH='s390x'
;;
- arm|armv4l|armv5tel|armv5tejl)
- KBUILD_HOST_ARCH='arm'
+ sh|sh2|sh2a|sh3|sh3|sh4|sh4a|sh4al|sh4al-dsp|shmedia)
+ KBUILD_HOST_ARCH='sh32'
+ ;;
+ sh64)
+ KBUILD_HOST_ARCH='sh64'
+ ;;
+ sparc32|sparc|sparcv8|sparcv7|sparcv8e)
+ KBUILD_HOST_ARCH='sparc32'
;;
- alpha)
- KBUILD_HOST_ARCH='alpha'
+ sparc64|sparcv9)
+ KBUILD_HOST_ARCH='sparc64'
;;
*) echo "$0: unknown cpu/arch - $KBUILD_HOST_ARCH" 1>&${ERR_REDIR}
diff --git a/kBuild/header.kmk b/kBuild/header.kmk
index 21a0e3d..648a03f 100644
--- a/kBuild/header.kmk
+++ b/kBuild/header.kmk
@@ -1,4 +1,4 @@
-# $Id: header.kmk 2971 2016-09-27 11:25:09Z bird $
+# $Id: header.kmk 3093 2017-10-13 13:07:39Z bird $
## @file
# kBuild - File included at top of a makefile.
#
@@ -79,7 +79,7 @@ endif
# The revision in which this file was last modified.
# This can be useful when using development versions of kBuild.
#
-KMK_REVISION := $(patsubst %:,, $Rev: 2971 $ )
+KMK_REVISION := $(patsubst %:,, $Rev: 3093 $ )
#
@@ -170,6 +170,14 @@ SQUOTE := '
# Double quote character.
DQUOTE := "
+##
+# Opening parenthesis.
+OPENPAR := (
+
+##
+# Closing parenthesis.
+CLOSEPAR := )
+
#
# The list of standard build types in kBuild.
@@ -188,10 +196,11 @@ KBUILD_BLD_TYPES := release profile debug
# this keyword namespace is shared between OSes, architectures, cpus and
# build types. (PORTME)
#
-KBUILD_OSES := darwin dos dragonfly freebsd haiku l4 linux netbsd nt openbsd os2 solaris win os-agnostic
-KBUILD_ARCHES := x86 amd64 sparc32 sparc64 s390 s390x ppc32 ppc64 mips32 mips64 ia64 hppa32 hppa64 arm alpha noarch
-KBUILD_ARCHES_64 := amd64 sparc64 s390x ppc64 mips64 ia64 hppa64 alpha
-KBUILD_ARCHES_32 := x86 sparc32 s390 ppc32 mips32 hppa32 arm
+KBUILD_OSES := darwin dos dragonfly freebsd gnukfbsd gnuknbsd haiku l4 linux netbsd nt openbsd os2 solaris win os-agnostic
+KBUILD_ARCHES := x86 amd64 noarch alpha arm32 arm64 hppa32 hppa64 ia64 mips32 mips64 ppc32 ppc64 s390 s390x sh32 sh64 sparc32 sparc64
+KBUILD_ARCHES_64 := amd64 alpha arm64 hppa64 ia64 mips64 ppc64 s390x sh64 sparc64
+KBUILD_ARCHES_32 := x86 arm32 hppa32 mips32 ppc32 s390 sh32 sparc32
+
#
@@ -585,21 +594,25 @@ if1of ($(KBUILD_HOST), win nt)
# Win, Win32, Win64, NT.
EXEC_X86_WIN32 :=
HOSTSUFF_EXE := .exe
+HOST_PATH_SEP := $(SEMICOLON)
# OS/2.
else ifeq ($(KBUILD_HOST),os2)
EXEC_X86_WIN32 := innopec.exe
HOSTSUFF_EXE := .exe
+HOST_PATH_SEP := $(SEMICOLON)
-else if1of ($(KBUILD_HOST), freebsd dragonfly linux openbsd netbsd)
+else if1of ($(KBUILD_HOST), dragonfly freebsd gnukfbsd gnuknbsd linux openbsd netbsd)
# Unix (like) systems with wine.
EXEC_X86_WIN32 := wine
HOSTSUFF_EXE :=
+HOST_PATH_SEP := $(COLON)
else
# Unix (like) systems without wine.
EXEC_X86_WIN32 := false
HOSTSUFF_EXE :=
+HOST_PATH_SEP := $(COLON)
endif
@@ -635,7 +648,7 @@ SUFF_OBJ := .o
SUFF_LIB := .a
SUFF_DLL := .so
SUFF_EXE :=
- if1of ($(KBUILD_TARGET), dragonfly freebsd linux netbsd openbsd) ## @todo check netbsd and openbsd.
+ if1of ($(KBUILD_TARGET), dragonfly freebsd gnukfbsd gnuknbsd linux netbsd openbsd) ## @todo check netbsd, gnuknbsd and openbsd.
SUFF_SYS := .ko
else
SUFF_SYS :=
@@ -757,6 +770,14 @@ TIME_EXT := $(KBUILD_BIN_PATH)/kmk_time$(HOSTSUFF_EXE)
TIME_INT := $(TIME_EXT)
TIME := $(TIME_INT)
+TOUCH_EXT := $(KBUILD_BIN_PATH)/kmk_touch$(HOSTSUFF_EXE)
+if $(KBUILD_KMK_REVISION) >= 3060
+TOUCH_INT := kmk_builtin_touch
+else
+TOUCH_INT := $(TOUCH_EXT)
+endif
+TOUCH := $(TOUCH_INT)
+
# Our default shell is the Almquist shell from *BSD.
ASH := $(KBUILD_BIN_PATH)/kmk_ash$(HOSTSUFF_EXE)
MAKESHELL := $(ASH)
@@ -946,6 +967,50 @@ endif
#
+# Somewhat simple solution for automatic command dependencies.
+#
+
+##
+# Advanced version of KB_FN_AUTO_CMD_DEPS_COMMANDS_EX where you set
+# the dependency file name yourself.
+#
+# After or before the recipe do $(call KB_FN_AUTO_CMD_DEPS_EX,<recipe-target>,<dep-file>).
+#
+# @param 1 dep file.
+define KB_FN_AUTO_CMD_DEPS_COMMANDS_EX
+ %$(QUIET2)$(RM) -f -- "$1"
+ %$(QUIET2)$(APPEND) "$1" 'define AUTO_CMD_DEP_$(translate $@,:,_)_PREV_CMDS'
+ %$(QUIET2)$(APPEND) -c "$1" '$@'
+ %$(QUIET2)$(APPEND) "$1" 'endef'
+endef
+
+##
+# Advanced version of KB_FN_AUTO_CMD_DEPS
+#
+# @param 1 recipe name
+# @param 2 dep file.
+KB_FN_AUTO_CMD_DEPS_EX = $(eval includedep $2)$(eval _DEPFILES_INCLUDED += $2)$1: .MUST_MAKE = $$(comp-cmds-ex $$(AUTO_CMD_DEP_$(translate $1,:,_)_PREV_CMDS),$$(commands $1),FORCE)
+
+##
+# $(call KB_FN_AUTO_CMD_DEPS_COMMANDS) as the first command in a recipe to
+# automatically generate command dependencies.
+# After or before the recipe do $(call KB_FN_AUTO_CMD_DEPS,<recipe-target>).
+define KB_FN_AUTO_CMD_DEPS_COMMANDS
+ %$(QUIET2)$(RM) -f -- "$@.auto-dep"
+ %$(QUIET2)$(APPEND) "$@.auto-dep" 'define AUTO_CMD_DEP_$(translate $@,:,_)_PREV_CMDS'
+ %$(QUIET2)$(APPEND) -c "$@.auto-dep" '$@'
+ %$(QUIET2)$(APPEND) "$@.auto-dep" 'endef'
+endef
+
+##
+# Call before or after defining a recipe that you want automatic command
+# dependencies on. The recipe must start off by $(call KB_FN_AUTO_CMD_DEPS_COMMANDS).
+#
+# @param 1 recipe name
+KB_FN_AUTO_CMD_DEPS = $(call KB_FN_AUTO_CMD_DEPS_EX,$1,$1.auto-dep)
+
+
+#
# Initialize some of the globals which the Config.kmk and
# others can add stuff to if they like for processing in the footer.
#
@@ -1317,14 +1382,22 @@ ifeq ($(KBUILD_TARGET),darwin)
/Developer/usr/
KBUILD_LIB_SEARCH_SUBS := lib/
-else if1of ($(KBUILD_TARGET), freebsd netbsd openbsd dragonfly)
+else if1of ($(KBUILD_TARGET), freebsd openbsd dragonfly)
+ KBUILD_LIB_SEARCH_ROOTS := \
+ / \
+ /usr/ \
+ /usr/local/
+ KBUILD_LIB_SEARCH_SUBS := lib/
+
+else ifeq ($(KBUILD_TARGET),netbsd)
KBUILD_LIB_SEARCH_ROOTS := \
/ \
/usr/ \
+ /usr/pkg/ \
/usr/local/
KBUILD_LIB_SEARCH_SUBS := lib/
-else ifeq ($(KBUILD_TARGET),linux)
+else if1of ($(KBUILD_TARGET), gnukfbsd gnuknbsd linux)
ifeq ($(realpath /bin),/usr/bin)
KBUILD_LIB_SEARCH_ROOTS := \
/usr/ \
@@ -1601,9 +1674,11 @@ else
endif
+##
+# An internal define used by subheader.kmk, subfooter.kmk, and
+# KB_FN_PASS_0_ON_TARGET.
#
-# An internal define used by subheader.kmk and subfooter.kmk.
-# We keep them here to avoid redefining them for each sub-makefile.
+# @param target The target to process.
#
define def_subfooter_header_target_pass
ifndef $(target)_PATH
@@ -1623,6 +1698,13 @@ define def_subfooter_header_target_pass
endif
endef
+##
+# Function to call to set _0_OUTDIR, _DEFPATH, and _MAKEFILE earlier than subfooter.
+# Can be used to avoid exploiting double expansion.
+#
+# @param 1 The target name.
+KB_FN_DO_PASS0_ON_TARGET = $(foreach target,$1,$(if-expr defined($(target)_0_OUTDIR),,$(evalval def_subfooter_header_target_pass)))
+
#
# Validate any KBUILD_BLD_TYPES additions and finally the KBUILD_TYPE.
diff --git a/kBuild/tools/GCC32.kmk b/kBuild/tools/GCC32.kmk
index 595e78a..88fb941 100644
--- a/kBuild/tools/GCC32.kmk
+++ b/kBuild/tools/GCC32.kmk
@@ -1,4 +1,4 @@
-# $Id: GCC32.kmk 2775 2015-02-03 20:00:15Z bird $
+# $Id: GCC32.kmk 3062 2017-09-30 11:26:21Z bird $
## @file
# kBuild Tool Config - Generic 32-bit GCC v3.2.x or later Using The System GCC.
#
@@ -46,7 +46,7 @@ TOOL_GCC32_LDFLAGS.dll ?= -shared
else
TOOL_GCC32_LDFLAGS.dll ?= $(TOOL_GCC32_LDFLAGS.$(KBUILD_TARGET))
endif
-TOOL_GCC32_LDFLAGS.sysmod ?= -r -m elf_i386$(if-expr "$(KBUILD_TARGET)" == "freebsd",_fbsd,)
+TOOL_GCC32_LDFLAGS.sysmod ?= -r -m elf_i386$(if-expr "$(KBUILD_TARGET)" == "freebsd" || "$(KBUILD_TARGET)" == "gnukfbsd",_fbsd,)
TOOL_GCC32_LD_SONAME ?= -Wl,-soname=$(firstword $($(1)_SONAME.$(KBUILD_TARGET).$(KBUILD_TYPE)) $($(1)_SONAME.$(KBUILD_TARGET)) $($(1)_SONAME.$(KBUILD_TYPE)) $($(1)_SONAME) $(notdir $(2)))
ifeq ($(KBUILD_TARGET),os2)
TOOL_GCC32_LD_MAP ?= -Zmap=$(1)
diff --git a/kBuild/tools/GCC64.kmk b/kBuild/tools/GCC64.kmk
index 586f737..154f7d8 100644
--- a/kBuild/tools/GCC64.kmk
+++ b/kBuild/tools/GCC64.kmk
@@ -1,4 +1,4 @@
-# $Id: GCC64.kmk 2774 2015-02-03 19:56:24Z bird $
+# $Id: GCC64.kmk 3062 2017-09-30 11:26:21Z bird $
## @file
# kBuild Tool Config - Generic 64-bit GCC v3.2.x or later Using The System GCC.
#
@@ -46,7 +46,7 @@ TOOL_GCC64_LDFLAGS.dll ?= -shared
else
TOOL_GCC64_LDFLAGS.dll ?= $(TOOL_GCC64_LDFLAGS.$(KBUILD_TARGET))
endif
-TOOL_GCC64_LDFLAGS.sysmod ?= -r -m elf_x86_64$(if-expr "$(KBUILD_TARGET)" == "freebsd",_fbsd,)
+TOOL_GCC64_LDFLAGS.sysmod ?= -r -m elf_x86_64$(if-expr "$(KBUILD_TARGET)" == "freebsd" || "$(KBUILD_TARGET)" == "gnukfbsd",_fbsd,)
TOOL_GCC64_LD_SONAME ?= -Wl,-soname=$(firstword $($(1)_SONAME.$(KBUILD_TARGET).$(KBUILD_TYPE)) $($(1)_SONAME.$(KBUILD_TARGET)) $($(1)_SONAME.$(KBUILD_TYPE)) $($(1)_SONAME) $(notdir $(2)))
ifeq ($(KBUILD_TARGET),os2)
TOOL_GCC64_LD_MAP ?= -Zmap=$(1)
diff --git a/kBuild/tools/GXX32.kmk b/kBuild/tools/GXX32.kmk
index 49463d2..cda007f 100644
--- a/kBuild/tools/GXX32.kmk
+++ b/kBuild/tools/GXX32.kmk
@@ -1,4 +1,4 @@
-# $Id: GXX32.kmk 2775 2015-02-03 20:00:15Z bird $
+# $Id: GXX32.kmk 3062 2017-09-30 11:26:21Z bird $
## @file
# kBuild Tool Config - Generic 32-bit GCC v3.2.x or later using the system GCC, for building C++ code.
#
@@ -46,7 +46,7 @@ TOOL_GXX32_LDFLAGS.dll ?= -shared
else
TOOL_GXX32_LDFLAGS.dll ?= $(TOOL_GXX32_LDFLAGS.$(KBUILD_TARGET))
endif
-TOOL_GXX32_LDFLAGS.sysmod ?= -r -m elf_i386$(if-expr "$(KBUILD_TARGET)" == "freebsd",_fbsd,)
+TOOL_GXX32_LDFLAGS.sysmod ?= -r -m elf_i386$(if-expr "$(KBUILD_TARGET)" == "freebsd" || "$(KBUILD_TARGET)" == "gnukfbsd",_fbsd,)
TOOL_GXX32_LD_SONAME ?= -Wl,-soname=$(firstword $($(1)_SONAME.$(KBUILD_TARGET).$(KBUILD_TYPE)) $($(1)_SONAME.$(KBUILD_TARGET)) $($(1)_SONAME.$(KBUILD_TYPE)) $($(1)_SONAME) $(notdir $(2)))
ifeq ($(KBUILD_TARGET),os2)
TOOL_GXX32_LD_MAP ?= -Zmap=$(1)
diff --git a/kBuild/tools/GXX64.kmk b/kBuild/tools/GXX64.kmk
index 03973fc..0c319ea 100644
--- a/kBuild/tools/GXX64.kmk
+++ b/kBuild/tools/GXX64.kmk
@@ -1,4 +1,4 @@
-# $Id: GXX64.kmk 2774 2015-02-03 19:56:24Z bird $
+# $Id: GXX64.kmk 3062 2017-09-30 11:26:21Z bird $
## @file
# kBuild Tool Config - Generic 64-bit GCC v3.2.x or later using the system GCC, for building C++ code.
#
@@ -46,7 +46,7 @@ TOOL_GXX64_LDFLAGS.dll ?= -shared
else
TOOL_GXX64_LDFLAGS.dll ?= $(TOOL_GXX64_LDFLAGS.$(KBUILD_TARGET))
endif
-TOOL_GXX64_LDFLAGS.sysmod ?= -r -m elf_x86_64$(if-expr "$(KBUILD_TARGET)" == "freebsd",_fbsd,)
+TOOL_GXX64_LDFLAGS.sysmod ?= -r -m elf_x86_64$(if-expr "$(KBUILD_TARGET)" == "freebsd" || "$(KBUILD_TARGET)" == "gnukfbsd",_fbsd,)
TOOL_GXX64_LD_SONAME ?= -Wl,-soname=$(firstword $($(1)_SONAME.$(KBUILD_TARGET).$(KBUILD_TYPE)) $($(1)_SONAME.$(KBUILD_TARGET)) $($(1)_SONAME.$(KBUILD_TYPE)) $($(1)_SONAME) $(notdir $(2)))
ifeq ($(KBUILD_TARGET),os2)
TOOL_GXX64_LD_MAP ?= -Zmap=$(1)
diff --git a/kBuild/tools/VAC308.kmk b/kBuild/tools/VAC308.kmk
index 8899f19..7b9e78f 100644
--- a/kBuild/tools/VAC308.kmk
+++ b/kBuild/tools/VAC308.kmk
@@ -1,4 +1,4 @@
-# $Id: VAC308.kmk 3023 2017-01-07 17:24:57Z bird $
+# $Id: VAC308.kmk 3055 2017-08-31 15:34:33Z bird $
## @file
# kBuild Tool Config - VisualAge for C++ v3.08.
#
@@ -68,6 +68,7 @@ ifneq ($(PATH_TOOL_VAC308),)
-E 'DPATH=$(PATH_TOOL_VAC308_LOCALE);$(PATH_TOOL_VAC308_HELP);$(DPATH)' \
-E 'LIB=$1' \
-E 'INCLUDE=' \
+ $2 \
--
TOOL_VAC308_CC ?= $(PATH_TOOL_VAC308_BIN)/icc$(HOSTSUFF_EXE)
TOOL_VAC308_CXX ?= $(PATH_TOOL_VAC308_BIN)/icc$(HOSTSUFF_EXE)
@@ -81,6 +82,7 @@ else
TOOL_VAC308_ENV_SETUP ?= $(REDIRECT) \
-E 'LIB=$1' \
-E 'INCLUDE=' \
+ $2 \
--
TOOL_VAC308_CC ?= icc$(HOSTSUFF_EXE)
TOOL_VAC308_CXX ?= icc$(HOSTSUFF_EXE)
@@ -125,30 +127,30 @@ TOOL_VAC308_LDFLAGS.debug ?= -Ti+
TOOL_VAC308_COMPILE_C_DEPEND =
TOOL_VAC308_COMPILE_C_DEPORD =
-TOOL_VAC308_COMPILE_C_OUTPUT =
+TOOL_VAC308_COMPILE_C_OUTPUT = $(obj).ii
define TOOL_VAC308_COMPILE_C_CMDS
$(QUIET) $(call TOOL_VAC308_ENV_SETUP) $(TOOL_VAC308_CC) -c\
$(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
-Fo$(obj)\
$(abspath $(source))
- $(QUIET) $(call TOOL_VAC308_ENV_SETUP) $(TOOL_VAC308_CC) -P+ -Pd+ \
+ $(QUIET) $(call TOOL_VAC308_ENV_SETUP,,-wo $(obj).ii) $(TOOL_VAC308_CC) -P+ -Pd+ \
$(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
- $(abspath $(source)) \
- | $(DEP_PRE) -f -s -o $(dep) -t $(obj) -
+ $(abspath $(source))
+ $(QUIET)$(DEP_PRE) -f -s -o $(dep) -t $(obj) $(obj).ii
endef
TOOL_VAC308_COMPILE_CXX_DEPEND =
TOOL_VAC308_COMPILE_CXX_DEPORD =
-TOOL_VAC308_COMPILE_CXX_OUTPUT =
+TOOL_VAC308_COMPILE_CXX_OUTPUT = $(obj).ii
define TOOL_VAC308_COMPILE_CXX_CMDS
$(QUIET) $(call TOOL_VAC308_ENV_SETUP) $(TOOL_VAC308_CXX) -c\
$(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
-Fo$(obj)\
$(abspath $(source))
- $(QUIET) $(call TOOL_VAC308_ENV_SETUP) $(TOOL_VAC308_CXX) -P+ -Pd+ \
+ $(QUIET) $(call TOOL_VAC308_ENV_SETUP,,-wo $(obj).ii) $(TOOL_VAC308_CXX) -P+ -Pd+ \
$(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
- $(abspath $(source)) \
- | $(DEP_PRE) -f -s -o $(dep) -t $(obj) -
+ $(abspath $(source))
+ $(QUIET)$(DEP_PRE) -f -s -o $(dep) -t $(obj) $(obj).ii
endef
TOOL_VAC308_COMPILE_RC_OUTPUT =
diff --git a/kBuild/tools/VCC120.kmk b/kBuild/tools/VCC120.kmk
new file mode 100644
index 0000000..eb67a1b
--- /dev/null
+++ b/kBuild/tools/VCC120.kmk
@@ -0,0 +1,432 @@
+# $Id: VCC120.kmk 3037 2017-05-10 09:24:06Z bird $
+## @file
+# kBuild Tool Config - Visual C++ 12.0 (aka Visual 2013 and MSC v18), targeting $(KBUILD_TARGET).
+#
+
+#
+# Copyright (c) 2004-2017 knut st. osmundsen <bird-kBuild-spam-xiv at anduin.net>
+#
+# This file is part of kBuild.
+#
+# kBuild is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# kBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with kBuild; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+#
+# As a special exception you are granted permission to include this file, via
+# the kmk include directive, as you wish without this in itself causing the
+# resulting makefile, program or whatever to be covered by the GPL license.
+# This exception does not however invalidate any other reasons why the makefile,
+# program, whatever should not be covered the GPL.
+#
+#
+
+TOOL_VCC120 := Visual C++ 12.0 (aka Visual 2013 and MSC v18), targeting $(KBUILD_TARGET).
+
+# Tool Specific Properties
+ifndef PATH_TOOL_VCC120
+ PATH_TOOL_VCC120 := $(wildcard $(KBUILD_DEVTOOLS_TRG)/vcc/v12*)
+ ifeq ($(PATH_TOOL_VCC120),)
+ PATH_TOOL_VCC120 := $(wildcard $(KBUILD_DEVTOOLS)/win.x86/vcc/v12*)
+ endif
+ ifeq ($(PATH_TOOL_VCC120),)
+ PATH_TOOL_VCC120 := $(wildcard $(KBUILD_DEVTOOLS)/x86.win32/vcc/v12*)
+ endif
+ ifeq ($(PATH_TOOL_VCC120),)
+ PATH_TOOL_VCC120 := $(wildcard $(KBUILD_DEVTOOLS)/win.amd64/vcc/v12*)
+ endif
+ ifeq ($(PATH_TOOL_VCC120),)
+ PATH_TOOL_VCC120 := $(lastword $(sort $(PATH_TOOL_VCC120)))
+ endif
+ # if not found, we'll enter 'pathless' mode.
+else
+ # Resolve any fancy stuff once and for all.
+ PATH_TOOL_VCC120 := $(PATH_TOOL_VCC120)
+endif
+ifneq ($(PATH_TOOL_VCC120),)
+ if "$(KBUILD_HOST).$(KBUILD_HOST_ARCH)" == "win.amd64" && exists("$(PATH_TOOL_VCC120AMD64)/bin/amd64") # Missing in express edition.
+ PATH_TOOL_VCC120_BIN.amd64 ?= $(PATH_TOOL_VCC120)/bin/amd64
+ else
+ PATH_TOOL_VCC120_BIN.amd64 ?= $(PATH_TOOL_VCC120)/bin/x86_amd64
+ endif
+ PATH_TOOL_VCC120_BIN.x86 ?= $(PATH_TOOL_VCC120)/bin
+ PATH_TOOL_VCC120_BIN ?= $(PATH_TOOL_VCC120_BIN.$(KBUILD_TARGET_ARCH))
+ PATH_TOOL_VCC120_LIB.amd64 ?= $(PATH_TOOL_VCC120)/lib/amd64
+ PATH_TOOL_VCC120_LIB.x86 ?= $(PATH_TOOL_VCC120)/lib
+ PATH_TOOL_VCC120_LIB ?= $(PATH_TOOL_VCC120_LIB.$(KBUILD_TARGET_ARCH))
+ PATH_TOOL_VCC120_INC ?= $(PATH_TOOL_VCC120)/include
+ PATH_TOOL_VCC120_ATLMFC ?= $(PATH_TOOL_VCC120X86)/atlmfc
+ PATH_TOOL_VCC120_ATLMFC_INC ?= $(PATH_TOOL_VCC120_ATLMFC)/include
+ PATH_TOOL_VCC120_ATLMFC_LIB.amd64 ?= $(PATH_TOOL_VCC120_ATLMFC)/lib
+ PATH_TOOL_VCC120_ATLMFC_LIB.x86 ?= $(PATH_TOOL_VCC120_ATLMFC)/lib/amd64
+ PATH_TOOL_VCC120_ATLMFC_LIB ?= $(PATH_TOOL_VCC120_ATLMFC_LIB.$(KBUILD_TARGET_ARCH))
+ TOOL_VCC120_CC ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120_BIN)/cl.exe
+ TOOL_VCC120_CXX ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120_BIN)/cl.exe
+ TOOL_VCC120_AS ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120_BIN)/ml64.exe
+ TOOL_VCC120_AR ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120_BIN)/lib.exe
+ TOOL_VCC120_LD ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120_BIN)/link.exe
+ TOOL_VCC120_DUMPBIN ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120_BIN)/dumpbin.exe
+ TOOL_VCC120_EDITBIN ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120_BIN)/editbin.exe
+else
+ # Pathless, relies on the environment.
+ TOOL_VCC120_CC ?= $(EXEC_X86_WIN32) cl.exe
+ TOOL_VCC120_CXX ?= $(EXEC_X86_WIN32) cl.exe
+ TOOL_VCC120_AS ?= $(EXEC_X86_WIN32) ml64.exe
+ TOOL_VCC120_AR ?= $(EXEC_X86_WIN32) lib.exe
+ TOOL_VCC120_LD ?= $(EXEC_X86_WIN32) link.exe
+ TOOL_VCC120_DUMPBIN ?= $(EXEC_X86_WIN32) dumpbin.exe
+ TOOL_VCC120_EDITBIN ?= $(EXEC_X86_WIN32) editbin.exe
+endif
+TOOL_VCC120_RC ?= $(EXEC_X86_WIN32) $(call TOOL_VCC120_FN_FIND_SDK_TOOL,rc.exe,[Rr][Cc].[Ee][Xx][Ee],TOOL_VCC120_RC_CACHED)
+TOOL_VCC120_MT ?= $(EXEC_X86_WIN32) $(call TOOL_VCC120_FN_FIND_SDK_TOOL,mt.exe,[Mm][Tt].[Ee][Xx][Ee],TOOL_VCC120_MT_CACHED)
+
+# The following in duplicated in VCC120.kmk and VCC120X86.kmk.
+TOOL_VCC120_FN_FIND_SDK_TOOL_SUB = $(eval $3 := $(firstword \
+ $(if-expr defined(PATH_SDK_WINPSDK71_BIN), $(wildcard $(PATH_SDK_WINPSDK71_BIN)/$2)) \
+ $(if-expr defined(PATH_SDK_WINPSDK_BIN) , $(wildcard $(PATH_SDK_WINPSDK_BIN)/$2)) \
+ $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/sdk/*/[Bb][Ii][Nn]/$2)) \
+ $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST_ALT)/sdk/*/[Bb][Ii][Nn]/$2)) \
+ $1))
+TOOL_VCC120_FN_FIND_SDK_TOOL = $(if-expr !defined($3),$(TOOL_VCC120_FN_FIND_SDK_TOOL_SUB),)$($3)
+
+## Disabled fast DEP_IDB based dependencies.
+#VCC120_OLD_DEPS = 1
+
+## Constructs the correct .pdb name (the name is lowercased).
+# @param $(1) Base name, no extention.
+# @param $(2) The extension.
+TOOL_VCC120_PDB = $(dir $(1))$(tolower $(notdir $(1))).$(2)
+
+
+# General Properties used by kBuild
+TOOL_VCC120_COBJSUFF ?= .obj
+TOOL_VCC120_CFLAGS ?= -TC -nologo -Zi
+TOOL_VCC120_CFLAGS.debug ?=
+TOOL_VCC120_CFLAGS.dbgopt ?= -O2
+TOOL_VCC120_CFLAGS.release ?= -O2
+TOOL_VCC120_CFLAGS.profile ?= -O2
+TOOL_VCC120_CINCS ?= $(PATH_TOOL_VCC120_INC)
+TOOL_VCC120_CDEFS ?=
+
+TOOL_VCC120_CXXOBJSUFF ?= .obj
+TOOL_VCC120_CXXFLAGS ?= -TP -nologo -Zi
+TOOL_VCC120_CXXFLAGS.debug ?=
+TOOL_VCC120_CXXFLAGS.dbgopt ?= -O2
+TOOL_VCC120_CXXFLAGS.release ?= -O2
+TOOL_VCC120_CXXFLAGS.profile ?= -O2
+TOOL_VCC120_CXXINCS ?= $(PATH_TOOL_VCC120_INC) $(PATH_TOOL_VCC120_ATLMFC_INC)
+TOOL_VCC120_CXXDEFS ?=
+
+TOOL_VCC120_ASOBJSUFF ?= .obj
+
+TOOL_VCC120_RCOBJSUFF ?= .res
+TOOL_VCC120_RCINCS ?= $(PATH_TOOL_VCC120_INC) $(PATH_TOOL_VCC120_ATLMFC_INC)
+
+TOOL_VCC120_ARFLAGS.amd64 ?= -machine:amd64
+TOOL_VCC120_ARFLAGS.x86 ?= -machine:x86
+TOOL_VCC120_ARFLAGS ?= -nologo
+TOOL_VCC120_ARLIBSUFF ?= .lib
+
+TOOL_VCC120_LDFLAGS.amd64 ?= -machine:amd64
+TOOL_VCC120_LDFLAGS.x86 ?= -machine:x86
+TOOL_VCC120_LDFLAGS ?= -nologo
+TOOL_VCC120_LDFLAGS.debug ?= -debug
+TOOL_VCC120_LDFLAGS.dbgopt ?= -debug
+TOOL_VCC120_LDFLAGS.profile ?= -debug
+TOOL_VCC120_LDFLAGS.release ?=
+TOOL_VCC120_LIBPATH.amd64 ?= $(PATH_TOOL_VCC120_LIB.amd64) $(PATH_TOOL_VCC120_ATLMFC_LIB.amd64)
+TOOL_VCC120_LIBPATH.x86 ?= $(PATH_TOOL_VCC120_LIB.x86) $(PATH_TOOL_VCC120_ATLMFC_LIB.x86)
+
+
+
+## Compile C source.
+# @param $(target) Normalized main target name.
+# @param $(source) Source filename (relative).
+# @param $(obj) Object file name. This shall be (re)created by the compilation.
+# @param $(dep) Dependcy file. This shall be (re)created by the compilation.
+# @param $(flags) Flags.
+# @param $(defs) Definitions. No -D or something.
+# @param $(incs) Includes. No -I or something.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+# @param $(objsuff) Object suffix.
+TOOL_VCC120_COMPILE_C_DEPEND =
+TOOL_VCC120_COMPILE_C_DEPORD =
+TOOL_VCC120_COMPILE_C_OUTPUT =
+TOOL_VCC120_COMPILE_C_OUTPUT_MAYBE = $(call TOOL_VCC120_PDB, $(outbase)-obj,pdb) $(call TOOL_VCC120_PDB, $(outbase)-obj,idb)
+define TOOL_VCC120_COMPILE_C_CMDS
+ $(QUIET)$(TOOL_VCC120_CC) -c\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ -Fd$(outbase)-obj.pdb \
+ -Fo$(obj)\
+ $(subst /,\\,$(abspath $(source)))
+ $(QUIET)$(DEP_OBJ) -f -s -q -o $(dep) -t $(obj) $(obj)
+endef
+
+
+## Compile C++ source.
+# @param $(target) Normalized main target name.
+# @param $(source) Source filename (relative).
+# @param $(obj) Object file name. This shall be (re)created by the compilation.
+# @param $(dep) Dependcy file. This shall be (re)created by the compilation.
+# @param $(flags) Flags.
+# @param $(defs) Definitions. No -D or something.
+# @param $(incs) Includes. No -I or something.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+# @param $(objsuff) Object suffix.
+TOOL_VCC120_COMPILE_CXX_DEPEND = $($(target)_1_VCC_PCH_FILE)
+TOOL_VCC120_COMPILE_CXX_DEPORD =
+TOOL_VCC120_COMPILE_CXX_OUTPUT =
+TOOL_VCC120_COMPILE_CXX_OUTPUT_MAYBE = $(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB)\
+ ,,$(call TOOL_VCC120_PDB, $(outbase)-obj,pdb) $(call TOOL_VCC120_PDB, $(outbase)-obj,idb))
+define TOOL_VCC120_COMPILE_CXX_CMDS
+ $(QUIET)$(TOOL_VCC120_CXX) -c\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ $(if-expr defined($(target)_PCH_HDR)\
+ ,-FI$($(target)_PCH_HDR) -Yu$($(target)_PCH_HDR) -Fp$($(target)_1_VCC_PCH_FILE) -FS,)\
+ -Fd$(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB),$($(target)_1_VCC_COMMON_OBJ_PDB),$(outbase)-obj.pdb) \
+ -Fo$(obj)\
+ $(subst /,\\,$(abspath $(source)))
+ $(QUIET)$(DEP_OBJ) -f -s -q -o $(dep) -t $(obj) $(obj)
+endef
+
+
+#
+# Helper tool for creating the precompiled C++ header.
+#
+# It only have the C++ compile bits and it's purpose is to skip bits
+# related _1_VCC_PCH_FILE and add -Yc.
+#
+TOOL_VCC120-PCH := Helper for creating precompiled header using CXX handling.
+TOOL_VCC120-PCH_EXTENDS := VCC120
+TOOL_VCC120-PCH_CXXOBJSUFF := .obj
+TOOL_VCC120-PCH_CXXINCS = $(TOOL_VCC120_CXXINCS)
+TOOL_VCC120-PCH_CXXFLAGS = $(TOOL_VCC120_CXXFLAGS) -FS
+TOOL_VCC120-PCH_CXXFLAGS.debug = $(TOOL_VCC120_CXXFLAGS.debug)
+TOOL_VCC120-PCH_CXXFLAGS.dbgopt = $(TOOL_VCC120_CXXFLAGS.dbgopt)
+TOOL_VCC120-PCH_CXXFLAGS.release = $(TOOL_VCC120_CXXFLAGS.release)
+TOOL_VCC120-PCH_CXXFLAGS.profile = $(TOOL_VCC120_CXXFLAGS.profile)
+TOOL_VCC120-PCH_COMPILE_CXX_DEPEND = $(NO_SUCH_VARIABLE)
+TOOL_VCC120-PCH_COMPILE_CXX_DEPORD = $(NO_SUCH_VARIABLE)
+TOOL_VCC120-PCH_COMPILE_CXX_OUTPUT = $($(target)_1_VCC_PCH_FILE) $($(target)_1_VCC_COMMON_OBJ_PDB)
+TOOL_VCC120-PCH_COMPILE_CXX_OUTPUT_MAYBE = $(NO_SUCH_VARIABLE)
+ifdef TOOL_VCC120_KSUBMIT
+ define TOOL_VCC120-PCH_COMPILE_CXX_CMDS
+ $(QUIET)$(TOOL_VCC120_KSUBMIT) --no-pch-caching -P $(DEP_OBJ_INT) -f -s -q -e .pch -o $(dep) -t $(obj) $(obj)\
+ -- $(TOOL_VCC120_CXX) -c -Yc\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ -Fp$($(target)_1_VCC_PCH_FILE) \
+ -Fd$($(target)_1_VCC_COMMON_OBJ_PDB) \
+ -Fo$(obj)\
+ -TP \
+ $(subst /,\\,$(abspath $(source)))
+ endef
+else
+ define TOOL_VCC120-PCH_COMPILE_CXX_CMDS
+ $(QUIET)$(TOOL_VCC120_CXX) -c -Yc\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ -Fp$($(target)_1_VCC_PCH_FILE) \
+ -Fd$($(target)_1_VCC_COMMON_OBJ_PDB) \
+ -Fo$(obj)\
+ -TP \
+ $(subst /,\\,$(abspath $(source)))
+ $(QUIET)$(DEP_OBJ) -f -s -q -e .pch -o $(dep) -t $(obj) $(obj)
+
+ endef
+endif # !TOOL_VCC120_KSUBMIT
+
+
+## @todo configure the assembler template.
+
+## Compile resource source.
+# @param $(target) Normalized main target name.
+# @param $(source) Source filename (relative).
+# @param $(obj) Object file name. This shall be (re)created by the compilation.
+# @param $(dep) Dependcy file. This shall be (re)created by the compilation.
+# @param $(flags) Flags.
+# @param $(defs) Definitions. No -D or something.
+# @param $(incs) Includes. No -I or something.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+# @param $(objsuff) Object suffix.
+TOOL_VCC120_COMPILE_RC_OUTPUT =
+TOOL_VCC120_COMPILE_RC_DEPEND =
+TOOL_VCC120_COMPILE_RC_DEPORD =
+define TOOL_VCC120_COMPILE_RC_CMDS
+ $(QUIET)$(TOOL_VCC120_RC) \
+ $(flags) $(addprefix /i, $(subst /,\\,$(incs))) $(addprefix /d, $(defs))\
+ /fo$(obj)\
+ $(subst /,\\,$(abspath $(source)))
+endef
+
+
+## Link library
+# @param $(target) Normalized main target name.
+# @param $(out) Library name.
+# @param $(objs) Object files to put in the library.
+# @param $(flags) Flags.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+# @param $(othersrc) Unhandled sources.
+# @param $(outbase) Output basename (full). Use this for list files and such.
+#
+TOOL_VCC120_LINK_LIBRARY_DEPEND = $(othersrc)
+TOOL_VCC120_LINK_LIBRARY_DEPORD =
+TOOL_VCC120_LINK_LIBRARY_OUTPUT = $(outbase).rsp
+TOOL_VCC120_LINK_LIBRARY_OUTPUT_MAYBE = $(outbase).lst $(outbase).exp $(outbase).pdb
+define TOOL_VCC120_LINK_LIBRARY_CMDS
+ $(QUIET)$(APPEND) -tn $(outbase).rsp \
+ $(foreach arg,\
+ $(subst /,\\,$(objs) \
+ $(filter-out %.def,$(othersrc))) \
+ $(addprefix /DEF:,$(filter %.def,$(othersrc))) \
+ ,\"$(arg)\")
+ $(QUIET)$(TOOL_VCC120_AR) $(flags) /OUT:$(out) @$(outbase).rsp
+endef
+
+
+## Link program
+# @param $(target) Normalized main target name.
+# @param $(out) Program name.
+# @param $(objs) Object files to link together.
+# @param $(libs) Libraries to search.
+# @param $(libpath) Library search paths.
+# @param $(flags) Flags.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+# @param $(othersrc) Unhandled sources.
+# @param $(custom_pre) Custom step invoked before linking.
+# @param $(custom_post) Custom step invoked after linking.
+# @param $(outbase) Output basename (full). Use this for list files and such.
+#
+TOOL_VCC120_LINK_PROGRAM_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
+TOOL_VCC120_LINK_PROGRAM_DEPORD =
+TOOL_VCC120_LINK_PROGRAM_OUTPUT = $(outbase).map $(outbase).rsp
+TOOL_VCC120_LINK_PROGRAM_OUTPUT_MAYBE = $(outbase).lib $(outbase).exp $(outbase).ilk $(out).manifest
+TOOL_VCC120_LINK_PROGRAM_OUTPUT_DEBUG = $(outbase).pdb
+TOOL_VCC120_LINK_PROGRAM_DEBUG_INSTALL_FN = $(2).pdb=>$(basename $(3)).pdb
+define TOOL_VCC120_LINK_PROGRAM_CMDS
+ $(QUIET)$(APPEND) -tn $(outbase).rsp \
+ $(foreach arg,\
+ $(subst /,\\,$(objs)) \
+ $(subst /,\\,$(libs)) \
+ ,\"$(arg)\")
+ $(QUIET)$(TOOL_VCC120_LD) $(flags) \
+ /OUT:$(out) \
+ /MAPINFO:EXPORTS /INCREMENTAL:NO \
+ /MAP:$(outbase).map \
+ $(foreach def,$(filter %.def,$(othersrc)), /DEF:$(def)) \
+ $(subst /,\\,$(filter %.exp %.res,$(othersrc))) \
+ $(foreach p,$(libpath), /LIBPATH:$(p)) \
+ @$(outbase).rsp
+ifndef TOOL_VCC120_NO_AUTO_MANIFEST
+ $(QUIET)$(TEST) -f $(out).manifest -- \
+ $(TOOL_VCC120_MT) -manifest $(subst /,\\,$(out)).manifest -outputresource:$(subst /,\\,$(out))
+endif
+endef
+
+
+## Link DLL.
+# @param $(target) Normalized main target name.
+# @param $(out) DLL name.
+# @param $(objs) Object files to link together.
+# @param $(libs) Libraries to search.
+# @param $(libpath) Library search paths.
+# @param $(flags) Flags.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+# @param $(othersrc) Unhandled sources.
+# @param $(custom_pre) Custom step invoked before linking.
+# @param $(custom_post) Custom step invoked after linking.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+TOOL_VCC120_LINK_DLL_DEPEND = $(objs) $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
+TOOL_VCC120_LINK_DLL_DEPORD = $(call DIRDEP,$(PATH_STAGE_LIB))
+TOOL_VCC120_LINK_DLL_OUTPUT = $(outbase).map $(outbase).lib $(outbase).exp $(outbase).rsp
+TOOL_VCC120_LINK_DLL_OUTPUT_MAYBE = $(outbase).ilk $(out).manifest $(PATH_STAGE_LIB)/$(notdir $(outbase)).exp
+TOOL_VCC120_LINK_DLL_OUTPUT_MAYBE_PRECIOUS = $(PATH_STAGE_LIB)/$(notdir $(outbase)).lib
+TOOL_VCC120_LINK_DLL_OUTPUT_DEBUG = $(outbase).pdb
+TOOL_VCC120_LINK_DLL_DEBUG_INSTALL_FN = $(2).pdb=>$(basename $(3)).pdb
+define TOOL_VCC120_LINK_DLL_CMDS
+ $(QUIET)$(APPEND) -tn $(outbase).rsp \
+ $(foreach arg,\
+ $(subst /,\\,$(objs)) \
+ $(subst /,\\,$(libs)) \
+ ,\"$(arg)\")
+ $(QUIET)$(TOOL_VCC120_LD) $(flags) \
+ /OUT:$(out) \
+ /IMPLIB:$(outbase).lib \
+ /MAPINFO:EXPORTS /INCREMENTAL:NO \
+ /MAP:$(outbase).map \
+ /DLL \
+ $(foreach def,$(filter %.def,$(othersrc)), /DEF:$(def)) \
+ $(subst /,\\,$(filter %.exp %.res,$(othersrc))) \
+ $(foreach p,$(libpath), /LIBPATH:$(p)) \
+ @$(outbase).rsp
+ifndef TOOL_VCC120_NO_AUTO_MANIFEST
+ $(QUIET)$(TEST) -f $(out).manifest -- \
+ $(TOOL_VCC120_MT) -manifest $(subst /,\\,$(out)).manifest '-outputresource:$(subst /,\\,$(out));#2'
+endif
+ $(QUIET)$(TEST) -f $(outbase).lib -- $(KLIBTWEAKER_EXT) --clear-timestamps $(outbase).lib
+ $(QUIET)$(CP) --changed --ignore-non-existing $(outbase).exp $(outbase).lib $(PATH_STAGE_LIB)/
+$(eval _DIRS += $(PATH_STAGE_LIB))
+endef
+
+
+## Link system module (windows aka driver, linux aka kernel module)
+# @param $(target) Normalized main target name.
+# @param $(out) System module name.
+# @param $(objs) Object files to link together.
+# @param $(libs) Libraries to search.
+# @param $(libpath) Library search paths.
+# @param $(flags) Flags.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+# @param $(othersrc) Unhandled sources.
+# @param $(custom_pre) Custom step invoked before linking.
+# @param $(custom_post) Custom step invoked after linking.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+TOOL_VCC120_LINK_SYSMOD_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
+TOOL_VCC120_LINK_SYSMOD_DEPORD =
+TOOL_VCC120_LINK_SYSMOD_OUTPUT = $(outbase).map $(outbase).rsp
+TOOL_VCC120_LINK_SYSMOD_OUTPUT_MAYBE = $(outbase).lib $(outbase).exp $(outbase).ilk $(out).manifest
+TOOL_VCC120_LINK_SYSMOD_OUTPUT_DEBUG = $(outbase).pdb
+TOOL_VCC120_LINK_SYSMOD_DEBUG_INSTALL_FN = $(2).pdb=>$(basename $(3)).pdb
+define TOOL_VCC120_LINK_SYSMOD_CMDS
+ $(QUIET)$(APPEND) -tn $(outbase).rsp \
+ $(foreach arg,\
+ $(subst /,\\,$(objs)) \
+ $(subst /,\\,$(libs)) \
+ ,\"$(arg)\")
+ $(QUIET)$(TOOL_VCC120_LD) $(flags) \
+ /OUT:$(out) \
+ /MAPINFO:EXPORTS /INCREMENTAL:NO \
+ /MAP:$(outbase).map \
+ $(foreach def,$(filter %.def,$(othersrc)), /DEF:$(def)) \
+ $(subst /,\\,$(filter %.exp %.res,$(othersrc))) \
+ $(foreach p,$(libpath), /LIBPATH:$(p)) \
+ @$(outbase).rsp
+ifndef TOOL_VCC120_NO_AUTO_MANIFEST
+ $(QUIET)$(TEST) -f $(out).manifest -- \
+ $(TOOL_VCC120_MT) -manifest $(subst /,\\,$(out)).manifest '-outputresource:$(subst /,\\,$(out));#2'
+endif
+endef
+
diff --git a/kBuild/tools/VCC120AMD64.kmk b/kBuild/tools/VCC120AMD64.kmk
new file mode 100644
index 0000000..225b358
--- /dev/null
+++ b/kBuild/tools/VCC120AMD64.kmk
@@ -0,0 +1,465 @@
+# $Id: VCC120AMD64.kmk 3044 2017-05-11 13:29:49Z bird $
+## @file
+# kBuild Tool Config - Visual C++ 12.0 (aka Visual 2013 and MSC v18), targeting AMD64.
+#
+
+#
+# Copyright (c) 2004-2017 knut st. osmundsen <bird-kBuild-spam-xiv at anduin.net>
+#
+# This file is part of kBuild.
+#
+# kBuild is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# kBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with kBuild; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+#
+# As a special exception you are granted permission to include this file, via
+# the kmk include directive, as you wish without this in itself causing the
+# resulting makefile, program or whatever to be covered by the GPL license.
+# This exception does not however invalidate any other reasons why the makefile,
+# program, whatever should not be covered the GPL.
+#
+#
+
+TOOL_VCC120AMD64 := Visual C++ 12.0 (aka Visual 2013 and MSC v18), targeting AMD64
+
+# Tool Specific Properties
+ifndef PATH_TOOL_VCC120AMD64
+ PATH_TOOL_VCC120AMD64 := $(wildcard $(KBUILD_DEVTOOLS)/win.x86/vcc/v12*)
+ ifeq ($(PATH_TOOL_VCC120AMD64),)
+ PATH_TOOL_VCC120AMD64 := $(PATH_TOOL_VCC120)
+ endif
+ ifeq ($(PATH_TOOL_VCC120AMD64),)
+ PATH_TOOL_VCC120AMD64 := $(PATH_TOOL_VCC120X86)
+ endif
+ ifeq ($(PATH_TOOL_VCC120AMD64),)
+ PATH_TOOL_VCC120AMD64 := $(wildcard $(KBUILD_DEVTOOLS)/win.x86/vcc/v12*)
+ endif
+ ifneq ($(PATH_TOOL_VCC120AMD64),)
+ PATH_TOOL_VCC120AMD64 := $(lastword $(sort $(PATH_TOOL_VCC120AMD64)))
+ else
+ $(warning kBuild: PATH_TOOL_VCC120AMD64 cannot be determined!)
+ PATH_TOOL_VCC120AMD64 := $(KBUILD_DEVTOOLS)/win.x86/vcc/v12
+ endif
+else
+ # Resolve any fancy stuff once and for all.
+ PATH_TOOL_VCC120AMD64 := $(PATH_TOOL_VCC120AMD64)
+endif
+if "$(KBUILD_HOST).$(KBUILD_HOST_ARCH)" == "win.amd64" && exists("$(PATH_TOOL_VCC120AMD64)/bin/amd64") # Missing in express edition.
+PATH_TOOL_VCC120AMD64_BIN ?= $(PATH_TOOL_VCC120AMD64)/bin/amd64
+#$(error works now: $(PATH_TOOL_VCC120AMD64)/bin/amd64)
+else
+#$(error no joy: $(PATH_TOOL_VCC120AMD64)/bin/amd64)
+PATH_TOOL_VCC120AMD64_BIN_DLL ?= $(PATH_TOOL_VCC120AMD64)/bin
+PATH_TOOL_VCC120AMD64_BIN ?= $(PATH_TOOL_VCC120AMD64)/bin/x86_amd64
+endif
+PATH_TOOL_VCC120AMD64_LIB ?= $(PATH_TOOL_VCC120AMD64)/lib/amd64
+PATH_TOOL_VCC120AMD64_INC ?= $(PATH_TOOL_VCC120AMD64)/include
+PATH_TOOL_VCC120AMD64_ATLMFC ?= $(PATH_TOOL_VCC120AMD64)/atlmfc
+PATH_TOOL_VCC120AMD64_ATLMFC_INC ?= $(PATH_TOOL_VCC120AMD64_ATLMFC)/include
+PATH_TOOL_VCC120AMD64_ATLMFC_LIB ?= $(PATH_TOOL_VCC120AMD64_ATLMFC)/lib/amd64
+TOOL_VCC120AMD64_CC ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120AMD64_BIN)/cl.exe
+TOOL_VCC120AMD64_CXX ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120AMD64_BIN)/cl.exe
+TOOL_VCC120AMD64_AS ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120AMD64_BIN)/ml64.exe
+#TOOL_VCC120AMD64_AR ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120AMD64_BIN)/lib.exe - just an exec wrapper for the below
+TOOL_VCC120AMD64_AR ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120AMD64_BIN)/link.exe /LIB
+TOOL_VCC120AMD64_LD ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120AMD64_BIN)/link.exe
+TOOL_VCC120AMD64_DUMPBIN ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120AMD64_BIN)/dumpbin.exe
+TOOL_VCC120AMD64_EDITBIN ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120AMD64_BIN)/editbin.exe
+TOOL_VCC120AMD64_RC ?= $(EXEC_X86_WIN32) $(call TOOL_VCC120_FN_FIND_SDK_TOOL,rc.exe,[Rr][Cc].[Ee][Xx][Ee],TOOL_VCC120_RC_CACHED)
+TOOL_VCC120AMD64_MT ?= $(EXEC_X86_WIN32) $(call TOOL_VCC120_FN_FIND_SDK_TOOL,mt.exe,[Mm][Tt].[Ee][Xx][Ee],TOOL_VCC120_MT_CACHED)
+ifdef TOOL_VCC120AMD64_USE_KSUBMIT
+ ifeq ($(KBUILD_HOST),win)
+ ifneq ($(substr $(PATH_TOOL_VCC120AMD64_BIN),-9),x86_amd64)
+ TOOL_VCC120AMD64_KSUBMIT ?= kmk_builtin_kSubmit --64-bit
+ ifdef PATH_TOOL_VCC120AMD64_BIN_DLL
+ TOOL_VCC120AMD64_KSUBMIT += --prepend 'PATH=$(PATH_TOOL_VCC120AMD64_BIN_DLL)$(HOST_PATH_SEP)'
+ endif
+ TOOL_VCC120AMD64_KSUBMIT_DD = $(TOOL_VCC120AMD64_KSUBMIT) --
+ else
+ # "fatal error C1902: Program database manager mismatch; please check your installation" when mixing with the 32-bit compiler.
+ #TOOL_VCC120AMD64_KSUBMIT ?= kmk_builtin_kSubmit --32-bit
+ #TOOL_VCC120AMD64_KSUBMIT_DD = $(TOOL_VCC120AMD64_KSUBMIT) --
+ endif
+ endif
+else ifdef PATH_TOOL_VCC120AMD64_BIN_DLL
+ TOOL_VCC120AMD64_KSUBMIT_DD = $(REDIRECT) --prepend 'PATH=$(PATH_TOOL_VCC120AMD64_BIN_DLL)$(HOST_PATH_SEP)' --
+endif
+
+# The following in duplicated in VCC120.kmk and VCC120X86.kmk.
+TOOL_VCC120_FN_FIND_SDK_TOOL_SUB = $(eval $3 := $(firstword \
+ $(if-expr defined(PATH_SDK_WINPSDK71_BIN), $(wildcard $(PATH_SDK_WINPSDK71_BIN)/$2)) \
+ $(if-expr defined(PATH_SDK_WINPSDK_BIN) , $(wildcard $(PATH_SDK_WINPSDK_BIN)/$2)) \
+ $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/sdk/*/[Bb][Ii][Nn]/$2)) \
+ $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST_ALT)/sdk/*/[Bb][Ii][Nn]/$2)) \
+ $1))
+TOOL_VCC120_FN_FIND_SDK_TOOL = $(if-expr !defined($3),$(TOOL_VCC120_FN_FIND_SDK_TOOL_SUB),)$($3)
+
+## Disabled fast DEP_IDB based dependencies.
+#VCC120AMD64_OLD_DEPS = 1
+
+## Constructs the correct .pdb name (the name is lowercased).
+# @param $(1) Base name, no extention.
+# @param $(2) The extension.
+TOOL_VCC120AMD64_PDB = $(dir $(1))$(tolower $(notdir $(1))).$(2)
+
+
+# General Properties used by kBuild
+TOOL_VCC120AMD64_COBJSUFF ?= .obj
+TOOL_VCC120AMD64_CFLAGS ?= -TC -nologo -Zi
+TOOL_VCC120AMD64_CFLAGS.debug ?=
+TOOL_VCC120AMD64_CFLAGS.dbgopt ?= -O2
+TOOL_VCC120AMD64_CFLAGS.release ?= -O2
+TOOL_VCC120AMD64_CFLAGS.profile ?= -O2
+TOOL_VCC120AMD64_CINCS ?= $(PATH_TOOL_VCC120AMD64_INC)
+TOOL_VCC120AMD64_CDEFS ?=
+
+TOOL_VCC120AMD64_CXXOBJSUFF ?= .obj
+TOOL_VCC120AMD64_CXXFLAGS ?= -TP -nologo -Zi
+TOOL_VCC120AMD64_CXXFLAGS.debug ?=
+TOOL_VCC120AMD64_CXXFLAGS.dbgopt ?= -O2
+TOOL_VCC120AMD64_CXXFLAGS.release ?= -O2
+TOOL_VCC120AMD64_CXXFLAGS.profile ?= -O2
+TOOL_VCC120AMD64_CXXINCS ?= $(PATH_TOOL_VCC120AMD64_INC) $(PATH_TOOL_VCC120AMD64_ATLMFC_INC)
+TOOL_VCC120AMD64_CXXDEFS ?=
+
+TOOL_VCC120AMD64_ASOBJSUFF ?= .obj
+
+TOOL_VCC120AMD64_RCOBJSUFF ?= .res
+TOOL_VCC120AMD64_RCINCS ?= $(PATH_TOOL_VCC120AMD64_INC) $(PATH_TOOL_VCC120AMD64_ATLMFC_INC)
+
+TOOL_VCC120AMD64_ARFLAGS ?= -nologo -machine:amd64
+TOOL_VCC120AMD64_ARLIBSUFF ?= .lib
+
+TOOL_VCC120AMD64_LDFLAGS ?= -nologo -machine:amd64
+TOOL_VCC120AMD64_LDFLAGS.debug ?= -debug
+TOOL_VCC120AMD64_LDFLAGS.dbgopt ?= -debug
+TOOL_VCC120AMD64_LDFLAGS.profile ?= -debug
+TOOL_VCC120AMD64_LDFLAGS.release ?=
+
+
+
+## Compile C source.
+# @param $(target) Normalized main target name.
+# @param $(source) Source filename (relative).
+# @param $(obj) Object file name. This shall be (re)created by the compilation.
+# @param $(dep) Dependcy file. This shall be (re)created by the compilation.
+# @param $(flags) Flags.
+# @param $(defs) Definitions. No -D or something.
+# @param $(incs) Includes. No -I or something.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+# @param $(objsuff) Object suffix.
+TOOL_VCC120AMD64_COMPILE_C_DEPEND =
+TOOL_VCC120AMD64_COMPILE_C_DEPORD =
+TOOL_VCC120AMD64_COMPILE_C_OUTPUT =
+TOOL_VCC120AMD64_COMPILE_C_OUTPUT_MAYBE = $(call TOOL_VCC120AMD64_PDB, $(outbase)-obj,pdb) $(call TOOL_VCC120AMD64_PDB, $(outbase)-obj,idb)
+ifdef TOOL_VCC120AMD64_KSUBMIT
+ TOOL_VCC120AMD64_COMPILE_C_DONT_PURGE_OUTPUT := 1 # speed
+ define TOOL_VCC120AMD64_COMPILE_C_CMDS
+ $(QUIET)$(TOOL_VCC120AMD64_KSUBMIT) -P $(DEP_OBJ_INT) -f -s -q -o $(dep) -t $(obj) $(obj)\
+ -- $(TOOL_VCC120AMD64_CC) -c\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ -Fd$(outbase)-obj.pdb \
+ -Fo$(obj)\
+ $(subst /,\\,$(abspath $(source)))
+ endef
+else
+ define TOOL_VCC120AMD64_COMPILE_C_CMDS
+ $(QUIET)$(if-expr defined(PATH_TOOL_VCC120AMD64_BIN_DLL)\
+ ,$(REDIRECT) --prepend 'PATH=$(PATH_TOOL_VCC120AMD64_BIN_DLL)$(HOST_PATH_SEP)' -- ,)$(TOOL_VCC120AMD64_CC) -c\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ -Fd$(outbase)-obj.pdb \
+ -Fo$(obj)\
+ $(subst /,\\,$(abspath $(source)))
+ $(QUIET)$(DEP_OBJ) -f -s -q -o $(dep) -t $(obj) $(obj)
+ endef
+endif # !TOOL_VCC120AMD64_KSUBMIT
+
+
+## Compile C++ source.
+# @param $(target) Normalized main target name.
+# @param $(source) Source filename (relative).
+# @param $(obj) Object file name. This shall be (re)created by the compilation.
+# @param $(dep) Dependcy file. This shall be (re)created by the compilation.
+# @param $(flags) Flags.
+# @param $(defs) Definitions. No -D or something.
+# @param $(incs) Includes. No -I or something.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+# @param $(objsuff) Object suffix.
+TOOL_VCC120AMD64_COMPILE_CXX_DEPEND = $($(target)_1_VCC_PCH_FILE)
+TOOL_VCC120AMD64_COMPILE_CXX_DEPORD =
+TOOL_VCC120AMD64_COMPILE_CXX_OUTPUT =
+TOOL_VCC120AMD64_COMPILE_CXX_OUTPUT_MAYBE = $(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB)\
+ ,,$(call TOOL_VCC120AMD64_PDB, $(outbase)-obj,pdb) $(call TOOL_VCC120AMD64_PDB, $(outbase)-obj,idb))
+ifdef TOOL_VCC120AMD64_KSUBMIT
+ TOOL_VCC120AMD64_COMPILE_CXX_DONT_PURGE_OUTPUT := 1 # speed
+ define TOOL_VCC120AMD64_COMPILE_CXX_CMDS
+ $(QUIET)$(TOOL_VCC120AMD64_KSUBMIT) -P $(DEP_OBJ_INT) -f -s -q -o $(dep) -t $(obj) $(obj)\
+ -- $(TOOL_VCC120AMD64_CXX) -c\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ $(if-expr defined($(target)_PCH_HDR)\
+ ,-FI$($(target)_PCH_HDR) -Yu$($(target)_PCH_HDR) -Fp$($(target)_1_VCC_PCH_FILE) -FS,)\
+ -Fd$(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB),$($(target)_1_VCC_COMMON_OBJ_PDB),$(outbase)-obj.pdb) \
+ -Fo$(obj)\
+ $(subst /,\\,$(abspath $(source)))
+ endef
+else
+ define TOOL_VCC120AMD64_COMPILE_CXX_CMDS
+ $(QUIET)$(if-expr defined(PATH_TOOL_VCC120AMD64_BIN_DLL)\
+ ,$(REDIRECT) --prepend 'PATH=$(PATH_TOOL_VCC120AMD64_BIN_DLL)$(HOST_PATH_SEP)' -- ,)$(TOOL_VCC120AMD64_CXX) -c\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ $(if-expr defined($(target)_PCH_HDR)\
+ ,-FI$($(target)_PCH_HDR) -Yu$($(target)_PCH_HDR) -Fp$($(target)_1_VCC_PCH_FILE) -FS,)\
+ -Fd$(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB),$($(target)_1_VCC_COMMON_OBJ_PDB),$(outbase)-obj.pdb) \
+ -Fo$(obj)\
+ $(subst /,\\,$(abspath $(source)))
+ $(QUIET)$(DEP_OBJ) -f -s -q -o $(dep) -t $(obj) $(obj)
+ endef
+endif # !TOOL_VCC120AMD64_KSUBMIT
+
+
+#
+# Helper tool for creating the precompiled C++ header.
+#
+# It only have the C++ compile bits and it's purpose is to skip bits
+# related _1_VCC_PCH_FILE and add -Yc.
+#
+TOOL_VCC120AMD64-PCH := Helper for creating precompiled header using CXX handling.
+TOOL_VCC120AMD64-PCH_EXTENDS := VCC120AMD64
+TOOL_VCC120AMD64-PCH_CXXOBJSUFF := .obj
+TOOL_VCC120AMD64-PCH_CXXINCS = $(TOOL_VCC120AMD64_CXXINCS)
+TOOL_VCC120AMD64-PCH_CXXFLAGS = $(TOOL_VCC120AMD64_CXXFLAGS) -FS
+TOOL_VCC120AMD64-PCH_CXXFLAGS.debug = $(TOOL_VCC120AMD64_CXXFLAGS.debug)
+TOOL_VCC120AMD64-PCH_CXXFLAGS.dbgopt = $(TOOL_VCC120AMD64_CXXFLAGS.dbgopt)
+TOOL_VCC120AMD64-PCH_CXXFLAGS.release = $(TOOL_VCC120AMD64_CXXFLAGS.release)
+TOOL_VCC120AMD64-PCH_CXXFLAGS.profile = $(TOOL_VCC120AMD64_CXXFLAGS.profile)
+TOOL_VCC120AMD64-PCH_COMPILE_CXX_DEPEND = $(NO_SUCH_VARIABLE)
+TOOL_VCC120AMD64-PCH_COMPILE_CXX_DEPORD = $(NO_SUCH_VARIABLE)
+TOOL_VCC120AMD64-PCH_COMPILE_CXX_OUTPUT = $($(target)_1_VCC_PCH_FILE) $($(target)_1_VCC_COMMON_OBJ_PDB)
+TOOL_VCC120AMD64-PCH_COMPILE_CXX_OUTPUT_MAYBE = $(NO_SUCH_VARIABLE)
+ifdef TOOL_VCC120AMD64_KSUBMIT
+ define TOOL_VCC120AMD64-PCH_COMPILE_CXX_CMDS
+ $(QUIET)$(RM) -f -- $($(target)_1_VCC_PCH_FILE) $($(target)_1_VCC_COMMON_OBJ_PDB)
+ $(QUIET)$(TOOL_VCC120AMD64_KSUBMIT) --no-pch-caching -P $(DEP_OBJ_INT) -f -s -q -e .pch -o $(dep) -t $(obj) $(obj)\
+ -- $(TOOL_VCC120AMD64_CXX) -c -Yc\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ -Fp$($(target)_1_VCC_PCH_FILE) \
+ -Fd$($(target)_1_VCC_COMMON_OBJ_PDB) \
+ -Fo$(obj)\
+ -TP \
+ $(subst /,\\,$(abspath $(source)))
+ endef
+else
+ define TOOL_VCC120AMD64-PCH_COMPILE_CXX_CMDS
+ $(QUIET)$(RM) -f -- $($(target)_1_VCC_PCH_FILE) $($(target)_1_VCC_COMMON_OBJ_PDB)
+ $(QUIET)$(if-expr defined(PATH_TOOL_VCC120AMD64_BIN_DLL)\
+ ,$(REDIRECT) --prepend 'PATH=$(PATH_TOOL_VCC120AMD64_BIN_DLL)$(HOST_PATH_SEP)' -- ,)$(TOOL_VCC120AMD64_CXX) -c -Yc\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ -Fp$($(target)_1_VCC_PCH_FILE) \
+ -Fd$($(target)_1_VCC_COMMON_OBJ_PDB) \
+ -Fo$(obj)\
+ -TP \
+ $(subst /,\\,$(abspath $(source)))
+ $(QUIET)$(DEP_OBJ) -f -s -q -e .pch -o $(dep) -t $(obj) $(obj)
+
+ endef
+endif # !TOOL_VCC120AMD64_KSUBMIT
+
+
+## @todo configure the assembler template.
+
+## Compile resource source.
+# @param $(target) Normalized main target name.
+# @param $(source) Source filename (relative).
+# @param $(obj) Object file name. This shall be (re)created by the compilation.
+# @param $(dep) Dependcy file. This shall be (re)created by the compilation.
+# @param $(flags) Flags.
+# @param $(defs) Definitions. No -D or something.
+# @param $(incs) Includes. No -I or something.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+# @param $(objsuff) Object suffix.
+TOOL_VCC120AMD64_COMPILE_RC_DEPEND =
+TOOL_VCC120AMD64_COMPILE_RC_DEPORD =
+TOOL_VCC120AMD64_COMPILE_RC_OUTPUT =
+## @todo Fix kmk_redirect so we can use it for setting PATH without spawning a shell or two
+define TOOL_VCC120AMD64_COMPILE_RC_CMDS
+ $(QUIET)$(if-expr defined(PATH_TOOL_VCC120AMD64_BIN_DLL)\
+ ,$(REDIRECT) --prepend 'PATH=$(PATH_TOOL_VCC120AMD64_BIN_DLL)$(HOST_PATH_SEP)' -- ,)$(TOOL_VCC120AMD64_RC) \
+ $(flags) $(addprefix /i, $(subst /,\\,$(incs))) $(addprefix /d, $(defs))\
+ /fo$(obj)\
+ $(subst /,\\,$(abspath $(source)))
+endef
+
+
+## Link library
+# @param $(target) Normalized main target name.
+# @param $(out) Library name.
+# @param $(objs) Object files to put in the library.
+# @param $(flags) Flags.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+# @param $(othersrc) Unhandled sources.
+# @param $(outbase) Output basename (full). Use this for list files and such.
+#
+TOOL_VCC120AMD64_LINK_LIBRARY_DEPEND = $(othersrc)
+TOOL_VCC120AMD64_LINK_LIBRARY_DEPORD =
+TOOL_VCC120AMD64_LINK_LIBRARY_OUTPUT = $(outbase).rsp
+TOOL_VCC120AMD64_LINK_LIBRARY_OUTPUT_MAYBE = $(outbase).lst $(outbase).exp $(outbase).pdb
+define TOOL_VCC120AMD64_LINK_LIBRARY_CMDS
+ $(QUIET)$(APPEND) -tn $(outbase).rsp \
+ $(foreach arg,\
+ $(subst /,\\,$(objs) \
+ $(filter-out %.def,$(othersrc))) \
+ $(addprefix /DEF:,$(filter %.def,$(othersrc))) \
+ ,\"$(arg)\")
+ $(QUIET)$(TOOL_VCC120AMD64_KSUBMIT_DD) $(TOOL_VCC120AMD64_AR) $(flags) /OUT:$(out) @$(outbase).rsp
+endef
+
+
+## Link program
+# @param $(target) Normalized main target name.
+# @param $(out) Program name.
+# @param $(objs) Object files to link together.
+# @param $(libs) Libraries to search.
+# @param $(libpath) Library search paths.
+# @param $(flags) Flags.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+# @param $(othersrc) Unhandled sources.
+# @param $(custom_pre) Custom step invoked before linking.
+# @param $(custom_post) Custom step invoked after linking.
+# @param $(outbase) Output basename (full). Use this for list files and such.
+#
+TOOL_VCC120AMD64_LINK_PROGRAM_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
+TOOL_VCC120AMD64_LINK_PROGRAM_DEPORD =
+TOOL_VCC120AMD64_LINK_PROGRAM_OUTPUT = $(outbase).map $(outbase).rsp
+TOOL_VCC120AMD64_LINK_PROGRAM_OUTPUT_MAYBE = $(outbase).lib $(outbase).exp $(outbase).ilk $(out).manifest
+TOOL_VCC120AMD64_LINK_PROGRAM_OUTPUT_DEBUG = $(outbase).pdb
+TOOL_VCC120AMD64_LINK_PROGRAM_DEBUG_INSTALL_FN = $(2).pdb=>$(basename $(3)).pdb
+define TOOL_VCC120AMD64_LINK_PROGRAM_CMDS
+ $(QUIET)$(APPEND) -tn $(outbase).rsp \
+ $(foreach arg,\
+ $(subst /,\\,$(objs)) \
+ $(subst /,\\,$(libs)) \
+ ,\"$(arg)\")
+ $(QUIET)$(TOOL_VCC120AMD64_KSUBMIT_DD) $(TOOL_VCC120AMD64_LD) $(flags) \
+ /OUT:$(out) \
+ /MAPINFO:EXPORTS /INCREMENTAL:NO \
+ /MAP:$(outbase).map \
+ $(foreach def,$(filter %.def,$(othersrc)), /DEF:$(def)) \
+ $(subst /,\\,$(filter %.exp %.res,$(othersrc))) \
+ $(foreach p,$(libpath), /LIBPATH:$(p)) \
+ @$(outbase).rsp
+ifndef TOOL_VCC120AMD64_NO_AUTO_MANIFEST
+ $(QUIET)$(TEST) -f $(out).manifest -- \
+ $(TOOL_VCC120AMD64_MT) -manifest $(subst /,\\,$(out)).manifest -outputresource:$(subst /,\\,$(out))
+endif
+endef
+
+
+## Link DLL.
+# @param $(target) Normalized main target name.
+# @param $(out) DLL name.
+# @param $(objs) Object files to link together.
+# @param $(libs) Libraries to search.
+# @param $(libpath) Library search paths.
+# @param $(flags) Flags.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+# @param $(othersrc) Unhandled sources.
+# @param $(custom_pre) Custom step invoked before linking.
+# @param $(custom_post) Custom step invoked after linking.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+TOOL_VCC120AMD64_LINK_DLL_DEPEND = $(objs) $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
+TOOL_VCC120AMD64_LINK_DLL_DEPORD = $(call DIRDEP,$(PATH_STAGE_LIB))
+TOOL_VCC120AMD64_LINK_DLL_OUTPUT = $(outbase).map $(outbase).lib $(outbase).exp $(outbase).rsp
+TOOL_VCC120AMD64_LINK_DLL_OUTPUT_MAYBE = $(outbase).ilk $(out).manifest $(PATH_STAGE_LIB)/$(notdir $(outbase)).exp
+TOOL_VCC120AMD64_LINK_DLL_OUTPUT_MAYBE_PRECIOUS = $(PATH_STAGE_LIB)/$(notdir $(outbase)).lib
+TOOL_VCC120AMD64_LINK_DLL_OUTPUT_DEBUG = $(outbase).pdb
+TOOL_VCC120AMD64_LINK_DLL_DEBUG_INSTALL_FN = $(2).pdb=>$(basename $(3)).pdb
+define TOOL_VCC120AMD64_LINK_DLL_CMDS
+ $(QUIET)$(APPEND) -tn $(outbase).rsp \
+ $(foreach arg,\
+ $(subst /,\\,$(objs)) \
+ $(subst /,\\,$(libs)) \
+ ,\"$(arg)\")
+ $(QUIET)$(TOOL_VCC120AMD64_KSUBMIT_DD) $(TOOL_VCC120AMD64_LD) $(flags) \
+ /OUT:$(out) \
+ /IMPLIB:$(outbase).lib \
+ /MAPINFO:EXPORTS /INCREMENTAL:NO \
+ /MAP:$(outbase).map \
+ /DLL \
+ $(foreach def,$(filter %.def,$(othersrc)), /DEF:$(def)) \
+ $(subst /,\\,$(filter %.exp %.res,$(othersrc))) \
+ $(foreach p,$(libpath), /LIBPATH:$(p)) \
+ @$(outbase).rsp
+ifndef TOOL_VCC120AMD64_NO_AUTO_MANIFEST
+ $(QUIET)$(TEST) -f $(out).manifest -- \
+ $(TOOL_VCC120AMD64_MT) -manifest $(subst /,\\,$(out)).manifest '-outputresource:$(subst /,\\,$(out));#2'
+endif
+ $(QUIET)$(TEST) -f $(outbase).lib -- $(KLIBTWEAKER_EXT) --clear-timestamps $(outbase).lib
+ $(QUIET)$(CP) --changed -v --ignore-non-existing $(outbase).exp $(outbase).lib $(PATH_STAGE_LIB)/
+$(eval _DIRS += $(PATH_STAGE_LIB))
+endef
+
+
+## Link system module (windows aka driver, linux aka kernel module)
+# @param $(target) Normalized main target name.
+# @param $(out) System module name.
+# @param $(objs) Object files to link together.
+# @param $(libs) Libraries to search.
+# @param $(libpath) Library search paths.
+# @param $(flags) Flags.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+# @param $(othersrc) Unhandled sources.
+# @param $(custom_pre) Custom step invoked before linking.
+# @param $(custom_post) Custom step invoked after linking.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+TOOL_VCC120AMD64_LINK_SYSMOD_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
+TOOL_VCC120AMD64_LINK_SYSMOD_DEPORD =
+TOOL_VCC120AMD64_LINK_SYSMOD_OUTPUT = $(outbase).map $(outbase).rsp
+TOOL_VCC120AMD64_LINK_SYSMOD_OUTPUT_MAYBE = $(outbase).lib $(outbase).exp $(outbase).ilk $(out).manifest
+TOOL_VCC120AMD64_LINK_SYSMOD_OUTPUT_DEBUG = $(outbase).pdb
+TOOL_VCC120AMD64_LINK_SYSMOD_DEBUG_INSTALL_FN = $(2).pdb=>$(basename $(3)).pdb
+define TOOL_VCC120AMD64_LINK_SYSMOD_CMDS
+ $(QUIET)$(APPEND) -tn $(outbase).rsp \
+ $(foreach arg,\
+ $(subst /,\\,$(objs)) \
+ $(subst /,\\,$(libs)) \
+ ,\"$(arg)\")
+ $(QUIET)$(TOOL_VCC120AMD64_KSUBMIT_DD) $(TOOL_VCC120AMD64_LD) $(flags) \
+ /OUT:$(out) \
+ /MAPINFO:EXPORTS /INCREMENTAL:NO \
+ /MAP:$(outbase).map \
+ $(foreach def,$(filter %.def,$(othersrc)), /DEF:$(def)) \
+ $(subst /,\\,$(filter %.exp %.res,$(othersrc))) \
+ $(foreach p,$(libpath), /LIBPATH:$(p)) \
+ @$(outbase).rsp
+ifndef TOOL_VCC120AMD64_NO_AUTO_MANIFEST
+ $(QUIET)$(TEST) -f $(out).manifest -- \
+ $(TOOL_VCC120AMD64_MT) -manifest $(subst /,\\,$(out)).manifest '-outputresource:$(subst /,\\,$(out));#2'
+endif
+endef
+
diff --git a/kBuild/tools/VCC120X86.kmk b/kBuild/tools/VCC120X86.kmk
new file mode 100644
index 0000000..7092f5c
--- /dev/null
+++ b/kBuild/tools/VCC120X86.kmk
@@ -0,0 +1,465 @@
+# $Id: VCC120X86.kmk 3048 2017-05-19 11:55:36Z bird $
+## @file
+# kBuild Tool Config - Visual C++ 12.0 (aka Visual 2013 and MSC v18), targeting x86.
+#
+
+#
+# Copyright (c) 2004-2017 knut st. osmundsen <bird-kBuild-spam-xiv at anduin.net>
+#
+# This file is part of kBuild.
+#
+# kBuild is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# kBuild is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with kBuild; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+#
+# As a special exception you are granted permission to include this file, via
+# the kmk include directive, as you wish without this in itself causing the
+# resulting makefile, program or whatever to be covered by the GPL license.
+# This exception does not however invalidate any other reasons why the makefile,
+# program, whatever should not be covered the GPL.
+#
+#
+
+TOOL_VCC120X86 := Visual C++ 12.0 (aka Visual 2013 and MSC v18), targeting x86.
+
+# Tool Specific Properties
+ifndef PATH_TOOL_VCC120X86
+ PATH_TOOL_VCC120X86 := $(wildcard $(KBUILD_DEVTOOLS)/win.x86/vcc/v12*)
+ ifeq ($(PATH_TOOL_VCC120X86),)
+ PATH_TOOL_VCC120X86 := $(PATH_TOOL_VCC120)
+ endif
+ ifeq ($(PATH_TOOL_VCC120X86),)
+ PATH_TOOL_VCC120X86 := $(PATH_TOOL_VCC120AMD64)
+ endif
+ ifeq ($(PATH_TOOL_VCC120X86),)
+ PATH_TOOL_VCC120X86 := $(wildcard $(KBUILD_DEVTOOLS)/x86.win32/vcc/v12*)
+ endif
+ ifeq ($(PATH_TOOL_VCC120X86),)
+ PATH_TOOL_VCC120X86 := $(wildcard $(KBUILD_DEVTOOLS)/win.amd64/vcc/v12*)
+ endif
+ ifneq ($(PATH_TOOL_VCC120X86),)
+ PATH_TOOL_VCC120X86 := $(lastword $(sort $(PATH_TOOL_VCC120X86)))
+ else
+ $(warning kBuild: PATH_TOOL_VCC120X86 cannot be determined!)
+ PATH_TOOL_VCC120X86 := $(KBUILD_DEVTOOLS)/x86.win/vcc/v12
+ endif
+else
+ # Resolve any fancy stuff once and for all.
+ PATH_TOOL_VCC120X86 := $(PATH_TOOL_VCC120X86)
+endif
+
+if "$(KBUILD_HOST).$(KBUILD_HOST_ARCH)" == "win.amd64" && exists("$(PATH_TOOL_VCC120AMD64)/bin/amd64_x86") # Missing in express edition.
+ PATH_TOOL_VCC120X86_BIN_DLL ?= $(PATH_TOOL_VCC120X86)/bin/amd64
+ PATH_TOOL_VCC120X86_BIN ?= $(PATH_TOOL_VCC120X86)/bin/amd64_x86
+else
+ PATH_TOOL_VCC120X86_BIN_DLL ?=
+ PATH_TOOL_VCC120X86_BIN ?= $(PATH_TOOL_VCC120X86)/bin
+endif
+PATH_TOOL_VCC120X86_BIN ?= $(PATH_TOOL_VCC120X86)/bin
+PATH_TOOL_VCC120X86_LIB ?= $(PATH_TOOL_VCC120X86)/lib
+PATH_TOOL_VCC120X86_INC ?= $(PATH_TOOL_VCC120X86)/include
+PATH_TOOL_VCC120X86_ATLMFC ?= $(PATH_TOOL_VCC120X86)/atlmfc
+PATH_TOOL_VCC120X86_ATLMFC_INC ?= $(PATH_TOOL_VCC120X86_ATLMFC)/include
+PATH_TOOL_VCC120X86_ATLMFC_LIB ?= $(PATH_TOOL_VCC120X86_ATLMFC)/lib
+TOOL_VCC120X86_CC ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120X86_BIN)/cl.exe
+TOOL_VCC120X86_CXX ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120X86_BIN)/cl.exe
+TOOL_VCC120X86_AS ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120X86_BIN)/ml.exe
+#TOOL_VCC120X86_AR ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120X86_BIN)/lib.exe - just an exec wrapper for the below
+TOOL_VCC120X86_AR ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120X86_BIN)/link.exe /LIB
+TOOL_VCC120X86_LD ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120X86_BIN)/link.exe
+TOOL_VCC120X86_DUMPBIN ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120X86_BIN)/dumpbin.exe
+TOOL_VCC120X86_EDITBIN ?= $(EXEC_X86_WIN32) $(PATH_TOOL_VCC120X86_BIN)/editbin.exe
+TOOL_VCC120X86_RC ?= $(EXEC_X86_WIN32) $(call TOOL_VCC120_FN_FIND_SDK_TOOL,rc.exe,[Rr][Cc].[Ee][Xx][Ee],TOOL_VCC120_RC_CACHED)
+TOOL_VCC120X86_MT ?= $(EXEC_X86_WIN32) $(call TOOL_VCC120_FN_FIND_SDK_TOOL,mt.exe,[Mm][Tt].[Ee][Xx][Ee],TOOL_VCC120_MT_CACHED)
+ifdef TOOL_VCC120X86_USE_KSUBMIT
+ ifeq ($(KBUILD_HOST),win)
+ if "$(substr $(PATH_TOOL_VCC120X86_BIN),-10)" == "/amd64_x86"
+ TOOL_VCC120X86_KSUBMIT ?= kmk_builtin_kSubmit --64-bit
+ else
+ TOOL_VCC120X86_KSUBMIT ?= kmk_builtin_kSubmit --32-bit
+ endif
+ ifdef PATH_TOOL_VCC120X86_BIN_DLL
+ TOOL_VCC120X86_KSUBMIT += --prepend 'PATH=$(PATH_TOOL_VCC120X86_BIN_DLL)$(HOST_PATH_SEP)'
+ endif
+ TOOL_VCC120X86_KSUBMIT_DD = $(TOOL_VCC120X86_KSUBMIT) --
+ endif
+else ifdef PATH_TOOL_VCC120X86_BIN_DLL
+ TOOL_VCC120X86_KSUBMIT_DD = $(REDIRECT) --prepend 'PATH=$(PATH_TOOL_VCC120X86_BIN_DLL)$(HOST_PATH_SEP)' --
+endif
+
+# The following in duplicated in VCC120.kmk and VCC120X86.kmk.
+TOOL_VCC120_FN_FIND_SDK_TOOL_SUB = $(eval $3 := $(firstword \
+ $(if-expr defined(PATH_SDK_WINPSDK71_BIN), $(wildcard $(PATH_SDK_WINPSDK71_BIN)/$2)) \
+ $(if-expr defined(PATH_SDK_WINPSDK_BIN) , $(wildcard $(PATH_SDK_WINPSDK_BIN)/$2)) \
+ $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST)/sdk/*/[Bb][Ii][Nn]/$2)) \
+ $(rsort $(wildcard $(KBUILD_DEVTOOLS_HST_ALT)/sdk/*/[Bb][Ii][Nn]/$2)) \
+ $1))
+TOOL_VCC120_FN_FIND_SDK_TOOL = $(if-expr !defined($3),$(TOOL_VCC120_FN_FIND_SDK_TOOL_SUB),)$($3)
+
+## Disabled fast DEP_IDB based dependencies.
+#VCC120X86_OLD_DEPS = 1
+
+## Constructs the correct .pdb name (the name is lowercased).
+# @param $(1) Base name, no extention.
+# @param $(2) The extension.
+TOOL_VCC120X86_PDB = $(dir $(1))$(tolower $(notdir $(1))).$(2)
+
+
+# General Properties used by kBuild
+TOOL_VCC120X86_COBJSUFF ?= .obj
+TOOL_VCC120X86_CFLAGS ?= -TC -nologo -Zi
+TOOL_VCC120X86_CFLAGS.debug ?=
+TOOL_VCC120X86_CFLAGS.dbgopt ?= -O2
+TOOL_VCC120X86_CFLAGS.release ?= -O2
+TOOL_VCC120X86_CFLAGS.profile ?= -O2
+TOOL_VCC120X86_CINCS ?= $(PATH_TOOL_VCC120X86_INC)
+TOOL_VCC120X86_CDEFS ?=
+
+TOOL_VCC120X86_CXXOBJSUFF ?= .obj
+TOOL_VCC120X86_CXXFLAGS ?= -TP -nologo -Zi
+TOOL_VCC120X86_CXXFLAGS.debug ?=
+TOOL_VCC120X86_CXXFLAGS.dbgopt ?= -O2
+TOOL_VCC120X86_CXXFLAGS.release ?= -O2
+TOOL_VCC120X86_CXXFLAGS.profile ?= -O2
+TOOL_VCC120X86_CXXINCS ?= $(PATH_TOOL_VCC120X86_INC) $(PATH_TOOL_VCC120X86_ATLMFC_INC)
+TOOL_VCC120X86_CXXDEFS ?=
+
+TOOL_VCC120X86_ASOBJSUFF ?= .obj
+
+TOOL_VCC120X86_RCOBJSUFF ?= .res
+TOOL_VCC120X86_RCINCS ?= $(PATH_TOOL_VCC120X86_INC) $(PATH_TOOL_VCC120X86_ATLMFC_INC)
+
+TOOL_VCC120X86_ARFLAGS ?= -nologo -machine:x86
+TOOL_VCC120X86_ARLIBSUFF ?= .lib
+
+TOOL_VCC120X86_LDFLAGS ?= -nologo -machine:x86
+TOOL_VCC120X86_LDFLAGS.debug ?= -debug
+TOOL_VCC120X86_LDFLAGS.dbgopt ?= -debug
+TOOL_VCC120X86_LDFLAGS.profile ?= -debug
+TOOL_VCC120X86_LDFLAGS.release ?=
+
+
+
+## Compile C source.
+# @param $(target) Normalized main target name.
+# @param $(source) Source filename (relative).
+# @param $(obj) Object file name. This shall be (re)created by the compilation.
+# @param $(dep) Dependcy file. This shall be (re)created by the compilation.
+# @param $(flags) Flags.
+# @param $(defs) Definitions. No -D or something.
+# @param $(incs) Includes. No -I or something.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+# @param $(objsuff) Object suffix.
+TOOL_VCC120X86_COMPILE_C_DEPEND =
+TOOL_VCC120X86_COMPILE_C_DEPORD =
+TOOL_VCC120X86_COMPILE_C_OUTPUT =
+TOOL_VCC120X86_COMPILE_C_OUTPUT_MAYBE = $(call TOOL_VCC120X86_PDB, $(outbase)-obj,pdb) $(call TOOL_VCC120X86_PDB, $(outbase)-obj,idb)
+ifdef TOOL_VCC120X86_KSUBMIT
+ TOOL_VCC120X86_COMPILE_C_DONT_PURGE_OUTPUT = 1 # speed
+ define TOOL_VCC120X86_COMPILE_C_CMDS
+ $(QUIET)$(TOOL_VCC120X86_KSUBMIT) -P $(DEP_OBJ_INT) -f -s -q -o $(dep) -t $(obj) $(obj)\
+ -- $(TOOL_VCC120X86_CC) -c\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ -Fd$(outbase)-obj.pdb \
+ -Fo$(obj)\
+ $(subst /,\\,$(abspath $(source)))
+ endef
+else
+ define TOOL_VCC120X86_COMPILE_C_CMDS
+ $(QUIET)$(if-expr defined(PATH_TOOL_VCC120X86_BIN_DLL)\
+ ,$(REDIRECT) --prepend 'PATH=$(PATH_TOOL_VCC120X86_BIN_DLL)$(HOST_PATH_SEP)' -- ,)$(TOOL_VCC120X86_CC) -c\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ -Fd$(outbase)-obj.pdb \
+ -Fo$(obj)\
+ $(subst /,\\,$(abspath $(source)))
+ $(QUIET)$(DEP_OBJ) -f -s -q -o $(dep) -t $(obj) $(obj)
+ endef
+endif # !TOOL_VCC120X86_KSUBMIT
+
+
+## Compile C++ source.
+# @param $(target) Normalized main target name.
+# @param $(source) Source filename (relative).
+# @param $(obj) Object file name. This shall be (re)created by the compilation.
+# @param $(dep) Dependcy file. This shall be (re)created by the compilation.
+# @param $(flags) Flags.
+# @param $(defs) Definitions. No -D or something.
+# @param $(incs) Includes. No -I or something.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+# @param $(objsuff) Object suffix.
+TOOL_VCC120X86_COMPILE_CXX_DEPEND = $($(target)_1_VCC_PCH_FILE)
+TOOL_VCC120X86_COMPILE_CXX_DEPORD =
+TOOL_VCC120X86_COMPILE_CXX_OUTPUT =
+TOOL_VCC120X86_COMPILE_CXX_OUTPUT_MAYBE = $(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB)\
+ ,,$(call TOOL_VCC120X86_PDB, $(outbase)-obj,pdb) $(call TOOL_VCC120X86_PDB, $(outbase)-obj,idb))
+ifdef TOOL_VCC120X86_KSUBMIT
+ TOOL_VCC120X86_COMPILE_CXX_DONT_PURGE_OUTPUT = 1 # speed
+ define TOOL_VCC120X86_COMPILE_CXX_CMDS
+ $(QUIET)$(TOOL_VCC120X86_KSUBMIT) -P $(DEP_OBJ_INT) -f -s -q -o $(dep) -t $(obj) $(obj)\
+ -- $(TOOL_VCC120X86_CXX) -c\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ $(if-expr defined($(target)_PCH_HDR)\
+ ,-FI$($(target)_PCH_HDR) -Yu$($(target)_PCH_HDR) -Fp$($(target)_1_VCC_PCH_FILE) -FS,)\
+ -Fd$(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB),$($(target)_1_VCC_COMMON_OBJ_PDB),$(outbase)-obj.pdb) \
+ -Fo$(obj)\
+ $(subst /,\\,$(abspath $(source)))
+ endef
+else
+ define TOOL_VCC120X86_COMPILE_CXX_CMDS
+ $(QUIET)$(if-expr defined(PATH_TOOL_VCC120X86_BIN_DLL)\
+ ,$(REDIRECT) --prepend 'PATH=$(PATH_TOOL_VCC120X86_BIN_DLL)$(HOST_PATH_SEP)' -- ,)$(TOOL_VCC120X86_CXX) -c\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ $(if-expr defined($(target)_PCH_HDR)\
+ ,-FI$($(target)_PCH_HDR) -Yu$($(target)_PCH_HDR) -Fp$($(target)_1_VCC_PCH_FILE) -FS,)\
+ -Fd$(if-expr defined($(target)_1_VCC_COMMON_OBJ_PDB),$($(target)_1_VCC_COMMON_OBJ_PDB),$(outbase)-obj.pdb) \
+ -Fo$(obj)\
+ $(subst /,\\,$(abspath $(source)))
+ $(QUIET)$(DEP_OBJ) -f -s -q -o $(dep) -t $(obj) $(obj)
+ endef
+endif # !TOOL_VCC120X86_KSUBMIT
+
+
+#
+# Helper tool for creating the precompiled C++ header.
+#
+# It only have the C++ compile bits and it's purpose is to skip bits
+# related _1_VCC_PCH_FILE and add -Yc.
+#
+TOOL_VCC120X86-PCH := Helper for creating precompiled header using CXX handling.
+TOOL_VCC120X86-PCH_EXTENDS := VCC120X86
+TOOL_VCC120X86-PCH_CXXOBJSUFF := .obj
+TOOL_VCC120X86-PCH_CXXINCS = $(TOOL_VCC120X86_CXXINCS)
+TOOL_VCC120X86-PCH_CXXFLAGS = $(TOOL_VCC120X86_CXXFLAGS) -FS
+TOOL_VCC120X86-PCH_CXXFLAGS.debug = $(TOOL_VCC120X86_CXXFLAGS.debug)
+TOOL_VCC120X86-PCH_CXXFLAGS.dbgopt = $(TOOL_VCC120X86_CXXFLAGS.dbgopt)
+TOOL_VCC120X86-PCH_CXXFLAGS.release = $(TOOL_VCC120X86_CXXFLAGS.release)
+TOOL_VCC120X86-PCH_CXXFLAGS.profile = $(TOOL_VCC120X86_CXXFLAGS.profile)
+TOOL_VCC120X86-PCH_COMPILE_CXX_DEPEND = $(NO_SUCH_VARIABLE)
+TOOL_VCC120X86-PCH_COMPILE_CXX_DEPORD = $(NO_SUCH_VARIABLE)
+TOOL_VCC120X86-PCH_COMPILE_CXX_OUTPUT = $($(target)_1_VCC_PCH_FILE) $($(target)_1_VCC_COMMON_OBJ_PDB)
+TOOL_VCC120X86-PCH_COMPILE_CXX_OUTPUT_MAYBE = $(NO_SUCH_VARIABLE)
+ifdef TOOL_VCC120X86_KSUBMIT
+ define TOOL_VCC120X86-PCH_COMPILE_CXX_CMDS
+ $(QUIET)$(TOOL_VCC120X86_KSUBMIT) --no-pch-caching -P $(DEP_OBJ_INT) -f -s -q -e .pch -o $(dep) -t $(obj) $(obj)\
+ -- $(TOOL_VCC120X86_CXX) -c -Yc\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ -Fp$($(target)_1_VCC_PCH_FILE) \
+ -Fd$($(target)_1_VCC_COMMON_OBJ_PDB) \
+ -Fo$(obj)\
+ -TP \
+ $(subst /,\\,$(abspath $(source)))
+ endef
+else
+ define TOOL_VCC120X86-PCH_COMPILE_CXX_CMDS
+ $(QUIET)$(if-expr defined(PATH_TOOL_VCC120X86_BIN_DLL)\
+ ,$(REDIRECT) --prepend 'PATH=$(PATH_TOOL_VCC120X86_BIN_DLL)$(HOST_PATH_SEP)' -- ,)$(TOOL_VCC120X86_CXX) -c -Yc\
+ $(flags) $(addprefix -I, $(incs)) $(addprefix -D, $(defs))\
+ -Fp$($(target)_1_VCC_PCH_FILE) \
+ -Fd$($(target)_1_VCC_COMMON_OBJ_PDB) \
+ -Fo$(obj)\
+ -TP \
+ $(subst /,\\,$(abspath $(source)))
+ $(QUIET)$(DEP_OBJ) -f -s -q -e .pch -o $(dep) -t $(obj) $(obj)
+
+ endef
+endif # !TOOL_VCC120X86_KSUBMIT
+
+
+## @todo configure the assembler template.
+
+## Compile resource source.
+# @param $(target) Normalized main target name.
+# @param $(source) Source filename (relative).
+# @param $(obj) Object file name. This shall be (re)created by the compilation.
+# @param $(dep) Dependcy file. This shall be (re)created by the compilation.
+# @param $(flags) Flags.
+# @param $(defs) Definitions. No -D or something.
+# @param $(incs) Includes. No -I or something.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+# @param $(objsuff) Object suffix.
+TOOL_VCC120X86_COMPILE_RC_DEPEND =
+TOOL_VCC120X86_COMPILE_RC_DEPORD =
+TOOL_VCC120X86_COMPILE_RC_OUTPUT =
+## @todo Fix kmk_redirect so we can use it for setting PATH without spawning a shell or two
+define TOOL_VCC120X86_COMPILE_RC_CMDS
+ $(QUIET)$(if-expr defined(PATH_TOOL_VCC120X86_BIN_DLL)\
+ ,$(REDIRECT) --prepend 'PATH=$(PATH_TOOL_VCC120X86_BIN_DLL)$(HOST_PATH_SEP)' -- ,) $(TOOL_VCC120X86_RC) \
+ $(flags) $(addprefix /i, $(subst /,\\,$(incs))) $(addprefix /d, $(defs))\
+ /fo$(obj)\
+ $(subst /,\\,$(abspath $(source)))
+endef
+
+
+## Link library
+# @param $(target) Normalized main target name.
+# @param $(out) Library name.
+# @param $(objs) Object files to put in the library.
+# @param $(flags) Flags.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+# @param $(othersrc) Unhandled sources.
+# @param $(outbase) Output basename (full). Use this for list files and such.
+#
+TOOL_VCC120X86_LINK_LIBRARY_DEPEND = $(othersrc)
+TOOL_VCC120X86_LINK_LIBRARY_DEPORD =
+TOOL_VCC120X86_LINK_LIBRARY_OUTPUT = $(outbase).rsp
+TOOL_VCC120X86_LINK_LIBRARY_OUTPUT_MAYBE = $(outbase).lst $(outbase).exp $(outbase).pdb
+define TOOL_VCC120X86_LINK_LIBRARY_CMDS
+ $(QUIET)$(APPEND) -tn $(outbase).rsp \
+ $(foreach arg,\
+ $(subst /,\\,$(objs) \
+ $(filter-out %.def,$(othersrc))) \
+ $(addprefix /DEF:,$(filter %.def,$(othersrc))) \
+ ,\"$(arg)\")
+ $(QUIET)$(TOOL_VCC120X86_KSUBMIT_DD) $(TOOL_VCC120X86_AR) $(flags) /OUT:$(out) @$(outbase).rsp
+endef
+
+
+## Link program
+# @param $(target) Normalized main target name.
+# @param $(out) Program name.
+# @param $(objs) Object files to link together.
+# @param $(libs) Libraries to search.
+# @param $(libpath) Library search paths.
+# @param $(flags) Flags.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+# @param $(othersrc) Unhandled sources.
+# @param $(custom_pre) Custom step invoked before linking.
+# @param $(custom_post) Custom step invoked after linking.
+# @param $(outbase) Output basename (full). Use this for list files and such.
+#
+TOOL_VCC120X86_LINK_PROGRAM_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
+TOOL_VCC120X86_LINK_PROGRAM_DEPORD =
+TOOL_VCC120X86_LINK_PROGRAM_OUTPUT = $(outbase).map $(outbase).rsp
+TOOL_VCC120X86_LINK_PROGRAM_OUTPUT_MAYBE = $(outbase).lib $(outbase).exp $(outbase).ilk $(out).manifest
+TOOL_VCC120X86_LINK_PROGRAM_OUTPUT_DEBUG = $(outbase).pdb
+TOOL_VCC120X86_LINK_PROGRAM_DEBUG_INSTALL_FN = $(2).pdb=>$(basename $(3)).pdb
+define TOOL_VCC120X86_LINK_PROGRAM_CMDS
+ $(QUIET)$(APPEND) -tn $(outbase).rsp \
+ $(foreach arg,\
+ $(subst /,\\,$(objs)) \
+ $(subst /,\\,$(libs)) \
+ ,\"$(arg)\")
+ $(QUIET)$(TOOL_VCC120X86_KSUBMIT_DD) $(TOOL_VCC120X86_LD) $(flags) \
+ /OUT:$(out) \
+ /MAPINFO:EXPORTS /INCREMENTAL:NO \
+ /MAP:$(outbase).map \
+ $(foreach def,$(filter %.def,$(othersrc)), /DEF:$(def)) \
+ $(subst /,\\,$(filter %.exp %.res,$(othersrc))) \
+ $(foreach p,$(libpath), /LIBPATH:$(p)) \
+ @$(outbase).rsp
+ifndef TOOL_VCC120X86_NO_AUTO_MANIFEST
+ $(QUIET)$(TEST) -f $(out).manifest -- \
+ $(TOOL_VCC120X86_MT) -manifest $(subst /,\\,$(out)).manifest -outputresource:$(subst /,\\,$(out))
+endif
+endef
+
+
+## Link DLL.
+# @param $(target) Normalized main target name.
+# @param $(out) DLL name.
+# @param $(objs) Object files to link together.
+# @param $(libs) Libraries to search.
+# @param $(libpath) Library search paths.
+# @param $(flags) Flags.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+# @param $(othersrc) Unhandled sources.
+# @param $(custom_pre) Custom step invoked before linking.
+# @param $(custom_post) Custom step invoked after linking.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+TOOL_VCC120X86_LINK_DLL_DEPEND = $(objs) $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
+TOOL_VCC120X86_LINK_DLL_DEPORD = $(call DIRDEP,$(PATH_STAGE_LIB))
+TOOL_VCC120X86_LINK_DLL_OUTPUT = $(outbase).map $(outbase).lib $(outbase).exp $(outbase).rsp
+TOOL_VCC120X86_LINK_DLL_OUTPUT_MAYBE = $(outbase).ilk $(out).manifest $(PATH_STAGE_LIB)/$(notdir $(outbase)).exp
+TOOL_VCC120X86_LINK_DLL_OUTPUT_MAYBE_PRECIOUS = $(PATH_STAGE_LIB)/$(notdir $(outbase)).lib
+TOOL_VCC120X86_LINK_DLL_OUTPUT_DEBUG = $(outbase).pdb
+TOOL_VCC120X86_LINK_DLL_DEBUG_INSTALL_FN = $(2).pdb=>$(basename $(3)).pdb
+define TOOL_VCC120X86_LINK_DLL_CMDS
+ $(QUIET)$(APPEND) -tn $(outbase).rsp \
+ $(foreach arg,\
+ $(subst /,\\,$(objs)) \
+ $(subst /,\\,$(libs)) \
+ ,\"$(arg)\")
+ $(QUIET)$(TOOL_VCC120X86_KSUBMIT_DD) $(TOOL_VCC120X86_LD) $(flags) \
+ /OUT:$(out) \
+ /IMPLIB:$(outbase).lib \
+ /MAPINFO:EXPORTS /INCREMENTAL:NO \
+ /MAP:$(outbase).map \
+ /DLL \
+ $(foreach def,$(filter %.def,$(othersrc)), /DEF:$(def)) \
+ $(subst /,\\,$(filter %.exp %.res,$(othersrc))) \
+ $(foreach p,$(libpath), /LIBPATH:$(p)) \
+ @$(outbase).rsp
+ifndef TOOL_VCC120X86_NO_AUTO_MANIFEST
+ $(QUIET)$(TEST) -f $(out).manifest -- \
+ $(TOOL_VCC120X86_MT) -manifest $(subst /,\\,$(out)).manifest '-outputresource:$(subst /,\\,$(out));#2'
+endif
+ $(QUIET)$(TEST) -f $(outbase).lib -- $(KLIBTWEAKER_EXT) --clear-timestamps $(outbase).lib
+ $(QUIET)$(CP) --changed --ignore-non-existing $(outbase).exp $(outbase).lib $(PATH_STAGE_LIB)/
+$(eval _DIRS += $(PATH_STAGE_LIB))
+endef
+
+
+## Link system module (windows aka driver, linux aka kernel module)
+# @param $(target) Normalized main target name.
+# @param $(out) System module name.
+# @param $(objs) Object files to link together.
+# @param $(libs) Libraries to search.
+# @param $(libpath) Library search paths.
+# @param $(flags) Flags.
+# @param $(dirdep) Directory creation dependency.
+# @param $(deps) Other dependencies.
+# @param $(othersrc) Unhandled sources.
+# @param $(custom_pre) Custom step invoked before linking.
+# @param $(custom_post) Custom step invoked after linking.
+#
+# @param $(outbase) Output basename (full). Use this for list files and such.
+TOOL_VCC120X86_LINK_SYSMOD_DEPEND = $(foreach lib,$(libs),$(if $(findstring $(lib),$(subst /,x,$(lib))),, $(lib))) $(othersrc)
+TOOL_VCC120X86_LINK_SYSMOD_DEPORD =
+TOOL_VCC120X86_LINK_SYSMOD_OUTPUT = $(outbase).map $(outbase).rsp
+TOOL_VCC120X86_LINK_SYSMOD_OUTPUT_MAYBE = $(outbase).lib $(outbase).exp $(outbase).ilk $(out).manifest
+TOOL_VCC120X86_LINK_SYSMOD_OUTPUT_DEBUG = $(outbase).pdb
+TOOL_VCC120X86_LINK_SYSMOD_DEBUG_INSTALL_FN = $(2).pdb=>$(basename $(3)).pdb
+define TOOL_VCC120X86_LINK_SYSMOD_CMDS
+ $(QUIET)$(APPEND) -tn $(outbase).rsp \
+ $(foreach arg,\
+ $(subst /,\\,$(objs)) \
+ $(subst /,\\,$(libs)) \
+ ,\"$(arg)\")
+ $(QUIET)$(TOOL_VCC120X86_KSUBMIT_DD) $(TOOL_VCC120X86_LD) $(flags) \
+ /OUT:$(out) \
+ /MAPINFO:EXPORTS /INCREMENTAL:NO \
+ /MAP:$(outbase).map \
+ $(foreach def,$(filter %.def,$(othersrc)), /DEF:$(def)) \
+ $(subst /,\\,$(filter %.exp %.res,$(othersrc))) \
+ $(foreach p,$(libpath), /LIBPATH:$(p)) \
+ @$(outbase).rsp
+ifndef TOOL_VCC120X86_NO_AUTO_MANIFEST
+ $(QUIET)$(TEST) -f $(out).manifest -- \
+ $(TOOL_VCC120X86_MT) -manifest $(subst /,\\,$(out)).manifest '-outputresource:$(subst /,\\,$(out));#2'
+endif
+endef
+
diff --git a/src/kDepPre/kDepPre.c b/src/kDepPre/kDepPre.c
index e677b5b..1243ca1 100644
--- a/src/kDepPre/kDepPre.c
+++ b/src/kDepPre/kDepPre.c
@@ -1,4 +1,4 @@
-/* $Id: kDepPre.c 2955 2016-09-21 19:05:53Z bird $ */
+/* $Id: kDepPre.c 3065 2017-09-30 12:52:35Z bird $ */
/** @file
* kDepPre - Dependency Generator using Precompiler output.
*/
@@ -293,14 +293,14 @@ int main(int argc, char *argv[])
*/
case 'l':
{
- const char *psz = &argv[i][2];
- if (*psz == '=')
- psz++;
- if (!strcmp(psz, "c"))
+ const char *pszValue = &argv[i][2];
+ if (*pszValue == '=')
+ pszValue++;
+ if (!strcmp(pszValue, "c"))
;
else
{
- fprintf(stderr, "%s: error: The '%s' language is not supported.\n", argv[0], psz);
+ fprintf(stderr, "%s: error: The '%s' language is not supported.\n", argv[0], pszValue);
return 1;
}
break;
diff --git a/src/kObjCache/kObjCache.c b/src/kObjCache/kObjCache.c
index fdb0697..e3d590c 100644
--- a/src/kObjCache/kObjCache.c
+++ b/src/kObjCache/kObjCache.c
@@ -1,4 +1,4 @@
-/* $Id: kObjCache.c 2955 2016-09-21 19:05:53Z bird $ */
+/* $Id: kObjCache.c 3065 2017-09-30 12:52:35Z bird $ */
/** @file
* kObjCache - Object Cache.
*/
@@ -69,6 +69,9 @@
# ifndef O_BINARY
# define O_BINARY 0
# endif
+# ifndef __sun__
+# include <sys/file.h> /* flock */
+# endif
#endif
#if defined(__WIN__)
# include <Windows.h>
@@ -1070,6 +1073,10 @@ kOCDepConsumer(PKOCDEP pDepState, const char *pszInput, size_t cchInput)
off++;
}
}
+
+ case kOCDepState_Invalid:
+ assert(0);
+ break;
}
/* next newline */
@@ -2354,10 +2361,10 @@ static void kOCEntryRead(PKOCENTRY pEntry)
else if (!strncmp(g_szLine, "cc-argv-#", sizeof("cc-argv-#") - 1))
{
char *pszNext;
- unsigned i = strtoul(&g_szLine[sizeof("cc-argv-#") - 1], &pszNext, 0);
- if ((fBad = i >= pEntry->Old.cArgvCompile || pEntry->Old.papszArgvCompile[i] || (pszNext && *pszNext)))
+ unsigned iArg = strtoul(&g_szLine[sizeof("cc-argv-#") - 1], &pszNext, 0);
+ if ((fBad = iArg >= pEntry->Old.cArgvCompile || pEntry->Old.papszArgvCompile[iArg] || (pszNext && *pszNext)))
break;
- pEntry->Old.papszArgvCompile[i] = xstrdup(pszVal);
+ pEntry->Old.papszArgvCompile[iArg] = xstrdup(pszVal);
}
else if (!strcmp(g_szLine, "cc-argv-sum"))
{
@@ -2490,13 +2497,13 @@ static void kOCEntryWrite(PKOCENTRY pEntry)
do { int cch = expr; if (cch >= KOBJCACHE_MAX_LINE_LEN) FatalDie("Line too long: %d (max %d)\nexpr: %s\n", cch, KOBJCACHE_MAX_LINE_LEN, #expr); } while (0)
fprintf(pFile, "magic=kObjCacheEntry-v0.1.1\n");
- CHECK_LEN(fprintf(pFile, "target=%s\n", pEntry->New.pszTarget ? pEntry->New.pszTarget : pEntry->Old.pszTarget));
- CHECK_LEN(fprintf(pFile, "key=%lu\n", (unsigned long)pEntry->uKey));
+ CHECK_LEN(fprintf(pFile, "target=%s\n", pEntry->New.pszTarget ? pEntry->New.pszTarget : pEntry->Old.pszTarget));
+ CHECK_LEN(fprintf(pFile, "key=%lu\n", (unsigned long)pEntry->uKey));
CHECK_LEN(fprintf(pFile, "obj=%s\n", pEntry->New.pszObjName ? pEntry->New.pszObjName : pEntry->Old.pszObjName));
CHECK_LEN(fprintf(pFile, "cpp=%s\n", pEntry->New.pszCppName ? pEntry->New.pszCppName : pEntry->Old.pszCppName));
- CHECK_LEN(fprintf(pFile, "cpp-size=%lu\n", pEntry->New.pszCppName ? pEntry->New.cbCpp : pEntry->Old.cbCpp));
- CHECK_LEN(fprintf(pFile, "cpp-ms=%lu\n", pEntry->New.pszCppName ? pEntry->New.cMsCpp : pEntry->Old.cMsCpp));
- CHECK_LEN(fprintf(pFile, "cc-ms=%lu\n", pEntry->New.pszCppName ? pEntry->New.cMsCompile : pEntry->Old.cMsCompile));
+ CHECK_LEN(fprintf(pFile, "cpp-size=%lu\n", (unsigned long)(pEntry->New.pszCppName ? pEntry->New.cbCpp : pEntry->Old.cbCpp)));
+ CHECK_LEN(fprintf(pFile, "cpp-ms=%lu\n", (unsigned long)(pEntry->New.pszCppName ? pEntry->New.cMsCpp : pEntry->Old.cMsCpp)));
+ CHECK_LEN(fprintf(pFile, "cc-ms=%lu\n", (unsigned long)(pEntry->New.pszCppName ? pEntry->New.cMsCompile : pEntry->Old.cMsCompile)));
if (!kOCSumIsEmpty(&pEntry->New.SumCompArgv))
{
@@ -5087,7 +5094,7 @@ int main(int argc, char **argv)
}
else if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version"))
{
- printf("kObjCache - kBuild version %d.%d.%d ($Revision: 2955 $)\n"
+ printf("kObjCache - kBuild version %d.%d.%d ($Revision: 3065 $)\n"
"Copyright (c) 2007-2012 knut st. osmundsen\n",
KBUILD_VERSION_MAJOR, KBUILD_VERSION_MINOR, KBUILD_VERSION_PATCH);
return 0;
diff --git a/src/kWorker/Makefile.kmk b/src/kWorker/Makefile.kmk
index 2f0331b..c2647f2 100644
--- a/src/kWorker/Makefile.kmk
+++ b/src/kWorker/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk 2968 2016-09-26 18:14:50Z bird $
+# $Id: Makefile.kmk 3042 2017-05-11 10:23:12Z bird $
## @file
# Sub-makefile for kWorker.
#
@@ -152,6 +152,25 @@ kStuff_SOURCES.darwin += \
kStuff/kHlp/Bare/kHlpSys-darwin.c
+#
+# A couple of dummy DLLs we use for grabbing LDR TLS entries.
+#
+DLLS += kWorkerTls1K kWorkerTls64K kWorkerTls512K
+kWorkerTls1K_TEMPLATE = BIN-STATIC-THREADED
+kWorkerTls1K_DEFS = KWORKER_BASE=0x10000 TLS_SIZE=1024
+kWorkerTls1K_SOURCES = kWorkerTlsXxxK.c
+kWorkerTls1K_LDFLAGS = /Entry:DummyDllEntry
+
+kWorkerTls64K_TEMPLATE = BIN-STATIC-THREADED
+kWorkerTls64K_DEFS = KWORKER_BASE=0x10000 TLS_SIZE=65536
+kWorkerTls64K_SOURCES = kWorkerTlsXxxK.c
+kWorkerTls64K_LDFLAGS = /Entry:DummyDllEntry
+
+kWorkerTls512K_TEMPLATE = BIN-STATIC-THREADED
+kWorkerTls512K_DEFS = KWORKER_BASE=0x10000 TLS_SIZE=524288
+kWorkerTls512K_SOURCES = kWorkerTlsXxxK.c
+kWorkerTls512K_LDFLAGS = /Entry:DummyDllEntry
+
include $(KBUILD_PATH)/subfooter.kmk
diff --git a/src/kWorker/kWorker.c b/src/kWorker/kWorker.c
index 13e7d94..05ba245 100644
--- a/src/kWorker/kWorker.c
+++ b/src/kWorker/kWorker.c
@@ -1,4 +1,4 @@
-/* $Id: kWorker.c 2987 2016-11-01 18:27:39Z bird $ */
+/* $Id: kWorker.c 3089 2017-10-04 13:10:41Z bird $ */
/** @file
* kWorker - experimental process reuse worker for Windows.
*
@@ -292,6 +292,20 @@ typedef struct KWMODULE
/** How much to zero. */
KSIZE cbToZero;
} aQuickZeroChunks[3];
+
+ /** TLS index if one was allocated, otherwise KU32_MAX. */
+ KU32 idxTls;
+ /** Offset (RVA) of the TLS initialization data. */
+ KU32 offTlsInitData;
+ /** Number of bytes of TLS initialization data. */
+ KU32 cbTlsInitData;
+ /** Number of allocated bytes for TLS. */
+ KU32 cbTlsAlloc;
+ /** Number of TLS callbacks. */
+ KU32 cTlsCallbacks;
+ /** Offset (RVA) of the TLS callback table. */
+ KU32 offTlsCallbacks;
+
/** Number of imported modules. */
KSIZE cImpMods;
/** Import array (variable size). */
@@ -892,6 +906,9 @@ static KWGETMODULEHANDLECACHE g_aGetModuleHandleCache[] =
{ MOD_CACHE_STRINGS("mscoree.dll"), NULL },
};
+/** Module pending TLS allocation. See kwLdrModuleCreateNonNativeSetupTls. */
+static PKWMODULE g_pModPendingTlsAlloc = NULL;
+
/** The file system cache. */
static PKFSCACHE g_pFsCache;
@@ -1017,11 +1034,13 @@ static KSIZE g_cbWriteFileToInMemTemp;
* Internal Functions *
*********************************************************************************************************************************/
static FNKLDRMODGETIMPORT kwLdrModuleGetImportCallback;
-static int kwLdrModuleResolveAndLookup(const char *pszName, PKWMODULE pExe, PKWMODULE pImporter, PKWMODULE *ppMod);
+static int kwLdrModuleResolveAndLookup(const char *pszName, PKWMODULE pExe, PKWMODULE pImporter,
+ const char *pszSearchPath, PKWMODULE *ppMod);
static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle, HANDLE hHandle);
#ifdef WITH_CONSOLE_OUTPUT_BUFFERING
static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pLineBuf, const char *pchBuffer, KU32 cchToWrite);
#endif
+static PPEB kwSandboxGetProcessEnvironmentBlock(void);
@@ -2001,6 +2020,178 @@ static void kwLdrModuleCreateNonNativeSetupQuickZeroAndCopy(PKWMODULE pMod)
/**
+ * Called from TLS allocation DLL during DLL_PROCESS_ATTACH.
+ *
+ * @param hDll The DLL handle.
+ * @param idxTls The allocated TLS index.
+ * @param ppfnTlsCallback Pointer to the TLS callback table entry.
+ */
+__declspec(dllexport) void kwLdrTlsAllocationHook(void *hDll, ULONG idxTls, PIMAGE_TLS_CALLBACK *ppfnTlsCallback)
+{
+ /*
+ * Do the module initialization thing first.
+ */
+ PKWMODULE pMod = g_pModPendingTlsAlloc;
+ if (pMod)
+ {
+ PPEB pPeb = kwSandboxGetProcessEnvironmentBlock();
+ LIST_ENTRY *pHead;
+ LIST_ENTRY *pCur;
+
+ pMod->u.Manual.idxTls = idxTls;
+ KWLDR_LOG(("kwLdrTlsAllocationHook: idxTls=%d (%#x) for %s\n", idxTls, idxTls, pMod->pszPath));
+
+ /*
+ * Try sabotage the DLL name so we can load this module again.
+ */
+ pHead = &pPeb->Ldr->InMemoryOrderModuleList;
+ for (pCur = pHead->Blink; pCur != pHead; pCur = pCur->Blink)
+ {
+ LDR_DATA_TABLE_ENTRY *pMte;
+ pMte = (LDR_DATA_TABLE_ENTRY *)((KUPTR)pCur - K_OFFSETOF(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks));
+ if (((KUPTR)pMte->DllBase & ~(KUPTR)31) == ((KUPTR)hDll & ~(KUPTR)31))
+ {
+ PUNICODE_STRING pStr = &pMte->FullDllName;
+ KSIZE off = pStr->Length / sizeof(pStr->Buffer[0]);
+ pStr->Buffer[--off]++;
+ pStr->Buffer[--off]++;
+ pStr->Buffer[--off]++;
+ KWLDR_LOG(("kwLdrTlsAllocationHook: patched the MTE (%p) for %p\n", pMte, hDll));
+ break;
+ }
+ }
+ }
+}
+
+
+/**
+ * Allocates and initializes TLS variables.
+ *
+ * @returns 0 on success, non-zero failure.
+ * @param pMod The module.
+ */
+static int kwLdrModuleCreateNonNativeSetupTls(PKWMODULE pMod)
+{
+ KU8 *pbImg = (KU8 *)pMod->u.Manual.pbCopy;
+ IMAGE_NT_HEADERS const *pNtHdrs;
+ IMAGE_DATA_DIRECTORY const *pTlsDir;
+
+ if (((PIMAGE_DOS_HEADER)pbImg)->e_magic == IMAGE_DOS_SIGNATURE)
+ pNtHdrs = (PIMAGE_NT_HEADERS)&pbImg[((PIMAGE_DOS_HEADER)pbImg)->e_lfanew];
+ else
+ pNtHdrs = (PIMAGE_NT_HEADERS)pbImg;
+ kHlpAssert(pNtHdrs->Signature == IMAGE_NT_SIGNATURE);
+
+ pTlsDir = &pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS];
+ if (pTlsDir->Size >= sizeof(IMAGE_TLS_DIRECTORY))
+ {
+ PIMAGE_TLS_DIRECTORY const paEntries = (PIMAGE_TLS_DIRECTORY)&pbImg[pTlsDir->VirtualAddress];
+ KU32 const cEntries = pTlsDir->Size / sizeof(IMAGE_TLS_DIRECTORY);
+ KU32 iEntry;
+ KUPTR offIndex;
+ KUPTR offCallbacks;
+ KUPTR const *puCallbacks;
+ KSIZE cbData;
+ const wchar_t *pwszTlsDll;
+ HMODULE hmodTlsDll;
+
+ /*
+ * Check and log.
+ */
+ for (iEntry = 0; iEntry < cEntries; iEntry++)
+ {
+ KUPTR offIndex = (KUPTR)paEntries[iEntry].AddressOfIndex - (KUPTR)pMod->u.Manual.pbLoad;
+ KUPTR offCallbacks = (KUPTR)paEntries[iEntry].AddressOfCallBacks - (KUPTR)pMod->u.Manual.pbLoad;
+ KUPTR const *puCallbacks = (KUPTR const *)&pbImg[offCallbacks];
+ KWLDR_LOG(("TLS DIR #%u: %#x-%#x idx=@%#x (%#x) callbacks=@%#x (%#x) cbZero=%#x flags=%#x\n",
+ iEntry, paEntries[iEntry].StartAddressOfRawData, paEntries[iEntry].EndAddressOfRawData,
+ paEntries[iEntry].AddressOfIndex, offIndex, paEntries[iEntry].AddressOfCallBacks, offCallbacks,
+ paEntries[iEntry].SizeOfZeroFill, paEntries[iEntry].Characteristics));
+
+ if (offIndex >= pMod->cbImage)
+ {
+ kwErrPrintf("TLS entry #%u in %s has an invalid index address: %p, RVA %p, image size %#x\n",
+ iEntry, pMod->pszPath, paEntries[iEntry].AddressOfIndex, offIndex, pMod->cbImage);
+ return -1;
+ }
+ if (offCallbacks >= pMod->cbImage)
+ {
+ kwErrPrintf("TLS entry #%u in %s has an invalid callbacks address: %p, RVA %p, image size %#x\n",
+ iEntry, pMod->pszPath, paEntries[iEntry].AddressOfCallBacks, offCallbacks, pMod->cbImage);
+ return -1;
+ }
+ while (*puCallbacks != 0)
+ {
+ KWLDR_LOG(("TLS DIR #%u: callback %p, RVA %#x\n",
+ iEntry, *puCallbacks, *puCallbacks - (KUPTR)pMod->u.Manual.pbLoad));
+ puCallbacks++;
+ }
+ if (paEntries[iEntry].Characteristics > IMAGE_SCN_ALIGN_16BYTES)
+ {
+ kwErrPrintf("TLS entry #%u in %s has an unsupported alignment restriction: %#x\n",
+ iEntry, pMod->pszPath, paEntries[iEntry].Characteristics);
+ return -1;
+ }
+ }
+
+ if (cEntries > 1)
+ {
+ kwErrPrintf("More than one TLS directory entry in %s: %u\n", pMod->pszPath, cEntries);
+ return -1;
+ }
+
+ /*
+ * Make the allocation by loading a new instance of one of the TLS dlls.
+ * The DLL will make a call to
+ */
+ offIndex = (KUPTR)paEntries[0].AddressOfIndex - (KUPTR)pMod->u.Manual.pbLoad;
+ offCallbacks = (KUPTR)paEntries[0].AddressOfCallBacks - (KUPTR)pMod->u.Manual.pbLoad;
+ puCallbacks = (KUPTR const *)&pbImg[offCallbacks];
+ cbData = paEntries[0].SizeOfZeroFill + (paEntries[0].EndAddressOfRawData - paEntries[0].StartAddressOfRawData);
+ if (cbData <= 1024)
+ pwszTlsDll = L"kWorkerTls1K.dll";
+ else if (cbData <= 65536)
+ pwszTlsDll = L"kWorkerTls64K.dll";
+ else if (cbData <= 524288)
+ pwszTlsDll = L"kWorkerTls512K.dll";
+ else
+ {
+ kwErrPrintf("TLS data size in %s is too big: %u (%#p), max 512KB\n", pMod->pszPath, (unsigned)cbData, cbData);
+ return -1;
+ }
+
+ pMod->u.Manual.idxTls = KU32_MAX;
+ pMod->u.Manual.offTlsInitData = (KU32)((KUPTR)paEntries[0].StartAddressOfRawData - (KUPTR)pMod->u.Manual.pbLoad);
+ pMod->u.Manual.cbTlsInitData = (KU32)(paEntries[0].EndAddressOfRawData - paEntries[0].StartAddressOfRawData);
+ pMod->u.Manual.cbTlsAlloc = (KU32)cbData;
+ pMod->u.Manual.cTlsCallbacks = 0;
+ while (puCallbacks[pMod->u.Manual.cTlsCallbacks] != 0)
+ pMod->u.Manual.cTlsCallbacks++;
+ pMod->u.Manual.offTlsCallbacks = pMod->u.Manual.cTlsCallbacks ? (KU32)offCallbacks : KU32_MAX;
+
+ g_pModPendingTlsAlloc = pMod;
+ hmodTlsDll = LoadLibraryExW(pwszTlsDll, NULL /*hFile*/, 0);
+ g_pModPendingTlsAlloc = NULL;
+ if (hmodTlsDll == NULL)
+ {
+ kwErrPrintf("TLS allocation failed for '%s': LoadLibraryExW(%ls) -> %u\n", pMod->pszPath, pwszTlsDll, GetLastError());
+ return -1;
+ }
+ if (pMod->u.Manual.idxTls == KU32_MAX)
+ {
+ kwErrPrintf("TLS allocation failed for '%s': idxTls = KU32_MAX\n", pMod->pszPath, GetLastError());
+ return -1;
+ }
+
+ *(KU32 *)&pMod->u.Manual.pbCopy[offIndex] = pMod->u.Manual.idxTls;
+ KWLDR_LOG(("kwLdrModuleCreateNonNativeSetupTls: idxTls=%d hmodTlsDll=%p (%ls) cbData=%#x\n",
+ pMod->u.Manual.idxTls, hmodTlsDll, pwszTlsDll, cbData));
+ }
+ return 0;
+}
+
+
+/**
* Creates a module using the our own loader.
*
* @returns Module w/ 1 reference on success, NULL on failure.
@@ -2011,8 +2202,10 @@ static void kwLdrModuleCreateNonNativeSetupQuickZeroAndCopy(PKWMODULE pMod)
* into the global module table.
* @param pExeMod The executable module of the process (for
* resolving imports). NULL if fExe is set.
+ * @param pszSearchPath The PATH to search for imports. Can be NULL.
*/
-static PKWMODULE kwLdrModuleCreateNonNative(const char *pszPath, KU32 uHashPath, KBOOL fExe, PKWMODULE pExeMod)
+static PKWMODULE kwLdrModuleCreateNonNative(const char *pszPath, KU32 uHashPath, KBOOL fExe,
+ PKWMODULE pExeMod, const char *pszSearchPath)
{
/*
* Open the module and check the type.
@@ -2068,10 +2261,16 @@ static PKWMODULE kwLdrModuleCreateNonNative(const char *pszPath, KU32 uHashPath,
#if defined(KBUILD_OS_WINDOWS) && defined(KBUILD_ARCH_AMD64)
pMod->u.Manual.fRegisteredFunctionTable = K_FALSE;
#endif
- pMod->u.Manual.fUseLdBuf = K_FALSE;
- pMod->u.Manual.fCanDoQuick = K_FALSE;
+ pMod->u.Manual.fUseLdBuf = K_FALSE;
+ pMod->u.Manual.fCanDoQuick = K_FALSE;
pMod->u.Manual.cQuickZeroChunks = 0;
pMod->u.Manual.cQuickCopyChunks = 0;
+ pMod->u.Manual.idxTls = KU32_MAX;
+ pMod->u.Manual.offTlsInitData = KU32_MAX;
+ pMod->u.Manual.cbTlsInitData = 0;
+ pMod->u.Manual.cbTlsAlloc = 0;
+ pMod->u.Manual.cTlsCallbacks = 0;
+ pMod->u.Manual.offTlsCallbacks = 0;
pMod->pszPath = (char *)kHlpMemCopy(&pMod->u.Manual.apImpMods[cImports + 1], pszPath, cbPath);
pMod->pwszPath = (wchar_t *)(pMod->pszPath + cbPath + (cbPath & 1));
kwStrToUtf16(pMod->pszPath, (wchar_t *)pMod->pwszPath, cbPath * 2);
@@ -2105,6 +2304,7 @@ static PKWMODULE kwLdrModuleCreateNonNative(const char *pszPath, KU32 uHashPath,
kwLdrModuleLink(pMod);
KW_LOG(("New module: %p LB %#010x %s (kLdr)\n",
pMod->u.Manual.pbLoad, pMod->cbImage, pMod->pszPath));
+ KW_LOG(("TODO: .reload /f %s=%p\n", pMod->pszPath, pMod->u.Manual.pbLoad));
kwDebuggerPrintf("TODO: .reload /f %s=%p\n", pMod->pszPath, pMod->u.Manual.pbLoad);
for (iImp = 0; iImp < cImports; iImp++)
@@ -2113,7 +2313,8 @@ static PKWMODULE kwLdrModuleCreateNonNative(const char *pszPath, KU32 uHashPath,
rc = kLdrModGetImport(pMod->pLdrMod, NULL /*pvBits*/, iImp, szName, sizeof(szName));
if (rc == 0)
{
- rc = kwLdrModuleResolveAndLookup(szName, pExeMod, pMod, &pMod->u.Manual.apImpMods[iImp]);
+ rc = kwLdrModuleResolveAndLookup(szName, pExeMod, pMod, pszSearchPath,
+ &pMod->u.Manual.apImpMods[iImp]);
if (rc == 0)
continue;
}
@@ -2156,15 +2357,21 @@ static PKWMODULE kwLdrModuleCreateNonNative(const char *pszPath, KU32 uHashPath,
kwLdrModuleCreateNonNativeSetupQuickZeroAndCopy(pMod);
- /*
- * Final finish.
- */
- pMod->u.Manual.pvBits = pMod->u.Manual.pbCopy;
- pMod->u.Manual.enmState = KWMODSTATE_NEEDS_BITS;
- g_cModules++;
- g_cNonNativeModules++;
- return pMod;
+ rc = kwLdrModuleCreateNonNativeSetupTls(pMod);
+ if (rc == 0)
+ {
+ /*
+ * Final finish.
+ */
+ pMod->u.Manual.pvBits = pMod->u.Manual.pbCopy;
+ pMod->u.Manual.enmState = KWMODSTATE_NEEDS_BITS;
+ g_cModules++;
+ g_cNonNativeModules++;
+ return pMod;
+ }
}
+ else
+ kwErrPrintf("kLdrModGetBits failed for %s: %#x (%d)\n", pszPath, rc, rc);
}
kwLdrModuleRelease(pMod);
@@ -2231,6 +2438,7 @@ static int kwLdrModuleGetImportCallback(PKLDRMOD pMod, KU32 iImport, KU32 iSymbo
}
//printf("iImport=%u (%s) %*.*s rc=%d\n", iImport, &pImpMod->pszPath[pImpMod->offFilename], cchSymbol, cchSymbol, pchSymbol, rc);
+ KW_LOG(("iImport=%u (%s) %*.*s rc=%d\n", iImport, &pImpMod->pszPath[pImpMod->offFilename], cchSymbol, cchSymbol, pchSymbol, rc));
return rc;
}
@@ -2401,8 +2609,9 @@ static KBOOL kwLdrModuleIsRegularFile(const char *pszPath)
* the heuristics for determining if we can use the
* native loader or need to sandbox the DLL.
* @param pExe The executable (optional).
+ * @param pszSearchPath The PATH to search (optional).
*/
-static PKWMODULE kwLdrModuleTryLoadDll(const char *pszPath, KWLOCATION enmLocation, PKWMODULE pExeMod)
+static PKWMODULE kwLdrModuleTryLoadDll(const char *pszPath, KWLOCATION enmLocation, PKWMODULE pExeMod, const char *pszSearchPath)
{
/*
* Does the file exists and is it a regular file?
@@ -2439,7 +2648,7 @@ static PKWMODULE kwLdrModuleTryLoadDll(const char *pszPath, KWLOCATION enmLocati
pMod = kwLdrModuleCreateNative(szNormPath, uHashPath,
kwLdrModuleShouldDoNativeReplacements(pszName, enmLocation));
else
- pMod = kwLdrModuleCreateNonNative(szNormPath, uHashPath, K_FALSE /*fExe*/, pExeMod);
+ pMod = kwLdrModuleCreateNonNative(szNormPath, uHashPath, K_FALSE /*fExe*/, pExeMod, pszSearchPath);
if (pMod)
return pMod;
return (PKWMODULE)~(KUPTR)0;
@@ -2461,9 +2670,11 @@ static PKWMODULE kwLdrModuleTryLoadDll(const char *pszPath, KWLOCATION enmLocati
* @param pszName The name of the import module.
* @param pExe The executable (optional).
* @param pImporter The module doing the importing (optional).
+ * @param pszSearchPath The PATH to search (optional).
* @param ppMod Where to return the module pointer w/ reference.
*/
-static int kwLdrModuleResolveAndLookup(const char *pszName, PKWMODULE pExe, PKWMODULE pImporter, PKWMODULE *ppMod)
+static int kwLdrModuleResolveAndLookup(const char *pszName, PKWMODULE pExe, PKWMODULE pImporter,
+ const char *pszSearchPath, PKWMODULE *ppMod)
{
KSIZE const cchName = kHlpStrLen(pszName);
char szPath[1024];
@@ -2482,7 +2693,7 @@ static int kwLdrModuleResolveAndLookup(const char *pszName, PKWMODULE pExe, PKWM
psz = (char *)kHlpMemPCopy(kHlpMemPCopy(szPath, pImporter->pszPath, pImporter->offFilename), pszName, cchName + 1);
if (fNeedSuffix)
kHlpMemCopy(psz - 1, ".dll", sizeof(".dll"));
- pMod = kwLdrModuleTryLoadDll(szPath, KWLOCATION_IMPORTER_DIR, pExe);
+ pMod = kwLdrModuleTryLoadDll(szPath, KWLOCATION_IMPORTER_DIR, pExe, pszSearchPath);
}
/* Application directory first. */
@@ -2493,7 +2704,7 @@ static int kwLdrModuleResolveAndLookup(const char *pszName, PKWMODULE pExe, PKWM
psz = (char *)kHlpMemPCopy(kHlpMemPCopy(szPath, pExe->pszPath, pExe->offFilename), pszName, cchName + 1);
if (fNeedSuffix)
kHlpMemCopy(psz - 1, ".dll", sizeof(".dll"));
- pMod = kwLdrModuleTryLoadDll(szPath, KWLOCATION_EXE_DIR, pExe);
+ pMod = kwLdrModuleTryLoadDll(szPath, KWLOCATION_EXE_DIR, pExe, pszSearchPath);
}
/* The windows directory. */
@@ -2507,7 +2718,44 @@ static int kwLdrModuleResolveAndLookup(const char *pszName, PKWMODULE pExe, PKWM
psz = (char *)kHlpMemPCopy(&szPath[cchDir], pszName, cchName + 1);
if (fNeedSuffix)
kHlpMemCopy(psz - 1, ".dll", sizeof(".dll"));
- pMod = kwLdrModuleTryLoadDll(szPath, KWLOCATION_SYSTEM32, pExe);
+ pMod = kwLdrModuleTryLoadDll(szPath, KWLOCATION_SYSTEM32, pExe, pszSearchPath);
+ }
+
+ /* The path. */
+ if ( pMod == NULL
+ && pszSearchPath)
+ {
+ const char *pszCur = pszSearchPath;
+ while (*pszCur != '\0')
+ {
+ /* Find the end of the component */
+ KSIZE cch = 0;
+ while (pszCur[cch] != ';' && pszCur[cch] != '\0')
+ cch++;
+
+ if ( cch > 0 /* wrong, but whatever */
+ && cch + 1 + cchName + cchSuffix < sizeof(szPath))
+ {
+ char *pszDst = kHlpMemPCopy(szPath, pszCur, cch);
+ if ( szPath[cch - 1] != ':'
+ && szPath[cch - 1] != '/'
+ && szPath[cch - 1] != '\\')
+ *pszDst++ = '\\';
+ pszDst = kHlpMemPCopy(pszDst, pszName, cchName);
+ if (fNeedSuffix)
+ pszDst = kHlpMemPCopy(pszDst, ".dll", 4);
+ *pszDst = '\0';
+
+ pMod = kwLdrModuleTryLoadDll(szPath, KWLOCATION_SYSTEM32, pExe, pszSearchPath);
+ if (pMod)
+ break;
+ }
+
+ /* Advance */
+ pszCur += cch;
+ while (*pszCur == ';')
+ pszCur++;
+ }
}
/* Return. */
@@ -2522,6 +2770,50 @@ static int kwLdrModuleResolveAndLookup(const char *pszName, PKWMODULE pExe, PKWM
/**
+ * Does the TLS memory initialization for a module on the current thread.
+ *
+ * @returns 0 on success, error on failure.
+ * @param pMod The module.
+ */
+static int kwLdrCallTlsAllocateAndInit(PKWMODULE pMod)
+{
+ if (pMod->u.Manual.idxTls != KU32_MAX)
+ {
+ PTEB pTeb = NtCurrentTeb();
+ void **ppvTls = *(void ***)( (KUPTR)pTeb + (sizeof(void *) == 4 ? 0x2c : 0x58) );
+ KU8 *pbData = (KU8 *)ppvTls[pMod->u.Manual.idxTls];
+ KWLDR_LOG(("%s: TLS: Initializing %#x (%#x), idxTls=%d\n",
+ pMod->pszPath, pbData, pMod->u.Manual.cbTlsAlloc, pMod->u.Manual.cbTlsInitData, pMod->u.Manual.idxTls));
+ if (pMod->u.Manual.cbTlsInitData < pMod->u.Manual.cbTlsAlloc)
+ kHlpMemSet(&pbData[pMod->u.Manual.cbTlsInitData], 0, pMod->u.Manual.cbTlsAlloc);
+ if (pMod->u.Manual.cbTlsInitData)
+ kHlpMemCopy(pbData, &pMod->u.Manual.pbCopy[pMod->u.Manual.offTlsInitData], pMod->u.Manual.cbTlsInitData);
+ }
+ return 0;
+}
+
+
+/**
+ * Does the TLS callbacks for a module.
+ *
+ * @param pMod The module.
+ * @param dwReason The callback reason.
+ */
+static void kwLdrCallTlsCallbacks(PKWMODULE pMod, DWORD dwReason)
+{
+ if (pMod->u.Manual.cTlsCallbacks)
+ {
+ PIMAGE_TLS_CALLBACK *pCallback = (PIMAGE_TLS_CALLBACK *)&pMod->u.Manual.pbLoad[pMod->u.Manual.offTlsCallbacks];
+ do
+ {
+ KWLDR_LOG(("%s: Calling TLS callback %p(%p,%#x,0)\n", pMod->pszPath, *pCallback, pMod->hOurMod, dwReason));
+ (*pCallback)(pMod->hOurMod, dwReason, 0);
+ } while (*++pCallback);
+ }
+}
+
+
+/**
* Does module initialization starting at @a pMod.
*
* This is initially used on the executable. Later it is used by the
@@ -2535,6 +2827,9 @@ static int kwLdrModuleInitTree(PKWMODULE pMod)
int rc = 0;
if (!pMod->fNative)
{
+ KWLDR_LOG(("kwLdrModuleInitTree: enmState=%#x idxTls=%u %s\n",
+ pMod->u.Manual.enmState, pMod->u.Manual.idxTls, pMod->pszPath));
+
/*
* Need to copy bits?
*/
@@ -2606,6 +2901,7 @@ static int kwLdrModuleInitTree(PKWMODULE pMod)
}
#endif
+
if (pMod->u.Manual.enmState == KWMODSTATE_NEEDS_INIT)
{
/*
@@ -2622,6 +2918,14 @@ static int kwLdrModuleInitTree(PKWMODULE pMod)
return rc;
}
+ /* Do TLS allocations for module init? */
+ rc = kwLdrCallTlsAllocateAndInit(pMod);
+ if (rc != 0)
+ return rc;
+ if (pMod->u.Manual.cTlsCallbacks > 0)
+ kwLdrCallTlsCallbacks(pMod, DLL_PROCESS_ATTACH);
+
+ /* Finally call the entry point. */
rc = kLdrModCallInit(pMod->pLdrMod, pMod->u.Manual.pbLoad, (KUPTR)pMod->hOurMod);
if (rc == 0)
pMod->u.Manual.enmState = KWMODSTATE_READY;
@@ -2828,8 +3132,9 @@ static int kwToolAddModuleAndImports(PKWTOOL pTool, PKWMODULE pMod)
*
* A reference is donated by the caller and must be
* released.
+ * @param pszSearchPath The PATH environment variable value, or NULL.
*/
-static PKWTOOL kwToolEntryCreate(PKFSOBJ pToolFsObj)
+static PKWTOOL kwToolEntryCreate(PKFSOBJ pToolFsObj, const char *pszSearchPath)
{
KSIZE cwcPath = pToolFsObj->cwcParent + pToolFsObj->cwcName + 1;
KSIZE cbPath = pToolFsObj->cchParent + pToolFsObj->cchName + 1;
@@ -2847,7 +3152,8 @@ static PKWTOOL kwToolEntryCreate(PKFSOBJ pToolFsObj)
kHlpAssert(fRc);
pTool->enmType = KWTOOLTYPE_SANDBOXED;
- pTool->u.Sandboxed.pExe = kwLdrModuleCreateNonNative(pTool->pszPath, kwStrHash(pTool->pszPath), K_TRUE /*fExe*/, NULL);
+ pTool->u.Sandboxed.pExe = kwLdrModuleCreateNonNative(pTool->pszPath, kwStrHash(pTool->pszPath), K_TRUE /*fExe*/,
+ NULL /*pEexeMod*/, pszSearchPath);
if (pTool->u.Sandboxed.pExe)
{
int rc = kwLdrModuleQueryMainEntrypoint(pTool->u.Sandboxed.pExe, &pTool->u.Sandboxed.uMainAddr);
@@ -2884,20 +3190,32 @@ static PKWTOOL kwToolEntryCreate(PKFSOBJ pToolFsObj)
/**
* Looks up the given tool, creating a new tool table entry if necessary.
*
- * @returns Pointer to the tool entry. NULL on failure.
+ * @returns Pointer to the tool entry. NULL on failure (fully bitched).
* @param pszExe The executable for the tool (not normalized).
+ * @param cEnvVars Number of environment varibles.
+ * @param papszEnvVars Environment variables. For getting the PATH.
*/
-static PKWTOOL kwToolLookup(const char *pszExe)
+static PKWTOOL kwToolLookup(const char *pszExe, KU32 cEnvVars, const char **papszEnvVars)
{
/*
* We associate the tools instances with the file system objects.
+ *
+ * We'd like to do the lookup without invaliding the volatile parts of the
+ * cache, thus the double lookup here. The cache gets invalidate later on.
*/
KFSLOOKUPERROR enmError;
PKFSOBJ pToolFsObj = kFsCacheLookupA(g_pFsCache, pszExe, &enmError);
+ if ( !pToolFsObj
+ || pToolFsObj->bObjType != KFSOBJ_TYPE_FILE)
+ {
+ kFsCacheInvalidateCustomBoth(g_pFsCache);
+ pToolFsObj = kFsCacheLookupA(g_pFsCache, pszExe, &enmError);
+ }
if (pToolFsObj)
{
if (pToolFsObj->bObjType == KFSOBJ_TYPE_FILE)
{
+ const char *pszSearchPath;
PKWTOOL pTool = (PKWTOOL)kFsCacheObjGetUserData(g_pFsCache, pToolFsObj, KW_DATA_KEY_TOOL);
if (pTool)
{
@@ -2908,10 +3226,30 @@ static PKWTOOL kwToolLookup(const char *pszExe)
/*
* Need to create a new tool.
*/
- return kwToolEntryCreate(pToolFsObj);
+ pszSearchPath = NULL;
+ while (cEnvVars-- > 0)
+ if (_strnicmp(papszEnvVars[cEnvVars], "PATH=", 5) == 0)
+ {
+ pszSearchPath = &papszEnvVars[cEnvVars][5];
+ break;
+ }
+
+ pTool = kwToolEntryCreate(pToolFsObj, pszSearchPath);
+ if (pTool)
+ return pTool;
+
+ kwErrPrintf("kwToolLookup(%s) -> NULL: kwToolEntryCreate failed\n", pszExe);
+ }
+ else
+ {
+ kFsCacheObjRelease(g_pFsCache, pToolFsObj);
+ kwErrPrintf("kwToolLookup(%s) -> NULL: not file (bObjType=%d fFlags=%#x uCacheGen=%u auGenerationsMissing=[%u,%u])\n",
+ pszExe, pToolFsObj->bObjType, pToolFsObj->fFlags, pToolFsObj->uCacheGen,
+ g_pFsCache->auGenerationsMissing[0], g_pFsCache->auGenerationsMissing[1]);
}
- kFsCacheObjRelease(g_pFsCache, pToolFsObj);
}
+ else
+ kwErrPrintf("kwToolLookup(%s) -> NULL: enmError=%d\n", pszExe, enmError);
return NULL;
}
@@ -3473,6 +3811,42 @@ static uintptr_t __cdecl kwSandbox_msvcrt__beginthread(void (__cdecl *pfnThreadP
}
+/** _beginthreadex - create a new thread, msvcr120.dll hack for c2.dll. */
+static uintptr_t __cdecl kwSandbox_msvcr120__beginthreadex(void *pvSecAttr, unsigned cbStack,
+ unsigned (__stdcall *pfnThreadProc)(void *), void *pvUser,
+ unsigned fCreate, unsigned *pidThread)
+{
+ /*
+ * The VC++ 12 (VS 2013) compiler pass two is now threaded. Let it do
+ * whatever it needs to.
+ */
+ KW_LOG(("kwSandbox_msvcr120__beginthreadex: pvSecAttr=%p (inh=%d) cbStack=%#x pfnThreadProc=%p pvUser=%p fCreate=%#x pidThread=%p\n",
+ pvSecAttr, pvSecAttr ? ((LPSECURITY_ATTRIBUTES)pvSecAttr)->bInheritHandle : 0, cbStack,
+ pfnThreadProc, pvUser, fCreate, pidThread));
+ if (g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL)
+ {
+ uintptr_t rcRet;
+ static uintptr_t (__cdecl *s_pfnReal)(void *, unsigned , unsigned (__stdcall *)(void *), void *, unsigned , unsigned *);
+ if (!s_pfnReal)
+ {
+ *(FARPROC *)&s_pfnReal = GetProcAddress(GetModuleHandleA("msvcr120.dll"), "_beginthreadex");
+ if (!s_pfnReal)
+ {
+ kwErrPrintf("kwSandbox_msvcr120__beginthreadex: Failed to resolve _beginthreadex in msvcr120.dll!\n");
+ __debugbreak();
+ }
+ }
+ rcRet = s_pfnReal(pvSecAttr, cbStack, pfnThreadProc, pvUser, fCreate, pidThread);
+ KW_LOG(("kwSandbox_msvcr120__beginthreadex: returns %p *pidThread=%#x\n", rcRet, pidThread ? *pidThread : -1));
+ return rcRet;
+ }
+
+ kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
+ KWFS_TODO();
+ return 0;
+}
+
+
/** _beginthreadex - create a new thread. */
static uintptr_t __cdecl kwSandbox_msvcrt__beginthreadex(void *pvSecAttr, unsigned cbStack,
unsigned (__stdcall *pfnThreadProc)(void *), void *pvUser,
@@ -4331,6 +4705,7 @@ static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA_VirtualApiModule(PKWDYNL
static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA(LPCSTR pszFilename, HANDLE hFile, DWORD fFlags)
{
KSIZE cchFilename = kHlpStrLen(pszFilename);
+ const char *pszSearchPath;
PKWDYNLOAD pDynLoad;
PKWMODULE pMod;
int rc;
@@ -4339,7 +4714,8 @@ static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA(LPCSTR pszFilename, HAND
/*
* Deal with a couple of extremely unlikely special cases right away.
*/
- if ( !(fFlags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)
+ if ( ( !(fFlags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)
+ || (fFlags & LOAD_LIBRARY_AS_IMAGE_RESOURCE))
&& (hFile == NULL || hFile == INVALID_HANDLE_VALUE) )
{ /* likely */ }
else
@@ -4389,6 +4765,7 @@ static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA(LPCSTR pszFilename, HAND
*/
if (fFlags & ( DONT_RESOLVE_DLL_REFERENCES
| LOAD_LIBRARY_AS_DATAFILE
+ | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
| LOAD_LIBRARY_AS_IMAGE_RESOURCE) )
return kwSandbox_Kernel32_LoadLibraryExA_Resource(pDynLoad, fFlags);
@@ -4403,15 +4780,16 @@ static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA(LPCSTR pszFilename, HAND
* Normal library loading.
* We start by being very lazy and reusing the code for resolving imports.
*/
+ pszSearchPath = kwSandboxDoGetEnvA(&g_Sandbox, "PATH", 4);
if (!kHlpIsFilenameOnly(pszFilename))
- pMod = kwLdrModuleTryLoadDll(pszFilename, KWLOCATION_UNKNOWN, g_Sandbox.pTool->u.Sandboxed.pExe);
+ pMod = kwLdrModuleTryLoadDll(pszFilename, KWLOCATION_UNKNOWN, g_Sandbox.pTool->u.Sandboxed.pExe, pszSearchPath);
else
{
- rc = kwLdrModuleResolveAndLookup(pszFilename, g_Sandbox.pTool->u.Sandboxed.pExe, NULL /*pImporter*/, &pMod);
+ rc = kwLdrModuleResolveAndLookup(pszFilename, g_Sandbox.pTool->u.Sandboxed.pExe, NULL /*pImporter*/, pszSearchPath, &pMod);
if (rc != 0)
pMod = NULL;
}
- if (pMod)
+ if (pMod && pMod != (PKWMODULE)~(KUPTR)0)
{
/* Enter it into the tool module table and dynamic link request cache. */
kwToolAddModuleAndImports(g_Sandbox.pTool, pMod);
@@ -4439,12 +4817,81 @@ static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA(LPCSTR pszFilename, HAND
{
KWFS_TODO();
kHlpFree(pDynLoad);
- SetLastError(ERROR_MOD_NOT_FOUND);
+ SetLastError(pMod ? ERROR_BAD_EXE_FORMAT : ERROR_MOD_NOT_FOUND);
}
return NULL;
}
+/** Kernel32 - LoadLibraryExA() for native overloads */
+static HMODULE WINAPI kwSandbox_Kernel32_Native_LoadLibraryExA(LPCSTR pszFilename, HANDLE hFile, DWORD fFlags)
+{
+ char szPath[1024];
+ KWLDR_LOG(("kwSandbox_Kernel32_Native_LoadLibraryExA(%s, %p, %#x)\n", pszFilename, hFile, fFlags));
+
+ /*
+ * We may have to help resolved unqualified DLLs living in the executable directory.
+ */
+ if (kHlpIsFilenameOnly(pszFilename))
+ {
+ KSIZE cchFilename = kHlpStrLen(pszFilename);
+ KSIZE cchExePath = g_Sandbox.pTool->u.Sandboxed.pExe->offFilename;
+ if (cchExePath + cchFilename + 1 <= sizeof(szPath))
+ {
+ kHlpMemCopy(szPath, g_Sandbox.pTool->u.Sandboxed.pExe->pszPath, cchExePath);
+ kHlpMemCopy(&szPath[cchExePath], pszFilename, cchFilename + 1);
+ if (kwFsPathExists(szPath))
+ {
+ KWLDR_LOG(("kwSandbox_Kernel32_Native_LoadLibraryExA: %s -> %s\n", pszFilename, szPath));
+ pszFilename = szPath;
+ }
+ }
+
+ if (pszFilename != szPath)
+ {
+ KSIZE cchSuffix = 0;
+ KBOOL fNeedSuffix = K_FALSE;
+ const char *pszCur = kwSandboxDoGetEnvA(&g_Sandbox, "PATH", 4);
+ while (*pszCur != '\0')
+ {
+ /* Find the end of the component */
+ KSIZE cch = 0;
+ while (pszCur[cch] != ';' && pszCur[cch] != '\0')
+ cch++;
+
+ if ( cch > 0 /* wrong, but whatever */
+ && cch + 1 + cchFilename + cchSuffix < sizeof(szPath))
+ {
+ char *pszDst = kHlpMemPCopy(szPath, pszCur, cch);
+ if ( szPath[cch - 1] != ':'
+ && szPath[cch - 1] != '/'
+ && szPath[cch - 1] != '\\')
+ *pszDst++ = '\\';
+ pszDst = kHlpMemPCopy(pszDst, pszFilename, cchFilename);
+ if (fNeedSuffix)
+ pszDst = kHlpMemPCopy(pszDst, ".dll", 4);
+ *pszDst = '\0';
+
+ if (kwFsPathExists(szPath))
+ {
+ KWLDR_LOG(("kwSandbox_Kernel32_Native_LoadLibraryExA: %s -> %s\n", pszFilename, szPath));
+ pszFilename = szPath;
+ break;
+ }
+ }
+
+ /* Advance */
+ pszCur += cch;
+ while (*pszCur == ';')
+ pszCur++;
+ }
+ }
+ }
+
+ return LoadLibraryExA(pszFilename, hFile, fFlags);
+}
+
+
/** Kernel32 - LoadLibraryExW() */
static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExW(LPCWSTR pwszFilename, HANDLE hFile, DWORD fFlags)
{
@@ -4492,6 +4939,7 @@ static HMODULE WINAPI kwSandbox_Kernel32_GetModuleHandleA(LPCSTR pszModule)
{
KSIZE i;
KSIZE cchModule;
+ PKWDYNLOAD pDynLoad;
kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
/*
@@ -4513,7 +4961,27 @@ static HMODULE WINAPI kwSandbox_Kernel32_GetModuleHandleA(LPCSTR pszModule)
return g_aGetModuleHandleCache[i].hmod = GetModuleHandleA(pszModule);
}
+ /*
+ * Modules we've dynamically loaded.
+ */
+ for (pDynLoad = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; pDynLoad; pDynLoad = pDynLoad->pNext)
+ if ( pDynLoad->pMod
+ && ( stricmp(pDynLoad->pMod->pszPath, pszModule) == 0
+ || stricmp(&pDynLoad->pMod->pszPath[pDynLoad->pMod->offFilename], pszModule) == 0) )
+ {
+ if ( pDynLoad->pMod->fNative
+ || pDynLoad->pMod->u.Manual.enmState == KWMODSTATE_READY)
+ {
+ KW_LOG(("kwSandbox_Kernel32_GetModuleHandleA(%s,,) -> %p [dynload]\n", pszModule, pDynLoad->hmod));
+ return pDynLoad->hmod;
+ }
+ SetLastError(ERROR_MOD_NOT_FOUND);
+ return NULL;
+ }
+
+ kwErrPrintf("pszModule=%s\n", pszModule);
KWFS_TODO();
+ SetLastError(ERROR_MOD_NOT_FOUND);
return NULL;
}
@@ -4523,6 +4991,7 @@ static HMODULE WINAPI kwSandbox_Kernel32_GetModuleHandleW(LPCWSTR pwszModule)
{
KSIZE i;
KSIZE cwcModule;
+ PKWDYNLOAD pDynLoad;
kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
/*
@@ -4544,7 +5013,27 @@ static HMODULE WINAPI kwSandbox_Kernel32_GetModuleHandleW(LPCWSTR pwszModule)
return g_aGetModuleHandleCache[i].hmod = GetModuleHandleW(pwszModule);
}
+ /*
+ * Modules we've dynamically loaded.
+ */
+ for (pDynLoad = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; pDynLoad; pDynLoad = pDynLoad->pNext)
+ if ( pDynLoad->pMod
+ && ( _wcsicmp(pDynLoad->pMod->pwszPath, pwszModule) == 0
+ || _wcsicmp(&pDynLoad->pMod->pwszPath[pDynLoad->pMod->offFilename], pwszModule) == 0) ) /** @todo wrong offset */
+ {
+ if ( pDynLoad->pMod->fNative
+ || pDynLoad->pMod->u.Manual.enmState == KWMODSTATE_READY)
+ {
+ KW_LOG(("kwSandbox_Kernel32_GetModuleHandleW(%ls,,) -> %p [dynload]\n", pwszModule, pDynLoad->hmod));
+ return pDynLoad->hmod;
+ }
+ SetLastError(ERROR_MOD_NOT_FOUND);
+ return NULL;
+ }
+
+ kwErrPrintf("pwszModule=%ls\n", pwszModule);
KWFS_TODO();
+ SetLastError(ERROR_MOD_NOT_FOUND);
return NULL;
}
@@ -8759,6 +9248,17 @@ static void * __cdecl kwSandbox_msvcrt_memcpy(void *pvDst, void const *pvSrc, si
return pvDst;
}
+
+/** CRT - memset */
+static void * __cdecl kwSandbox_msvcrt_memset(void *pvDst, int bFiller, size_t cb)
+{
+ KU8 *pbDst = (KU8 *)pvDst;
+ KSIZE cbLeft = cb;
+ while (cbLeft-- > 0)
+ *pbDst++ = bFiller;
+ return pvDst;
+}
+
#endif /* NDEBUG */
@@ -8881,6 +9381,7 @@ KWREPLACEMENTFUNCTION const g_aSandboxReplacements[] =
{ TUPLE("_beginthread"), NULL, (KUPTR)kwSandbox_msvcrt__beginthread },
{ TUPLE("_beginthreadex"), NULL, (KUPTR)kwSandbox_msvcrt__beginthreadex },
+ { TUPLE("_beginthreadex"), "msvcr120.dll", (KUPTR)kwSandbox_msvcr120__beginthreadex }, /* higher priority last */
{ TUPLE("__argc"), NULL, (KUPTR)&g_Sandbox.cArgs },
{ TUPLE("__argv"), NULL, (KUPTR)&g_Sandbox.papszArgs },
@@ -8920,6 +9421,7 @@ KWREPLACEMENTFUNCTION const g_aSandboxReplacements[] =
#ifndef NDEBUG
{ TUPLE("memcpy"), NULL, (KUPTR)kwSandbox_msvcrt_memcpy },
+ { TUPLE("memset"), NULL, (KUPTR)kwSandbox_msvcrt_memset },
#endif
};
/** Number of entries in g_aReplacements. */
@@ -8969,6 +9471,7 @@ KWREPLACEMENTFUNCTION const g_aSandboxNativeReplacements[] =
{ TUPLE("DeleteFileW"), NULL, (KUPTR)kwSandbox_Kernel32_DeleteFileW },
#endif
{ TUPLE("SetConsoleCtrlHandler"), NULL, (KUPTR)kwSandbox_Kernel32_SetConsoleCtrlHandler },
+ { TUPLE("LoadLibraryExA"), NULL, (KUPTR)kwSandbox_Kernel32_Native_LoadLibraryExA },
{ TUPLE("WriteConsoleA"), NULL, (KUPTR)kwSandbox_Kernel32_WriteConsoleA },
{ TUPLE("WriteConsoleW"), NULL, (KUPTR)kwSandbox_Kernel32_WriteConsoleW },
@@ -9280,8 +9783,9 @@ static int kwSandboxInit(PKWSANDBOX pSandbox, PKWTOOL pTool,
{
const char *pszVar = papszEnvVars[i];
KSIZE cchVar = kHlpStrLen(pszVar);
+ const char *pszEqual;
if ( cchVar > 0
- && kHlpMemChr(pszVar, '=', cchVar) != NULL)
+ && (pszEqual = kHlpMemChr(pszVar, '=', cchVar)) != NULL)
{
char *pszCopy = kHlpDup(pszVar, cchVar + 1);
wchar_t *pwszCopy = kwStrToUtf16AllocN(pszVar, cchVar + 1);
@@ -9291,6 +9795,16 @@ static int kwSandboxInit(PKWSANDBOX pSandbox, PKWTOOL pTool,
pSandbox->environ[iDst] = pszCopy;
pSandbox->papwszEnvVars[iDst] = pwszCopy;
pSandbox->wenviron[iDst] = pwszCopy;
+
+ /* When we see the path, we must tell the system or native exec and module loading won't work . */
+ if ( (pszEqual - pszVar) == 4
+ && ( pszCopy[0] == 'P' || pszCopy[0] == 'p')
+ && ( pszCopy[1] == 'A' || pszCopy[1] == 'a')
+ && ( pszCopy[2] == 'T' || pszCopy[2] == 't')
+ && ( pszCopy[3] == 'H' || pszCopy[3] == 'h'))
+ if (!SetEnvironmentVariableW(L"Path", &pwszCopy[5]))
+ kwErrPrintf("kwSandboxInit: SetEnvironmentVariableW(Path,) failed: %u\n", GetLastError());
+
iDst++;
}
else
@@ -9311,7 +9825,6 @@ static int kwSandboxInit(PKWSANDBOX pSandbox, PKWTOOL pTool,
else
return kwErrPrintfRc(KERR_NO_MEMORY, "Error setting up environment variables: kwSandboxGrowEnv failed\n");
-
/*
* Invalidate the volatile parts of cache (kBuild output directory,
* temporary directory, whatever).
@@ -9821,7 +10334,7 @@ static int kSubmitHandleJobUnpacked(const char *pszExecutable, const char *pszCw
/*
* Lookup the tool.
*/
- pTool = kwToolLookup(pszExecutable);
+ pTool = kwToolLookup(pszExecutable, cEnvVars, papszEnvVars);
if (pTool)
{
/*
@@ -10620,11 +11133,44 @@ int main(int argc, char **argv)
}
else if (strcmp(argv[i], "--test") == 0)
return kwTestRun(argc - i - 1, &argv[i + 1]);
+ else if (strcmp(argv[i], "--priority") == 0)
+ {
+ i++;
+ if (i < argc)
+ {
+ char *pszEnd = NULL;
+ unsigned long uValue = strtoul(argv[i], &pszEnd, 16);
+ if ( *argv[i]
+ && pszEnd != NULL
+ && *pszEnd == '\0'
+ && uValue >= 1
+ && uValue <= 5)
+ {
+ DWORD dwClass, dwPriority;
+ switch (uValue)
+ {
+ case 1: dwClass = IDLE_PRIORITY_CLASS; dwPriority = THREAD_PRIORITY_IDLE; break;
+ case 2: dwClass = BELOW_NORMAL_PRIORITY_CLASS; dwPriority = THREAD_PRIORITY_BELOW_NORMAL; break;
+ case 3: dwClass = NORMAL_PRIORITY_CLASS; dwPriority = THREAD_PRIORITY_NORMAL; break;
+ case 4: dwClass = HIGH_PRIORITY_CLASS; dwPriority = 0xffffffff; break;
+ case 5: dwClass = REALTIME_PRIORITY_CLASS; dwPriority = 0xffffffff; break;
+ }
+ SetPriorityClass(GetCurrentProcess(), dwClass);
+ if (dwPriority != 0xffffffff)
+ SetThreadPriority(GetCurrentThread(), dwPriority);
+ }
+ else
+ return kwErrPrintfRc(2, "Invalid --priority argument: %s\n", argv[i]);
+ }
+ else
+ return kwErrPrintfRc(2, "--priority takes an argument!\n");
+
+ }
else if ( strcmp(argv[i], "--help") == 0
|| strcmp(argv[i], "-h") == 0
|| strcmp(argv[i], "-?") == 0)
{
- printf("usage: kWorker [--volatile dir] --pipe <pipe-handle>\n"
+ printf("usage: kWorker [--volatile dir] [--priority <1-5>] --pipe <pipe-handle>\n"
"usage: kWorker <--help|-h>\n"
"usage: kWorker <--version|-V>\n"
"usage: kWorker [--volatile dir] --test [<times> [--chdir <dir>] [--breakpoint] -- args\n"
diff --git a/src/kWorker/kWorkerTlsXxxK.c b/src/kWorker/kWorkerTlsXxxK.c
new file mode 100644
index 0000000..6bd9e47
--- /dev/null
+++ b/src/kWorker/kWorkerTlsXxxK.c
@@ -0,0 +1,110 @@
+/* $Id: kWorkerTlsXxxK.c 3042 2017-05-11 10:23:12Z bird $ */
+/** @file
+ * kWorkerTlsXxxK - Loader TLS allocation hack DLL.
+ */
+
+/*
+ * Copyright (c) 2017 knut st. osmundsen <bird-kBuild-spamx at anduin.net>
+ *
+ * This file is part of kBuild.
+ *
+ * kBuild is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * kBuild is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with kBuild. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <windows.h>
+
+
+/*********************************************************************************************************************************
+* Structures and Typedefs *
+*********************************************************************************************************************************/
+typedef void KWLDRTLSALLOCATIONHOOK(void *hDll, ULONG idxTls, PIMAGE_TLS_CALLBACK *ppfnTlsCallback);
+
+
+/*********************************************************************************************************************************
+* Internal Functions *
+*********************************************************************************************************************************/
+__declspec(dllexport) void __stdcall DummyTlsCallback(void *hDll, DWORD dwReason, void *pvContext);
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+/** The TLS pointer array. The 2nd entry is NULL and serve to terminate the array.
+ * The first entry can be used by kWorker if it needs to. */
+__declspec(dllexport) PIMAGE_TLS_CALLBACK g_apfnTlsCallbacks[2] = { DummyTlsCallback, NULL };
+
+/**
+ * The TLS index.
+ */
+__declspec(dllexport) ULONG g_idxTls = ~(ULONG)0;
+
+/**
+ * Initialization data.
+ */
+static char const g_abDummy[TLS_SIZE] = {0x42};
+
+/**
+ * The TLS directory entry. Not possible to get more than one from the linker
+ * and probably also the loader doesn't want more than one anyway.
+ */
+#pragma section(".rdata$T", long, read)
+__declspec(allocate(".rdata$T")) const IMAGE_TLS_DIRECTORY _tls_used =
+{
+ (ULONG_PTR)&g_abDummy,
+ (ULONG_PTR)&g_abDummy + sizeof(g_abDummy),
+ (ULONG_PTR)&g_idxTls,
+ (ULONG_PTR)&g_apfnTlsCallbacks,
+ 0, /* This SizeOfZeroFill bugger doesn't work on w10/amd64 from what I can tell! */
+ IMAGE_SCN_ALIGN_32BYTES
+};
+
+
+/*
+ * This is just a dummy TLS callback function.
+ * We'll be replacing g_apfnTlsCallbacks[0] from kWorker.c after loading it.
+ *
+ * Note! W10 doesn't seem to want to process the TLS directory if the DLL
+ * doesn't have any imports (to snap).
+ */
+__declspec(dllexport) void __stdcall DummyTlsCallback(void *hDll, DWORD dwReason, void *pvContext)
+{
+ (void)hDll; (void)dwReason; (void)pvContext;
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ HMODULE hModExe = (HMODULE)(ULONG_PTR)KWORKER_BASE;
+ KWLDRTLSALLOCATIONHOOK *pfnHook = (KWLDRTLSALLOCATIONHOOK *)GetProcAddress(hModExe, "kwLdrTlsAllocationHook");
+ if (pfnHook)
+ {
+ pfnHook(hDll, g_idxTls, &g_apfnTlsCallbacks[0]);
+ return;
+ }
+ __debugbreak();
+ }
+}
+
+
+/*
+ * Dummy DLL entry point to avoid dragging in unnecessary CRT stuff. kWorkerTls1K!_tls_index
+ */
+BOOL __stdcall DummyDllEntry(void *hDll, DWORD dwReason, void *pvContext)
+{
+ (void)hDll; (void)dwReason; (void)pvContext;
+ return TRUE;
+}
+
diff --git a/src/kash/Makefile.kmk b/src/kash/Makefile.kmk
index f378c8e..63f068b 100644
--- a/src/kash/Makefile.kmk
+++ b/src/kash/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk 2652 2012-09-09 17:21:48Z bird $
+# $Id: Makefile.kmk 3073 2017-10-02 08:45:19Z bird $
## @file
# Sub-makefile for kash.
#
@@ -52,6 +52,9 @@ kash_DEFS.dragonfly = \
HAVE_SYS_SIGNAME HAVE_SYSCTL_H HAVE_SETPROGNAME
kash_DEFS.freebsd = \
HAVE_SYS_SIGNAME HAVE_SYSCTL_H HAVE_SETPROGNAME
+kash_DEFS.gnukfbsd = HAVE_SYSCTL_H
+kash_DEFS.netbsd = \
+ HAVE_SYS_SIGNAME HAVE_SYSCTL_H HAVE_SETPROGNAME
kash_DEFS.openbsd = \
HAVE_SYS_SIGNAME HAVE_SYSCTL_H HAVE_SETPROGNAME
kash_INCS = $(kash_0_OUTDIR) . # (the last is because of error.h)
@@ -99,6 +102,12 @@ kash_SOURCES = \
shheap.c \
shthread.c \
shfile.c
+kash_SOURCES.gnukfbsd = \
+ sys_signame.c \
+ strlcpy.c
+kash_SOURCES.gnuknbsd = \
+ sys_signame.c \
+ strlcpy.c
kash_SOURCES.haiku = \
sys_signame.c \
strlcpy.c
@@ -107,7 +116,7 @@ kash_SOURCES.linux = \
strlcpy.c
kash_SOURCES.solaris = \
sys_signame.c \
- strlcpy.c
+ strlcpy.c
kash_SOURCES.win = \
sys_signame.c \
strlcpy.c \
@@ -135,6 +144,10 @@ kash_main.c_DEFS = KBUILD_SVN_REV=$(KBUILD_SVN_REV)
if1of ($(KBUILD_TARGET), win os2)
+ KASH_USE_PREGENERATED_CODE = 1
+endif
+
+ifdef KASH_USE_PREGENERATED_CODE
#
# Use the pregenerated code.
@@ -154,7 +167,7 @@ endef
$(foreach src, arith.h arith.c arith_lex.c builtins.h builtins.c nodes.h nodes.c token.h init.c,\
$(eval $(def_copy_generated)))
-else
+else # !KASH_USE_PREGENERATED_CODE
#
# Generate the code on the fly.
@@ -208,7 +221,7 @@ $$(kash_0_OUTDIR)/init.c: \
$(BOOTSTRAP_SHELL) $+
$(MV) init.c $@
-endif
+endif # !KASH_USE_PREGENERATED_CODE
#
# For debugging file handle inheritance on Windows.
diff --git a/src/kash/eval.c b/src/kash/eval.c
index d96c2a3..78ae637 100644
--- a/src/kash/eval.c
+++ b/src/kash/eval.c
@@ -678,7 +678,7 @@ evalcommand(shinstance *psh, union node *cmd, int flags, struct backcmd *backcmd
char **envp;
int numvars;
struct strlist *sp;
- int mode;
+ int mode = 0;
int pip[2];
struct cmdentry cmdentry;
struct job *jp;
@@ -692,11 +692,13 @@ evalcommand(shinstance *psh, union node *cmd, int flags, struct backcmd *backcmd
const char *path = pathval(psh);
volatile int temp_path;
#if __GNUC__
- /* Avoid longjmp clobbering */
+ /* Try avoid longjmp clobbering */
(void) &argv;
(void) &argc;
(void) &lastarg;
(void) &flags;
+ (void) &path;
+ (void) &mode;
#endif
psh->vforked = 0;
diff --git a/src/kash/exec.c b/src/kash/exec.c
index d76bf2a..9fa8b32 100644
--- a/src/kash/exec.c
+++ b/src/kash/exec.c
@@ -121,32 +121,48 @@ shellexec(shinstance *psh, char **argv, char **envp, const char *path, int idx,
{
char *cmdname;
int e;
+ const char *argv0 = argv[0];
+ int argv0len = (int)strlen(argv0);
+ char kmkcmd[48];
#ifdef PC_EXE_EXTS
- int has_ext = (int)strlen(argv[0]) - 4;
+ int has_ext = argv0len - 4;
has_ext = has_ext > 0
- && argv[0][has_ext] == '.'
+ && argv0[has_ext] == '.'
/* use strstr and upper/lower permuated extensions to avoid multiple strcasecmp calls. */
&& strstr("exe;" "Exe;" "EXe;" "EXE;" "ExE;" "eXe;" "eXE;" "exE;"
"cmd;" "Cmd;" "CMd;" "CMD;" "CmD;" "cMd;" "cMD;" "cmD;"
"com;" "Com;" "COm;" "COM;" "CoM;" "cOm;" "cOM;" "coM;"
"bat;" "Bat;" "BAt;" "BAT;" "BaT;" "bAt;" "bAT;" "baT;"
"btm;" "Btm;" "BTm;" "BTM;" "BtM;" "bTm;" "bTM;" "btM;",
- argv[0] + has_ext + 1)
+ argv0 + has_ext + 1)
!= NULL;
#else
const int has_ext = 1;
#endif
- TRACE((psh, "shellexec: argv[0]=%s idx=%d\n", argv[0], idx));
- if (strchr(argv[0], '/') != NULL) {
- cmdname = stalloc(psh, strlen(argv[0]) + 5);
- strcpy(cmdname, argv[0]);
+ TRACE((psh, "shellexec: argv[0]=%s idx=%d\n", argv0, idx));
+ if (strchr(argv0, '/') != NULL) {
+ cmdname = stalloc(psh, argv0len + 5);
+ strcpy(cmdname, argv0);
tryexec(psh, cmdname, argv, envp, vforked, has_ext);
TRACE((psh, "shellexec: cmdname=%s\n", cmdname));
stunalloc(psh, cmdname);
e = errno;
} else {
+ /* Before we search the PATH, transform kmk_builtin_% to kmk_% so we don't
+ need to be too careful mixing internal and external kmk command. */
+ if ( argv0len > 12
+ && argv0len < 42
+ && strncmp(argv0, "kmk_builtin_", 12) == 0
+ && strpbrk(argv0 + 12, "./\\-:;<>") == NULL) {
+ memcpy(kmkcmd, "kmk_", 4);
+ memcpy(&kmkcmd[4], argv0 + 12, argv0len + 1 - 8);
+ TRACE((psh, "shellexec: dropped '_builtin' from %s to %s\n", argv0, kmkcmd));
+ argv0len -= 8;
+ argv0 = kmkcmd;
+ }
+
e = ENOENT;
- while ((cmdname = padvance(psh, &path, argv[0])) != NULL) {
+ while ((cmdname = padvance(psh, &path, argv0)) != NULL) {
if (--idx < 0 && psh->pathopt == NULL) {
tryexec(psh, cmdname, argv, envp, vforked, has_ext);
if (errno != ENOENT && errno != ENOTDIR)
@@ -552,9 +568,10 @@ find_command(shinstance *psh, char *name, struct cmdentry *entry, int act, const
struct stat statb;
int e;
int (*bltin)(shinstance*,int,char **);
-
+ int argv0len = (int)strlen(name);
+ char kmkcmd[48];
#ifdef PC_EXE_EXTS
- int has_ext = (int)(strlen(name) - 4);
+ int has_ext = argv0len - 4;
has_ext = has_ext > 0
&& name[has_ext] == '.'
/* use strstr and upper/lower permuated extensions to avoid multiple strcasecmp calls. */
@@ -639,6 +656,19 @@ find_command(shinstance *psh, char *name, struct cmdentry *entry, int act, const
prev = cmdp->param.index;
}
+ /* Before we search the PATH, transform kmk_builtin_% to kmk_% so we don't
+ need to be too careful mixing internal and external kmk command. */
+ if ( argv0len > 12
+ && argv0len < (int)sizeof(kmkcmd)
+ && strncmp(name, "kmk_builtin_", 12) == 0
+ && strpbrk(name + 12, "./\\-:;<>") == NULL) {
+ memcpy(kmkcmd, "kmk_", 4);
+ memcpy(&kmkcmd[4], name + 12, argv0len + 1 - 8);
+ TRACE((psh, "find_command: dropped '_builtin' from %s to %s\n", name, kmkcmd));
+ argv0len -= 8;
+ name = kmkcmd;
+ }
+
e = ENOENT;
idx = -1;
loop:
diff --git a/src/kash/input.c b/src/kash/input.c
index c3036fa..35ba917 100644
--- a/src/kash/input.c
+++ b/src/kash/input.c
@@ -280,7 +280,9 @@ preadbuffer(shinstance *psh)
{
char *p, *q;
int more;
+#ifndef SMALL
int something;
+#endif
char savec;
if (psh->parsefile->strpush) {
@@ -304,7 +306,9 @@ again:
q = p = psh->parsenextc;
/* delete nul characters */
+#ifndef SMALL
something = 0;
+#endif
for (more = 1; more;) {
switch (*p) {
case '\0':
@@ -321,7 +325,9 @@ again:
break;
default:
+#ifndef SMALL
something = 1;
+#endif
break;
}
diff --git a/src/kash/mystring.h b/src/kash/mystring.h
index 78a0cfb..cc9662d 100644
--- a/src/kash/mystring.h
+++ b/src/kash/mystring.h
@@ -44,7 +44,7 @@ void scopyn(const char *, char *, ssize_t);
int prefix(const char *, const char *);
int number(struct shinstance *, const char *);
int is_number(const char *);
-#ifdef _MSC_VER
+#if !defined(RT_OS_FREEBSD) && !defined(RT_OS_NETBSD) && !defined(RT_OS_OPENBSD) && !defined(RT_OS_OS2)
size_t strlcpy(char *dst, const char *src, size_t siz);
#endif
diff --git a/src/kash/parser.c b/src/kash/parser.c
index b0dbad7..2eea32e 100644
--- a/src/kash/parser.c
+++ b/src/kash/parser.c
@@ -913,7 +913,7 @@ readtoken1(shinstance *psh, int firstc, char const *syntax, char *eofmark, int s
int len;
char line[EOFMARKLEN + 1];
struct nodelist *bqlist;
- int quotef;
+ int quotef = 0;
int *dblquotep = NULL;
size_t maxnest = 32;
int dblquote;
@@ -922,8 +922,20 @@ readtoken1(shinstance *psh, int firstc, char const *syntax, char *eofmark, int s
int parenlevel; /* levels of parens in arithmetic */
int oldstyle;
char const *prevsyntax; /* syntax before arithmetic */
+
+ psh->startlinno = psh->plinno;
+ dblquote = 0;
+ varnest = 0;
+ if (syntax == DQSYNTAX) {
+ SETDBLQUOTE();
+ }
+ quotef = 0;
+ bqlist = NULL;
+ arinest = 0;
+ parenlevel = 0;
+
#if __GNUC__
- /* Avoid longjmp clobbering */
+ /* Try avoid longjmp clobbering */
(void) &maxnest;
(void) &dblquotep;
(void) &out;
@@ -937,17 +949,6 @@ readtoken1(shinstance *psh, int firstc, char const *syntax, char *eofmark, int s
(void) &syntax;
#endif
- psh->startlinno = psh->plinno;
- dblquote = 0;
- varnest = 0;
- if (syntax == DQSYNTAX) {
- SETDBLQUOTE();
- }
- quotef = 0;
- bqlist = NULL;
- arinest = 0;
- parenlevel = 0;
-
STARTSTACKSTR(psh, out);
loop: { /* for each line, until end of word */
#if ATTY
diff --git a/src/kash/shell.h b/src/kash/shell.h
index 9294204..53c652b 100644
--- a/src/kash/shell.h
+++ b/src/kash/shell.h
@@ -61,11 +61,13 @@
# define BSD 1
#endif
+#if 0
#ifndef DO_SHAREDVFORK
# if __NetBSD_Version__ >= 104000000
# define DO_SHAREDVFORK
# endif
#endif
+#endif
typedef void *pointer;
#ifndef NULL
diff --git a/src/kmk/Makefile.am b/src/kmk/Makefile.am
index 99a9a6a..bad8c4a 100644
--- a/src/kmk/Makefile.am
+++ b/src/kmk/Makefile.am
@@ -56,6 +56,8 @@ kmk_SOURCES = ar.c arscan.c commands.c default.c dir.c expand.c file.c \
electric.c \
../lib/md5.c \
../lib/kDep.c \
+ ../lib/kbuild_version.c \
+ ../lib/maybe_con_fwrite.c \
\
kmkbuiltin.c \
kmkbuiltin/append.c \
@@ -75,10 +77,13 @@ kmk_SOURCES = ar.c arscan.c commands.c default.c dir.c expand.c file.c \
kmkbuiltin/mkdir.c \
kmkbuiltin/mv.c \
kmkbuiltin/printf.c \
+ kmkbuiltin/redirect.c \
kmkbuiltin/rm.c \
kmkbuiltin/rmdir.c \
kmkbuiltin/sleep.c \
kmkbuiltin/test.c \
+ kmkbuiltin/touch.c \
+ \
kmkbuiltin/err.c \
kmkbuiltin/fts.c \
kmkbuiltin/setmode.c \
@@ -86,9 +91,14 @@ kmk_SOURCES = ar.c arscan.c commands.c default.c dir.c expand.c file.c \
kmkbuiltin/strlcpy.c \
kmkbuiltin/osdep.c \
kmkbuiltin/kbuild_protection.c \
- kmkbuiltin/kbuild_version.c
+ kmkbuiltin/common-env-and-cwd-opt.c
+
+kmk_redirect_SOURCES = kmkbuiltin/redirect.c \
+ kmkbuiltin/common-env-and-cwd-opt.c \
+ kmkbuiltin/err.c \
+ ../lib/kbuild_version.c
+kmk_redirect_CFLAGS = -UKMK
-kmk_redirect_SOURCES = kmkbuiltin/redirect.c
EXTRA_kmk_SOURCES = vmsjobs.c remote-stub.c remote-cstms.c
@@ -171,7 +181,7 @@ DEFS = \
-DCONFIG_WITH_KMK_BUILTIN \
@DEFS@
-AM_CPPFLAGS = $(GLOBINC) -I$(srcdir)/../lib
+AM_CPPFLAGS = $(GLOBINC) -I$(srcdir)/../lib -I$(srcdir)/../lib/kStuff/include
# Only process if target is MS-Windows
if WINDOWSENV
AM_CPPFLAGS += $(W32INC)
diff --git a/src/kmk/Makefile.kmk b/src/kmk/Makefile.kmk
index 25a9da6..a86e8fc 100644
--- a/src/kmk/Makefile.kmk
+++ b/src/kmk/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk 2994 2016-11-01 22:41:41Z bird $
+# $Id: Makefile.kmk 3062 2017-09-30 11:26:21Z bird $
## @file
# Sub-makefile for kmk / GNU Make.
#
@@ -107,6 +107,12 @@ kmkmissing_SOURCES.dragonfly = \
kmkmissing_SOURCES.freebsd = \
glob/fnmatch.c
+kmkmissing_SOURCES.gnukfbsd += \
+ kmkbuiltin/strlcpy.c
+
+kmkmissing_SOURCES.gnuknbsd += \
+ kmkbuiltin/strlcpy.c
+
kmkmissing_SOURCES.haiku = \
kmkbuiltin/haikufakes.c \
glob/fnmatch.c
@@ -114,6 +120,10 @@ kmkmissing_SOURCES.haiku = \
kmkmissing_SOURCES.linux += \
kmkbuiltin/strlcpy.c
+kmkmissing_SOURCES.netbsd = \
+ glob/glob.c \
+ glob/fnmatch.c
+
kmkmissing_SOURCES.openbsd = \
kmkbuiltin/openbsd.c
@@ -285,7 +295,8 @@ kmk_SOURCES += \
kmkbuiltin/rmdir.c \
$(if-expr $(KBUILD_TARGET) == win,kmkbuiltin/kSubmit.c) \
kmkbuiltin/sleep.c \
- kmkbuiltin/test.c
+ kmkbuiltin/test.c \
+ kmkbuiltin/touch.c
## @todo kmkbuiltin/redirect.c
@@ -317,6 +328,7 @@ PROGRAMS += \
kmk_rmdir \
kmk_sleep \
kmk_test \
+ kmk_touch \
kDepIDB \
kDepObj \
@@ -416,6 +428,11 @@ kmk_test_DEFS = kmk_builtin_test=main
kmk_test_SOURCES = \
kmkbuiltin/test.c
+kmk_touch_TEMPLATE = BIN-KMK
+kmk_touch_DEFS = kmk_builtin_touch=main
+kmk_touch_SOURCES = \
+ kmkbuiltin/touch.c
+
kDepIDB_TEMPLATE = BIN-KMK
kDepIDB_DEFS = kmk_builtin_kDepIDB=main
kDepIDB_INCS = .
diff --git a/src/kmk/config.h.netbsd b/src/kmk/config.h.netbsd
new file mode 100755
index 0000000..77c43d1
--- /dev/null
+++ b/src/kmk/config.h.netbsd
@@ -0,0 +1,459 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.in by autoheader. */
+
+/* Define to 1 if the `closedir' function returns void instead of `int'. */
+/* #undef CLOSEDIR_VOID */
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to 1 if using `alloca.c'. */
+/* #undef C_ALLOCA */
+
+/* Define to 1 if using `getloadavg.c'. */
+/* #undef C_GETLOADAVG */
+
+/* Define to 1 for DGUX with <sys/dg_sys_info.h>. */
+/* #undef DGUX */
+
+/* Use high resolution file timestamps if nonzero. */
+#define FILE_TIMESTAMP_HI_RES 0
+
+/* Define to 1 if the `getloadavg' function needs to be run setuid or setgid.
+ */
+/* #undef GETLOADAVG_PRIVILEGED */
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define to 1 if your compiler conforms to the ANSI C standard. */
+#define HAVE_ANSI_COMPILER 1
+
+/* Define to 1 if you have the `atexit' function. */
+#define HAVE_ATEXIT 1
+
+/* Use case insensitive file names */
+/* #undef HAVE_CASE_INSENSITIVE_FS */
+
+/* Define to 1 if you have the clock_gettime function. */
+/* #undef HAVE_CLOCK_GETTIME */
+
+/* Define to 1 if you have the declaration of `bsd_signal', and to 0 if you
+ don't. */
+#define HAVE_DECL_BSD_SIGNAL 0
+
+/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
+ don't. */
+#define HAVE_DECL_SYS_SIGLIST 1
+
+/* Define to 1 if you have the declaration of `_sys_siglist', and to 0 if you
+ don't. */
+#define HAVE_DECL__SYS_SIGLIST 0
+
+/* Define to 1 if you have the declaration of `__sys_siglist', and to 0 if you
+ don't. */
+#define HAVE_DECL___SYS_SIGLIST 0
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* Use platform specific coding */
+/* #undef HAVE_DOS_PATHS */
+
+/* Define to 1 if you have the `dup2' function. */
+#define HAVE_DUP2 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `fdopen' function. */
+#define HAVE_FDOPEN 1
+
+/* Define to 1 if you have the `fileno' function. */
+#define HAVE_FILENO 1
+
+/* Define to 1 if you have the `fork' function. */
+#define HAVE_FORK 1
+
+/* Define to 1 if you have the `getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define to 1 if you have the `getgroups' function. */
+#define HAVE_GETGROUPS 1
+
+/* Define to 1 if you have the `gethostbyname' function. */
+/* #undef HAVE_GETHOSTBYNAME */
+
+/* Define to 1 if you have the `gethostname' function. */
+/* #undef HAVE_GETHOSTNAME */
+
+/* Define to 1 if you have the `getloadavg' function. */
+#define HAVE_GETLOADAVG 1
+
+/* Define to 1 if you have the `getrlimit' function. */
+#define HAVE_GETRLIMIT 1
+
+/* Define to 1 if you have a standard gettimeofday function */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `dgc' library (-ldgc). */
+/* #undef HAVE_LIBDGC */
+
+/* Define to 1 if you have the `kstat' library (-lkstat). */
+/* #undef HAVE_LIBKSTAT */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define to 1 if you have the `lstat' function. */
+#define HAVE_LSTAT 1
+
+/* Define to 1 if you have the <mach/mach.h> header file. */
+/* #undef HAVE_MACH_MACH_H */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mkstemp' function. */
+#define HAVE_MKSTEMP 1
+
+/* Define to 1 if you have the `mktemp' function. */
+#define HAVE_MKTEMP 1
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the <nlist.h> header file. */
+/* #undef HAVE_NLIST_H */
+
+/* Define to 1 if you have the `pipe' function. */
+#define HAVE_PIPE 1
+
+/* Define to 1 if you have the `pstat_getdynamic' function. */
+/* #undef HAVE_PSTAT_GETDYNAMIC */
+
+/* Define to 1 if you have the `readlink' function. */
+#define HAVE_READLINK 1
+
+/* Define to 1 if you have the `realpath' function. */
+#define HAVE_REALPATH 1
+
+/* Define to 1 if <signal.h> defines the SA_RESTART constant. */
+#define HAVE_SA_RESTART 1
+
+/* Define to 1 if you have the `setegid' function. */
+#define HAVE_SETEGID 1
+
+/* Define to 1 if you have the `seteuid' function. */
+#define HAVE_SETEUID 1
+
+/* Define to 1 if you have the `setlinebuf' function. */
+#define HAVE_SETLINEBUF 1
+
+/* Define to 1 if you have the `setlocale' function. */
+/* #undef HAVE_SETLOCALE */
+
+/* Define to 1 if you have the `setregid' function. */
+#define HAVE_SETREGID 1
+
+/* Define to 1 if you have the `setreuid' function. */
+#define HAVE_SETREUID 1
+
+/* Define to 1 if you have the `setrlimit' function. */
+#define HAVE_SETRLIMIT 1
+
+/* Define to 1 if you have the `setvbuf' function. */
+#define HAVE_SETVBUF 1
+
+/* Define to 1 if you have the `sigaction' function. */
+#define HAVE_SIGACTION 1
+
+/* Define to 1 if you have the `sigsetmask' function. */
+#define HAVE_SIGSETMASK 1
+
+/* Define to 1 if you have the `socket' function. */
+/* #undef HAVE_SOCKET */
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strcmpi' function. */
+/* #undef HAVE_STRCMPI */
+
+/* Define to 1 if you have the `strcoll' function and it is properly defined.
+ */
+#define HAVE_STRCOLL 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the `stricmp' function. */
+/* #undef HAVE_STRICMP */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the `strncmpi' function. */
+/* #undef HAVE_STRNCMPI */
+
+/* Define to 1 if you have the `strndup' function. */
+#define HAVE_STRNDUP 1
+
+/* Define to 1 if you have the `strnicmp' function. */
+/* #undef HAVE_STRNICMP */
+
+/* Define to 1 if you have the `strsignal' function. */
+#define HAVE_STRSIGNAL 1
+
+/* Define to 1 if `n_un.n_name' is a member of `struct nlist'. */
+/* #undef HAVE_STRUCT_NLIST_N_UN_N_NAME */
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/timeb.h> header file. */
+#define HAVE_SYS_TIMEB_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the \`union wait' type in <sys/wait.h>. */
+/* #undef HAVE_UNION_WAIT */
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the <varargs.h> header file. */
+/* #undef HAVE_VARARGS_H */
+
+/* Define to 1 if you have the `vfork' function. */
+#define HAVE_VFORK 1
+
+/* Define to 1 if you have the <vfork.h> header file. */
+/* #undef HAVE_VFORK_H */
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Define to 1 if you have the `wait3' function. */
+#define HAVE_WAIT3 1
+
+/* Define to 1 if you have the `waitpid' function. */
+#define HAVE_WAITPID 1
+
+/* Define to 1 if `fork' works. */
+#define HAVE_WORKING_FORK 1
+
+/* Define to 1 if `vfork' works. */
+#define HAVE_WORKING_VFORK 1
+
+/* Build host information. (not used by kmk) */
+#define MAKE_HOST "i386-unknown-netbsdelf5.1."
+
+/* Define to 1 to enable job server support in GNU make. */
+#define MAKE_JOBSERVER 1
+
+/* Define to 1 to enable symbolic link timestamp checking. */
+#define MAKE_SYMLINKS 1
+
+/* Define to 1 if your `struct nlist' has an `n_un' member. Obsolete, depend
+ on `HAVE_STRUCT_NLIST_N_UN_N_NAME */
+/* #undef NLIST_NAME_UNION */
+
+/* Define to 1 if struct nlist.n_name is a pointer rather than an array. */
+/* #undef NLIST_STRUCT */
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* Name of package */
+#define PACKAGE "make"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "bug-make at gnu.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "GNU make"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "GNU make 3.82"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "make"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL "http://www.gnu.org/software/make/"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "3.82"
+
+/* Define to the character that separates directories in PATH. */
+#define PATH_SEPARATOR_CHAR ':'
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to the name of the SCCS 'get' command. */
+#define SCCS_GET "get"
+
+/* Define to 1 if the SCCS 'get' command understands the '-G<file>' option. */
+/* #undef SCCS_GET_MINUS_G */
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+/* #undef STACK_DIRECTION */
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if struct stat contains a nanoseconds field */
+/* #undef ST_MTIM_NSEC */
+
+/* Define to 1 on System V Release 4. */
+/* #undef SVR4 */
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to 1 for Encore UMAX. */
+/* #undef UMAX */
+
+/* Define to 1 for Encore UMAX 4.3 that has <inq_status/cpustats.h> instead of
+ <sys/cpustats.h>. */
+/* #undef UMAX4_3 */
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+
+
+/* Version number of package */
+#define VERSION "3.82"
+
+/* Use platform specific coding */
+/* #undef WINDOWS32 */
+
+/* Define if using the dmalloc debugging malloc package */
+/* #undef WITH_DMALLOC */
+
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to 1 if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef gid_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef pid_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef uid_t */
+
+/* Define uintmax_t if not defined in <stdint.h> or <inttypes.h>. */
+/* #undef uintmax_t */
+
+/* Define as `fork' if `vfork' does not work. */
+/* #undef vfork */
+
+#include "inlined_memchr.h"
diff --git a/src/kmk/dir.c b/src/kmk/dir.c
index c9b1b37..0e44824 100644
--- a/src/kmk/dir.c
+++ b/src/kmk/dir.c
@@ -710,7 +710,7 @@ static int
dir_contents_file_exists_p (struct directory_contents *dir,
const char *filename)
{
- unsigned int hash;
+ /*unsigned int hash;*/
struct dirfile *df;
struct dirent *d;
#ifdef WINDOWS32
@@ -744,7 +744,7 @@ dir_contents_file_exists_p (struct directory_contents *dir,
filename = vmsify (filename,0);
#endif
- hash = 0;
+ /*hash = 0;*/
if (filename != 0)
{
struct dirfile dirfile_key;
@@ -1340,11 +1340,7 @@ void print_dir_stats (void)
/* Hooks for globbing. */
-#if defined(KMK) && !defined(__OS2__)
-# include "glob/glob.h"
-#else
#include <glob.h>
-#endif
/* Structure describing state of iterating through a directory hash table. */
@@ -1479,7 +1475,7 @@ dir_setup_glob (glob_t *gl)
#ifdef __EMX__ /* The FreeBSD implementation actually uses gl_lstat!! */
gl->gl_lstat = local_stat;
#endif
-#if defined(KMK) && !defined(__OS2__)
+#ifdef GLOB_WITH_EXTENDED_KMK_MEMBERS
gl->gl_exists = file_exists_p;
gl->gl_isdir = dir_exists_p;
#endif
diff --git a/src/kmk/expreval.c b/src/kmk/expreval.c
index 4d9cb5f..f887a7c 100644
--- a/src/kmk/expreval.c
+++ b/src/kmk/expreval.c
@@ -1,5 +1,5 @@
#ifdef CONFIG_WITH_IF_CONDITIONALS
-/* $Id: expreval.c 2573 2012-05-13 19:39:47Z bird $ */
+/* $Id: expreval.c 3065 2017-09-30 12:52:35Z bird $ */
/** @file
* expreval - Expressions evaluator, C / BSD make / nmake style.
*/
@@ -390,7 +390,7 @@ static EXPRRET expr_string_to_num(PEXPR pThis, EXPRINT64 *piDst, const char *psz
i = -i;
*piDst = i;
if (!fQuiet)
- expr_error(pThis, "Invalid a number \"%.80s\"", pszSrc);
+ expr_error(pThis, "Invalid number \"%.80s\"", pszSrc);
return kExprRet_Error;
}
@@ -1396,7 +1396,7 @@ static EXPRRET expr_op_equal(PEXPR pThis)
}
expr_pop_and_delete_var(pThis);
- return kExprRet_Ok;
+ return rc;
}
diff --git a/src/kmk/glob/glob.h b/src/kmk/glob/glob.h
index f987d03..ef004c0 100644
--- a/src/kmk/glob/glob.h
+++ b/src/kmk/glob/glob.h
@@ -137,6 +137,7 @@ typedef struct
int (*gl_stat) __PMT ((__const char *, struct stat *));
#endif
#ifdef KMK
+# define GLOB_WITH_EXTENDED_KMK_MEMBERS
int (*gl_exists) __PMT ((__const char *));
int (*gl_isdir) __PMT ((__const char *));
#endif
diff --git a/src/kmk/job.c b/src/kmk/job.c
index 06efde3..8cd910e 100644
--- a/src/kmk/job.c
+++ b/src/kmk/job.c
@@ -464,9 +464,30 @@ child_error (const char *target_name,
#else
if (exit_sig == 0)
# if defined(KMK) && defined(KBUILD_OS_WINDOWS)
- error (NILF, ignored ? _("[%s] Error %d (%#x) (ignored)") :
- _("*** [%s] Error %d (%#x)"),
- target_name, exit_code, exit_code);
+ {
+ const char *name = NULL;
+ switch ((unsigned)exit_code)
+ {
+ case 0xc0000005U: name = "STATUS_ACCESS_VIOLATION"; break;
+ case 0xc000013aU: name = "STATUS_CONTROL_C_EXIT"; break;
+ case 0xc0000374U: name = "STATUS_HEAP_CORRUPTION"; break;
+ case 0xc0000409U: name = "STATUS_STACK_BUFFER_OVERRUN"; break;
+ case 0xc0000417U: name = "STATUS_INVALID_CRUNTIME_PARAMETER"; break;
+ case 0x80000003U: name = "STATUS_BREAKPOINT"; break;
+ case 0x40000015U: name = "STATUS_FATAL_APP_EXIT"; break;
+ case 0x40010004U: name = "DBG_TERMINATE_PROCESS"; break;
+ case 0x40010005U: name = "DBG_CONTROL_C"; break;
+ case 0x40010008U: name = "DBG_CONTROL_BREAK"; break;
+ }
+ if (name)
+ error(NILF, ignored ? _("[%s] Error %d (%s) (ignored)") :
+ _("*** [%s] Error %d (%s)"),
+ target_name, exit_code, name);
+ else
+ error(NILF, ignored ? _("[%s] Error %d (%#x) (ignored)") :
+ _("*** [%s] Error %d (%#x)"),
+ target_name, exit_code, exit_code);
+ }
# else
error (NILF, ignored ? _("[%s] Error %d (ignored)") :
_("*** [%s] Error %d"),
@@ -840,9 +861,13 @@ reap_children (int block, int err)
#ifdef KMK
{
child_error (c->file->name, exit_code, exit_sig, coredump, 0);
- if (( c->file->cmds->lines_flags[c->command_line - 1]
- & (COMMANDS_SILENT | COMMANDS_RECURSE))
- == COMMANDS_SILENT)
+ if ( ( c->file->cmds->lines_flags[c->command_line - 1]
+ & (COMMANDS_SILENT | COMMANDS_RECURSE))
+ == COMMANDS_SILENT
+# ifdef KBUILD_OS_WINDOWS /* show commands for NT statuses */
+ || (exit_code & 0xc0000000)
+# endif
+ || exit_sig != 0)
message (0, "The failing command:\n%s", c->file->cmds->command_lines[c->command_line - 1]);
}
#else /* !KMK */
@@ -2680,7 +2705,9 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
int i;
char *p;
char *ap;
+#ifndef NDEBUG
char *end;
+#endif
int instring, word_has_equals, seen_nonequals, last_argument_was_empty;
char **new_argv = 0;
char *argstr = 0;
@@ -2768,6 +2795,11 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
* shell after this function returns. */
default_shell = xstrdup (shell);
}
+# ifdef KMK
+ if (is_kmk_shell)
+ { /* done above already */ }
+ else
+# endif
if (unixy_shell)
{
sh_chars = sh_chars_sh;
@@ -2809,7 +2841,9 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
/* All the args can fit in a buffer as big as LINE is. */
ap = new_argv[0] = argstr = xmalloc (i);
+#ifndef NDEBUG
end = ap + i;
+#endif
/* I is how many complete arguments have been found. */
i = 0;
@@ -3119,7 +3153,9 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
unsigned int shell_len = strlen (shell);
unsigned int line_len = strlen (line);
unsigned int sflags_len = strlen (shellflags);
+# ifdef WINDOWS32
char *command_ptr = NULL; /* used for batch_mode_shell mode */
+# endif
char *new_line;
# ifdef __EMX__ /* is this necessary? */
@@ -3200,7 +3236,9 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
memcpy (ap, shellflags, sflags_len);
ap += sflags_len;
*(ap++) = ' ';
+#ifdef WINDOWS32
command_ptr = ap;
+#endif
for (p = line; *p != '\0'; ++p)
{
if (restp != NULL && *p == '\n')
diff --git a/src/kmk/kbuild-object.c b/src/kmk/kbuild-object.c
index 07c4b9f..51977f4 100644
--- a/src/kmk/kbuild-object.c
+++ b/src/kmk/kbuild-object.c
@@ -1,4 +1,4 @@
-/* $Id: kbuild-object.c 2720 2014-01-01 22:59:50Z bird $ */
+/* $Id: kbuild-object.c 3065 2017-09-30 12:52:35Z bird $ */
/** @file
* kBuild objects.
*/
@@ -276,6 +276,7 @@ eval_kbuild_type_from_string(const char *pchWord, size_t cchWord)
+#if 0 /* unused */
/**
* Helper function for caching variable name strings.
*
@@ -292,6 +293,7 @@ kbuild_variable_name(const char *pszName, const char **ppszCache)
*ppszCache = pszRet = strcache2_add(&variable_strcache, pszName, strlen(pszName));
return pszRet;
}
+#endif
static struct kbuild_object *
lookup_kbuild_object(enum kBuildType enmType, const char *pchName, size_t cchName)
@@ -558,7 +560,7 @@ try_define_kbuild_object_variable_via_accessor(const char *pchName, size_t cchNa
{
assert(pObj != NULL);
if (!is_valid_kbuild_object_variable_name(pchVarNm, cchVarNm))
- fatal(pFileLoc, _("Invalid kBuild object variable name: '%.*s' ('%s')"),
+ fatal(pFileLoc, _("Invalid kBuild object variable name: '%.*s' ('%.*s')"),
(int)cchVarNm, pchVarNm, (int)cchName, pchName);
return define_kbuild_object_variable_cached(pObj, strcache2_add(&variable_strcache, pchVarNm, cchVarNm),
pszValue, cchValue, fDuplicateValue, enmOrigin, fRecursive,
@@ -1321,8 +1323,8 @@ parse_kbuild_object_variable_accessor(const char *pchExpr, size_t cchExpr,
struct variable *
lookup_kbuild_object_variable_accessor(const char *pchName, size_t cchName)
{
- const char * const pchOrgName = pchName;
- size_t const cchOrgName = cchName;
+ /*const char * const pchOrgName = pchName;*/
+ /*size_t const cchOrgName = cchName;*/
const char * pchVarNm;
size_t cchVarNm;
struct kbuild_object *pObj;
diff --git a/src/kmk/kbuild.c b/src/kmk/kbuild.c
index 1a2399f..f57e198 100644
--- a/src/kmk/kbuild.c
+++ b/src/kmk/kbuild.c
@@ -1,4 +1,4 @@
-/* $Id: kbuild.c 2861 2016-09-01 22:42:55Z bird $ */
+/* $Id: kbuild.c 3068 2017-10-01 13:10:47Z bird $ */
/** @file
* kBuild specific make functionality.
*/
@@ -47,6 +47,7 @@
#endif
#include "kbuild.h"
+#include "k/kDefs.h"
#include <assert.h>
@@ -65,14 +66,14 @@
else \
switch (len) \
{ \
- case 8: dst[7] = src[7]; \
- case 7: dst[6] = src[6]; \
- case 6: dst[5] = src[5]; \
- case 5: dst[4] = src[4]; \
- case 4: dst[3] = src[3]; \
- case 3: dst[2] = src[2]; \
- case 2: dst[1] = src[1]; \
- case 1: dst[0] = src[0]; \
+ case 8: dst[7] = src[7]; /* fall thru */ \
+ case 7: dst[6] = src[6]; /* fall thru */ \
+ case 6: dst[5] = src[5]; /* fall thru */ \
+ case 5: dst[4] = src[4]; /* fall thru */ \
+ case 4: dst[3] = src[3]; /* fall thru */ \
+ case 3: dst[2] = src[2]; /* fall thru */ \
+ case 2: dst[1] = src[1]; /* fall thru */ \
+ case 1: dst[0] = src[0]; /* fall thru */ \
case 0: break; \
} \
} while (0)
@@ -612,8 +613,14 @@ kbuild_lookup_variable_n(const char *pszName, size_t cchName)
MY_ASSERT_MSG(strlen(pVar->value) == pVar->value_length,
("%u != %u %.*s\n", pVar->value_length, (unsigned int)strlen(pVar->value), (int)cchName, pVar->name));
- /* Make sure the variable is simple, convert it if necessary. */
- if (pVar->recursive)
+ /* Make sure the variable is simple, convert it if necessary.
+ Note! Must NOT do this for the dynamic INCS of sdks/ReorderCompilerIncs.kmk */
+ if (!pVar->recursive)
+ { /* likely */ }
+ else if ( cchName < sizeof("SDK_ReorderCompilerIncs_INCS.") - 1U
+ || pszName[0] != 'S'
+ || pszName[4] != 'R'
+ || memcmp(pszName, "SDK_ReorderCompilerIncs_INCS.", sizeof("SDK_ReorderCompilerIncs_INCS.") - 1U) == 0)
kbuild_simplify_variable(pVar);
}
return pVar;
@@ -1994,7 +2001,10 @@ func_kbuild_source_one(char *o, char **argv, const char *pszFuncName)
struct variable *pTool = kbuild_get_source_tool(pTarget, pSource, pType, pBldTrg, pBldTrgArch, "tool");
struct variable *pOutBase = kbuild_get_object_base(pTarget, pSource, "outbase");
struct variable *pObjSuff = kbuild_get_object_suffix(pTarget, pSource, pTool, pType, pBldTrg, pBldTrgArch, "objsuff");
- struct variable *pDefs, *pIncs, *pFlags, *pDeps, *pOrderDeps, *pDirDep, *pDep, *pVar, *pOutput, *pOutputMaybe;
+ struct variable *pDeps, *pOrderDeps, *pDirDep, *pDep, *pVar, *pOutput, *pOutputMaybe;
+#if 0 /* not used */
+ struct variable *pDefs, *pIncs, *pFlags;
+#endif
struct variable *pObj = kbuild_set_object_name_and_dep_and_dirdep_and_PATH_target_source(pTarget, pSource, pOutBase, pObjSuff, "obj", &pDep, &pDirDep);
int fInstallOldVars = 0;
char *pszDstVar, *pszDst, *pszSrcVar, *pszSrc, *pszVal, *psz;
@@ -2047,11 +2057,11 @@ func_kbuild_source_one(char *o, char **argv, const char *pszFuncName)
pDefPath = NULL;
- pDefs = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu, NULL,
+ /*pDefs =*/ kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu, NULL,
ST("DEFS"), ST("defs"), 1/* left-to-right */);
- pIncs = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu, pDefPath,
+ /*pIncs =*/ kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu, pDefPath,
ST("INCS"), ST("incs"), -1/* right-to-left */);
- pFlags = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu, NULL,
+ /*pFlags =*/ kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu, NULL,
ST("FLAGS"), ST("flags"), 1/* left-to-right */);
pDeps = kbuild_collect_source_prop(pTarget, pSource, pTool, &Sdks, pType, pBldType, pBldTrg, pBldTrgArch, pBldTrgCpu, pDefPath,
ST("DEPS"), ST("deps"), 1/* left-to-right */);
diff --git a/src/kmk/kmkbuiltin.c b/src/kmk/kmkbuiltin.c
index 3cca960..af7bdf1 100644
--- a/src/kmk/kmkbuiltin.c
+++ b/src/kmk/kmkbuiltin.c
@@ -1,4 +1,4 @@
-/* $Id: kmkbuiltin.c 2912 2016-09-14 13:36:15Z bird $ */
+/* $Id: kmkbuiltin.c 3059 2017-09-21 13:34:15Z bird $ */
/** @file
* kMk Builtin command execution.
*/
@@ -42,126 +42,182 @@
extern char **environ;
#endif
+
int kmk_builtin_command(const char *pszCmd, struct child *pChild, char ***ppapszArgvToSpawn, pid_t *pPidSpawned)
{
int argc;
char **argv;
int rc;
+ char *pszzCmd;
+ char *pszDst;
+ int fOldStyle = 0;
/*
* Check and skip the prefix.
*/
if (strncmp(pszCmd, "kmk_builtin_", sizeof("kmk_builtin_") - 1))
{
- printf("kmk_builtin: Invalid command prefix '%s'!\n", pszCmd);
+ fprintf(stderr, "kmk_builtin: Invalid command prefix '%s'!\n", pszCmd);
return 1;
}
/*
* Parse arguments.
*/
- argc = 0;
- argv = NULL;
- while (*pszCmd)
+ rc = 0;
+ argc = 0;
+ argv = NULL;
+ pszzCmd = pszDst = (char *)strdup(pszCmd);
+ if (!pszDst)
{
- const char *pszEnd;
- const char *pszNext;
- int fEscaped = 0;
- size_t cch;
-
- /*
- * Find start and end of the current command.
- */
- if (*pszCmd == '"' || *pszCmd == '\'')
- {
- pszEnd = pszCmd;
- for (;;)
- {
- pszEnd = strchr(pszEnd + 1, *pszCmd);
- if (!pszEnd)
- {
- printf("kmk_builtin: Unbalanced quote in argument %d: %s\n", argc + 1, pszCmd);
- while (argc--)
- free(argv[argc]);
- free(argv);
- return 1;
- }
- /* two quotes -> escaped quote. */
- if (pszEnd[0] != pszEnd[1])
- break;
- fEscaped = 1;
- }
- pszNext = pszEnd + 1;
- pszCmd++;
- }
- else
- {
- pszEnd = pszCmd;
- while (!isspace(*pszEnd) && *pszEnd)
- pszEnd++;
- pszNext = pszEnd;
- }
+ fprintf(stderr, "kmk_builtin: out of memory. argc=%d\n", argc);
+ return 1;
+ }
+ do
+ {
+ const char * const pszSrcStart = pszCmd;
+ char ch;
+ char chQuote;
/*
- * Make argument.
+ * Start new argument.
*/
if (!(argc % 16))
{
void *pv = realloc(argv, sizeof(char *) * (argc + 17));
if (!pv)
{
- printf("kmk_builtin: out of memory. argc=%d\n", argc);
+ fprintf(stderr, "kmk_builtin: out of memory. argc=%d\n", argc);
+ rc = 1;
break;
}
argv = (char **)pv;
}
- cch = pszEnd - pszCmd;
- argv[argc] = malloc(cch + 1);
- if (!argv[argc])
+ argv[argc++] = pszDst;
+ argv[argc] = NULL;
+
+ if (!fOldStyle)
{
- printf("kmk_builtin: out of memory. argc=%d len=%d\n", argc, (int)(pszEnd - pszCmd + 1));
- break;
+ /*
+ * Process the next argument, bourne style.
+ */
+ chQuote = 0;
+ ch = *pszCmd++;
+ do
+ {
+ /* Unquoted mode? */
+ if (chQuote == 0)
+ {
+ if (ch != '\'' && ch != '"')
+ {
+ if (!isspace(ch))
+ {
+ if (ch != '\\')
+ *pszDst++ = ch;
+ else
+ {
+ ch = *pszCmd++;
+ if (ch)
+ *pszDst++ = ch;
+ else
+ {
+ fprintf(stderr, "kmk_builtin: Incomplete escape sequence in argument %d: %s\n",
+ argc, pszSrcStart);
+ rc = 1;
+ break;
+ }
+ }
+ }
+ else
+ break;
+ }
+ else
+ chQuote = ch;
+ }
+ /* Quoted mode */
+ else if (ch != chQuote)
+ {
+ if ( ch != '\\'
+ || chQuote == '\'')
+ *pszDst++ = ch;
+ else
+ {
+ ch = *pszCmd++;
+ if (ch)
+ {
+ if ( ch != '\\'
+ && ch != '"'
+ && ch != '`'
+ && ch != '$'
+ && ch != '\n')
+ *pszDst++ = '\\';
+ *pszDst++ = ch;
+ }
+ else
+ {
+ fprintf(stderr, "kmk_builtin: Unbalanced quote in argument %d: %s\n", argc, pszSrcStart);
+ rc = 1;
+ break;
+ }
+ }
+ }
+ else
+ chQuote = 0;
+ } while ((ch = *pszCmd++) != '\0');
}
- memcpy(argv[argc], pszCmd, cch);
- argv[argc][cch] = '\0';
-
- /* unescape quotes? */
- if (fEscaped)
+ else
{
- char ch = pszCmd[-1];
- char *pszW = argv[argc];
- char *pszR = argv[argc];
- while (*pszR)
+ /*
+ * Old style in case we ever need it.
+ */
+ ch = *pszCmd++;
+ if (ch != '"' && ch != '\'')
+ {
+ do
+ *pszDst++ = ch;
+ while ((ch = *pszCmd++) != '\0' && !isspace(ch));
+ }
+ else
{
- if (*pszR == ch)
- pszR++;
- *pszW++ = *pszR++;
+ chQuote = ch;
+ for (;;)
+ {
+ char *pszEnd = strchr(pszCmd, chQuote);
+ if (pszEnd)
+ {
+ fprintf(stderr, "kmk_builtin: Unbalanced quote in argument %d: %s\n", argc, pszSrcStart);
+ rc = 1;
+ break;
+ }
+ memcpy(pszDst, pszCmd, pszEnd - pszCmd);
+ pszDst += pszEnd - pszCmd;
+ if (pszEnd[1] != chQuote)
+ break;
+ *pszDst++ = chQuote;
+ }
}
- *pszW = '\0';
}
- /* commit it */
- argv[++argc] = NULL;
+ *pszDst++ = '\0';
/*
- * Next
+ * Skip argument separators (IFS=space() for now). Check for EOS.
*/
- pszCmd = pszNext;
- if (isspace(*pszCmd) && *pszCmd)
- pszCmd++;
- }
+ if (ch != 0)
+ while ((ch = *pszCmd) && isspace(ch))
+ pszCmd++;
+ if (ch == 0)
+ break;
+ } while (rc == 0);
/*
* Execute the command if parsing was successful.
*/
- if (!*pszCmd)
+ if (rc == 0)
rc = kmk_builtin_command_parsed(argc, argv, pChild, ppapszArgvToSpawn, pPidSpawned);
- else
- rc = 1;
/* clean up and return. */
- while (argc--)
- free(argv[argc]);
free(argv);
+ free(pszzCmd);
return rc;
}
@@ -177,7 +233,7 @@ int kmk_builtin_command_parsed(int argc, char **argv, struct child *pChild, char
*/
if (strncmp(pszCmd, "kmk_builtin_", sizeof("kmk_builtin_") - 1))
{
- printf("kmk_builtin: Invalid command prefix '%s'!\n", pszCmd);
+ fprintf(stderr, "kmk_builtin: Invalid command prefix '%s'!\n", pszCmd);
return 1;
}
pszCmd += sizeof("kmk_builtin_") - 1;
@@ -230,6 +286,8 @@ int kmk_builtin_command_parsed(int argc, char **argv, struct child *pChild, char
rc = kmk_builtin_cmp(argc, argv, environ);
else if (!strcmp(pszCmd, "cat"))
rc = kmk_builtin_cat(argc, argv, environ);
+ else if (!strcmp(pszCmd, "touch"))
+ rc = kmk_builtin_touch(argc, argv, environ);
else if (!strcmp(pszCmd, "sleep"))
rc = kmk_builtin_sleep(argc, argv, environ);
else if (!strcmp(pszCmd, "dircache"))
@@ -240,7 +298,7 @@ int kmk_builtin_command_parsed(int argc, char **argv, struct child *pChild, char
#endif
else
{
- printf("kmk_builtin: Unknown command '%s'!\n", pszCmd);
+ fprintf(stderr, "kmk_builtin: Unknown command '%s'!\n", pszCmd);
return 1;
}
diff --git a/src/kmk/kmkbuiltin.h b/src/kmk/kmkbuiltin.h
index 03d0a98..077b51a 100644
--- a/src/kmk/kmkbuiltin.h
+++ b/src/kmk/kmkbuiltin.h
@@ -1,4 +1,4 @@
-/* $Id: kmkbuiltin.h 2912 2016-09-14 13:36:15Z bird $ */
+/* $Id: kmkbuiltin.h 3059 2017-09-21 13:34:15Z bird $ */
/** @file
* kMk Builtin command handling.
*/
@@ -63,6 +63,7 @@ extern int kmk_builtin_test(int argc, char **argv, char **envp
, char ***ppapszArgvSpawn
#endif
);
+extern int kmk_builtin_touch(int argc, char **argv, char **envp);
#ifdef KBUILD_OS_WINDOWS
extern int kmk_builtin_kSubmit(int argc, char **argv, char **envp, struct child *pChild, pid_t *pPidSpawned);
extern int kSubmitSubProcGetResult(intptr_t pvUser, int *prcExit, int *piSigNo);
@@ -77,6 +78,10 @@ extern char *kmk_builtin_func_printf(char *o, char **argv, const char *funcname)
/* common-env-and-cwd-opt.c: */
extern int kBuiltinOptEnvSet(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAllocatedEnvVars,
int cVerbosity, const char *pszValue);
+extern int kBuiltinOptEnvAppend(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAllocatedEnvVars,
+ int cVerbosity, const char *pszValue);
+extern int kBuiltinOptEnvPrepend(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAllocatedEnvVars,
+ int cVerbosity, const char *pszValue);
extern int kBuiltinOptEnvUnset(char **papszEnv, unsigned *pcEnvVars, int cVerbosity, const char *pszVarToRemove);
extern int kBuiltinOptChDir(char *pszCwd, size_t cbCwdBuf, const char *pszValue);
diff --git a/src/kmk/kmkbuiltin/cmp.c b/src/kmk/kmkbuiltin/cmp.c
index e24ca17..2c098bb 100644
--- a/src/kmk/kmkbuiltin/cmp.c
+++ b/src/kmk/kmkbuiltin/cmp.c
@@ -34,6 +34,9 @@
static char sccsid[] = "@(#)cmp.c 8.3 (Berkeley) 4/2/94";
__RCSID("$NetBSD: cmp.c,v 1.15 2006/01/19 20:44:57 garbled Exp $"); */
+#ifdef _MSC_VER
+# define MSC_DO_64_BIT_IO /* for correct off_t */
+#endif
#include "config.h"
#include <sys/types.h>
#include "err.h"
@@ -45,7 +48,6 @@ __RCSID("$NetBSD: cmp.c,v 1.15 2006/01/19 20:44:57 garbled Exp $"); */
#ifndef _MSC_VER
# include <unistd.h>
#else
-# define MSC_DO_64_BIT_IO /* for correct off_t */
# include "mscfakes.h"
#endif
#include "getopt.h"
diff --git a/src/kmk/kmkbuiltin/cmp_util.c b/src/kmk/kmkbuiltin/cmp_util.c
index 905ac13..c79c001 100644
--- a/src/kmk/kmkbuiltin/cmp_util.c
+++ b/src/kmk/kmkbuiltin/cmp_util.c
@@ -35,6 +35,9 @@
/*__COPYRIGHT("@(#) Copyright (c) 1987, 1990, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n");*/
+#ifdef _MSC_VER
+# define MSC_DO_64_BIT_IO
+#endif
#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -54,7 +57,6 @@
# define O_BINARY 0
# endif
#else
-# define MSC_DO_64_BIT_IO
# include "mscfakes.h"
#endif
#include "err.h"
@@ -359,7 +361,7 @@ c_regular(int fd1, const char *file1, off_t skip1, off_t len1,
for (blk_sz = CMP_BUF_SIZE; length != 0; length -= blk_sz)
{
if ((off_t)blk_sz > length)
- blk_sz = length;
+ blk_sz = (size_t)length;
bytes_read = read(fd1, b1, blk_sz);
if (bytes_read != (off_t)blk_sz)
diff --git a/src/kmk/kmkbuiltin/common-env-and-cwd-opt.c b/src/kmk/kmkbuiltin/common-env-and-cwd-opt.c
index 21b76d5..88c649a 100644
--- a/src/kmk/kmkbuiltin/common-env-and-cwd-opt.c
+++ b/src/kmk/kmkbuiltin/common-env-and-cwd-opt.c
@@ -1,4 +1,4 @@
-/* $Id: common-env-and-cwd-opt.c 2912 2016-09-14 13:36:15Z bird $ */
+/* $Id: common-env-and-cwd-opt.c 3039 2017-05-10 10:55:51Z bird $ */
/** @file
* kMk Builtin command - Commmon environment and CWD option handling code.
*/
@@ -45,10 +45,80 @@
/**
- * Handles the --set var=value option.
+ * Common worker for kBuiltinOptEnvSet and kBuiltinOptEnvAppendPrepend that adds
+ * a new variable to the environment.
+ *
+ * @returns 0 on success, non-zero exit code on error.
+ * @param papszEnv The environment vector.
+ * @param pcEnvVars Pointer to the variable holding the number of
+ * environment variables held by @a papszEnv.
+ * @param pcAllocatedEnvVars Pointer to the variable holding max size of the
+ * environment vector.
+ * @param cVerbosity The verbosity level.
+ * @param pszValue The var=value string to apply.
+ */
+static int kBuiltinOptEnvAddVar(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAllocatedEnvVars,
+ int cVerbosity, const char *pszValue)
+{
+ /* Append new variable. We probably need to resize the vector. */
+ char **papszEnv = *ppapszEnv;
+ unsigned cEnvVars = *pcEnvVars;
+ if ((cEnvVars + 2) > *pcAllocatedEnvVars)
+ {
+ *pcAllocatedEnvVars = (cEnvVars + 2 + 0xf) & ~(unsigned)0xf;
+ papszEnv = (char **)realloc(papszEnv, *pcAllocatedEnvVars * sizeof(papszEnv[0]));
+ if (!papszEnv)
+ return errx(1, "out of memory!");
+ *ppapszEnv = papszEnv;
+ }
+ papszEnv[cEnvVars] = strdup(pszValue);
+ if (!papszEnv[cEnvVars])
+ return errx(1, "out of memory!");
+ papszEnv[++cEnvVars] = NULL;
+ *pcEnvVars = cEnvVars;
+ if (cVerbosity > 0)
+ warnx("added '%s'", papszEnv[cEnvVars - 1]);
+ return 0;
+}
+
+
+/**
+ * Common worker for kBuiltinOptEnvSet and kBuiltinOptEnvAppendPrepend that
+ * remove duplicates.
*
* @returns 0 on success, non-zero exit code on error.
* @param papszEnv The environment vector.
+ * @param cEnvVars Number of environment variables.
+ * @param cVerbosity The verbosity level.
+ * @param pszValue The var=value string to apply.
+ * @param cchVar The length of the variable part of @a pszValue.
+ * @param iEnvVar Where to start searching after.
+ */
+static int kBuiltinOptEnvRemoveDuplicates(char **papszEnv, unsigned cEnvVars, int cVerbosity,
+ const char *pszValue, size_t cchVar, unsigned iEnvVar)
+{
+ for (iEnvVar++; iEnvVar < cEnvVars; iEnvVar++)
+ if ( KSUBMIT_ENV_NCMP(papszEnv[iEnvVar], pszValue, cchVar) == 0
+ && papszEnv[iEnvVar][cchVar] == '=')
+ {
+ if (cVerbosity > 0)
+ warnx("removing duplicate '%s'", papszEnv[iEnvVar]);
+ free(papszEnv[iEnvVar]);
+ cEnvVars--;
+ if (iEnvVar != cEnvVars)
+ papszEnv[iEnvVar] = papszEnv[cEnvVars];
+ papszEnv[cEnvVars] = NULL;
+ iEnvVar--;
+ }
+ return 0;
+}
+
+
+/**
+ * Handles the --set var=value option.
+ *
+ * @returns 0 on success, non-zero exit code on error.
+ * @param ppapszEnv The environment vector pointer.
* @param pcEnvVars Pointer to the variable holding the number of
* environment variables held by @a papszEnv.
* @param pcAllocatedEnvVars Pointer to the variable holding max size of the
@@ -77,50 +147,108 @@ int kBuiltinOptEnvSet(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAlloca
papszEnv[iEnvVar] = strdup(pszValue);
if (!papszEnv[iEnvVar])
return errx(1, "out of memory!");
- break;
+
+ return kBuiltinOptEnvRemoveDuplicates(papszEnv, cEnvVars, cVerbosity, pszValue, cchVar, iEnvVar);
}
}
- if (iEnvVar == cEnvVars)
+ return kBuiltinOptEnvAddVar(ppapszEnv, pcEnvVars, pcAllocatedEnvVars, cVerbosity, pszValue);
+ }
+ return errx(1, "Missing '=': -E %s", pszValue);
+}
+
+
+/**
+ * Common worker for kBuiltinOptEnvAppend and kBuiltinOptEnvPrepend.
+ *
+ * @returns 0 on success, non-zero exit code on error.
+ * @param ppapszEnv The environment vector pointer.
+ * @param pcEnvVars Pointer to the variable holding the number of
+ * environment variables held by @a papszEnv.
+ * @param pcAllocatedEnvVars Pointer to the variable holding max size of the
+ * environment vector.
+ * @param cVerbosity The verbosity level.
+ * @param pszValue The var=value string to apply.
+ */
+static int kBuiltinOptEnvAppendPrepend(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAllocatedEnvVars,
+ int cVerbosity, const char *pszValue, int fAppend)
+{
+ const char *pszEqual = strchr(pszValue, '=');
+ if (pszEqual)
+ {
+ char **papszEnv = *ppapszEnv;
+ unsigned iEnvVar;
+ unsigned cEnvVars = *pcEnvVars;
+ size_t const cchVar = pszEqual - pszValue;
+ for (iEnvVar = 0; iEnvVar < cEnvVars; iEnvVar++)
{
- /* Append new variable. We probably need to resize the vector. */
- if ((cEnvVars + 2) > *pcAllocatedEnvVars)
+ char *pszCur = papszEnv[iEnvVar];
+ if ( KSUBMIT_ENV_NCMP(pszCur, pszValue, cchVar) == 0
+ && pszCur[cchVar] == '=')
{
- *pcAllocatedEnvVars = (cEnvVars + 2 + 0xf) & ~(unsigned)0xf;
- papszEnv = (char **)realloc(papszEnv, *pcAllocatedEnvVars * sizeof(papszEnv[0]));
- if (!papszEnv)
+ size_t cchOldValue = strlen(papszEnv[iEnvVar]) - cchVar - 1;
+ size_t cchNewValue = strlen(pszValue) - cchVar - 1;
+ char *pszNew = malloc(cchVar + 1 + cchOldValue + cchNewValue);
+ if (!papszEnv[iEnvVar])
return errx(1, "out of memory!");
- *ppapszEnv = papszEnv;
- }
- papszEnv[cEnvVars] = strdup(pszValue);
- if (!papszEnv[cEnvVars])
- return errx(1, "out of memory!");
- papszEnv[++cEnvVars] = NULL;
- *pcEnvVars = cEnvVars;
- if (cVerbosity > 0)
- warnx("added '%s'", papszEnv[iEnvVar]);
- }
- else
- {
- /* Check for duplicates. */
- for (iEnvVar++; iEnvVar < cEnvVars; iEnvVar++)
- if ( KSUBMIT_ENV_NCMP(papszEnv[iEnvVar], pszValue, cchVar) == 0
- && papszEnv[iEnvVar][cchVar] == '=')
+ if (fAppend)
+ {
+ memcpy(pszNew, papszEnv[iEnvVar], cchVar + 1 + cchOldValue);
+ memcpy(&pszNew[cchVar + 1 + cchOldValue], &pszValue[cchVar + 1], cchNewValue + 1);
+ }
+ else
{
- if (cVerbosity > 0)
- warnx("removing duplicate '%s'", papszEnv[iEnvVar]);
- free(papszEnv[iEnvVar]);
- cEnvVars--;
- if (iEnvVar != cEnvVars)
- papszEnv[iEnvVar] = papszEnv[cEnvVars];
- papszEnv[cEnvVars] = NULL;
- iEnvVar--;
+ memcpy(pszNew, papszEnv[iEnvVar], cchVar + 1); /* preserve variable name case */
+ memcpy(&pszNew[cchVar + 1], &pszValue[cchVar + 1], cchNewValue);
+ memcpy(&pszNew[cchVar + 1 + cchNewValue], &papszEnv[iEnvVar][cchVar + 1], cchOldValue + 1);
}
+
+ if (cVerbosity > 0)
+ warnx("replacing '%s' with '%s'", papszEnv[iEnvVar], pszNew);
+ free(papszEnv[iEnvVar]);
+ papszEnv[iEnvVar] = pszNew;
+
+ return kBuiltinOptEnvRemoveDuplicates(papszEnv, cEnvVars, cVerbosity, pszValue, cchVar, iEnvVar);
+ }
}
+ return kBuiltinOptEnvAddVar(ppapszEnv, pcEnvVars, pcAllocatedEnvVars, cVerbosity, pszValue);
}
- else
- return errx(1, "Missing '=': -E %s", pszValue);
+ return errx(1, "Missing '=': -E %s", pszValue);
+}
- return 0;
+
+/**
+ * Handles the --append var=value option.
+ *
+ * @returns 0 on success, non-zero exit code on error.
+ * @param ppapszEnv The environment vector pointer.
+ * @param pcEnvVars Pointer to the variable holding the number of
+ * environment variables held by @a papszEnv.
+ * @param pcAllocatedEnvVars Pointer to the variable holding max size of the
+ * environment vector.
+ * @param cVerbosity The verbosity level.
+ * @param pszValue The var=value string to apply.
+ */
+int kBuiltinOptEnvAppend(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAllocatedEnvVars, int cVerbosity, const char *pszValue)
+{
+ return kBuiltinOptEnvAppendPrepend(ppapszEnv, pcEnvVars, pcAllocatedEnvVars, cVerbosity, pszValue, 1 /*fAppend*/);
+}
+
+
+/**
+ * Handles the --prepend var=value option.
+ *
+ * @returns 0 on success, non-zero exit code on error.
+ * @param ppapszEnv The environment vector pointer.
+ * @param pcEnvVars Pointer to the variable holding the number of
+ * environment variables held by @a papszEnv.
+ * @param pcAllocatedEnvVars Pointer to the variable holding max size of the
+ * environment vector.
+ * @param cVerbosity The verbosity level.
+ * @param pszValue The var=value string to apply.
+ */
+int kBuiltinOptEnvPrepend(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAllocatedEnvVars, int cVerbosity, const char *pszValue)
+{
+ return kBuiltinOptEnvAppendPrepend(ppapszEnv, pcEnvVars, pcAllocatedEnvVars, cVerbosity, pszValue, 0 /*fAppend*/);
}
diff --git a/src/kmk/kmkbuiltin/echo.c b/src/kmk/kmkbuiltin/echo.c
index dff8cb2..a0153ef 100644
--- a/src/kmk/kmkbuiltin/echo.c
+++ b/src/kmk/kmkbuiltin/echo.c
@@ -72,20 +72,22 @@ static void
errexit(const char *prog, const char *reason)
{
char *errstr = strerror(errno);
+ ssize_t cchIgn = 0; /* this is to shut up irrelevant warnings on linux. */
#ifdef _MSC_VER
int doserrno = _doserrno;
- char szDosErr[48];
- sprintf(szDosErr, " (doserrno=%d)", doserrno);
+ char szDosErr[48];
+ sprintf(szDosErr, " (doserrno=%d)", doserrno);
#endif
- write(STDERR_FILENO, prog, strlen(prog));
- write(STDERR_FILENO, ": ", 2);
- write(STDERR_FILENO, reason, strlen(reason));
- write(STDERR_FILENO, ": ", 2);
- write(STDERR_FILENO, errstr, strlen(errstr));
+ cchIgn += write(STDERR_FILENO, prog, strlen(prog));
+ cchIgn += write(STDERR_FILENO, ": ", 2);
+ cchIgn += write(STDERR_FILENO, reason, strlen(reason));
+ cchIgn += write(STDERR_FILENO, ": ", 2);
+ cchIgn += write(STDERR_FILENO, errstr, strlen(errstr));
#ifdef _MSC_VER
- write(STDERR_FILENO, szDosErr, strlen(szDosErr));
+ cchIgn += write(STDERR_FILENO, szDosErr, strlen(szDosErr));
#endif
- write(STDERR_FILENO, "\n", 1);
+ cchIgn += write(STDERR_FILENO, "\n", 1);
+ (void)cchIgn;
}
int
diff --git a/src/kmk/kmkbuiltin/err.c b/src/kmk/kmkbuiltin/err.c
index 90d99e4..da0a27f 100644
--- a/src/kmk/kmkbuiltin/err.c
+++ b/src/kmk/kmkbuiltin/err.c
@@ -1,4 +1,4 @@
-/* $Id: err.c 2911 2016-09-10 11:16:59Z bird $ */
+/* $Id: err.c 3065 2017-09-30 12:52:35Z bird $ */
/** @file
* Override err.h so we get the program name right.
*/
@@ -54,18 +54,18 @@ int err(int eval, const char *fmt, ...)
one go so it won't be split by other output. */
char szMsg[4096];
int cchMsg = snprintf(szMsg, sizeof(szMsg), "%s: ", g_progname);
- if (cchMsg < sizeof(szMsg) - 1 && cchMsg > 0)
+ if (cchMsg < (int)sizeof(szMsg) - 1 && cchMsg > 0)
{
int cchMsg2;
va_start(args, fmt);
cchMsg += cchMsg2 = vsnprintf(&szMsg[cchMsg], sizeof(szMsg) - cchMsg, fmt, args);
va_end(args);
- if ( cchMsg < sizeof(szMsg) - 1
+ if ( cchMsg < (int)sizeof(szMsg) - 1
&& cchMsg2 >= 0)
{
cchMsg += cchMsg2 = snprintf(&szMsg[cchMsg], sizeof(szMsg) - cchMsg, ": %s\n", strerror(error));
- if ( cchMsg < sizeof(szMsg) - 1
+ if ( cchMsg < (int)sizeof(szMsg) - 1
&& cchMsg2 >= 0)
{
fwrite(szMsg, cchMsg, 1, stderr);
@@ -95,14 +95,14 @@ int errx(int eval, const char *fmt, ...)
one go so it won't be split by other output. */
char szMsg[4096];
int cchMsg = snprintf(szMsg, sizeof(szMsg), "%s: ", g_progname);
- if (cchMsg < sizeof(szMsg) - 1 && cchMsg > 0)
+ if (cchMsg < (int)sizeof(szMsg) - 1 && cchMsg > 0)
{
int cchMsg2;
va_start(args, fmt);
cchMsg += cchMsg2 = vsnprintf(&szMsg[cchMsg], sizeof(szMsg) - cchMsg, fmt, args);
va_end(args);
- if ( cchMsg < sizeof(szMsg) - 1
+ if ( cchMsg < (int)sizeof(szMsg) - 1
&& cchMsg2 >= 0)
{
szMsg[cchMsg++] = '\n';
@@ -131,18 +131,18 @@ void warn(const char *fmt, ...)
one go so it won't be split by other output. */
char szMsg[4096];
int cchMsg = snprintf(szMsg, sizeof(szMsg), "%s: ", g_progname);
- if (cchMsg < sizeof(szMsg) - 1 && cchMsg > 0)
+ if (cchMsg < (int)sizeof(szMsg) - 1 && cchMsg > 0)
{
int cchMsg2;
va_start(args, fmt);
cchMsg += cchMsg2 = vsnprintf(&szMsg[cchMsg], sizeof(szMsg) - cchMsg, fmt, args);
va_end(args);
- if ( cchMsg < sizeof(szMsg) - 1
+ if ( cchMsg < (int)sizeof(szMsg) - 1
&& cchMsg2 >= 0)
{
cchMsg += cchMsg2 = snprintf(&szMsg[cchMsg], sizeof(szMsg) - cchMsg, ": %s\n", strerror(error));
- if ( cchMsg < sizeof(szMsg) - 1
+ if ( cchMsg < (int)sizeof(szMsg) - 1
&& cchMsg2 >= 0)
{
fwrite(szMsg, cchMsg, 1, stderr);
@@ -168,14 +168,14 @@ void warnx(const char *fmt, ...)
one go so it won't be split by other output. */
char szMsg[4096];
int cchMsg = snprintf(szMsg, sizeof(szMsg), "%s: ", g_progname);
- if (cchMsg < sizeof(szMsg) - 1 && cchMsg > 0)
+ if (cchMsg < (int)sizeof(szMsg) - 1 && cchMsg > 0)
{
int cchMsg2;
va_start(args, fmt);
cchMsg += cchMsg2 = vsnprintf(&szMsg[cchMsg], sizeof(szMsg) - cchMsg, fmt, args);
va_end(args);
- if ( cchMsg < sizeof(szMsg) - 1
+ if ( cchMsg < (int)sizeof(szMsg) - 1
&& cchMsg2 >= 0)
{
szMsg[cchMsg++] = '\n';
diff --git a/src/kmk/kmkbuiltin/install.c b/src/kmk/kmkbuiltin/install.c
index 13bec72..afccab1 100644
--- a/src/kmk/kmkbuiltin/install.c
+++ b/src/kmk/kmkbuiltin/install.c
@@ -73,6 +73,10 @@ __FBSDID("$FreeBSD: src/usr.bin/xinstall/xinstall.c,v 1.66 2005/01/25 14:34:57 s
#ifndef __HAIKU__
# include <sysexits.h>
#endif
+#ifdef __NetBSD__
+# include <util.h>
+# define strtofflags(a, b, c) string_to_flags(a, b, c)
+#endif
#include <unistd.h>
#if defined(__EMX__) || defined(_MSC_VER)
# include <process.h>
diff --git a/src/kmk/kmkbuiltin/kDepObj.c b/src/kmk/kmkbuiltin/kDepObj.c
index 5cb090a..3445798 100644
--- a/src/kmk/kmkbuiltin/kDepObj.c
+++ b/src/kmk/kmkbuiltin/kDepObj.c
@@ -1,4 +1,4 @@
-/* $Id: kDepObj.c 2955 2016-09-21 19:05:53Z bird $ */
+/* $Id: kDepObj.c 3064 2017-09-30 11:38:48Z bird $ */
/** @file
* kDepObj - Extract dependency information from an object file.
*/
@@ -52,9 +52,11 @@
#if 0
# define dprintf(a) printf a
# define dump(pb, cb, offBase) depHexDump(pb,cb,offBase)
+# define WITH_DPRINTF
#else
# define dprintf(a) do {} while (0)
# define dump(pb, cb, offBase) do {} while (0)
+# undef WITH_DPRINTF
#endif
/** @name OMF defines
@@ -386,13 +388,16 @@ int kDepObjOMFParse(const KU8 *pbFile, KSIZE cbFile)
KU16 uSeg = kDepObjOMFGetIndex(&uData, &cbRecLeft);
if (uSeg == KU16_MAX)
return kDepErr(1, "%#07lx - Bad LINNUM32 record\n", (long)((const KU8 *)pHdr - pbFile));
+ K_NOREF(uGrp);
if (uLinNumType == KU8_MAX)
{
+#ifdef WITH_DPRINTF
static const char * const s_apsz[5] =
{
"source file", "listing file", "source & listing file", "file names table", "path table"
};
+#endif
KU16 uLine;
KU8 uReserved;
KU16 uSeg2;
@@ -403,16 +408,17 @@ int kDepObjOMFParse(const KU8 *pbFile, KSIZE cbFile)
cbRecLeft -= 2+1+1+2+2+4;
uLine = *uData.pu16++;
uLinNumType = *uData.pu8++;
- uReserved = *uData.pu8++;
- cLinNums = *uData.pu16++;
- uSeg2 = *uData.pu16++;
- cbLinNames = *uData.pu32++;
+ uReserved = *uData.pu8++; K_NOREF(uReserved);
+ cLinNums = *uData.pu16++; K_NOREF(cLinNums);
+ uSeg2 = *uData.pu16++; K_NOREF(uSeg2);
+ cbLinNames = *uData.pu32++; K_NOREF(cbLinNames);
dprintf(("LINNUM32: uGrp=%#x uSeg=%#x uSeg2=%#x uLine=%#x (MBZ) uReserved=%#x\n",
uGrp, uSeg, uSeg2, uLine, uReserved));
dprintf(("LINNUM32: cLinNums=%#x (%u) cbLinNames=%#x (%u) uLinNumType=%#x (%s)\n",
cLinNums, cLinNums, cbLinNames, cbLinNames, uLinNumType,
uLinNumType < K_ELEMENTS(s_apsz) ? s_apsz[uLinNumType] : "??"));
+
if (uLine != 0)
return kDepErr(1, "%#07lx - Bad LINNUM32 record, line %#x (MBZ)\n", (long)((const KU8 *)pHdr - pbFile), uLine);
cLinFiles = iLinFile = KU32_MAX;
@@ -478,8 +484,8 @@ int kDepObjOMFParse(const KU8 *pbFile, KSIZE cbFile)
return kDepErr(1, "%#07lx - Bad LINNUM32 record, incomplete file/path table header\n", (long)((const KU8 *)pHdr - pbFile));
cbRecLeft -= 4+4+4;
- iFirstCol = *uData.pu32++;
- cCols = *uData.pu32++;
+ iFirstCol = *uData.pu32++; K_NOREF(iFirstCol);
+ cCols = *uData.pu32++; K_NOREF(cCols);
cLinFiles = *uData.pu32++;
dprintf(("%s table header: cLinFiles=%#" KX32_PRI " (%" KU32_PRI ") iFirstCol=%" KU32_PRI " cCols=%" KU32_PRI"\n",
uLinNumType == 3 ? "file names" : "path", cLinFiles, cLinFiles, iFirstCol, cCols));
@@ -1046,7 +1052,7 @@ int kmk_builtin_kDepObj(int argc, char *argv[], char **envp)
pszValue = argv[i];
else
{
- fprintf(stderr, "%s: syntax error: The '-%c' option takes a value.\n", chOpt);
+ fprintf(stderr, "%s: syntax error: The '-%c' option takes a value.\n", argv[0], chOpt);
return 2;
}
break;
@@ -1130,7 +1136,7 @@ int kmk_builtin_kDepObj(int argc, char *argv[], char **envp)
{
if (pszIgnoreExt)
{
- fprintf(stderr, "%s: syntax error: The '-e' option can only be used once!\n");
+ fprintf(stderr, "%s: syntax error: The '-e' option can only be used once!\n", argv[0]);
return 2;
}
pszIgnoreExt = pszValue;
diff --git a/src/kmk/kmkbuiltin/kSubmit.c b/src/kmk/kmkbuiltin/kSubmit.c
index b3132a4..50d8ca5 100644
--- a/src/kmk/kmkbuiltin/kSubmit.c
+++ b/src/kmk/kmkbuiltin/kSubmit.c
@@ -1,4 +1,4 @@
-/* $Id: kSubmit.c 2959 2016-09-21 20:53:32Z bird $ */
+/* $Id: kSubmit.c 3051 2017-07-24 10:59:59Z bird $ */
/** @file
* kMk Builtin command - submit job to a kWorker.
*/
@@ -382,13 +382,26 @@ static int kSubmitSpawnWorker(PWORKERINSTANCE pWorker, int cVerbosity)
if (pWorker->OverlappedRead.hEvent != NULL)
{
char szHandleArg[32];
- const char *apszArgs[6] =
- {
- szExecutable, "--pipe", szHandleArg,
- pVarVolatile ? "--volatile" : NULL, pVarVolatile ? pVarVolatile->value : NULL,
- NULL
- };
+ extern int process_priority; /* main.c */
+ char szPriorityArg[32];
+ const char *apszArgs[10];
+ int cArgs = 0;
+ apszArgs[cArgs++] = szExecutable;
+ apszArgs[cArgs++] = "--pipe";
_snprintf(szHandleArg, sizeof(szHandleArg), "%p", hWorkerPipe);
+ apszArgs[cArgs++] = szHandleArg;
+ if (pVarVolatile)
+ {
+ apszArgs[cArgs++] = "--volatile";
+ apszArgs[cArgs++] = pVarVolatile->value;
+ }
+ if (process_priority != 0)
+ {
+ apszArgs[cArgs++] = "--priority";
+ _snprintf(szPriorityArg, sizeof(szPriorityArg), "%u", process_priority);
+ apszArgs[cArgs++] = szPriorityArg;
+ }
+ apszArgs[cArgs] = NULL;
/*
* Create the worker process.
@@ -1168,6 +1181,7 @@ static int usage(FILE *pOut, const char *argv0)
{
fprintf(pOut,
"usage: %s [-Z|--zap-env] [-E|--set <var=val>] [-U|--unset <var=val>]\n"
+ " [-A|--append <var=val>] [-D|--prepend <var=val>]\n"
" [-C|--chdir <dir>] [--wcc-brain-damage] [--no-pch-caching]\n"
" [-3|--32-bit] [-6|--64-bit] [-v]\n"
" [-P|--post-cmd <cmd> [args]] -- <program> [args]\n"
@@ -1181,6 +1195,10 @@ static int usage(FILE *pOut, const char *argv0)
" Sets an enviornment variable putenv fashion. Position dependent.\n"
" -U, --unset <var>\n"
" Removes an environment variable. Position dependent.\n"
+ " -A, --append <var>=<value>\n"
+ " Appends the given value to the environment variable.\n"
+ " -D,--prepend <var>=<value>\n"
+ " Prepends the given value to the environment variable.\n"
" -C, --chdir <dir>\n"
" Specifies the current directory for the program. Relative paths\n"
" are relative to the previous -C option. Default is getcwd value.\n"
@@ -1295,6 +1313,10 @@ int kmk_builtin_kSubmit(int argc, char **argv, char **envp, struct child *pChild
chOpt = 'V';
else if (strcmp(pszArg, "set") == 0)
chOpt = 'E';
+ else if (strcmp(pszArg, "append") == 0)
+ chOpt = 'A';
+ else if (strcmp(pszArg, "prepend") == 0)
+ chOpt = 'D';
else if (strcmp(pszArg, "unset") == 0)
chOpt = 'U';
else if ( strcmp(pszArg, "zap-env") == 0
@@ -1326,9 +1348,11 @@ int kmk_builtin_kSubmit(int argc, char **argv, char **envp, struct child *pChild
const char *pszValue = NULL;
switch (chOpt)
{
+ case 'A':
+ case 'C':
case 'E':
case 'U':
- case 'C':
+ case 'D':
case 'e':
if (*pszArg != '\0')
pszValue = pszArg + (*pszArg == ':' || *pszArg == '=');
@@ -1359,6 +1383,20 @@ int kmk_builtin_kSubmit(int argc, char **argv, char **envp, struct child *pChild
break;
return rcExit;
+ case 'A':
+ rcExit = kBuiltinOptEnvAppend(&papszEnv, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
+ pChild->environment = papszEnv;
+ if (rcExit == 0)
+ break;
+ return rcExit;
+
+ case 'D':
+ rcExit = kBuiltinOptEnvPrepend(&papszEnv, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
+ pChild->environment = papszEnv;
+ if (rcExit == 0)
+ break;
+ return rcExit;
+
case 'U':
rcExit = kBuiltinOptEnvUnset(papszEnv, &cEnvVars, cVerbosity, pszValue);
if (rcExit == 0)
diff --git a/src/kmk/kmkbuiltin/mscfakes.c b/src/kmk/kmkbuiltin/mscfakes.c
index b820dd8..26d475c 100644
--- a/src/kmk/kmkbuiltin/mscfakes.c
+++ b/src/kmk/kmkbuiltin/mscfakes.c
@@ -1,4 +1,4 @@
-/* $Id: mscfakes.c 2901 2016-09-09 15:10:24Z bird $ */
+/* $Id: mscfakes.c 3094 2017-10-14 03:32:50Z bird $ */
/** @file
* Fake Unix stuff for MSC.
*/
@@ -36,13 +36,19 @@
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
+#include <sys/timeb.h>
#include "err.h"
#include "mscfakes.h"
+#include "nt/ntutimes.h"
+#undef utimes
+#undef lutimes
+
#define timeval windows_timeval
#include <Windows.h>
#undef timeval
+
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
@@ -459,13 +465,6 @@ int snprintf(char *buf, size_t size, const char *fmt, ...)
#endif
-int utimes(const char *pszPath, const struct timeval *paTimes)
-{
- /** @todo implement me! */
- return 0;
-}
-
-
/* We override the libc write function (in our modules only, unfortunately) so
we can kludge our way around a ENOSPC problem observed on build servers
capturing STDOUT and STDERR via pipes. Apparently this may happen when the
@@ -650,6 +649,67 @@ int vasprintf(char **strp, const char *fmt, va_list va)
}
+int utimes(const char *pszPath, const struct timeval *paTimes)
+{
+ if (paTimes)
+ {
+ BirdTimeVal_T aTimes[2];
+ aTimes[0].tv_sec = paTimes[0].tv_sec;
+ aTimes[0].tv_usec = paTimes[0].tv_usec;
+ aTimes[1].tv_sec = paTimes[1].tv_sec;
+ aTimes[1].tv_usec = paTimes[1].tv_usec;
+ return birdUtimes(pszPath, aTimes);
+ }
+ return birdUtimes(pszPath, NULL);
+}
+
+
+int lutimes(const char *pszPath, const struct timeval *paTimes)
+{
+ if (paTimes)
+ {
+ BirdTimeVal_T aTimes[2];
+ aTimes[0].tv_sec = paTimes[0].tv_sec;
+ aTimes[0].tv_usec = paTimes[0].tv_usec;
+ aTimes[1].tv_sec = paTimes[1].tv_sec;
+ aTimes[1].tv_usec = paTimes[1].tv_usec;
+ return birdUtimes(pszPath, aTimes);
+ }
+ return birdUtimes(pszPath, NULL);
+}
+
+
+int gettimeofday(struct timeval *pNow, void *pvIgnored)
+{
+ struct __timeb64 Now;
+ int rc = _ftime64_s(&Now);
+ if (rc == 0)
+ {
+ pNow->tv_sec = Now.time;
+ pNow->tv_usec = Now.millitm * 1000;
+ return 0;
+ }
+ errno = rc;
+ return -1;
+}
+
+
+struct tm *localtime_r(const __time64_t *pNow, struct tm *pResult)
+{
+ int rc = _localtime64_s(pResult, pNow);
+ if (rc == 0)
+ return pResult;
+ errno = rc;
+ return NULL;
+}
+
+
+__time64_t timegm(struct tm *pNow)
+{
+ return _mkgmtime64(pNow);
+}
+
+
/**
* Checks if the given file descriptor is a pipe or not.
*
diff --git a/src/kmk/kmkbuiltin/mscfakes.h b/src/kmk/kmkbuiltin/mscfakes.h
index 379875a..904f098 100644
--- a/src/kmk/kmkbuiltin/mscfakes.h
+++ b/src/kmk/kmkbuiltin/mscfakes.h
@@ -1,4 +1,4 @@
-/* $Id: mscfakes.h 2766 2015-01-30 03:32:38Z bird $ */
+/* $Id: mscfakes.h 3092 2017-10-11 17:55:09Z bird $ */
/** @file
* Unix fakes for MSC.
*/
@@ -27,6 +27,8 @@
#define ___mscfakes_h
#ifdef _MSC_VER
+#define timeval windows_timeval
+
/* Include the config file (kmk's) so we don't need to duplicate stuff from it here. */
#include "config.h"
@@ -45,11 +47,15 @@
#include <direct.h>
#include "nt/ntstat.h"
#include "nt/ntunlink.h"
-#if defined(MSC_DO_64_BIT_IO) && _MSC_VER >= 1400 /* We want 64-bit file lengths here when possible. */
-# define off_t __int64
-# define lseek _lseeki64
+#ifdef MSC_DO_64_BIT_IO
+# if _MSC_VER >= 1400 /* We want 64-bit file lengths here when possible. */
+# define off_t __int64
+# define lseek _lseeki64
+# endif
#endif
+#undef timeval
+
#undef PATH_MAX
#define PATH_MAX _MAX_PATH
#undef MAXPATHLEN
@@ -103,13 +109,11 @@ typedef signed short int16_t;
typedef signed int int32_t;
#endif
-#if !defined(timerisset) && defined(MSCFAKES_NO_WINDOWS_H)
struct timeval
{
- long tv_sec;
+ __time64_t tv_sec;
long tv_usec;
};
-#endif
struct iovec
{
@@ -133,7 +137,6 @@ int lchmod(const char *path, mode_t mode);
int msc_chmod(const char *path, mode_t mode);
#define chmod msc_chmod
#define lchown(path, uid, gid) chown(path, uid, gid)
-#define lutimes(path, tvs) utimes(path, tvs)
int link(const char *pszDst, const char *pszLink);
int mkdir_msc(const char *path, mode_t mode);
#define mkdir(path, mode) mkdir_msc(path, mode)
@@ -157,8 +160,15 @@ int snprintf(char *buf, size_t size, const char *fmt, ...);
#endif
int symlink(const char *pszDst, const char *pszLink);
int utimes(const char *pszPath, const struct timeval *paTimes);
+int lutimes(const char *pszPath, const struct timeval *paTimes);
ssize_t writev(int fd, const struct iovec *vector, int count);
+int gettimeofday(struct timeval *pNow, void *pvIgnored);
+struct tm *localtime_r(const __time64_t *pNow, struct tm *pResult);
+__time64_t timegm(struct tm *pNow);
+#undef mktime
+#define mktime _mktime64
+
/* bird write ENOSPC hacks. */
#undef write
#define write msc_write
diff --git a/src/kmk/kmkbuiltin/redirect.c b/src/kmk/kmkbuiltin/redirect.c
index 5f5a558..699c3db 100644
--- a/src/kmk/kmkbuiltin/redirect.c
+++ b/src/kmk/kmkbuiltin/redirect.c
@@ -1,4 +1,4 @@
-/* $Id: redirect.c 2916 2016-09-15 11:41:42Z bird $ */
+/* $Id: redirect.c 3085 2017-10-03 11:01:54Z bird $ */
/** @file
* kmk_redirect - Do simple program <-> file redirection (++).
*/
@@ -26,8 +26,8 @@
/*******************************************************************************
* Header Files *
*******************************************************************************/
-#ifdef __APPLE__
-# define _POSIX_C_SOURCE 1 /* 10.4 sdk and unsetenv */
+#if defined(__APPLE__)
+/*# define _POSIX_C_SOURCE 1 / * 10.4 sdk and unsetenv * / - breaks O_CLOEXEC on 10.8 */
#endif
#include "make.h"
#include <assert.h>
@@ -44,8 +44,18 @@
# include <io.h>
# include "quote_argv.h"
#else
+# ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
+# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
+# define USE_POSIX_SPAWN
+# endif
+# elif !defined(KBUILD_OS_WINDOWS) && !defined(KBUILD_OS_OS2)
+# define USE_POSIX_SPAWN
+# endif
# include <unistd.h>
-# include <spawn.h>
+# ifdef USE_POSIX_SPAWN
+# include <spawn.h>
+# endif
+# include <sys/wait.h>
#endif
#include <k/kDefs.h>
@@ -70,10 +80,6 @@
# endif
#endif
-#if !defined(KBUILD_OS_WINDOWS) && !defined(KBUILD_OS_OS2)
-# define USE_POSIX_SPAWN
-#endif
-
/* String + strlen tuple. */
#define TUPLE(a_sz) a_sz, sizeof(a_sz) - 1
@@ -89,7 +95,7 @@ static void __cdecl ignore_invalid_parameter(const wchar_t *a, const wchar_t *b,
#endif /* _MSC_VER */
-
+#if 0 /* unused */
/**
* Safely works around MS CRT's pedantic close() function.
*
@@ -106,6 +112,7 @@ static void safeCloseFd(int fd)
close(fd);
#endif
}
+#endif /* unused */
static const char *name(const char *pszName)
@@ -175,7 +182,7 @@ typedef struct REDIRECTORDERS
kRedirectOrder_Invalid = 0,
kRedirectOrder_Close,
kRedirectOrder_Open,
- kRedirectOrder_Dup,
+ kRedirectOrder_Dup
} enmOrder;
/** The target file handle. */
int fdTarget;
@@ -382,10 +389,11 @@ static int kRedirectOpenWithoutConflict(const char *pszFilename, int fOpen, mode
#elif defined(O_CLOEXEC)
int const fNoInherit = O_CLOEXEC;
#else
-# error "port me"
+ int const fNoInherit = 0;
+# define USE_FD_CLOEXEC
#endif
int aFdTries[32];
- int cTries;
+ unsigned cTries;
int fdOpened;
#ifdef KBUILD_OS_WINDOWS
@@ -404,7 +412,9 @@ static int kRedirectOpenWithoutConflict(const char *pszFilename, int fOpen, mode
if (fdOpened != fdTarget)
return fdOpened;
#ifndef _MSC_VER /* Stupid, stupid MSVCRT! No friggin way of making a handle inheritable (or not). */
- if (fcntl(fdOpened, F_SETFD, FD_CLOEXEC) != -1)
+# ifndef USE_FD_CLOEXEC
+ if (fcntl(fdOpened, F_SETFD, 0) != -1)
+# endif
return fdOpened;
#endif
}
@@ -426,8 +436,13 @@ static int kRedirectOpenWithoutConflict(const char *pszFilename, int fOpen, mode
)
{
#ifndef _MSC_VER
- if ( fdOpened != fdTarget
+# ifdef USE_FD_CLOEXEC
+ if ( fdOpened == fdTarget
|| fcntl(fdOpened, F_SETFD, FD_CLOEXEC) != -1)
+# else
+ if ( fdOpened != fdTarget
+ || fcntl(fdOpened, F_SETFD, 0) != -1)
+# endif
#endif
{
while (cTries-- > 0)
@@ -456,6 +471,35 @@ static int kRedirectOpenWithoutConflict(const char *pszFilename, int fOpen, mode
return -1;
}
+
+/**
+ * Cleans up the file operation orders.
+ *
+ * This does not restore stuff, just closes handles we've opened for the child.
+ *
+ * @param cOrders Number of file operation orders.
+ * @param paOrders The file operation orders.
+ * @param fFailed Set if it's a failure.
+ */
+static void kRedirectCleanupFdOrders(unsigned cOrders, REDIRECTORDERS *paOrders, KBOOL fFailure)
+{
+ unsigned i = cOrders;
+ while (i-- > 0)
+ {
+ if ( paOrders[i].enmOrder == kRedirectOrder_Open
+ && paOrders[i].fdSource != -1)
+ {
+ close(paOrders[i].fdSource);
+ paOrders[i].fdSource = -1;
+ if ( fFailure
+ && paOrders[i].fRemoveOnFailure
+ && paOrders[i].pszFilename)
+ remove(paOrders[i].pszFilename);
+ }
+ }
+}
+
+
#ifndef USE_POSIX_SPAWN
/**
@@ -573,34 +617,6 @@ static int kRedirectSaveHandle(REDIRECTORDERS *pToSave, unsigned cOrders, REDIRE
/**
- * Cleans up the file operation orders.
- *
- * This does not restore stuff, just closes handles we've opened for the guest.
- *
- * @param cOrders Number of file operation orders.
- * @param paOrders The file operation orders.
- * @param fFailed Set if it's a failure.
- */
-static void kRedirectCleanupFdOrders(unsigned cOrders, REDIRECTORDERS *paOrders, KBOOL fFailure)
-{
- unsigned i = cOrders;
- while (i-- > 0)
- {
- if ( paOrders[i].enmOrder == kRedirectOrder_Open
- && paOrders[i].fdSource != -1)
- {
- close(paOrders[i].fdSource);
- paOrders[i].fdSource = -1;
- if ( fFailure
- && paOrders[i].fRemoveOnFailure
- && paOrders[i].pszFilename)
- remove(paOrders[i].pszFilename);
- }
- }
-}
-
-
-/**
* Restores the target file descriptors affected by the file operation orders.
*
* @param cOrders Number of file operation orders.
@@ -637,7 +653,7 @@ static void kRedirectRestoreFdOrders(unsigned cOrders, REDIRECTORDERS *paOrders,
}
#ifndef KBUILD_OS_WINDOWS
else
- fprintf(*ppWorkingStdErr, "%s: dup2(%d,%d) failed: %s",
+ fprintf(*ppWorkingStdErr, "%s: dup2(%d,%d) failed: %s\n",
g_progname, paOrders[i].fdSaved, paOrders[i].fdTarget, strerror(errno));
#endif
}
@@ -645,10 +661,10 @@ static void kRedirectRestoreFdOrders(unsigned cOrders, REDIRECTORDERS *paOrders,
#ifndef KBUILD_OS_WINDOWS
if (paOrders[i].fSaved != -1)
{
- if (fcntl(paOrders[i].fdTarget, F_SETFD, paOrders[i].fSaved & FD_CLOEXEC) == -1)
+ if (fcntl(paOrders[i].fdTarget, F_SETFD, paOrders[i].fSaved & FD_CLOEXEC) != -1)
paOrders[i].fSaved = -1;
else
- fprintf(*ppWorkingStdErr, "%s: fcntl(%d,F_SETFD,%s) failed: %s",
+ fprintf(*ppWorkingStdErr, "%s: fcntl(%d,F_SETFD,%s) failed: %s\n",
g_progname, paOrders[i].fdTarget, paOrders[i].fSaved & FD_CLOEXEC ? "FD_CLOEXEC" : "0", strerror(errno));
}
#endif
@@ -700,13 +716,13 @@ static int kRedirectExecFdOrders(unsigned cOrders, REDIRECTORDERS *paOrders, FIL
|| errno == EBADF)
rcExit = 0;
else
- fprintf(*ppWorkingStdErr, "%s: fcntl(%d,F_SETFD,FD_CLOEXEC) failed: %s",
+ fprintf(*ppWorkingStdErr, "%s: fcntl(%d,F_SETFD,FD_CLOEXEC) failed: %s\n",
g_progname, fdTarget, strerror(errno));
}
else if (errno == EBADF)
rcExit = 0;
else
- fprintf(*ppWorkingStdErr, "%s: fcntl(%d,F_GETFD,0) failed: %s", g_progname, fdTarget, strerror(errno));
+ fprintf(*ppWorkingStdErr, "%s: fcntl(%d,F_GETFD,0) failed: %s\n", g_progname, fdTarget, strerror(errno));
}
# endif
else
@@ -724,10 +740,10 @@ static int kRedirectExecFdOrders(unsigned cOrders, REDIRECTORDERS *paOrders, FIL
else
{
if (paOrders[i].enmOrder == kRedirectOrder_Open)
- fprintf(*ppWorkingStdErr, "%s: dup2(%d [%s],%d) failed: %s", g_progname, paOrders[i].fdSource,
+ fprintf(*ppWorkingStdErr, "%s: dup2(%d [%s],%d) failed: %s\n", g_progname, paOrders[i].fdSource,
paOrders[i].pszFilename, paOrders[i].fdTarget, strerror(errno));
else
- fprintf(*ppWorkingStdErr, "%s: dup2(%d,%d) failed: %s",
+ fprintf(*ppWorkingStdErr, "%s: dup2(%d,%d) failed: %s\n",
g_progname, paOrders[i].fdSource, paOrders[i].fdTarget, strerror(errno));
rcExit = 10;
}
@@ -762,7 +778,7 @@ static int kRedirectExecFdOrders(unsigned cOrders, REDIRECTORDERS *paOrders, FIL
* @param papszArgs The child argument vector.
* @param fWatcomBrainDamage Whether MSC need to do quoting according to
* weird Watcom WCC rules.
- * @param papszEnv The child environment vector.
+ * @param papszEnvVars The child environment vector.
* @param pszCwd The current working directory of the child.
* @param pszSavedCwd The saved current working directory. This is
* NULL if the CWD doesn't need changing.
@@ -776,7 +792,7 @@ static int kRedirectExecFdOrders(unsigned cOrders, REDIRECTORDERS *paOrders, FIL
* @param pfIsChildExitCode Where to indicate whether the return exit code
* is from the child or from our setup efforts.
*/
-static int kRedirectDoSpawn(const char *pszExecutable, int cArgs, char **papszArgs, int fWatcomBrainDamage, char **papszEnv,
+static int kRedirectDoSpawn(const char *pszExecutable, int cArgs, char **papszArgs, int fWatcomBrainDamage, char **papszEnvVars,
const char *pszCwd, const char *pszSavedCwd, unsigned cOrders, REDIRECTORDERS *paOrders,
#ifdef USE_POSIX_SPAWN
posix_spawn_file_actions_t *pFileActions,
@@ -787,7 +803,7 @@ static int kRedirectDoSpawn(const char *pszExecutable, int cArgs, char **papszAr
#endif
KBOOL *pfIsChildExitCode)
{
- int rcExit;
+ int rcExit = 0;
int i;
#ifdef _MSC_VER
char **papszArgsOriginal = papszArgs;
@@ -862,7 +878,7 @@ static int kRedirectDoSpawn(const char *pszExecutable, int cArgs, char **papszAr
*/
#if defined(KBUILD_OS_WINDOWS)
/* Windows is slightly complicated due to handles and sub_proc.c. */
- HANDLE hProcess = (HANDLE)_spawnvpe(_P_NOWAIT, pszExecutable, papszArgs, papszEnv);
+ HANDLE hProcess = (HANDLE)_spawnvpe(_P_NOWAIT, pszExecutable, papszArgs, papszEnvVars);
kRedirectRestoreFdOrders(cOrders, paOrders, &pWorkingStdErr);
if ((intptr_t)hProcess != -1)
{
@@ -897,7 +913,7 @@ static int kRedirectDoSpawn(const char *pszExecutable, int cArgs, char **papszAr
rcExit = err(10, "_spawnvpe(%s) failed", pszExecutable);
# elif defined(KBUILD_OS_OS2)
- *pPidSpawned = _spawnve(_P_NOWAIT, pszExecutable, papszArgs, papszEnv);
+ *pPidSpawned = _spawnvpe(P_NOWAIT, pszExecutable, papszArgs, papszEnvVars);
kRedirectRestoreFdOrders(cOrders, paOrders, &pWorkingStdErr);
if (*pPidSpawned != -1)
{
@@ -929,7 +945,11 @@ static int kRedirectDoSpawn(const char *pszExecutable, int cArgs, char **papszAr
*/
# if defined(KBUILD_OS_WINDOWS) || defined(KBUILD_OS_OS2)
errno = 0;
- rcExit = (int)_spawnvpe(_P_WAIT, pszExecutable, papszArgs, papszEnv);
+# if defined(KBUILD_OS_WINDOWS)
+ rcExit = (int)_spawnvpe(_P_WAIT, pszExecutable, papszArgs, papszEnvVars);
+# else
+ rcExit = (int)_spawnvpe(P_WAIT, pszExecutable, papszArgs, papszEnvVars);
+# endif
kRedirectRestoreFdOrders(cOrders, paOrders, &pWorkingStdErr);
if (rcExit != -1 || errno == 0)
{
@@ -1022,7 +1042,7 @@ int main(int argc, char **argv, char **envp)
int iArg;
const char *pszExecutable = NULL;
- char **papszEnv = NULL;
+ char **papszEnvVars = NULL;
unsigned cAllocatedEnvVars;
unsigned iEnvVar;
unsigned cEnvVars;
@@ -1056,11 +1076,11 @@ int main(int argc, char **argv, char **envp)
#if defined(KMK)
/* We get it from kmk and just count it: */
- papszEnv = pChild->environment;
- if (!papszEnv)
- pChild->environment = papszEnv = target_environment(pChild->file);
+ papszEnvVars = pChild->environment;
+ if (!papszEnvVars)
+ pChild->environment = papszEnvVars = target_environment(pChild->file);
cEnvVars = 0;
- while (papszEnv[cEnvVars] != NULL)
+ while (papszEnvVars[cEnvVars] != NULL)
cEnvVars++;
cAllocatedEnvVars = cEnvVars;
#else
@@ -1070,20 +1090,20 @@ int main(int argc, char **argv, char **envp)
cEnvVars++;
cAllocatedEnvVars = cEnvVars + 4;
- papszEnv = malloc((cAllocatedEnvVars + 1) * sizeof(papszEnv));
- if (!papszEnv)
+ papszEnvVars = malloc((cAllocatedEnvVars + 1) * sizeof(papszEnvVars));
+ if (!papszEnvVars)
return errx(9, "out of memory!");
iEnvVar = cEnvVars;
- papszEnv[iEnvVar] = NULL;
+ papszEnvVars[iEnvVar] = NULL;
while (iEnvVar-- > 0)
{
- papszEnv[iEnvVar] = strdup(envp[iEnvVar]);
- if (!papszEnv[iEnvVar])
+ papszEnvVars[iEnvVar] = strdup(envp[iEnvVar]);
+ if (!papszEnvVars[iEnvVar])
{
while (iEnvVar-- > 0)
- free(papszEnv[iEnvVar]);
- free(papszEnv);
+ free(papszEnvVars[iEnvVar]);
+ free(papszEnvVars);
return errx(9, "out of memory!");
}
}
@@ -1114,11 +1134,16 @@ int main(int argc, char **argv, char **envp)
pszArg++;
if (chOpt == '-')
{
- /* '--' indicates where the bits to execute start. */
+ /* '--' indicates where the bits to execute start. Check if we're
+ relaunching ourselves here and just continue parsing if we are. */
if (*pszArg == '\0')
{
iArg++;
- break;
+ if ( iArg >= argc
+ || ( strcmp(argv[iArg], "kmk_builtin_redirect") != 0
+ && strcmp(argv[iArg], argv[0]) != 0))
+ break;
+ continue;
}
if ( strcmp(pszArg, "wcc-brain-damage") == 0
@@ -1136,6 +1161,10 @@ int main(int argc, char **argv, char **envp)
else if ( strcmp(pszArg, "set") == 0
|| strcmp(pszArg, "env") == 0)
chOpt = 'E';
+ else if (strcmp(pszArg, "append") == 0)
+ chOpt = 'A';
+ else if (strcmp(pszArg, "prepend") == 0)
+ chOpt = 'D';
else if (strcmp(pszArg, "unset") == 0)
chOpt = 'U';
else if ( strcmp(pszArg, "zap-env") == 0
@@ -1176,6 +1205,8 @@ int main(int argc, char **argv, char **envp)
* Get option value first, if the option takes one.
*/
if ( chOpt == 'E'
+ || chOpt == 'A'
+ || chOpt == 'D'
|| chOpt == 'U'
|| chOpt == 'C'
|| chOpt == 'c'
@@ -1214,7 +1245,7 @@ int main(int argc, char **argv, char **envp)
if (apszSavedLibPaths[ulVar] == NULL)
{
/* The max length is supposed to be 1024 bytes. */
- apszSavedLibPaths[ulVar] = calloc(1024 * 2);
+ apszSavedLibPaths[ulVar] = calloc(1024, 2);
if (apszSavedLibPaths[ulVar])
{
rc = DosQueryExtLIBPATH(apszSavedLibPaths[ulVar], ulVar);
@@ -1244,9 +1275,9 @@ int main(int argc, char **argv, char **envp)
{
if (pchEqual[1] != '\0')
{
- rcExit = kBuiltinOptEnvSet(&papszEnv, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
+ rcExit = kBuiltinOptEnvSet(&papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
#ifdef KMK
- pChild->environment = papszEnv;
+ pChild->environment = papszEnvVars;
#endif
}
else
@@ -1255,7 +1286,7 @@ int main(int argc, char **argv, char **envp)
if (pszCopy)
{
pszCopy[pchEqual - pszValue] = '\0';
- rcExit = kBuiltinOptEnvUnset(papszEnv, &cEnvVars, cVerbosity, pszCopy);
+ rcExit = kBuiltinOptEnvUnset(papszEnvVars, &cEnvVars, cVerbosity, pszCopy);
free(pszCopy);
}
else
@@ -1268,6 +1299,25 @@ int main(int argc, char **argv, char **envp)
}
/*
+ * Append or prepend value to and environment variable.
+ */
+ if (chOpt == 'A' || chOpt == 'D')
+ {
+#ifdef KBUILD_OS_OS2
+ if ( strcmp(pszValue, "BEGINLIBPATH") == 0
+ || strcmp(pszValue, "ENDLIBPATH") == 0
+ || strcmp(pszValue, "LIBPATHSTRICT") == 0)
+ rcExit = errx(2, "error: '%s' cannot currently be appended or prepended to. Please use -E/--set for now.", pszValue);
+ else
+#endif
+ if (chOpt == 'A')
+ rcExit = kBuiltinOptEnvAppend(&papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
+ else
+ rcExit = kBuiltinOptEnvPrepend(&papszEnvVars, &cEnvVars, &cAllocatedEnvVars, cVerbosity, pszValue);
+ continue;
+ }
+
+ /*
* Unset environment variable.
*/
if (chOpt == 'U')
@@ -1279,7 +1329,7 @@ int main(int argc, char **argv, char **envp)
rcExit = errx(2, "error: '%s' cannot be unset, only set to an empty value using -E/--set.", pszValue);
else
#endif
- rcExit = kBuiltinOptEnvUnset(papszEnv, &cEnvVars, cVerbosity, pszValue);
+ rcExit = kBuiltinOptEnvUnset(papszEnvVars, &cEnvVars, cVerbosity, pszValue);
continue;
}
@@ -1290,8 +1340,8 @@ int main(int argc, char **argv, char **envp)
|| chOpt == 'i' /* GNU env compatibility. */ )
{
for (iEnvVar = 0; iEnvVar < cEnvVars; iEnvVar++)
- free(papszEnv[iEnvVar]);
- papszEnv[0] = NULL;
+ free(papszEnvVars[iEnvVar]);
+ papszEnvVars[0] = NULL;
cEnvVars = 0;
continue;
}
@@ -1576,7 +1626,7 @@ int main(int argc, char **argv, char **envp)
cOrders++;
#ifdef USE_POSIX_SPAWN
- if (fdOpened != fdSource)
+ if (fdOpened != fd)
{
rcExit = posix_spawn_file_actions_adddup2(&FileActions, fdOpened, fd);
if (rcExit != 0)
@@ -1606,7 +1656,7 @@ int main(int argc, char **argv, char **envp)
/*
* Do the spawning in a separate function (main is far to large as it is by now).
*/
- rcExit = kRedirectDoSpawn(pszExecutable, argc - iArg, &argv[iArg], fWatcomBrainDamage, papszEnv, szCwd, pszSavedCwd,
+ rcExit = kRedirectDoSpawn(pszExecutable, argc - iArg, &argv[iArg], fWatcomBrainDamage, papszEnvVars, szCwd, pszSavedCwd,
#ifdef USE_POSIX_SPAWN
cOrders, aOrders, &FileActions, cVerbosity,
#else
@@ -1638,8 +1688,8 @@ int main(int argc, char **argv, char **envp)
#ifndef KMK
iEnvVar = cEnvVars;
while (iEnvVar-- > 0)
- free(papszEnv[iEnvVar]);
- free(papszEnv);
+ free(papszEnvVars[iEnvVar]);
+ free(papszEnvVars);
#endif
#ifdef KBUILD_OS_OS2
for (ulLibPath = 0; ulLibPath < K_ELEMENTS(apszSavedLibPaths); ulLibPath++)
@@ -1649,7 +1699,7 @@ int main(int argc, char **argv, char **envp)
if (rc != 0)
warnx("DosSetExtLIBPATH('%s',%u) failed with %u when restoring the original values!",
apszSavedLibPaths[ulLibPath], ulLibPath, rc);
- free(apszSavedLibPaths[ulLibPath])
+ free(apszSavedLibPaths[ulLibPath]);
}
#endif
diff --git a/src/kmk/kmkbuiltin/rm.c b/src/kmk/kmkbuiltin/rm.c
index 986f991..afa57e1 100644
--- a/src/kmk/kmkbuiltin/rm.c
+++ b/src/kmk/kmkbuiltin/rm.c
@@ -66,6 +66,10 @@ static char sccsid[] = "@(#)rm.c 8.5 (Berkeley) 4/18/94";
#ifdef __HAIKU__
# include "haikufakes.h"
#endif
+#ifdef __NetBSD__
+# include <util.h>
+# define fflagstostr(flags) flags_to_string(flags, "")
+#endif
#ifdef KBUILD_OS_WINDOWS
# ifdef _MSC_VER
# include "mscfakes.h"
diff --git a/src/kmk/kmkbuiltin/test.c b/src/kmk/kmkbuiltin/test.c
index 69dc2db..74e6d69 100644
--- a/src/kmk/kmkbuiltin/test.c
+++ b/src/kmk/kmkbuiltin/test.c
@@ -277,7 +277,7 @@ int kmk_builtin_test(int argc, char **argv, char **envp
# endif
#else /* in kmk */
/* let job.c spawn the process, make a job.c style argv_spawn copy. */
- char *buf, *cur, **argv_new;
+ char *cur, **argv_new;
size_t sz = 0;
int argc_new = 0;
while (argv_spawn[argc_new]) {
@@ -287,7 +287,7 @@ int kmk_builtin_test(int argc, char **argv, char **envp
}
argv_new = xmalloc((argc_new + 1) * sizeof(char *));
- buf = cur = xmalloc(sz);
+ cur = xmalloc(sz);
for (i = 0; i < argc_new; i++) {
size_t len = strlen(argv_spawn[i]) + 1;
argv_new[i] = memcpy(cur, argv_spawn[i], len);
diff --git a/src/kmk/kmkbuiltin/touch.c b/src/kmk/kmkbuiltin/touch.c
new file mode 100644
index 0000000..2f4adcd
--- /dev/null
+++ b/src/kmk/kmkbuiltin/touch.c
@@ -0,0 +1,967 @@
+/* $Id: touch.c 3074 2017-10-02 09:09:57Z bird $ */
+/** @file
+ * kmk_touch - Simple touch implementation.
+ */
+
+/*
+ * Copyright (c) 2017 knut st. osmundsen <bird-kBuild-spamx at anduin.net>
+ *
+ * This file is part of kBuild.
+ *
+ * kBuild is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * kBuild is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with kBuild. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "make.h"
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#if defined(_MSC_VER)
+# include <ctype.h>
+# include <io.h>
+# include <sys/timeb.h>
+#else
+# include <unistd.h>
+#endif
+
+#include <k/kDefs.h>
+#include <k/kTypes.h>
+#include "err.h"
+#include "kbuild_version.h"
+#include "kmkbuiltin.h"
+
+#ifdef _MSC_VER
+# include "nt/ntstat.h"
+# undef FILE_TIMESTAMP_HI_RES
+# define FILE_TIMESTAMP_HI_RES 1
+#endif
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+/** The program name to use in message. */
+#ifdef KMK
+# define TOUCH_NAME "kmk_builtin_touch"
+#else
+# define TOUCH_NAME "kmk_touch"
+#endif
+/** Converts a two digit decimal field to a number. */
+#define TWO_CHARS_TO_INT(chHigh, chLow) ( ((unsigned)(chHigh) - (unsigned)'0') * 10 + ((unsigned)(chLow) - (unsigned)'0') )
+/** Checks an alleged digit. */
+#define IS_DIGIT(chDigit, uMax) ( ((unsigned)(chDigit) - (unsigned)'0') <= (unsigned)(uMax) )
+
+
+/*********************************************************************************************************************************
+* Structures and Typedefs *
+*********************************************************************************************************************************/
+typedef enum KMKTOUCHTARGET
+{
+ kTouchAccessAndModify,
+ kTouchAccessOnly,
+ kTouchModifyOnly
+} KMKTOUCHTARGET;
+
+typedef enum KMKTOUCHACTION
+{
+ kTouchActionCurrent,
+ kTouchActionSet,
+ kTouchActionAdjust
+} KMKTOUCHACTION;
+
+
+typedef struct KMKTOUCHOPTS
+{
+ /** What timestamps to modify on the files. */
+ KMKTOUCHTARGET enmWhatToTouch;
+ /** How to update the time. */
+ KMKTOUCHACTION enmAction;
+ /** Whether to create files (K_TRUE) or ignore missing (K_FALSE). */
+ KBOOL fCreate;
+ /** Whether to dereference files. */
+ KBOOL fDereference;
+ /** The new access time value. */
+ struct timeval NewATime;
+ /** The new modified time value. */
+ struct timeval NewMTime;
+
+ /** Number of files. */
+ int cFiles;
+ /** The specified files. */
+ char **papszFiles;
+} KMKTOUCHOPTS;
+typedef KMKTOUCHOPTS *PKMKTOUCHOPTS;
+
+
+
+static int touch_error(const char *pszMsg, ...)
+{
+ va_list va;
+ fputs(TOUCH_NAME ": error: ", stderr);
+ va_start(va, pszMsg);
+ vfprintf(stderr, pszMsg, va);
+ va_end(va);
+ fputc('\n', stderr);
+ return 1;
+}
+
+static int touch_syntax(const char *pszMsg, ...)
+{
+ va_list va;
+ fputs(TOUCH_NAME ": syntax error: ", stderr);
+ va_start(va, pszMsg);
+ vfprintf(stderr, pszMsg, va);
+ va_end(va);
+ fputc('\n', stderr);
+ return 2;
+}
+
+static int touch_usage(void)
+{
+ fputs("Usage: " TOUCH_NAME " [options] [MMDDhhmm[YY]] <file1> [.. [fileN]]\n"
+ "\n"
+ "Options:\n"
+ " -A [-][[hh]mm]SS, --adjust=[-][[hh]mm]SS\n"
+ " Adjust timestamps by given delta.\n"
+ " -a, --time=atime, --time=access\n"
+ " Only change the accessed timestamp.\n"
+ " -c, --no-create\n"
+ " Ignore missing files and don't create them. (default create empty file)\n"
+ " -d YYYY-MM-DDThh:mm:SS[.frac][tz], --date=YYYY-MM-DDThh:mm:SS[.frac][tz]\n"
+ " Set the timestamps to the given one.\n"
+ " -f\n"
+ " Ignored for compatbility reasons.\n"
+ " -h, --no-dereference\n"
+ " Don't follow links, touch links. (Not applicable to -r.)\n"
+ " -m, --time=mtime, --time=modify\n"
+ " Only changed the modified timestamp.\n"
+ " -r <file>, --reference=<file>\n"
+ " Take the timestamps from <file>.\n"
+ " -t [[CC]YY]MMDDhhmm[.SS]\n"
+ " Set the timestamps to the given one.\n"
+ "\n"
+ "Note. For compatibility reasons the first file can be taken to be a 8 or 10\n"
+ " character long timestamp if it matches the given pattern and none of\n"
+ " the -A, -d, --date, -r, --reference, or -t options are given. So, use\n"
+ " absolute or relative paths when specifying more than one file.\n"
+ , stdout);
+ return 0;
+}
+
+
+#if K_OS == K_OS_SOLARIS
+/**
+ * Solaris doesn't have lutimes because System V doesn't believe in stuff like file modes on symbolic links.
+ */
+static int lutimes(const char *pszFile, struct timeval aTimes[2])
+{
+ struct stat Stat;
+ if (stat(pszFile, &Stat) != -1)
+ {
+ if (!S_ISLNK(Stat.st_mode))
+ return utimes(pszFile, aTimes);
+ return 0;
+ }
+ return -1;
+}
+#endif
+
+
+/**
+ * Parses adjustment value: [-][[hh]mm]SS
+ */
+static int touch_parse_adjust(const char *pszValue, int *piAdjustValue)
+{
+ const char * const pszInValue = pszValue;
+ size_t cchValue = strlen(pszValue);
+ KBOOL fNegative = K_FALSE;
+
+ /* Deal with negativity */
+ if (pszValue[0] == '-')
+ {
+ fNegative = K_TRUE;
+ pszValue++;
+ cchValue--;
+ }
+
+ /* Validate and convert. */
+ *piAdjustValue = 0;
+ switch (cchValue)
+ {
+ case 6:
+ if ( !IS_DIGIT(pszValue[0], 9)
+ || !IS_DIGIT(pszValue[0], 9))
+ return touch_syntax("Malformed hour part of -A value: %s", pszInValue);
+ *piAdjustValue = TWO_CHARS_TO_INT(pszValue[0], pszValue[1]) * 60 * 60;
+ /* fall thru */
+ case 4:
+ if ( !IS_DIGIT(pszValue[cchValue - 4], 9) /* don't bother limit to 60 minutes */
+ || !IS_DIGIT(pszValue[cchValue - 3], 9))
+ return touch_syntax("Malformed minute part of -A value: %s", pszInValue);
+ *piAdjustValue += TWO_CHARS_TO_INT(pszValue[cchValue - 4], pszValue[cchValue - 3]) * 60;
+ /* fall thru */
+ case 2:
+ if ( !IS_DIGIT(pszValue[cchValue - 2], 9) /* don't bother limit to 60 seconds */
+ || !IS_DIGIT(pszValue[cchValue - 1], 9))
+ return touch_syntax("Malformed second part of -A value: %s", pszInValue);
+ *piAdjustValue += TWO_CHARS_TO_INT(pszValue[cchValue - 2], pszValue[cchValue - 1]);
+ break;
+
+ default:
+ return touch_syntax("Invalid -A value (length): %s", pszInValue);
+ }
+
+ /* Apply negativity. */
+ if (fNegative)
+ *piAdjustValue = -*piAdjustValue;
+
+ return 0;
+}
+
+
+/**
+ * Parse -d timestamp: YYYY-MM-DDThh:mm:SS[.frac][tz]
+ */
+static int touch_parse_d_ts(const char *pszTs, struct timeval *pDst)
+{
+ const char * const pszTsIn = pszTs;
+ struct tm ExpTime;
+
+ /*
+ * Validate and parse the timestamp into the tm structure.
+ */
+ memset(&ExpTime, 0, sizeof(ExpTime));
+
+ /* year */
+ if ( !IS_DIGIT(pszTs[0], 9)
+ || !IS_DIGIT(pszTs[1], 9)
+ || !IS_DIGIT(pszTs[2], 9)
+ || !IS_DIGIT(pszTs[3], 9)
+ || pszTs[4] != '-')
+ return touch_error("Malformed timestamp '%s' given to -d: expected to start with 4 digit year followed by a dash",
+ pszTsIn);
+ ExpTime.tm_year = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]) * 100
+ + TWO_CHARS_TO_INT(pszTs[2], pszTs[3])
+ - 1900;
+ pszTs += 5;
+
+ /* month */
+ if ( !IS_DIGIT(pszTs[0], 1)
+ || !IS_DIGIT(pszTs[1], 9)
+ || pszTs[2] != '-')
+ return touch_error("Malformed timestamp '%s' given to -d: expected to two digit month at position 6 followed by a dash",
+ pszTsIn);
+ ExpTime.tm_mon = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]) - 1;
+ pszTs += 3;
+
+ /* day */
+ if ( !IS_DIGIT(pszTs[0], 3)
+ || !IS_DIGIT(pszTs[1], 9)
+ || (pszTs[2] != 'T' && pszTs[2] != 't' && pszTs[2] != ' ') )
+ return touch_error("Malformed timestamp '%s' given to -d: expected to two digit day of month at position 9 followed by 'T' or space",
+ pszTsIn);
+ ExpTime.tm_mday = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]);
+ pszTs += 3;
+
+ /* hour */
+ if ( !IS_DIGIT(pszTs[0], 2)
+ || !IS_DIGIT(pszTs[1], 9)
+ || pszTs[2] != ':')
+ return touch_error("Malformed timestamp '%s' given to -d: expected to two digit hour at position 12 followed by colon",
+ pszTsIn);
+ ExpTime.tm_hour = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]);
+ pszTs += 3;
+
+ /* minute */
+ if ( !IS_DIGIT(pszTs[0], 5)
+ || !IS_DIGIT(pszTs[1], 9)
+ || pszTs[2] != ':')
+ return touch_error("Malformed timestamp '%s' given to -d: expected to two digit minute at position 15 followed by colon",
+ pszTsIn);
+ ExpTime.tm_min = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]);
+ pszTs += 3;
+
+ /* seconds */
+ if ( !IS_DIGIT(pszTs[0], 5)
+ || !IS_DIGIT(pszTs[1], 9))
+ return touch_error("Malformed timestamp '%s' given to -d: expected to two digit seconds at position 12", pszTsIn);
+ ExpTime.tm_sec = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]);
+ pszTs += 2;
+
+ /* fraction */
+ pDst->tv_usec = 0;
+ if (*pszTs == '.' || *pszTs == ',')
+ {
+ int iFactor;
+
+ pszTs++;
+ if (!IS_DIGIT(*pszTs, 9))
+ return touch_error("Malformed timestamp '%s' given to -d: empty fraction", pszTsIn);
+
+ iFactor = 100000;
+ do
+ {
+ pDst->tv_usec += ((unsigned)*pszTs - (unsigned)'0') * iFactor;
+ iFactor /= 10;
+ pszTs++;
+ } while (IS_DIGIT(*pszTs, 9));
+ }
+
+ /* zulu time indicator */
+ ExpTime.tm_isdst = -1;
+ if (*pszTs == 'Z' || *pszTs == 'z')
+ {
+ ExpTime.tm_isdst = 0;
+ pszTs++;
+ if (*pszTs != '\0')
+ return touch_error("Malformed timestamp '%s' given to -d: Unexpected character(s) after zulu time indicator at end of timestamp",
+ pszTsIn);
+ }
+ else if (*pszTs != '\0')
+ return touch_error("Malformed timestamp '%s' given to -d: expected to 'Z' (zulu) or nothing at end of timestamp", pszTsIn);
+
+ /*
+ * Convert to UTC seconds using either timegm or mktime.
+ */
+ ExpTime.tm_yday = -1;
+ ExpTime.tm_wday = -1;
+ if (ExpTime.tm_isdst == 0)
+ {
+#if K_OS == K_OS_SOLARIS || K_OS == K_OS_OS2
+ pDst->tv_sec = mktime(&ExpTime) - timezone; /* best we can do for now */
+#else
+ pDst->tv_sec = timegm(&ExpTime);
+#endif
+ if (pDst->tv_sec == -1)
+ return touch_error("timegm failed on '%s': %s", pszTs, strerror(errno));
+ }
+ else
+ {
+ pDst->tv_sec = mktime(&ExpTime);
+ if (pDst->tv_sec == -1)
+ return touch_error("mktime failed on '%s': %s", pszTs, strerror(errno));
+ }
+ return 0;
+}
+
+
+/**
+ * Parse -t timestamp: [[CC]YY]MMDDhhmm[.SS]
+ */
+static int touch_parse_ts(const char *pszTs, struct timeval *pDst)
+{
+ size_t const cchTs = strlen(pszTs);
+ size_t cchTsNoSec;
+ struct tm ExpTime;
+ struct tm *pExpTime;
+ struct timeval Now;
+ int rc;
+
+ /*
+ * Do some input validations first.
+ */
+ if ((cchTs & 1) && pszTs[cchTs - 3] != '.')
+ return touch_error("Invalid timestamp given to -t: %s", pszTs);
+ switch (cchTs)
+ {
+ case 8: /* MMDDhhmm */
+ case 8 + 2: /* YYMMDDhhmm */
+ case 8 + 2 + 2: /* CCYYMMDDhhmm */
+ cchTsNoSec = cchTs;
+ break;
+ case 8 + 3: /* MMDDhhmm.SS */
+ case 8 + 3 + 2: /* YYMMDDhhmm.SS */
+ case 8 + 3 + 2 + 2: /* CCYYMMDDhhmm.SS */
+ if (pszTs[cchTs - 3] != '.')
+ return touch_error("Invalid timestamp (-t) '%s': missing dot for seconds part", pszTs);
+ if ( !IS_DIGIT(pszTs[cchTs - 2], 5)
+ || !IS_DIGIT(pszTs[cchTs - 1], 9))
+ return touch_error("Invalid timestamp (-t) '%s': malformed seconds part", pszTs);
+ cchTsNoSec = cchTs - 3;
+ break;
+ default:
+ return touch_error("Invalid timestamp (-t) '%s': wrong length (%d)", pszTs, (int)cchTs);
+ }
+
+ switch (cchTsNoSec)
+ {
+ case 8 + 2 + 2: /* CCYYMMDDhhmm */
+ if ( !IS_DIGIT(pszTs[cchTsNoSec - 12], 9)
+ || !IS_DIGIT(pszTs[cchTsNoSec - 11], 9))
+ return touch_error("Invalid timestamp (-t) '%s': malformed CC part", pszTs);
+ /* fall thru */
+ case 8 + 2: /* YYMMDDhhmm */
+ if ( !IS_DIGIT(pszTs[cchTsNoSec - 10], 9)
+ || !IS_DIGIT(pszTs[cchTsNoSec - 9], 9))
+ return touch_error("Invalid timestamp (-t) '%s': malformed YY part", pszTs);
+ /* fall thru */
+ case 8: /* MMDDhhmm */
+ if ( !IS_DIGIT(pszTs[cchTsNoSec - 8], 1)
+ || !IS_DIGIT(pszTs[cchTsNoSec - 7], 9) )
+ return touch_error("Invalid timestamp (-t) '%s': malformed month part", pszTs);
+ if ( !IS_DIGIT(pszTs[cchTsNoSec - 6], 3)
+ || !IS_DIGIT(pszTs[cchTsNoSec - 5], 9) )
+ return touch_error("Invalid timestamp (-t) '%s': malformed day part", pszTs);
+ if ( !IS_DIGIT(pszTs[cchTsNoSec - 4], 2)
+ || !IS_DIGIT(pszTs[cchTsNoSec - 3], 9) )
+ return touch_error("Invalid timestamp (-t) '%s': malformed hour part", pszTs);
+ if ( !IS_DIGIT(pszTs[cchTsNoSec - 2], 5)
+ || !IS_DIGIT(pszTs[cchTsNoSec - 1], 9) )
+ return touch_error("Invalid timestamp (-t) '%s': malformed minute part", pszTs);
+ break;
+ }
+
+ /*
+ * Get the current time and explode it.
+ */
+ rc = gettimeofday(&Now, NULL);
+ if (rc != 0)
+ return touch_error("gettimeofday failed: %s", strerror(errno));
+
+ pExpTime = localtime_r(&Now.tv_sec, &ExpTime);
+ if (pExpTime == NULL)
+ return touch_error("localtime_r failed: %s", strerror(errno));
+
+ /*
+ * Do the decoding.
+ */
+ if (cchTs & 1)
+ pExpTime->tm_sec = TWO_CHARS_TO_INT(pszTs[cchTs - 2], pszTs[cchTs - 1]);
+ else
+ pExpTime->tm_sec = 0;
+
+ if (cchTsNoSec == 8 + 2 + 2) /* CCYY */
+ pExpTime->tm_year = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]) * 100
+ + TWO_CHARS_TO_INT(pszTs[2], pszTs[3])
+ - 1900;
+ else if (cchTsNoSec == 8 + 2) /* YY */
+ {
+ pExpTime->tm_year = TWO_CHARS_TO_INT(pszTs[0], pszTs[1]);
+ if (pExpTime->tm_year < 69)
+ pExpTime->tm_year += 100;
+ }
+
+ pExpTime->tm_mon = TWO_CHARS_TO_INT(pszTs[cchTsNoSec - 8], pszTs[cchTsNoSec - 7]) - 1;
+ pExpTime->tm_mday = TWO_CHARS_TO_INT(pszTs[cchTsNoSec - 6], pszTs[cchTsNoSec - 5]);
+ pExpTime->tm_hour = TWO_CHARS_TO_INT(pszTs[cchTsNoSec - 4], pszTs[cchTsNoSec - 3]);
+ pExpTime->tm_min = TWO_CHARS_TO_INT(pszTs[cchTsNoSec - 2], pszTs[cchTsNoSec - 1]);
+
+ /*
+ * Use mktime to convert to UTC seconds.
+ */
+ pExpTime->tm_isdst = -1;
+ pExpTime->tm_yday = -1;
+ pExpTime->tm_wday = -1;
+ pDst->tv_usec = 0;
+ pDst->tv_sec = mktime(pExpTime);
+ if (pDst->tv_sec != -1)
+ return 0;
+ return touch_error("mktime failed on '%s': %s", pszTs, strerror(errno));
+}
+
+
+/**
+ * Check for old timestamp: MMDDhhmm[YY]
+ */
+static int touch_parse_old_ts(const char *pszOldTs, time_t Now, struct timeval *pDst)
+{
+ /*
+ * Check if this is a valid timestamp.
+ */
+ size_t const cchOldTs = strlen(pszOldTs);
+ if ( ( cchOldTs == 8
+ || cchOldTs == 10)
+ && IS_DIGIT(pszOldTs[0], 1)
+ && IS_DIGIT(pszOldTs[1], 9)
+ && IS_DIGIT(pszOldTs[2], 3)
+ && IS_DIGIT(pszOldTs[3], 9)
+ && IS_DIGIT(pszOldTs[4], 2)
+ && IS_DIGIT(pszOldTs[5], 9)
+ && IS_DIGIT(pszOldTs[6], 5)
+ && IS_DIGIT(pszOldTs[7], 9)
+ && ( cchOldTs == 8
+ || ( IS_DIGIT(pszOldTs[8], 9)
+ && IS_DIGIT(pszOldTs[9], 9) )) )
+ {
+ /*
+ * Explode the current time as local.
+ */
+ struct tm ExpTime;
+ struct tm *pExpTime;
+ pExpTime = localtime_r(&Now, &ExpTime);
+ if (pExpTime == NULL)
+ return touch_error("localtime_r failed: %s", strerror(errno));
+
+ /*
+ * Decode the bits we've got.
+ */
+ pExpTime->tm_mon = TWO_CHARS_TO_INT(pszOldTs[0], pszOldTs[1]) - 1;
+ pExpTime->tm_mday = TWO_CHARS_TO_INT(pszOldTs[2], pszOldTs[3]);
+ pExpTime->tm_hour = TWO_CHARS_TO_INT(pszOldTs[4], pszOldTs[5]);
+ pExpTime->tm_min = TWO_CHARS_TO_INT(pszOldTs[6], pszOldTs[7]);
+ if (cchOldTs == 10)
+ {
+ pExpTime->tm_year = TWO_CHARS_TO_INT(pszOldTs[8], pszOldTs[9]);
+ if (pExpTime->tm_year <= 38) /* up to 2038, 32-bit time_t style logic. */
+ pExpTime->tm_year += 100;
+ }
+
+ /*
+ * Use mktime to convert to UTC seconds.
+ */
+ pExpTime->tm_isdst = -1;
+ pExpTime->tm_yday = -1;
+ pExpTime->tm_wday = -1;
+ pDst->tv_usec = 0;
+ pDst->tv_sec = mktime(pExpTime);
+ if (pDst->tv_sec != -1)
+ return 0;
+ return touch_error("mktime failed on '%s': %s", pszOldTs, strerror(errno));
+ }
+
+ /* No valid timestamp present. */
+ return -1;
+}
+
+
+/**
+ * Parses the arguments into pOpts.
+ *
+ * @returns exit code.
+ * @param pOpts Options structure to return the parsed info in.
+ * Caller initalizes this with defaults.
+ * @param cArgs The number of arguments.
+ * @param papszArgs The arguments.
+ * @param pfExit Indicates whether to exit or to start processing
+ * files.
+ */
+static int touch_parse_args(PKMKTOUCHOPTS pOpts, int cArgs, char **papszArgs, KBOOL *pfExit)
+{
+ int iAdjustValue = 0;
+ int iArg;
+ int rc;
+
+ *pfExit = K_TRUE;
+ /*
+ * Parse arguments, skipping all files (GNU style).
+ */
+ for (iArg = 1; iArg < cArgs; iArg++)
+ {
+ const char *pszArg = papszArgs[iArg];
+ if (*pszArg == '-')
+ {
+ const char *pszLongValue = NULL;
+ char ch = *++pszArg;
+ pszArg++;
+
+ /*
+ * Deal with long options first, preferably translating them into short ones.
+ */
+ if (ch == '-')
+ {
+ const char *pszLong = pszArg;
+ ch = *pszArg++;
+ if (!ch)
+ {
+ while (++iArg < cArgs)
+ pOpts->papszFiles[pOpts->cFiles++] = papszArgs[iArg];
+ break; /* '--' */
+ }
+
+ /* Translate long options. */
+ pszArg = "";
+ if (strcmp(pszLong, "adjust") == 0)
+ ch = 'A';
+ else if (strncmp(pszLong, "adjust=", sizeof("adjust=") - 1) == 0)
+ {
+ ch = 'A';
+ pszLongValue = pszArg = pszLong + sizeof("adjust=") - 1;
+ }
+ else if (strcmp(pszLong, "no-create") == 0)
+ ch = 'c';
+ else if (strcmp(pszLong, "date") == 0)
+ ch = 'd';
+ else if (strncmp(pszLong, "date=", sizeof("date=") - 1) == 0)
+ {
+ ch = 'd';
+ pszLongValue = pszArg = pszLong + sizeof("date=") - 1;
+ }
+ else if (strcmp(pszLong, "no-dereference") == 0)
+ ch = 'h';
+ else if (strcmp(pszLong, "reference") == 0)
+ ch = 'r';
+ else if (strncmp(pszLong, "reference=", sizeof("reference=") - 1) == 0)
+ {
+ ch = 'r';
+ pszLongValue = pszArg = pszLong + sizeof("reference=") - 1;
+ }
+ else if (strcmp(pszLong, "time") == 0)
+ ch = 'T';
+ else if (strncmp(pszLong, "time=", sizeof("time=") - 1) == 0)
+ {
+ ch = 'T';
+ pszLongValue = pszArg = pszLong + sizeof("time=") - 1;
+ }
+ else if (strcmp(pszLong, "help") == 0)
+ return touch_usage();
+ else if (strcmp(pszLong, "version") == 0)
+ return kbuild_version(papszArgs[0]);
+ else
+ return touch_syntax("Unknown option: --%s", pszLong);
+ }
+
+ /*
+ * Process short options.
+ */
+ do
+ {
+ /* Some options takes a value. */
+ const char *pszValue;
+ switch (ch)
+ {
+ case 'A':
+ case 'd':
+ case 'r':
+ case 't':
+ case 'T':
+ if (*pszArg || pszLongValue)
+ {
+ pszValue = pszArg;
+ pszArg = "";
+ }
+ else if (iArg + 1 < cArgs)
+ pszValue = papszArgs[++iArg];
+ else
+ return touch_syntax("Option -%c requires a value", ch);
+ break;
+
+ default:
+ pszValue = NULL;
+ break;
+ }
+
+ switch (ch)
+ {
+ /* -A [-][[HH]MM]SS */
+ case 'A':
+ rc = touch_parse_adjust(pszValue, &iAdjustValue);
+ if (rc != 0)
+ return rc;
+ if (pOpts->enmAction != kTouchActionSet)
+ {
+ pOpts->enmAction = kTouchActionAdjust;
+ pOpts->NewATime.tv_sec = iAdjustValue;
+ pOpts->NewATime.tv_usec = 0;
+ pOpts->NewMTime = pOpts->NewATime;
+ }
+ /* else: applied after parsing everything. */
+ break;
+
+ case 'a':
+ pOpts->enmWhatToTouch = kTouchAccessOnly;
+ break;
+
+ case 'c':
+ pOpts->fCreate = K_FALSE;
+ break;
+
+ case 'd':
+ rc = touch_parse_d_ts(pszValue, &pOpts->NewATime);
+ if (rc != 0)
+ return rc;
+ pOpts->enmAction = kTouchActionSet;
+ pOpts->NewMTime = pOpts->NewATime;
+ break;
+
+ case 'f':
+ /* some historical thing, ignored. */
+ break;
+
+ case 'h':
+ pOpts->fDereference = K_FALSE;
+ break;
+
+ case 'm':
+ pOpts->enmWhatToTouch = kTouchModifyOnly;
+ break;
+
+ case 'r':
+ {
+ struct stat St;
+ if (stat(pszValue, &St) != 0)
+ return touch_error("Failed to stat '%s' (-r option): %s", pszValue, strerror(errno));
+
+ pOpts->enmAction = kTouchActionSet;
+ pOpts->NewATime.tv_sec = St.st_atime;
+ pOpts->NewMTime.tv_sec = St.st_mtime;
+#if FILE_TIMESTAMP_HI_RES
+ pOpts->NewATime.tv_usec = St.st_atim.tv_nsec / 1000;
+ pOpts->NewMTime.tv_usec = St.st_mtim.tv_nsec / 1000;
+#else
+ pOpts->NewATime.tv_usec = 0;
+ pOpts->NewMTime.tv_usec = 0;
+#endif
+ break;
+ }
+
+ case 't':
+ rc = touch_parse_ts(pszValue, &pOpts->NewATime);
+ if (rc != 0)
+ return rc;
+ pOpts->enmAction = kTouchActionSet;
+ pOpts->NewMTime = pOpts->NewATime;
+ break;
+
+ case 'T':
+ if ( strcmp(pszValue, "atime") == 0
+ || strcmp(pszValue, "access") == 0)
+ pOpts->enmWhatToTouch = kTouchAccessOnly;
+ else if ( strcmp(pszValue, "mtime") == 0
+ || strcmp(pszValue, "modify") == 0)
+ pOpts->enmWhatToTouch = kTouchModifyOnly;
+ else
+ return touch_syntax("Unknown --time value: %s", pszValue);
+ break;
+
+ case 'V':
+ return kbuild_version(papszArgs[0]);
+
+ default:
+ return touch_syntax("Unknown option: -%c (%c%s)", ch, ch, pszArg);
+ }
+
+ } while ((ch = *pszArg++) != '\0');
+ }
+ else
+ pOpts->papszFiles[pOpts->cFiles++] = papszArgs[iArg];
+ }
+
+ /*
+ * Allow adjusting specified timestamps too like BSD does.
+ */
+ if ( pOpts->enmAction == kTouchActionSet
+ && iAdjustValue != 0)
+ {
+ if ( pOpts->enmWhatToTouch == kTouchAccessAndModify
+ || pOpts->enmWhatToTouch == kTouchAccessOnly)
+ pOpts->NewATime.tv_sec += iAdjustValue;
+ if ( pOpts->enmWhatToTouch == kTouchAccessAndModify
+ || pOpts->enmWhatToTouch == kTouchModifyOnly)
+ pOpts->NewMTime.tv_sec += iAdjustValue;
+ }
+
+ /*
+ * Check for old timestamp: MMDDhhmm[YY]
+ */
+ if ( pOpts->enmAction == kTouchActionCurrent
+ && pOpts->cFiles >= 2)
+ {
+ struct timeval OldTs;
+ rc = touch_parse_old_ts(pOpts->papszFiles[0], pOpts->NewATime.tv_sec, &OldTs);
+ if (rc == 0)
+ {
+ int iFile;
+
+ pOpts->NewATime = OldTs;
+ pOpts->NewMTime = OldTs;
+ pOpts->enmAction = kTouchActionSet;
+
+ for (iFile = 1; iFile < pOpts->cFiles; iFile++)
+ pOpts->papszFiles[iFile - 1] = pOpts->papszFiles[iFile];
+ pOpts->cFiles--;
+ }
+ else if (rc > 0)
+ return rc;
+ }
+
+ /*
+ * Check that we've found at least one file argument.
+ */
+ if (pOpts->cFiles > 0)
+ {
+ *pfExit = K_FALSE;
+ return 0;
+ }
+ return touch_syntax("No file specified");
+}
+
+
+/**
+ * Touches one file.
+ *
+ * @returns exit code.
+ * @param pOpts The options.
+ * @param pszFile The file to touch.
+ */
+static int touch_process_file(PKMKTOUCHOPTS pOpts, const char *pszFile)
+{
+ int fd;
+ int rc;
+ struct stat St;
+ struct timeval aTimes[2];
+
+ /*
+ * Create the file if it doesn't exists. If the --no-create/-c option is
+ * in effect, we silently skip the file if it doesn't already exist.
+ */
+ if (pOpts->fDereference)
+ rc = stat(pszFile, &St);
+ else
+ rc = lstat(pszFile, &St);
+ if (rc != 0)
+ {
+ if (errno != ENOENT)
+ return touch_error("Failed to stat '%s': %s", pszFile, strerror(errno));
+
+ if (!pOpts->fCreate)
+ return 0;
+ fd = open(pszFile, O_WRONLY | O_CREAT, 0666);
+ if (fd == -1)
+ return touch_error("Failed to create '%s': %s", pszFile, strerror(errno));
+
+ /* If we're not setting the current time, we may need value stat info
+ on the file, so get it thru the file descriptor before closing it. */
+ if (pOpts->enmAction == kTouchActionCurrent)
+ rc = 0;
+ else
+ rc = fstat(fd, &St);
+ if (close(fd) != 0)
+ return touch_error("Failed to close '%s' after creation: %s", pszFile, strerror(errno));
+ if (rc != 0)
+ return touch_error("Failed to fstat '%s' after creation: %s", pszFile, strerror(errno));
+
+ /* We're done now if we're setting the current time. */
+ if (pOpts->enmAction == kTouchActionCurrent)
+ return 0;
+ }
+
+ /*
+ * Create aTimes and call utimes/lutimes.
+ */
+ aTimes[0].tv_sec = St.st_atime;
+ aTimes[1].tv_sec = St.st_mtime;
+#if FILE_TIMESTAMP_HI_RES
+ aTimes[0].tv_usec = St.st_atim.tv_nsec / 1000;
+ aTimes[1].tv_usec = St.st_mtim.tv_nsec / 1000;
+#else
+ aTimes[0].tv_usec = 0;
+ aTimes[1].tv_usec = 0;
+#endif
+ if ( pOpts->enmWhatToTouch == kTouchAccessAndModify
+ || pOpts->enmWhatToTouch == kTouchAccessOnly)
+ {
+ if ( pOpts->enmAction == kTouchActionCurrent
+ || pOpts->enmAction == kTouchActionSet)
+ aTimes[0] = pOpts->NewATime;
+ else
+ aTimes[0].tv_sec += pOpts->NewATime.tv_sec;
+ }
+ if ( pOpts->enmWhatToTouch == kTouchAccessAndModify
+ || pOpts->enmWhatToTouch == kTouchModifyOnly)
+ {
+ if ( pOpts->enmAction == kTouchActionCurrent
+ || pOpts->enmAction == kTouchActionSet)
+ aTimes[1] = pOpts->NewMTime;
+ else
+ aTimes[1].tv_sec += pOpts->NewMTime.tv_sec;
+ }
+
+ /*
+ * Try set the times. If we're setting current time, fall back on calling
+ * [l]utimes with a NULL timeval vector since that has slightly different
+ * permissions checks. (Note that we don't do that by default because it
+ * may do more than what we want (st_ctime).)
+ */
+ if (pOpts->fDereference)
+ rc = utimes(pszFile, aTimes);
+ else
+ rc = lutimes(pszFile, aTimes);
+ if (rc != 0)
+ {
+ if (pOpts->enmAction == kTouchActionCurrent)
+ {
+ if (pOpts->fDereference)
+ rc = utimes(pszFile, NULL);
+ else
+ rc = lutimes(pszFile, NULL);
+ }
+ if (rc != 0)
+ rc = touch_error("%stimes failed on '%s': %s", pOpts->fDereference ? "" : "l", pszFile, strerror(errno));
+ }
+
+ return rc;
+}
+
+
+/**
+ * The function that does almost everything here... ugly.
+ */
+#ifdef KMK
+int kmk_builtin_touch(int argc, char **argv, char **envp)
+#else
+int main(int argc, char **argv, char **envp)
+#endif
+{
+ int rc;
+ KMKTOUCHOPTS Opts;
+ K_NOREF(envp);
+
+ /*
+ * Initialize options with defaults and parse them.
+ */
+ Opts.enmWhatToTouch = kTouchAccessAndModify;
+ Opts.enmAction = kTouchActionCurrent;
+ Opts.fCreate = K_TRUE;
+ Opts.fDereference = K_TRUE;
+ Opts.cFiles = 0;
+ Opts.papszFiles = (char **)calloc(argc, sizeof(char *));
+ if (Opts.papszFiles)
+ {
+ rc = gettimeofday(&Opts.NewATime, NULL);
+ if (rc == 0)
+ {
+ KBOOL fExit;
+ Opts.NewMTime = Opts.NewATime;
+
+ rc = touch_parse_args(&Opts, argc, argv, &fExit);
+ if (rc == 0 && !fExit)
+ {
+ /*
+ * Process the files.
+ */
+ int iFile;
+ for (iFile = 0; iFile < Opts.cFiles; iFile++)
+ {
+ int rc2 = touch_process_file(&Opts, Opts.papszFiles[iFile]);
+ if (rc2 != 0 && rc == 0)
+ rc = rc2;
+ }
+ }
+ }
+ else
+ rc = touch_error("gettimeofday failed: %s", strerror(errno));
+ free(Opts.papszFiles);
+ }
+ else
+ rc = touch_error("calloc failed");
+ return rc;
+}
+
diff --git a/src/kmk/main.c b/src/kmk/main.c
index 7bb2437..2db8638 100644
--- a/src/kmk/main.c
+++ b/src/kmk/main.c
@@ -461,6 +461,8 @@ static const char *const usage[] =
3 = normal / nice 0;\n\
4 = high / nice -10;\n\
5 = realtime / nice -19;\n"),
+ N_("\
+ --nice Alias for --priority=1\n"),
#endif /* KMK */
#ifdef CONFIG_PRETTY_COMMAND_PRINTING
N_("\
@@ -534,6 +536,7 @@ static const struct command_switch switches[] =
(char *) &process_priority, (char *) &process_priority, "priority" },
{ CHAR_MAX+15, positive_int, (char *) &process_affinity, 1, 1, 0,
(char *) &process_affinity, (char *) &process_affinity, "affinity" },
+ { CHAR_MAX+17, flag, (char *) &process_priority, 1, 1, 0, 0, 0, "nice" },
#endif
{ 'q', flag, &question_flag, 1, 1, 1, 0, 0, "question" },
{ 'r', flag, &no_builtin_rules_flag, 1, 1, 0, 0, 0, "no-builtin-rules" },
@@ -855,24 +858,29 @@ static void
set_make_priority_and_affinity (void)
{
# ifdef WINDOWS32
- DWORD dwPriority;
+ DWORD dwClass, dwPriority;
+
if (process_affinity)
if (!SetProcessAffinityMask (GetCurrentProcess (), process_affinity))
- fprintf (stderr, "warning: SetPriorityClass (,%#x) failed with last error %d\n",
+ fprintf (stderr, "warning: SetProcessAffinityMask (,%#x) failed with last error %d\n",
process_affinity, GetLastError ());
switch (process_priority)
{
case 0: return;
- case 1: dwPriority = IDLE_PRIORITY_CLASS; break;
- case 2: dwPriority = BELOW_NORMAL_PRIORITY_CLASS; break;
- case 3: dwPriority = NORMAL_PRIORITY_CLASS; break;
- case 4: dwPriority = HIGH_PRIORITY_CLASS; break;
- case 5: dwPriority = REALTIME_PRIORITY_CLASS; break;
+ case 1: dwClass = IDLE_PRIORITY_CLASS; dwPriority = THREAD_PRIORITY_IDLE; break;
+ case 2: dwClass = BELOW_NORMAL_PRIORITY_CLASS; dwPriority = THREAD_PRIORITY_BELOW_NORMAL; break;
+ case 3: dwClass = NORMAL_PRIORITY_CLASS; dwPriority = THREAD_PRIORITY_NORMAL; break;
+ case 4: dwClass = HIGH_PRIORITY_CLASS; dwPriority = 0xffffffff; break;
+ case 5: dwClass = REALTIME_PRIORITY_CLASS; dwPriority = 0xffffffff; break;
default: fatal (NILF, _("invalid priority %d\n"), process_priority);
}
- if (!SetPriorityClass (GetCurrentProcess (), dwPriority))
+ if (!SetPriorityClass (GetCurrentProcess (), dwClass))
fprintf (stderr, "warning: SetPriorityClass (,%#x) failed with last error %d\n",
+ dwClass, GetLastError ());
+ if (dwPriority != 0xffffffff
+ && !SetThreadPriority (GetCurrentThread (), dwPriority))
+ fprintf (stderr, "warning: SetThreadPriority (,%#x) failed with last error %d\n",
dwPriority, GetLastError ());
#elif defined(__HAIKU__)
diff --git a/src/kmk/misc.c b/src/kmk/misc.c
index a22759b..63782d4 100644
--- a/src/kmk/misc.c
+++ b/src/kmk/misc.c
@@ -368,7 +368,7 @@ error (flocp, fmt, va_alist)
VA_START (args, fmt);
cchMsg += cchUser = vsnprintf (&szMsg[cchMsg], sizeof(szMsg) - cchMsg, fmt, args);
VA_END (args);
- if ( cchMsg < sizeof(szMsg)
+ if ( cchMsg < (int)sizeof(szMsg)
&& cchUser >= 0)
{
extern size_t maybe_con_fwrite(void const *, size_t, size_t, FILE *);
@@ -433,7 +433,7 @@ fatal (flocp, fmt, va_alist)
VA_START (args, fmt);
cchMsg += cchUser = vsnprintf (&szMsg[cchMsg], sizeof(szMsg) - cchMsg, fmt, args);
VA_END (args);
- if ( cchMsg + cchStop <= sizeof(szMsg)
+ if ( cchMsg + cchStop <= (int)sizeof(szMsg)
&& cchUser >= 0)
{
extern size_t maybe_con_fwrite(void const *, size_t, size_t, FILE *);
diff --git a/src/kmk/strcache.c b/src/kmk/strcache.c
index 90dceb6..fb6a767 100644
--- a/src/kmk/strcache.c
+++ b/src/kmk/strcache.c
@@ -259,7 +259,7 @@ void strcache_init (void)
{
strcache2_init(&file_strcache,
"file", /* name */
- 65536, /* hash size */
+ 131072, /* hash size */
0, /* default segment size*/
#ifdef HAVE_CASE_INSENSITIVE_FS
1, /* case insensitive */
diff --git a/src/kmk/strcache2.c b/src/kmk/strcache2.c
index 2f943c8..9da2185 100644
--- a/src/kmk/strcache2.c
+++ b/src/kmk/strcache2.c
@@ -1,4 +1,4 @@
-/* $Id: strcache2.c 2799 2015-09-19 20:36:31Z bird $ */
+/* $Id: strcache2.c 3091 2017-10-04 14:31:04Z bird $ */
/** @file
* strcache2 - New string cache.
*/
@@ -92,6 +92,7 @@ typedef signed int int32_t;
static struct strcache2 *strcache_head;
+#ifndef STRCACHE2_USE_MASK
/** Finds the closest primary number for power of two value (or something else
* useful if not support). */
MY_INLINE unsigned int strcache2_find_prime(unsigned int shift)
@@ -123,6 +124,7 @@ MY_INLINE unsigned int strcache2_find_prime(unsigned int shift)
return (1 << shift) - 1;
}
}
+#endif
/* The following is a bit experiment. It produces longer chains, i.e. worse
distribution of the strings in the table, however the actual make
@@ -410,6 +412,7 @@ strcache2_case_insensitive_hash (const char *str, unsigned int len)
return hash;
}
+#if 0
MY_INLINE int
strcache2_memcmp_inline_short (const char *xs, const char *ys, unsigned int length)
{
@@ -484,6 +487,7 @@ strcache2_memcmp_inline_short (const char *xs, const char *ys, unsigned int leng
/* memcmp for longer strings */
return memcmp (xs, ys, length);
}
+#endif
MY_INLINE int
strcache2_memcmp_inlined (const char *xs, const char *ys, unsigned int length)
@@ -493,9 +497,11 @@ strcache2_memcmp_inlined (const char *xs, const char *ys, unsigned int length)
#endif
if (!((size_t)xs & 3))
{
- int result;
/* aligned */
- while (length >= 8)
+ int result;
+ unsigned reminder = length & 7;
+ length >>= 3;
+ while (length-- > 0)
{
result = *(int32_t*)xs - *(int32_t*)ys;
result |= *(int32_t*)(xs + 4) - *(int32_t*)(ys + 4);
@@ -503,9 +509,8 @@ strcache2_memcmp_inlined (const char *xs, const char *ys, unsigned int length)
return result;
xs += 8;
ys += 8;
- length -= 8;
}
- switch (length)
+ switch (reminder)
{
case 7:
result = *(int32_t*)xs - *(int32_t*)ys;
@@ -544,7 +549,9 @@ strcache2_memcmp_inlined (const char *xs, const char *ys, unsigned int length)
{
/* unaligned */
int result;
- while (length >= 8)
+ unsigned reminder = length & 7;
+ length >>= 3;
+ while (length-- > 0)
{
#if defined(__i386__) || defined(__x86_64__)
result = ( ((int32_t)xs[3] << 24)
@@ -571,18 +578,18 @@ strcache2_memcmp_inlined (const char *xs, const char *ys, unsigned int length)
return result;
xs += 8;
ys += 8;
- length -= 8;
}
+
result = 0;
- switch (length)
+ switch (reminder)
{
- case 7: result |= xs[6] - ys[6];
- case 6: result |= xs[5] - ys[5];
- case 5: result |= xs[4] - ys[4];
- case 4: result |= xs[3] - ys[3];
- case 3: result |= xs[2] - ys[2];
- case 2: result |= xs[1] - ys[1];
- case 1: result |= xs[0] - ys[0];
+ case 7: result |= xs[6] - ys[6]; /* fall thru */
+ case 6: result |= xs[5] - ys[5]; /* fall thru */
+ case 5: result |= xs[4] - ys[4]; /* fall thru */
+ case 4: result |= xs[3] - ys[3]; /* fall thru */
+ case 3: result |= xs[2] - ys[2]; /* fall thru */
+ case 2: result |= xs[1] - ys[1]; /* fall thru */
+ case 1: result |= xs[0] - ys[0]; /* fall thru */
return result;
default:
case 0:
@@ -611,6 +618,7 @@ strcache2_is_equal (struct strcache2 *cache, struct strcache2_entry const *entry
#endif
}
+#if defined(HAVE_CASE_INSENSITIVE_FS)
MY_INLINE int
strcache2_is_iequal (struct strcache2 *cache, struct strcache2_entry const *entry,
const char *str, unsigned int length, unsigned int hash)
@@ -622,12 +630,13 @@ strcache2_is_iequal (struct strcache2 *cache, struct strcache2_entry const *entr
|| entry->length != length)
return 0;
-#if defined(_MSC_VER) || defined(__OS2__)
+# if defined(_MSC_VER) || defined(__OS2__)
return _memicmp (entry + 1, str, length) == 0;
-#else
+# else
return strncasecmp ((const char *)(entry + 1), str, length) == 0;
-#endif
+# endif
}
+#endif /* HAVE_CASE_INSENSITIVE_FS */
static void
strcache2_rehash (struct strcache2 *cache)
@@ -914,14 +923,14 @@ strcache2_iadd (struct strcache2 *cache, const char *str, unsigned int length)
entry = cache->hash_tab[idx];
if (!entry)
return strcache2_enter_string (cache, idx, str, length, hash);
- if (strcache2_is_equal (cache, entry, str, length, hash))
+ if (strcache2_is_iequal (cache, entry, str, length, hash))
return (const char *)(entry + 1);
MAKE_STATS (cache->collision_1st_count++);
entry = entry->next;
if (!entry)
return strcache2_enter_string (cache, idx, str, length, hash);
- if (strcache2_is_equal (cache, entry, str, length, hash))
+ if (strcache2_is_iequal (cache, entry, str, length, hash))
return (const char *)(entry + 1);
MAKE_STATS (cache->collision_2nd_count++);
@@ -931,7 +940,7 @@ strcache2_iadd (struct strcache2 *cache, const char *str, unsigned int length)
entry = entry->next;
if (!entry)
return strcache2_enter_string (cache, idx, str, length, hash);
- if (strcache2_is_equal (cache, entry, str, length, hash))
+ if (strcache2_is_iequal (cache, entry, str, length, hash))
return (const char *)(entry + 1);
MAKE_STATS (cache->collision_3rd_count++);
}
@@ -963,14 +972,14 @@ strcache2_iadd_hashed (struct strcache2 *cache, const char *str,
entry = cache->hash_tab[idx];
if (!entry)
return strcache2_enter_string (cache, idx, str, length, hash);
- if (strcache2_is_equal (cache, entry, str, length, hash))
+ if (strcache2_is_iequal (cache, entry, str, length, hash))
return (const char *)(entry + 1);
MAKE_STATS (cache->collision_1st_count++);
entry = entry->next;
if (!entry)
return strcache2_enter_string (cache, idx, str, length, hash);
- if (strcache2_is_equal (cache, entry, str, length, hash))
+ if (strcache2_is_iequal (cache, entry, str, length, hash))
return (const char *)(entry + 1);
MAKE_STATS (cache->collision_2nd_count++);
@@ -980,7 +989,7 @@ strcache2_iadd_hashed (struct strcache2 *cache, const char *str,
entry = entry->next;
if (!entry)
return strcache2_enter_string (cache, idx, str, length, hash);
- if (strcache2_is_equal (cache, entry, str, length, hash))
+ if (strcache2_is_iequal (cache, entry, str, length, hash))
return (const char *)(entry + 1);
MAKE_STATS (cache->collision_3rd_count++);
}
@@ -1006,14 +1015,14 @@ strcache2_ilookup (struct strcache2 *cache, const char *str, unsigned int length
entry = cache->hash_tab[idx];
if (!entry)
return NULL;
- if (strcache2_is_equal (cache, entry, str, length, hash))
+ if (strcache2_is_iequal (cache, entry, str, length, hash))
return (const char *)(entry + 1);
MAKE_STATS (cache->collision_1st_count++);
entry = entry->next;
if (!entry)
return NULL;
- if (strcache2_is_equal (cache, entry, str, length, hash))
+ if (strcache2_is_iequal (cache, entry, str, length, hash))
return (const char *)(entry + 1);
MAKE_STATS (cache->collision_2nd_count++);
@@ -1023,7 +1032,7 @@ strcache2_ilookup (struct strcache2 *cache, const char *str, unsigned int length
entry = entry->next;
if (!entry)
return NULL;
- if (strcache2_is_equal (cache, entry, str, length, hash))
+ if (strcache2_is_iequal (cache, entry, str, length, hash))
return (const char *)(entry + 1);
MAKE_STATS (cache->collision_3rd_count++);
}
diff --git a/src/kmk/variable.c b/src/kmk/variable.c
index 5e85e83..eb32468 100644
--- a/src/kmk/variable.c
+++ b/src/kmk/variable.c
@@ -246,7 +246,7 @@ init_hash_global_variable_set (void)
hash_init (&global_variable_set.table, VARIABLE_BUCKETS,
variable_hash_1, variable_hash_2, variable_hash_cmp);
#else /* CONFIG_WITH_STRCACHE2 */
- strcache2_init (&variable_strcache, "variable", 65536, 0, 0, 0);
+ strcache2_init (&variable_strcache, "variable", 262144, 0, 0, 0);
hash_init_strcached (&global_variable_set.table, VARIABLE_BUCKETS,
&variable_strcache, offsetof (struct variable, name));
#endif /* CONFIG_WITH_STRCACHE2 */
diff --git a/src/kmk/variable.h b/src/kmk/variable.h
index 3238108..5f3ea89 100644
--- a/src/kmk/variable.h
+++ b/src/kmk/variable.h
@@ -223,10 +223,10 @@ variable_buffer_output (char *ptr, const char *string, unsigned int length)
# ifndef _MSC_VER
switch (length)
{
- case 4: ptr[3] = string[3];
- case 3: ptr[2] = string[2];
- case 2: ptr[1] = string[1];
- case 1: ptr[0] = string[0];
+ case 4: ptr[3] = string[3]; /* fall thru */
+ case 3: ptr[2] = string[2]; /* fall thru */
+ case 2: ptr[1] = string[1]; /* fall thru */
+ case 1: ptr[0] = string[0]; /* fall thru */
case 0:
break;
default:
diff --git a/src/kmk/w32/pathstuff.c b/src/kmk/w32/pathstuff.c
index 1a5c7e0..80dd97b 100644
--- a/src/kmk/w32/pathstuff.c
+++ b/src/kmk/w32/pathstuff.c
@@ -15,7 +15,6 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
-#include <Windows.h> /* bird */
#include "make.h"
#include <string.h>
#include <stdlib.h>
diff --git a/src/kmk/w32/subproc/sub_proc.c b/src/kmk/w32/subproc/sub_proc.c
index f2e9b49..ff5c8e1 100644
--- a/src/kmk/w32/subproc/sub_proc.c
+++ b/src/kmk/w32/subproc/sub_proc.c
@@ -547,6 +547,7 @@ process_begin(
char *envblk=NULL;
#ifdef KMK
size_t exec_path_len;
+ extern int process_priority;
assert (pproc->enmType == kRegular);
#endif
@@ -715,6 +716,14 @@ process_begin(
kmk_cache_exec_image(exec_path);
else if (argv[0])
kmk_cache_exec_image(argv[0]);
+
+ switch (process_priority) {
+ case 1: flags |= CREATE_SUSPENDED | IDLE_PRIORITY_CLASS; break;
+ case 2: flags |= CREATE_SUSPENDED | BELOW_NORMAL_PRIORITY_CLASS; break;
+ case 3: flags |= CREATE_SUSPENDED | NORMAL_PRIORITY_CLASS; break;
+ case 4: flags |= CREATE_SUSPENDED | HIGH_PRIORITY_CLASS; break;
+ case 5: flags |= CREATE_SUSPENDED | REALTIME_PRIORITY_CLASS; break;
+ }
#endif
if (CreateProcess(
exec_path,
@@ -740,6 +749,16 @@ process_begin(
free( command_line );
return(-1);
}
+#ifdef KMK
+ switch (process_priority) {
+ case 1: SetThreadPriority(procInfo.hThread, THREAD_PRIORITY_IDLE); break;
+ case 2: SetThreadPriority(procInfo.hThread, THREAD_PRIORITY_BELOW_NORMAL); break;
+ case 3: SetThreadPriority(procInfo.hThread, THREAD_PRIORITY_NORMAL); break;
+ case 4: SetThreadPriority(procInfo.hThread, THREAD_PRIORITY_HIGHEST); break;
+ case 5: SetThreadPriority(procInfo.hThread, THREAD_PRIORITY_TIME_CRITICAL); break;
+ }
+ ResumeThread(procInfo.hThread);
+#endif
}
pproc->pid = (pid_t)procInfo.hProcess;
diff --git a/src/lib/Makefile.kmk b/src/lib/Makefile.kmk
index 0cd8307..b3f5a67 100644
--- a/src/lib/Makefile.kmk
+++ b/src/lib/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk 2994 2016-11-01 22:41:41Z bird $
+# $Id: Makefile.kmk 3060 2017-09-21 15:11:07Z bird $
## @file
# Sub-makefile for various libraries and stuff.
#
@@ -52,6 +52,7 @@ kUtil_SOURCES.win = \
nt/ntdir.c \
nt/ntstat.c \
nt/ntunlink.c \
+ nt/ntutimes.c \
nt/fts-nt.c \
nt/kFsCache.c \
kStuff/kHlp/CRT/kHlpCRTString.cpp \
diff --git a/src/lib/kDep.c b/src/lib/kDep.c
index 186c20c..caa63bd 100644
--- a/src/lib/kDep.c
+++ b/src/lib/kDep.c
@@ -1,4 +1,4 @@
-/* $Id: kDep.c 2955 2016-09-21 19:05:53Z bird $ */
+/* $Id: kDep.c 3063 2017-09-30 11:34:07Z bird $ */
/** @file
* kDep - Common Dependency Managemnt Code.
*/
@@ -129,7 +129,7 @@ static void fixcase(char *pszFilename)
* Find the next slash (or end of string) and terminate the string there.
*/
while (*psz != '/' && *psz)
- *psz++;
+ psz++;
chSlash = *psz;
*psz = '\0';
diff --git a/src/lib/kStuff/include/k/kDefs.h b/src/lib/kStuff/include/k/kDefs.h
index f805cc3..9730fbc 100644
--- a/src/lib/kStuff/include/k/kDefs.h
+++ b/src/lib/kStuff/include/k/kDefs.h
@@ -1,10 +1,10 @@
-/* $Id: kDefs.h 84 2016-09-04 13:54:11Z bird $ */
+/* $Id: kDefs.h 100 2017-10-01 13:08:49Z bird $ */
/** @file
* kTypes - Defines and Macros.
*/
/*
- * Copyright (c) 2006-2008 Knut St. Osmundsen <bird-kStuff-spamix at anduin.net>
+ * Copyright (c) 2006-2017 Knut St. Osmundsen <bird-kStuff-spamix at anduin.net>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -46,22 +46,26 @@
#define K_OS_DRAGONFLY 2
/** FreeBSD. */
#define K_OS_FREEBSD 3
+/** GNU/kFreeBSD. */
+#define K_OS_GNU_KFBSD 4
+/** GNU/kNetBSD or GNU/NetBSD or whatever the decide to call it. */
+#define K_OS_GNU_KNBSD 5
/** Linux. */
-#define K_OS_LINUX 4
+#define K_OS_LINUX 6
/** NetBSD. */
-#define K_OS_NETBSD 5
+#define K_OS_NETBSD 7
/** NT (native). */
-#define K_OS_NT 6
+#define K_OS_NT 8
/** OpenBSD*/
-#define K_OS_OPENBSD 7
+#define K_OS_OPENBSD 9
/** OS/2 */
-#define K_OS_OS2 8
+#define K_OS_OS2 10
/** Solaris */
-#define K_OS_SOLARIS 9
+#define K_OS_SOLARIS 11
/** Windows. */
-#define K_OS_WINDOWS 10
+#define K_OS_WINDOWS 12
/** The max K_OS_* value (exclusive). */
-#define K_OS_MAX 11
+#define K_OS_MAX 13
/** @} */
/** @def K_OS
@@ -80,12 +84,16 @@
# define K_OS K_OS_DARWIN
# elif defined(__DragonFly__)
# define K_OS K_OS_DRAGONFLY
-# elif defined(__FreeBSD__) /*??*/
+# elif defined(__FreeBSD__)
# define K_OS K_OS_FREEBSD
+# elif defined(__FreeBSD_kernel__)
+# define K_OS K_OS_GNU_KFBSD
# elif defined(__gnu_linux__)
# define K_OS K_OS_LINUX
# elif defined(__NetBSD__) /*??*/
# define K_OS K_OS_NETBSD
+# elif defined(__NetBSD_kernel__)
+# define K_OS K_OS_GNU_KNBSD
# elif defined(__OpenBSD__) /*??*/
# define K_OS K_OS_OPENBSD
# elif defined(__OS2__)
@@ -162,12 +170,16 @@
#define K_ARCH_S390_32 (15 | K_ARCH_BIT_32 | K_ARCH_END_BIG)
/** 64-bit S390. */
#define K_ARCH_S390_64 (16 | K_ARCH_BIT_64 | K_ARCH_END_BIG)
+/** 32-bit SuperH. */
+#define K_ARCH_SH_32 (17 | K_ARCH_BIT_32 | K_ARCH_END_BI)
+/** 64-bit SuperH. */
+#define K_ARCH_SH_64 (17 | K_ARCH_BIT_64 | K_ARCH_END_BI)
/** 32-bit SPARC. */
-#define K_ARCH_SPARC_32 (17 | K_ARCH_BIT_32 | K_ARCH_END_BIG)
+#define K_ARCH_SPARC_32 (18 | K_ARCH_BIT_32 | K_ARCH_END_BIG)
/** 64-bit SPARC. */
-#define K_ARCH_SPARC_64 (18 | K_ARCH_BIT_64 | K_ARCH_END_BI)
+#define K_ARCH_SPARC_64 (19 | K_ARCH_BIT_64 | K_ARCH_END_BI)
/** The end of the valid architecture values (exclusive). */
-#define K_ARCH_MAX (19)
+#define K_ARCH_MAX (20)
/** @} */
@@ -186,6 +198,8 @@
# define K_ARCH K_ARCH_ALPHA
# elif defined(__arm__) || defined(__arm32__)
# define K_ARCH K_ARCH_ARM_32
+# elif defined(__aarch64__) || defined(__arm64__)
+# define K_ARCH K_ARCH_ARM_64
# elif defined(__hppa__) && defined(__LP64__)
# define K_ARCH K_ARCH_PARISC_64
# elif defined(__hppa__)
@@ -206,6 +220,16 @@
# define K_ARCH K_ARCH_S390_64
# elif defined(__s390__)
# define K_ARCH K_ARCH_S390_32
+# elif defined(__sh__)
+# if !defined(__SH5__)
+# define K_ARCH K_ARCH_SH_32
+# else
+# if __SH5__ == 64
+# define K_ARCH K_ARCH_SH_64
+# else
+# define K_ARCH K_ARCH_SH_32
+# endif
+# endif
# else
# error "Port Me"
# endif
@@ -300,6 +324,14 @@
/* use K_ARCH if possible. */
# if K_ARCH_ENDIAN != K_ENDIAN_BI
# define K_ENDIAN K_ARCH_ENDIAN
+# elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__)
+# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define K_ENDIAN K_ARCH_LITTLE
+# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define K_ENDIAN K_ARCH_BIG
+# else
+# error "Port Me or define K_ENDIAN."
+# endif
# else
# error "Port Me or define K_ENDIAN."
# endif
diff --git a/src/lib/kStuff/include/k/kHlpAssert.h b/src/lib/kStuff/include/k/kHlpAssert.h
index aac38be..061f425 100644
--- a/src/lib/kStuff/include/k/kHlpAssert.h
+++ b/src/lib/kStuff/include/k/kHlpAssert.h
@@ -1,4 +1,4 @@
-/* $Id: kHlpAssert.h 93 2016-09-15 11:53:59Z bird $ */
+/* $Id: kHlpAssert.h 101 2017-10-02 10:37:39Z bird $ */
/** @file
* kHlpAssert - Assertion Macros.
*/
@@ -196,7 +196,103 @@ extern "C" {
} \
} while (0)
+/* Same as above, only no expression. */
+
+# define kHlpAssertFailed() \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ } while (0)
+
+# define kHlpAssertFailedStmt(stmt) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ } while (0)
+
+# define kHlpAssertFailedReturn(rcRet) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ return (rcRet); \
+ } while (0)
+
+# define kHlpAssertFailedStmtReturn(stmt, rcRet) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return (rcRet); \
+ } while (0)
+
+# define kHlpAssertFailedReturnVoid() \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ return; \
+ } while (0)
+
+# define kHlpAssertFailedStmtReturnVoid(stmt) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return; \
+ } while (0)
+
+# define kHlpAssertMsgFailed(msg) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ } while (0)
+
+# define kHlpAssertMsgFailedStmt(msg, stmt) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ } while (0)
+
+# define kHlpAssertMsgFailedReturn(msg, rcRet) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ return (rcRet); \
+ } while (0)
+
+# define kHlpAssertMsgFailedStmtReturn(msg, stmt, rcRet) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return (rcRet); \
+ } while (0)
+
+# define kHlpAssertMsgFailedReturnVoid(msg) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ return; \
+ } while (0)
+
+# define kHlpAssertMsgFailedStmtReturnVoid(msg, stmt) \
+ do { \
+ kHlpAssertMsg1("failed", __FILE__, __LINE__, K_FUNCTION); \
+ kHlpAssertMsg2 msg; \
+ kHlpAssertBreakpoint(); \
+ stmt; \
+ return; \
+ } while (0)
+
+
#else /* !K_STRICT */
+
# define kHlpAssert(expr) do { } while (0)
# define kHlpAssertStmt(expr, stmt) do { if (!(expr)) { stmt; } } while (0)
# define kHlpAssertReturn(expr, rcRet) do { if (!(expr)) return (rcRet); } while (0)
@@ -209,6 +305,20 @@ extern "C" {
# define kHlpAssertMsgStmtReturn(expr, msg, stmt, rcRet) do { if (!(expr)) { stmt; return (rcRet); } } while (0)
# define kHlpAssertMsgReturnVoid(expr, msg) do { if (!(expr)) return; } while (0)
# define kHlpAssertMsgStmtReturnVoid(expr, msg, stmt) do { if (!(expr)) { stmt; return; } } while (0)
+/* Same as above, only no expression: */
+# define kHlpAssertFailed() do { } while (0)
+# define kHlpAssertFailedStmt(stmt) do { stmt; } while (0)
+# define kHlpAssertFailedReturn(rcRet) do { return (rcRet); } while (0)
+# define kHlpAssertFailedStmtReturn(stmt, rcRet) do { stmt; return (rcRet); } while (0)
+# define kHlpAssertFailedReturnVoid() do { return; } while (0)
+# define kHlpAssertFailedStmtReturnVoid(stmt) do { stmt; return; } while (0)
+# define kHlpAssertMsgFailed(msg) do { } while (0)
+# define kHlpAssertMsgFailedStmt(msg, stmt) do { stmt; } while (0)
+# define kHlpAssertMsgFailedReturn(msg, rcRet) do { return (rcRet); } while (0)
+# define kHlpAssertMsgFailedStmtReturn(msg, stmt, rcRet) do { { stmt; return (rcRet); } } while (0)
+# define kHlpAssertMsgFailedReturnVoid(msg) do { return; } while (0)
+# define kHlpAssertMsgFailedStmtReturnVoid(msg, stmt) do { stmt; return; } while (0)
+
#endif /* !K_STRICT */
#define kHlpAssertPtr(ptr) kHlpAssertMsg(K_VALID_PTR(ptr), ("%s = %p\n", #ptr, (ptr)))
@@ -221,18 +331,7 @@ extern "C" {
#define kHlpAssertRC(rc) kHlpAssertMsg((rc) == 0, ("%s = %d\n", #rc, (rc)))
#define kHlpAssertRCReturn(rc, rcRet) kHlpAssertMsgReturn((rc) == 0, ("%s = %d -> %d\n", #rc, (rc), (rcRet)), (rcRet))
#define kHlpAssertRCReturnVoid(rc) kHlpAssertMsgReturnVoid((rc) == 0, ("%s = %d -> %d\n", #rc, (rc), (rcRet)))
-#define kHlpAssertFailed() kHlpAssert(0)
-#define kHlpAssertFailedStmt(stmt) kHlpAssertStmt(0, stmt)
-#define kHlpAssertFailedReturn(rcRet) kHlpAssertReturn(0, (rcRet))
-#define kHlpAssertFailedStmtReturn(stmt, rcRet) kHlpAssertStmtReturn(0, stmt, (rcRet))
-#define kHlpAssertFailedReturnVoid() kHlpAssertReturnVoid(0)
-#define kHlpAssertFailedStmtReturnVoid(stmt) kHlpAssertStmtReturnVoid(0, stmt)
-#define kHlpAssertMsgFailed(msg) kHlpAssertMsg(0, msg)
-#define kHlpAssertMsgFailedStmt(msg, stmt) kHlpAssertMsgStmt(0, msg, stmt)
-#define kHlpAssertMsgFailedReturn(msg, rcRet) kHlpAssertMsgReturn(0, msg, (rcRet))
-#define kHlpAssertMsgFailedStmtReturn(msg, stmt, rcRet) kHlpAssertMsgStmtReturn(0, msg, stmt, (rcRet))
-#define kHlpAssertMsgFailedReturnVoid(msg) kHlpAssertMsgReturnVoid(0, msg)
-#define kHlpAssertMsgFailedStmtReturnVoid(msg, stmt) kHlpAssertMsgStmtReturnVoid(0, msg, stmt)
+
/**
* Helper function that displays the first part of the assertion message.
diff --git a/src/lib/kStuff/kLdr/kLdrModLX.c b/src/lib/kStuff/kLdr/kLdrModLX.c
index 8af1421..f7d11c8 100644
--- a/src/lib/kStuff/kLdr/kLdrModLX.c
+++ b/src/lib/kStuff/kLdr/kLdrModLX.c
@@ -1,4 +1,4 @@
-/* $Id: kLdrModLX.c 87 2016-09-07 13:09:12Z bird $ */
+/* $Id: kLdrModLX.c 102 2017-10-02 10:45:31Z bird $ */
/** @file
* kLdr - The Module Interpreter for the Linear eXecutable (LX) Format.
*/
@@ -1486,6 +1486,7 @@ static int kldrModLXDoLoadBits(PKLDRMODLX pModLX, void *pvBits)
case RANGE:
KLDRMODLX_ASSERT(!"RANGE");
+ /* Falls through. */
default:
rc = KLDR_ERR_LX_BAD_PAGE_MAP;
break;
@@ -1522,7 +1523,7 @@ static int kldrModLXDoIterDataUnpacking(KU8 *pbDst, const KU8 *pbSrc, int cbSrc)
int cbDst = OBJPAGELEN;
/* Validate size of data. */
- if (cbSrc >= OBJPAGELEN - 2)
+ if (cbSrc >= (int)OBJPAGELEN - 2)
return KLDR_ERR_LX_BAD_ITERDATA;
/*
@@ -2443,6 +2444,7 @@ static int kldrModLXRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAd
case NRRENT:
KLDRMODLX_ASSERT(!"NRRENT");
+ /* Falls through. */
default:
iSelector = -1;
break;
@@ -2474,11 +2476,11 @@ static int kldrModLXRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAd
/* common / simple */
if ( (u.prlc->nr_stype & NRSRCMASK) == NROFF32
&& off >= 0
- && off <= OBJPAGELEN - 4)
+ && off <= (int)OBJPAGELEN - 4)
*(KU32 *)&pbPage[off] = (KU32)uValue;
else if ( (u.prlc->nr_stype & NRSRCMASK) == NRSOFF32
&& off >= 0
- && off <= OBJPAGELEN - 4)
+ && off <= (int)OBJPAGELEN - 4)
*(KU32 *)&pbPage[off] = (KU32)(uValue - (PageAddress + off + 4));
else
{
@@ -2499,7 +2501,7 @@ static int kldrModLXRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAd
while (c-- > 0)
{
int off = *poffSrc++;
- if (off >= 0 && off <= OBJPAGELEN - 4)
+ if (off >= 0 && off <= (int)OBJPAGELEN - 4)
*(KU32 *)&pbPage[off] = (KU32)uValue;
else
{
@@ -2514,7 +2516,7 @@ static int kldrModLXRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAd
while (c-- > 0)
{
int off = *poffSrc++;
- if (off >= 0 && off <= OBJPAGELEN - 4)
+ if (off >= 0 && off <= (int)OBJPAGELEN - 4)
*(KU32 *)&pbPage[off] = (KU32)(uValue - (PageAddress + off + 4));
else
{
@@ -2647,7 +2649,7 @@ static int kldrModLXDoReloc(KU8 *pbPage, int off, KLDRADDR PageAddress, const st
pbDst = pbPage + off;
while (cb-- > 0)
{
- if (off > OBJPAGELEN)
+ if (off > (int)OBJPAGELEN)
break;
if (off >= 0)
*pbDst = *pbSrc;
diff --git a/src/lib/kStuff/kLdr/kLdrModMachO.c b/src/lib/kStuff/kLdr/kLdrModMachO.c
index 6a11d30..48f2a9f 100644
--- a/src/lib/kStuff/kLdr/kLdrModMachO.c
+++ b/src/lib/kStuff/kLdr/kLdrModMachO.c
@@ -1,4 +1,4 @@
-/* $Id: kLdrModMachO.c 91 2016-09-07 14:29:58Z bird $ */
+/* $Id: kLdrModMachO.c 102 2017-10-02 10:45:31Z bird $ */
/** @file
* kLdr - The Module Interpreter for the MACH-O format.
*/
@@ -749,6 +749,7 @@ static int kldrModMachOPreParseLoadCommands(KU8 *pbLoadCommands, const mach_hea
/** @todo this requires a query API or flag... (e.g. C++ constructors) */ \
KLDRMODMACHO_CHECK_RETURN(fOpenFlags & KLDRMOD_OPEN_FLAGS_FOR_INFO, \
KLDR_ERR_MACHO_UNSUPPORTED_INIT_SECTION); \
+ /* Falls through. */ \
case S_MOD_TERM_FUNC_POINTERS: \
/** @todo this requires a query API or flag... (e.g. C++ destructors) */ \
KLDRMODMACHO_CHECK_RETURN(fOpenFlags & KLDRMOD_OPEN_FLAGS_FOR_INFO, \
@@ -852,7 +853,7 @@ static int kldrModMachOPreParseLoadCommands(KU8 *pbLoadCommands, const mach_hea
if (cSegments == 1) /* The link address is set by the first segment. */ \
*pLinkAddress = pSect->addr; \
} \
- /* fall thru */ \
+ /* Falls through. */ \
case MH_EXECUTE: \
case MH_DYLIB: \
case MH_BUNDLE: \
@@ -1854,7 +1855,7 @@ static int kldrModMachODoQuerySymbol32Bit(PKLDRMODMACHO pModMachO, const macho_n
case MACHO_N_INDR:
/** @todo implement indirect and prebound symbols. */
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_TODO);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_TODO);
}
return 0;
@@ -1982,7 +1983,7 @@ static int kldrModMachODoQuerySymbol64Bit(PKLDRMODMACHO pModMachO, const macho_n
case MACHO_N_INDR:
/** @todo implement indirect and prebound symbols. */
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_TODO);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_TODO);
}
return 0;
@@ -2029,7 +2030,7 @@ static int kldrModMachOEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR B
}
}
else
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_TODO);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_TODO);
return rc;
}
@@ -2133,7 +2134,7 @@ static int kldrModMachODoEnumSymbols32Bit(PKLDRMODMACHO pModMachO, const macho_n
case MACHO_N_INDR:
/** @todo implement indirect and prebound symbols. */
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_TODO);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_TODO);
}
/*
@@ -2245,7 +2246,7 @@ static int kldrModMachODoEnumSymbols64Bit(PKLDRMODMACHO pModMachO, const macho_n
case MACHO_N_INDR:
/** @todo implement indirect and prebound symbols. */
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_TODO);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_TODO);
}
/*
@@ -2774,7 +2775,7 @@ static int kldrModMachOObjDoFixups(PKLDRMODMACHO pModMachO, void *pvMapping, KL
(macho_nlist_64_t *)pModMachO->pvaSymbols,
pModMachO->cSymbols, NewBaseAddress);
else
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_TODO);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_TODO);
if (rc)
break;
}
@@ -2887,9 +2888,9 @@ static int kldrModMachOFixupSectionGeneric32Bit(PKLDRMODMACHO pModMachO, KU8 *p
case MACHO_N_INDR:
case MACHO_N_PBUD:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_TODO);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_TODO);
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_MACHO_BAD_SYMBOL);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_SYMBOL);
}
}
else if (Fixup.r.r_symbolnum != R_ABS)
@@ -3053,7 +3054,7 @@ static int kldrModMachOFixupSectionAMD64(PKLDRMODMACHO pModMachO, KU8 *pbSectBi
case 2: SymAddr = *uFixVirgin.pi32; break;
case 3: SymAddr = *uFixVirgin.pi64; break;
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_BAD_FIXUP);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_BAD_FIXUP);
}
/* Add symbol / section address. */
@@ -3079,9 +3080,9 @@ static int kldrModMachOFixupSectionAMD64(PKLDRMODMACHO pModMachO, KU8 *pbSectBi
break;
case MACHO_N_INDR:
case MACHO_N_PBUD:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_TODO);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_TODO);
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_MACHO_BAD_SYMBOL);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_SYMBOL);
}
SymAddr = sizeof(KU64) * Fixup.r.r_symbolnum + pModMachO->GotRVA + NewBaseAddress;
KLDRMODMACHO_CHECK_RETURN(Fixup.r.r_length == 2, KLDR_ERR_BAD_FIXUP);
@@ -3095,6 +3096,7 @@ static int kldrModMachOFixupSectionAMD64(PKLDRMODMACHO pModMachO, KU8 *pbSectBi
case X86_64_RELOC_SIGNED_2:
case X86_64_RELOC_SIGNED_4:
KLDRMODMACHO_CHECK_RETURN(Fixup.r.r_pcrel, KLDR_ERR_BAD_FIXUP);
+ /* Falls through. */
default:
{
/* Adjust with fixup specific addend and vierfy unsigned/r_pcrel. */
@@ -3114,7 +3116,7 @@ static int kldrModMachOFixupSectionAMD64(PKLDRMODMACHO pModMachO, KU8 *pbSectBi
SymAddr -= 4;
break;
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_BAD_FIXUP);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_BAD_FIXUP);
}
switch (pSym->n_type & MACHO_N_TYPE)
@@ -3146,9 +3148,9 @@ static int kldrModMachOFixupSectionAMD64(PKLDRMODMACHO pModMachO, KU8 *pbSectBi
case MACHO_N_INDR:
case MACHO_N_PBUD:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_TODO);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_TODO);
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_MACHO_BAD_SYMBOL);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_SYMBOL);
}
break;
}
@@ -3179,9 +3181,9 @@ static int kldrModMachOFixupSectionAMD64(PKLDRMODMACHO pModMachO, KU8 *pbSectBi
case MACHO_N_INDR:
case MACHO_N_PBUD:
- KLDRMODMACHO_CHECK_RETURN(0,KLDR_ERR_TODO);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_TODO);
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_MACHO_BAD_SYMBOL);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_SYMBOL);
}
/* Load the 2nd fixup, check sanity. */
@@ -3220,9 +3222,9 @@ static int kldrModMachOFixupSectionAMD64(PKLDRMODMACHO pModMachO, KU8 *pbSectBi
case MACHO_N_INDR:
case MACHO_N_PBUD:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_TODO);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_TODO);
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_MACHO_BAD_SYMBOL);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_SYMBOL);
}
}
else if (Fixup2.r_symbolnum != R_ABS)
@@ -3233,7 +3235,7 @@ static int kldrModMachOFixupSectionAMD64(PKLDRMODMACHO pModMachO, KU8 *pbSectBi
SymAddr += pSymSect->RVA + NewBaseAddress;
}
else
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_BAD_FIXUP);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_BAD_FIXUP);
}
break;
}
@@ -3260,7 +3262,7 @@ static int kldrModMachOFixupSectionAMD64(PKLDRMODMACHO pModMachO, KU8 *pbSectBi
/*case X86_64_RELOC_GOT: */
/*case X86_64_RELOC_SUBTRACTOR: - must be r_extern=1 says as. */
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_BAD_FIXUP);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_BAD_FIXUP);
}
if (Fixup.r.r_symbolnum != R_ABS)
{
@@ -3293,7 +3295,7 @@ static int kldrModMachOFixupSectionAMD64(PKLDRMODMACHO pModMachO, KU8 *pbSectBi
*uFix.pu32 = (KU32)SymAddr;
break;
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_BAD_FIXUP);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_BAD_FIXUP);
}
}
@@ -3671,7 +3673,7 @@ static int kldrModMachOMakeGOT(PKLDRMODMACHO pModMachO, void *pvBits, KLDRADDR N
}
default:
- KLDRMODMACHO_CHECK_RETURN(0, KLDR_ERR_TODO);
+ KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_TODO);
}
}
}
diff --git a/src/lib/maybe_con_write.c b/src/lib/maybe_con_write.c
index 0b28a42..0ddea09 100644
--- a/src/lib/maybe_con_write.c
+++ b/src/lib/maybe_con_write.c
@@ -1,4 +1,4 @@
-/* $Id: maybe_con_write.c 2900 2016-09-09 14:42:06Z bird $ */
+/* $Id: maybe_con_write.c 3065 2017-09-30 12:52:35Z bird $ */
/** @file
* maybe_con_write - Optimized console output on windows.
*/
@@ -97,7 +97,7 @@ ssize_t maybe_con_write(int fd, void *pvBuf, size_t cbToWrite)
* Semi regular write handling.
*/
cbWritten = write(fd, pvBuf, (to_write_t)cbToWrite);
- if (cbWritten == cbToWrite)
+ if (cbWritten == (ssize_t)cbToWrite)
{ /* likely */ }
else if (cbWritten >= 0 || errno == EINTR)
{
diff --git a/src/lib/md5.c b/src/lib/md5.c
index e9d9474..3f17d3a 100644
--- a/src/lib/md5.c
+++ b/src/lib/md5.c
@@ -144,7 +144,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
MD5Transform(ctx->buf, (uint32 *) ctx->in);
byteReverse((unsigned char *) ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
- memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
+ memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
}
diff --git a/src/lib/nt/kFsCache.c b/src/lib/nt/kFsCache.c
index 59fa467..763a383 100644
--- a/src/lib/nt/kFsCache.c
+++ b/src/lib/nt/kFsCache.c
@@ -1,4 +1,4 @@
-/* $Id: kFsCache.c 3007 2016-11-06 16:46:43Z bird $ */
+/* $Id: kFsCache.c 3082 2017-10-02 19:23:17Z bird $ */
/** @file
* ntdircache.c - NT directory content cache.
*/
@@ -2747,8 +2747,8 @@ static PKFSOBJ kFsCacheLookupUncShareW(PKFSCACHE pCache, const wchar_t *pwszPath
* @param penmError Where to return details as to why the lookup
* failed.
* @param ppLastAncestor Where to return the last parent element found
- * (referenced) in case of error an path/file not
- * found problem. Optional.
+ * (referenced) in case of error like an path/file
+ * not found problem. Optional.
*/
PKFSOBJ kFsCacheLookupRelativeToDirA(PKFSCACHE pCache, PKFSDIR pParent, const char *pszPath, KU32 cchPath, KU32 fFlags,
KFSLOOKUPERROR *penmError, PKFSOBJ *ppLastAncestor)
@@ -2794,7 +2794,11 @@ PKFSOBJ kFsCacheLookupRelativeToDirA(PKFSCACHE pCache, PKFSDIR pParent, const ch
|| kFsCachePopuplateOrRefreshDir(pCache, pParent, penmError))
{ /* likely */ }
else
+ {
+ if (ppLastAncestor)
+ *ppLastAncestor = kFsCacheObjRetainInternal(&pParent->Obj);
return NULL;
+ }
/*
* Search the current node for the name.
@@ -2835,7 +2839,11 @@ PKFSOBJ kFsCacheLookupRelativeToDirA(PKFSCACHE pCache, PKFSDIR pParent, const ch
|| kFsCacheRefreshMissing(pCache, pChild, penmError) )
{ /* likely */ }
else
+ {
+ if (ppLastAncestor)
+ *ppLastAncestor = kFsCacheObjRetainInternal(&pParent->Obj);
return NULL;
+ }
return kFsCacheObjRetainInternal(pChild);
}
@@ -2871,8 +2879,8 @@ PKFSOBJ kFsCacheLookupRelativeToDirA(PKFSCACHE pCache, PKFSDIR pParent, const ch
}
}
+ /* not reached */
return NULL;
-
}
@@ -2893,8 +2901,8 @@ PKFSOBJ kFsCacheLookupRelativeToDirA(PKFSCACHE pCache, PKFSDIR pParent, const ch
* @param penmError Where to return details as to why the lookup
* failed.
* @param ppLastAncestor Where to return the last parent element found
- * (referenced) in case of error an path/file not
- * found problem. Optional.
+ * (referenced) in case of error like an path/file
+ * not found problem. Optional.
*/
PKFSOBJ kFsCacheLookupRelativeToDirW(PKFSCACHE pCache, PKFSDIR pParent, const wchar_t *pwszPath, KU32 cwcPath, KU32 fFlags,
KFSLOOKUPERROR *penmError, PKFSOBJ *ppLastAncestor)
@@ -2940,7 +2948,11 @@ PKFSOBJ kFsCacheLookupRelativeToDirW(PKFSCACHE pCache, PKFSDIR pParent, const wc
|| kFsCachePopuplateOrRefreshDir(pCache, pParent, penmError))
{ /* likely */ }
else
+ {
+ if (ppLastAncestor)
+ *ppLastAncestor = kFsCacheObjRetainInternal(&pParent->Obj);
return NULL;
+ }
/*
* Search the current node for the name.
@@ -2981,7 +2993,11 @@ PKFSOBJ kFsCacheLookupRelativeToDirW(PKFSCACHE pCache, PKFSDIR pParent, const wc
|| kFsCacheRefreshMissing(pCache, pChild, penmError) )
{ /* likely */ }
else
+ {
+ if (ppLastAncestor)
+ *ppLastAncestor = kFsCacheObjRetainInternal(&pParent->Obj);
return NULL;
+ }
return kFsCacheObjRetainInternal(pChild);
}
@@ -3019,7 +3035,6 @@ PKFSOBJ kFsCacheLookupRelativeToDirW(PKFSCACHE pCache, PKFSDIR pParent, const wc
}
return NULL;
-
}
/**
@@ -3096,6 +3111,8 @@ static PKFSOBJ kFsCacheLookupAbsoluteA(PKFSCACHE pCache, const char *pszPath, KU
|| (fFlags & KFSCACHE_LOOKUP_F_NO_REFRESH)
|| kFsCacheRefreshObj(pCache, pRoot, penmError))
return kFsCacheObjRetainInternal(pRoot);
+ if (ppLastAncestor)
+ *ppLastAncestor = kFsCacheObjRetainInternal(pRoot);
return NULL;
}
@@ -3195,6 +3212,8 @@ static PKFSOBJ kFsCacheLookupAbsoluteW(PKFSCACHE pCache, const wchar_t *pwszPath
|| (fFlags & KFSCACHE_LOOKUP_F_NO_REFRESH)
|| kFsCacheRefreshObj(pCache, pRoot, penmError))
return kFsCacheObjRetainInternal(pRoot);
+ if (ppLastAncestor)
+ *ppLastAncestor = kFsCacheObjRetainInternal(pRoot);
return NULL;
}
@@ -3513,7 +3532,7 @@ static PKFSOBJ kFsCacheLookupHashedA(PKFSCACHE pCache, const char *pchPath, KU32
&& *penmError != KFSLOOKUPERROR_PATH_TOO_LONG)
|| *penmError == KFSLOOKUPERROR_UNSUPPORTED )
kFsCacheCreatePathHashTabEntryA(pCache, pFsObj, pchPath, cchPath, uHashPath, idxHashTab, fAbsolute,
- pLastAncestor ? pLastAncestor->bObjType & KFSOBJ_F_USE_CUSTOM_GEN : 0, *penmError);
+ pLastAncestor ? pLastAncestor->fFlags & KFSOBJ_F_USE_CUSTOM_GEN : 0, *penmError);
if (pLastAncestor)
kFsCacheObjRelease(pCache, pLastAncestor);
@@ -3621,7 +3640,7 @@ static PKFSOBJ kFsCacheLookupHashedW(PKFSCACHE pCache, const wchar_t *pwcPath, K
&& *penmError != KFSLOOKUPERROR_PATH_TOO_LONG)
|| *penmError == KFSLOOKUPERROR_UNSUPPORTED )
kFsCacheCreatePathHashTabEntryW(pCache, pFsObj, pwcPath, cwcPath, uHashPath, idxHashTab, fAbsolute,
- pLastAncestor ? pLastAncestor->bObjType & KFSOBJ_F_USE_CUSTOM_GEN : 0, *penmError);
+ pLastAncestor ? pLastAncestor->fFlags & KFSOBJ_F_USE_CUSTOM_GEN : 0, *penmError);
if (pLastAncestor)
kFsCacheObjRelease(pCache, pLastAncestor);
diff --git a/src/lib/nt/nthlp.h b/src/lib/nt/nthlp.h
index 18125e4..29b1b72 100644
--- a/src/lib/nt/nthlp.h
+++ b/src/lib/nt/nthlp.h
@@ -1,4 +1,4 @@
-/* $Id: nthlp.h 3009 2016-11-07 02:21:59Z bird $ */
+/* $Id: nthlp.h 3060 2017-09-21 15:11:07Z bird $ */
/** @file
* MSC + NT helper functions.
*/
@@ -88,5 +88,22 @@ static __inline void birdNtTimeToTimeSpec(__int64 iNtTime, BirdTimeSpec_T *pTime
}
+static __inline void birdNtTimeToTimeVal(__int64 iNtTime, BirdTimeVal_T *pTimeVal)
+{
+ iNtTime -= BIRD_NT_EPOCH_OFFSET_UNIX_100NS;
+ pTimeVal->tv_sec = iNtTime / 10000000;
+ pTimeVal->tv_usec = (iNtTime % 10000000) / 10;
+}
+
+
+static __inline __int64 birdNtTimeFromTimeVal(BirdTimeVal_T const *pTimeVal)
+{
+ __int64 iNtTime = pTimeVal->tv_sec * 10000000;
+ iNtTime += pTimeVal->tv_usec * 10;
+ iNtTime += BIRD_NT_EPOCH_OFFSET_UNIX_100NS;
+ return iNtTime;
+}
+
+
#endif
diff --git a/src/lib/nt/nttypes.h b/src/lib/nt/nttypes.h
index 8e714c4..fe669c8 100644
--- a/src/lib/nt/nttypes.h
+++ b/src/lib/nt/nttypes.h
@@ -1,10 +1,10 @@
-/* $Id: nttypes.h 2702 2013-11-21 00:11:08Z bird $ */
+/* $Id: nttypes.h 3060 2017-09-21 15:11:07Z bird $ */
/** @file
* MSC + NT basic & common types, various definitions.
*/
/*
- * Copyright (c) 2005-2013 knut st. osmundsen <bird-kBuild-spamx at anduin.net>
+ * Copyright (c) 2005-2017 knut st. osmundsen <bird-kBuild-spamx at anduin.net>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -33,6 +33,13 @@
#include <sys/types.h>
+typedef struct BirdTimeVal
+{
+ __int64 tv_sec;
+ __int32 tv_usec;
+ __int32 tv_padding0;
+} BirdTimeVal_T;
+
typedef struct BirdTimeSpec
{
__int64 tv_sec;
@@ -46,4 +53,3 @@ typedef struct BirdTimeSpec
#endif
-
diff --git a/src/lib/nt/ntunlink.c b/src/lib/nt/ntunlink.c
index 50921bd..fc0d82e 100644
--- a/src/lib/nt/ntunlink.c
+++ b/src/lib/nt/ntunlink.c
@@ -1,10 +1,10 @@
-/* $Id: ntunlink.c 3009 2016-11-07 02:21:59Z bird $ */
+/* $Id: ntunlink.c 3060 2017-09-21 15:11:07Z bird $ */
/** @file
* MSC + NT unlink and variations.
*/
/*
- * Copyright (c) 2005-2013 knut st. osmundsen <bird-kBuild-spamx at anduin.net>
+ * Copyright (c) 2005-2017 knut st. osmundsen <bird-kBuild-spamx at anduin.net>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -32,9 +32,7 @@
/*******************************************************************************
* Header Files *
*******************************************************************************/
-#include <stdio.h>
-#include <errno.h>
-#include <malloc.h>
+#include "ntunlink.h"
#include "ntstuff.h"
#include "nthlp.h"
diff --git a/src/lib/nt/ntunlink.h b/src/lib/nt/ntunlink.h
index 035a028..e7934be 100644
--- a/src/lib/nt/ntunlink.h
+++ b/src/lib/nt/ntunlink.h
@@ -1,4 +1,4 @@
-/* $Id: ntunlink.h 3009 2016-11-07 02:21:59Z bird $ */
+/* $Id: ntunlink.h 3060 2017-09-21 15:11:07Z bird $ */
/** @file
* MSC + NT unlink and variations.
*/
@@ -32,6 +32,7 @@
#define ___nt_ntunlink_h
#include "nttypes.h"
+#include <wchar.h>
int birdUnlink(const char *pszFile);
int birdUnlinkW(const wchar_t *pwszFile);
diff --git a/src/lib/nt/ntutimes.c b/src/lib/nt/ntutimes.c
new file mode 100644
index 0000000..554e6e6
--- /dev/null
+++ b/src/lib/nt/ntutimes.c
@@ -0,0 +1,99 @@
+/* $Id: ntutimes.c 3097 2017-10-14 03:52:44Z bird $ */
+/** @file
+ * MSC + NT utimes and lutimes
+ */
+
+/*
+ * Copyright (c) 2005-2017 knut st. osmundsen <bird-kBuild-spamx at anduin.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Alternatively, the content of this file may be used under the terms of the
+ * GPL version 2 or later, or LGPL version 2.1 or later.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "ntutimes.h"
+
+#include "ntstuff.h"
+#include "nthlp.h"
+
+
+
+static int birdUtimesInternal(const char *pszPath, BirdTimeVal_T paTimes[2], int fFollowLink)
+{
+ HANDLE hFile = birdOpenFileEx(NULL,
+ pszPath,
+ FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_OPEN,
+ FILE_OPEN_FOR_BACKUP_INTENT | (fFollowLink ? 0 : FILE_OPEN_REPARSE_POINT),
+ OBJ_CASE_INSENSITIVE);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ MY_FILE_BASIC_INFORMATION Info;
+ MY_IO_STATUS_BLOCK Ios;
+ MY_NTSTATUS rcNt;
+
+ memset(&Info, 0, sizeof(Info));
+ if (paTimes)
+ {
+ Info.LastAccessTime.QuadPart = birdNtTimeFromTimeVal(&paTimes[0]);
+ Info.LastWriteTime.QuadPart = birdNtTimeFromTimeVal(&paTimes[1]);
+ }
+ else
+ {
+ /** @todo replace this with something from ntdll */
+ FILETIME Now;
+ GetSystemTimeAsFileTime(&Now);
+ Info.LastAccessTime.HighPart = Now.dwHighDateTime;
+ Info.LastAccessTime.LowPart = Now.dwLowDateTime;
+ Info.LastWriteTime.HighPart = Now.dwHighDateTime;
+ Info.LastWriteTime.LowPart = Now.dwLowDateTime;
+ }
+
+ Ios.Information = -1;
+ Ios.u.Status = -1;
+
+ rcNt = g_pfnNtSetInformationFile(hFile, &Ios, &Info, sizeof(Info), MyFileBasicInformation);
+
+ birdCloseFile(hFile);
+
+ if (MY_NT_SUCCESS(rcNt))
+ return 0;
+ birdSetErrnoFromNt(rcNt);
+ }
+ return -1;
+}
+
+
+int birdUtimes(const char *pszFile, BirdTimeVal_T paTimes[2])
+{
+ return birdUtimesInternal(pszFile, paTimes, 1 /*fFollowLink*/);
+}
+
+int birdLUtimes(const char *pszFile, BirdTimeVal_T paTimes[2])
+{
+ return birdUtimesInternal(pszFile, paTimes, 0 /*fFollowLink*/);
+}
+
diff --git a/src/lib/nt/nttypes.h b/src/lib/nt/ntutimes.h
similarity index 70%
copy from src/lib/nt/nttypes.h
copy to src/lib/nt/ntutimes.h
index 8e714c4..42589ff 100644
--- a/src/lib/nt/nttypes.h
+++ b/src/lib/nt/ntutimes.h
@@ -1,10 +1,10 @@
-/* $Id: nttypes.h 2702 2013-11-21 00:11:08Z bird $ */
+/* $Id: ntutimes.h 3060 2017-09-21 15:11:07Z bird $ */
/** @file
- * MSC + NT basic & common types, various definitions.
+ * MSC + NT utimes and lutimes.
*/
/*
- * Copyright (c) 2005-2013 knut st. osmundsen <bird-kBuild-spamx at anduin.net>
+ * Copyright (c) 2005-2017 knut st. osmundsen <bird-kBuild-spamx at anduin.net>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -28,22 +28,18 @@
* GPL version 2 or later, or LGPL version 2.1 or later.
*/
-#ifndef ___nt_nttypes_h
-#define ___nt_nttypes_h
+#ifndef ___nt_ntutimes_h
+#define ___nt_ntutimes_h
-#include <sys/types.h>
+#include "nttypes.h"
-typedef struct BirdTimeSpec
-{
- __int64 tv_sec;
- __int32 tv_nsec;
- __int32 tv_padding0;
-} BirdTimeSpec_T;
+int birdUtimes(const char *pszFile, BirdTimeVal_T paTimes[2]);
+int birdLUtimes(const char *pszFile, BirdTimeVal_T paTimes[2]);
-/** The distance between the NT and unix epochs given in NT time (units of 100
- * ns). */
-#define BIRD_NT_EPOCH_OFFSET_UNIX_100NS 116444736000000000LL
+#undef utimes
+#define utimes(a_pszPath, a_paTimes) birdUtimes(a_pszPath, a_paTimes)
+#undef lutimes
+#define lutimes(a_pszPath, a_paTimes) birdLUtimes(a_pszPath, a_paTimes)
#endif
-
diff --git a/src/sed/Makefile.kmk b/src/sed/Makefile.kmk
index 1fec22c..f34b3e8 100644
--- a/src/sed/Makefile.kmk
+++ b/src/sed/Makefile.kmk
@@ -1,4 +1,4 @@
-# $Id: Makefile.kmk 2909 2016-09-09 22:54:17Z bird $
+# $Id: Makefile.kmk 3062 2017-09-30 11:26:21Z bird $
## @file
# Sub-Makefile for kmk_sed.
#
@@ -73,6 +73,10 @@ kmk_sed_SOURCES.freebsd = \
kmk_sed_SOURCES.haiku = \
lib/strverscmp.c \
lib/obstack.c
+kmk_sed_SOURCES.netbsd = \
+ lib/strverscmp.c \
+ lib/obstack.c \
+ lib/getline.c
kmk_sed_SOURCES.openbsd = \
lib/strverscmp.c \
lib/obstack.c \
diff --git a/src/sed/config.h.netbsd b/src/sed/config.h.netbsd
new file mode 100755
index 0000000..568e886
--- /dev/null
+++ b/src/sed/config.h.netbsd
@@ -0,0 +1,471 @@
+/* config.h. Generated from config_h.in by configure. */
+/* config_h.in. Generated from configure.ac by autoheader. */
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to 1 if using `alloca.c'. */
+/* #undef C_ALLOCA */
+
+/* Define to 1 if translation of program messages to the user's native
+ language is requested. */
+/* #undef ENABLE_NLS */
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define to 1 if you have the <argz.h> header file. */
+/* #undef HAVE_ARGZ_H */
+
+/* Define to 1 if you have the `asprintf' function. */
+#define HAVE_ASPRINTF 1
+
+/* Define to 1 if you have the `bcopy' function. */
+#define HAVE_BCOPY 1
+
+/* Define to 1 if you have the `btowc' function. */
+#define HAVE_BTOWC 1
+
+/* Define to 1 if you have the `bzero' function. */
+#define HAVE_BZERO 1
+
+/* Define if the GNU dcgettext() function is already present or preinstalled.
+ */
+/* #undef HAVE_DCGETTEXT */
+
+/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you
+ don't. */
+#define HAVE_DECL_FEOF_UNLOCKED 0
+
+/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if
+ you don't. */
+#define HAVE_DECL_FGETS_UNLOCKED 0
+
+/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you
+ don't. */
+#define HAVE_DECL_GETC_UNLOCKED 1
+
+/* Define to 1 if you have the declaration of `_snprintf', and to 0 if you
+ don't. */
+#define HAVE_DECL__SNPRINTF 0
+
+/* Define to 1 if you have the declaration of `_snwprintf', and to 0 if you
+ don't. */
+#define HAVE_DECL__SNWPRINTF 0
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the `fchmod' function. */
+#define HAVE_FCHMOD 1
+
+/* Define to 1 if you have the `fchown' function. */
+#define HAVE_FCHOWN 1
+
+/* Define to 1 if you have the `fwprintf' function. */
+#define HAVE_FWPRINTF 1
+
+/* Define to 1 if you have the `getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define to 1 if you have the `getegid' function. */
+#define HAVE_GETEGID 1
+
+/* Define to 1 if you have the `geteuid' function. */
+#define HAVE_GETEUID 1
+
+/* Define to 1 if you have the `getgid' function. */
+#define HAVE_GETGID 1
+
+/* Define to 1 if you have the `getpagesize' function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define if the GNU gettext() function is already present or preinstalled. */
+/* #undef HAVE_GETTEXT */
+
+/* Define to 1 if you have the `getuid' function. */
+#define HAVE_GETUID 1
+
+/* Define if you have the iconv() function. */
+#define HAVE_ICONV 1
+
+/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
+#define HAVE_INTMAX_T 1
+
+/* Define if <inttypes.h> exists and doesn't clash with <sys/types.h>. */
+#define HAVE_INTTYPES_H 1
+
+/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and
+ declares uintmax_t. */
+#define HAVE_INTTYPES_H_WITH_UINTMAX 1
+
+/* Define to 1 if you have the <io.h> header file. */
+/* #undef HAVE_IO_H */
+
+/* Define to 1 if you have the `isascii' function. */
+#define HAVE_ISASCII 1
+
+/* Define to 1 if you have the `isatty' function. */
+#define HAVE_ISATTY 1
+
+/* Define to 1 if you have the `isblank' function. */
+#define HAVE_ISBLANK 1
+
+/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
+#define HAVE_LANGINFO_CODESET 1
+
+/* Define if your <locale.h> file defines LC_MESSAGES. */
+#define HAVE_LC_MESSAGES 1
+
+/* Define to 1 if you have the `regex' library (-lregex). */
+/* #undef HAVE_LIBREGEX */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define if you have the 'long double' type. */
+#define HAVE_LONG_DOUBLE 1
+
+/* Define to 1 if you support file names longer than 14 characters. */
+#define HAVE_LONG_FILE_NAMES 1
+
+/* Define if you have the 'long long' type. */
+#define HAVE_LONG_LONG 1
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if mbrtowc and mbstate_t are properly declared. */
+#define HAVE_MBRTOWC 1
+
+/* Define to 1 if <wchar.h> declares mbstate_t. */
+#define HAVE_MBSTATE_T 1
+
+/* Define to 1 if you have the <mcheck.h> header file. */
+/* #undef HAVE_MCHECK_H */
+
+/* Define to 1 if you have the `memchr' function. */
+#define HAVE_MEMCHR 1
+
+/* Define to 1 if you have the `memcmp' function. */
+#define HAVE_MEMCMP 1
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mempcpy' function. */
+/* #undef HAVE_MEMPCPY */
+
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+
+/* Define to 1 if you have the `mkstemp' function. */
+#define HAVE_MKSTEMP 1
+
+/* Define to 1 if you have a working `mmap' system call. */
+#define HAVE_MMAP 1
+
+/* Define to 1 if you have the `munmap' function. */
+#define HAVE_MUNMAP 1
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the <nl_types.h> header file. */
+#define HAVE_NL_TYPES_H 1
+
+/* Define to 1 if libc includes obstacks. */
+/* #undef HAVE_OBSTACK */
+
+/* Define to 1 if you have the `pathconf' function. */
+#define HAVE_PATHCONF 1
+
+/* Define to 1 if you have the `popen' function. */
+#define HAVE_POPEN 1
+
+/* Define if your printf() function supports format strings with positions. */
+#define HAVE_POSIX_PRINTF 1
+
+/* Define to 1 if you have the `putenv' function. */
+#define HAVE_PUTENV 1
+
+/* Define to 1 if you have the <regex.h> header file. */
+/* #undef HAVE_REGEX_H */
+
+/* Define to 1 if you have the `setenv' function. */
+#define HAVE_SETENV 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares
+ uintmax_t. */
+#define HAVE_STDINT_H_WITH_UINTMAX 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `stpcpy' function. */
+/* #undef HAVE_STPCPY */
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strtoul' function. */
+#define HAVE_STRTOUL 1
+
+/* Define to 1 if you have the `strverscmp' function. */
+/* #undef HAVE_STRVERSCMP */
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#define HAVE_SYS_FILE_H 1
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the `tsearch' function. */
+#define HAVE_TSEARCH 1
+
+/* Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>. */
+#define HAVE_UINTMAX_T 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the 'unsigned long long' type. */
+#define HAVE_UNSIGNED_LONG_LONG 1
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#define HAVE_WCHAR_H 1
+
+/* Define if you have the 'wchar_t' type. */
+#define HAVE_WCHAR_T 1
+
+/* Define to 1 if you have the `wcrtomb' function. */
+#define HAVE_WCRTOMB 1
+
+/* Define to 1 if you have the `wcscoll' function. */
+#define HAVE_WCSCOLL 1
+
+/* Define to 1 if you have the `wcslen' function. */
+#define HAVE_WCSLEN 1
+
+/* Define to 1 if you have the <wctype.h> header file. */
+#define HAVE_WCTYPE_H 1
+
+/* Define if you have the 'wint_t' type. */
+#define HAVE_WINT_T 1
+
+/* Define to 1 if the system has the type `_Bool'. */
+#define HAVE__BOOL 1
+
+/* Define to 1 if you have the `__argz_count' function. */
+/* #undef HAVE___ARGZ_COUNT */
+
+/* Define to 1 if you have the `__argz_next' function. */
+/* #undef HAVE___ARGZ_NEXT */
+
+/* Define to 1 if you have the `__argz_stringify' function. */
+/* #undef HAVE___ARGZ_STRINGIFY */
+
+/* Define to 1 if you have the `__fsetlocking' function. */
+/* #undef HAVE___FSETLOCKING */
+
+/* Define as const if the declaration of iconv() needs const. */
+#define ICONV_CONST const
+
+/* Define if integer division by zero raises signal SIGFPE. */
+#define INTDIV0_RAISES_SIGFPE 1
+
+/* Name of package */
+#define PACKAGE "sed"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "bonzini at gnu.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "sed"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "sed 4.1.5"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "sed"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "4.1.5"
+
+/* Define if <inttypes.h> exists and defines unusable PRI* macros. */
+/* #undef PRI_MACROS_BROKEN */
+
+/* Define to the version of GNU sed whose features are supported by this sed.
+ */
+#define SED_FEATURE_VERSION "4.1"
+
+/* Define as the maximum value of type 'size_t', if the system doesn't define
+ it. */
+/* #undef SIZE_MAX */
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+/* #undef STACK_DIRECTION */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+
+
+/* Version number of package */
+#define VERSION "4.1.5"
+
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to 1 if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Include BSD functions in regex, used by the testsuite */
+#define _REGEX_RE_COMP 1
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to a type if <wchar.h> does not define. */
+/* #undef mbstate_t */
+
+/* Define to `long int' if <sys/types.h> does not define. */
+/* #undef off_t */
+
+/* Define as the type of the result of subtracting two pointers, if the system
+ doesn't define it. */
+/* #undef ptrdiff_t */
+
+/* Define to empty if the C compiler doesn't support this keyword. */
+/* #undef signed */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef ssize_t */
+
+/* Define to unsigned long or unsigned long long if <stdint.h> and
+ <inttypes.h> don't define. */
+/* #undef uintmax_t */
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-virtualbox/kbuild.git
More information about the Pkg-virtualbox-commits
mailing list