6754862: jdk/src/windows/bin/java_md.c: hardcoded reference to msvcr71.dll
6779412: VS2008 errors compiling jdk sources
Summary: Update Makefiles to tolerate newer Visual Studio releases and runtimes.
Reviewed-by: ohair
--- a/jdk/make/com/sun/java/pack/Makefile Wed Jul 05 16:44:40 2017 +0200
+++ b/jdk/make/com/sun/java/pack/Makefile Wed Jan 14 21:35:03 2009 -0800
@@ -142,9 +142,11 @@
$(UNPACK_EXE): $(UNPACK_EXE_FILES_o) winres
$(prep-target)
$(LINKER) $(LDDFLAGS) $(UNPACK_EXE_FILES_o) $(RES) $(LIBCXX) $(LDOUTPUT)$(TEMPDIR)/unpack200$(EXE_SUFFIX)
+ifdef MT
+ $(MT) /manifest $(TEMPDIR)/unpack200$(EXE_SUFFIX).manifest /outputresource:$(TEMPDIR)/unpack200$(EXE_SUFFIX);#1
+endif
$(CP) $(TEMPDIR)/unpack200$(EXE_SUFFIX) $(UNPACK_EXE)
-
ifeq ($(PLATFORM), windows)
$(RES):: $(VERSIONINFO_RESOURCE)
$(prep-target)
--- a/jdk/make/common/Defs-windows.gmk Wed Jul 05 16:44:40 2017 +0200
+++ b/jdk/make/common/Defs-windows.gmk Wed Jan 14 21:35:03 2009 -0800
@@ -68,11 +68,24 @@
# The following DLL's are considered MS runtime libraries and should
# not to be REBASEd, see deploy/make/common/Release.gmk.
-# msvcrt.dll, msvcr71.dll: Microsoft runtimes
+# msvcrt.dll, msvcrnn.dll [msvcr71 or msvcr80 or msvcr90] : Microsoft runtimes
MS_RUNTIME_LIBRARIES = msvcrt.dll
+MSVCRNN_DLL =
ifeq ($(ARCH_DATA_MODEL), 32)
ifeq ($(COMPILER_VERSION), VS2003)
- MS_RUNTIME_LIBRARIES += msvcr71.dll
+ MSVCRNN_DLL = msvcr71.dll
+ MSVCPNN_DLL = msvcp71.dll
+ MS_RUNTIME_LIBRARIES += $(MSVCRNN_DLL)
+ endif
+ ifeq ($(COMPILER_VERSION), VS2005)
+ MSVCRNN_DLL = msvcr80.dll
+ MSVCPNN_DLL = msvcp80.dll
+ MS_RUNTIME_LIBRARIES += $(MSVCRNN_DLL)
+ endif
+ ifeq ($(COMPILER_VERSION), VS2008)
+ MSVCRNN_DLL = msvcr90.dll
+ MSVCPNN_DLL = msvcp90.dll
+ MS_RUNTIME_LIBRARIES += $(MSVCRNN_DLL)
endif
endif
@@ -178,9 +191,22 @@
CC_OPT/LOWER = -O1
endif
endif
+ ifeq ($(COMPILER_VERSION), VS2008)
+ # Automatic precompiled header option to use (if COMPILE_APPROACH=batch)
+ AUTOMATIC_PCH_OPTION =
+ GX_OPTION = -EHsc
+ ifeq ($(ARCH_DATA_MODEL), 32)
+ CC_OPT/HIGHEST = -O2
+ CC_OPT/HIGHER = -O1
+ CC_OPT/LOWER = -O1
+ else
+ CC_OPT/HIGHEST = -O2
+ CC_OPT/HIGHER = -O1
+ CC_OPT/LOWER = -O1
+ endif
+ endif
else # CC_VERSION
-
# GCC not supported, but left for historical reference...
CC_OPT/NONE =
CC_OPT/LOWER = -O2
@@ -200,10 +226,13 @@
# -MTd Use static debug version (better than -MDd, no runtime issues)
# -D_DEBUG Change use of malloc/free/etc to use special debug ones (-MTd)
#
-# NOTE: We also will use /D _STATIC_CPPLIB so we don't need msvcp71.dll
+# NOTE: We also will use /D _STATIC_CPPLIB so we don't need msvcpnn.dll
#
+# If MS_RUNTIME_STATIC is requested, use -MT only with VS2003.
ifeq ($(MS_RUNTIME_STATIC),true)
- MS_RUNTIME_OPTION=-MT
+ ifeq ($(COMPILER_VERSION), VS2003)
+ MS_RUNTIME_OPTION=-MT
+ endif
else
MS_RUNTIME_OPTION=-MD
endif
@@ -238,7 +267,7 @@
# -YX -Fp/.../foobar.pch Use precompiled headers (try someday?)
# -nologo Don't print out startup message
# /D _STATIC_CPPLIB
- # Use static link for the C++ runtime (so msvcp71.dll not needed)
+ # Use static link for the C++ runtime (so msvcpnn.dll not needed)
#
CFLAGS_COMMON += -Zi -nologo
CFLAGS_OPT = $(CC_OPT)
@@ -277,8 +306,16 @@
# Always add bufferoverflowU.lib to VS2005 link commands (pack uses LDDFLAGS)
LFLAGS_VS2005 = $(BUFFEROVERFLOWLIB)
+ # VS2008 has bufferoverflow baked in:
+ LFLAGS_VS2008 =
+
# LFLAGS are the flags given to $(LINK) and used to build the actual DLL file
BASELFLAGS = -nologo /opt:REF /incremental:no
+ifdef MT
+ # VS2005, VS2008, and beyond: ask LINK to generate manifests for .dll & .exe
+ BASELFLAGS += /manifest
+endif
+
LFLAGS = $(BASELFLAGS) $(LDEBUG) $(EXTRA_LFLAGS) $(LFLAGS_$(COMPILER_VERSION))
LDDFLAGS += $(LFLAGS_$(COMPILER_VERSION))
--- a/jdk/make/common/Library.gmk Wed Jul 05 16:44:40 2017 +0200
+++ b/jdk/make/common/Library.gmk Wed Jan 14 21:35:03 2009 -0800
@@ -179,6 +179,9 @@
# build it into $(OBJDIR) so that the other generated files get put
# there, then copy just the DLL (and MAP file) to the requested directory.
#
+# In VS2005 or VS2008 the link command creates a .manifest file that we want
+# to insert into the linked artifact so we do not need to track it separately.
+# Use ";#2" for .dll and ";#1" for .exe in the MT command below:
$(ACTUAL_LIBRARY):: $(OBJDIR)/$(LIBRARY).lcf
@$(prep-target)
@$(MKDIR) -p $(OBJDIR)
@@ -186,6 +189,9 @@
-map:$(OBJDIR)/$(LIBRARY).map \
$(LFLAGS) @$(OBJDIR)/$(LIBRARY).lcf \
$(OTHER_LCF) $(JAVALIB) $(LDLIBS)
+ifdef MT
+ $(MT) /manifest $(OBJDIR)/$(@F).manifest /outputresource:$(OBJDIR)/$(@F);#2
+endif
$(CP) $(OBJDIR)/$(@F) $@
$(CP) $(OBJDIR)/$(LIBRARY).map $(@D)
$(CP) $(OBJDIR)/$(LIBRARY).pdb $(@D)
--- a/jdk/make/common/Program.gmk Wed Jul 05 16:44:40 2017 +0200
+++ b/jdk/make/common/Program.gmk Wed Jan 14 21:35:03 2009 -0800
@@ -153,6 +153,9 @@
STACK_SIZE=1048576
endif
+# In VS2005 or VS2008 the link command creates a .manifest file that we want
+# to insert into the linked artifact so we do not need to track it separately.
+# Use ";#2" for .dll and ";#1" for .exe in the MT command below:
$(OBJDIR)/$(PROGRAM)$(EXE_SUFFIX):: $(OBJDIR)/$(PROGRAM).lcf $(FILES_o) $(JLI_LCF)
@$(prep-target)
@set -- $?; \
@@ -160,6 +163,9 @@
$(LINK) -out:$@ /STACK:$(STACK_SIZE) \
-map:$(OBJDIR)/$(PROGRAM).map $(LFLAGS) $(LDFLAGS) \
@$(OBJDIR)/$(PROGRAM).lcf $(LDLIBS)
+ifdef MT
+ $(MT) /manifest $(OBJDIR)/$(PROGRAM).exe.manifest /outputresource:$@;#1
+endif
else # PLATFORM
--- a/jdk/make/common/shared/Compiler-msvc.gmk Wed Jul 05 16:44:40 2017 +0200
+++ b/jdk/make/common/shared/Compiler-msvc.gmk Wed Jan 14 21:35:03 2009 -0800
@@ -54,17 +54,10 @@
ifeq ($(ARCH_DATA_MODEL), 32)
LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
CC_MAJORVER :=$(call MajorVersion,$(CC_VER))
- REQUIRED_CC_VER = 13.10.3077
- REQUIRED_LINK_VER = 7.10.3077
- ifeq ($(CC_MAJORVER), 12)
- # This should be: CC_VER=12.00.8168 LINK_VER=6.00.8447
- COMPILER_NAME=Visual C++ 6.0 Professional + VC6-SP 3
- COMPILER_VERSION=VC6
- REBASE = $(COMPILER_PATH)rebase
- MTL = $(COMPILER_PATH)midl
- endif
ifeq ($(CC_MAJORVER), 13)
# This should be: CC_VER=13.10.3077 LINK_VER=7.10.3077
+ REQUIRED_CC_VER = 13.10.3077
+ REQUIRED_LINK_VER = 7.10.3077
COMPILER_NAME=Visual Studio .NET 2003 Professional C++
COMPILER_VERSION=VS2003
REBASE = $(COMPILER_PATH)../../Common7/Tools/Bin/rebase
@@ -74,17 +67,34 @@
endif
endif
ifeq ($(CC_MAJORVER), 14)
- # This should be: CC_VER=14.00.0000 LINK_VER=8.00.0000
- # NOTE: This compiler has not been tried yet on 32bit systems
- COMPILER_NAME=Visual Studio .NET 2005
+ # This should be: CC_VER=14.00.50727.42 LINK_VER=8.00.50727.42
+ REQUIRED_CC_VER = 14.00.50727.42
+ REQUIRED_LINK_VER = 8.00.50727.42
+ COMPILER_NAME=Visual Studio 8
COMPILER_VERSION=VS2005
REBASE = $(COMPILER_PATH)../../Common8/Tools/Bin/rebase
MTL = $(COMPILER_PATH)../../Common8/Tools/Bin/midl
+ MT = $(MSDEVTOOLS_PATH)mt
+ ifndef COMPILER_PATH
+ COMPILER_PATH := $(error COMPILER_PATH cannot be empty here)
+ endif
+ endif
+ ifeq ($(CC_MAJORVER), 15)
+ # This should be: CC_VER=15.00.21022.08 LINK_VER=9.00.21022.08
+ REQUIRED_CC_VER = 15.00.21022.08
+ REQUIRED_LINK_VER = 9.00.21022.08
+ COMPILER_NAME=Visual Studio 9
+ COMPILER_VERSION=VS2008
+ #rebase and midl moved out of Visual Studio into the SDK:
+ REBASE = $(MSDEVTOOLS_PATH)/rebase
+ MTL = $(MSDEVTOOLS_PATH)/midl.exe
+ MT = $(MSDEVTOOLS_PATH)mt
ifndef COMPILER_PATH
COMPILER_PATH := $(error COMPILER_PATH cannot be empty here)
endif
endif
else
+ # else ARCH_DATA_MODEL is 64
LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}')
CC_MAJORVER :=$(call MajorVersion,$(CC_VER))
CC_MINORVER :=$(call MinorVersion,$(CC_VER))
--- a/jdk/make/common/shared/Defs-windows.gmk Wed Jul 05 16:44:40 2017 +0200
+++ b/jdk/make/common/shared/Defs-windows.gmk Wed Jan 14 21:35:03 2009 -0800
@@ -74,7 +74,7 @@
# The ALT values should never really have spaces or use \.
# Suspect these environment variables to have spaces and/or \ characters:
# SYSTEMROOT, SystemRoot, WINDIR, windir, PROGRAMFILES, ProgramFiles,
-# DXSDK_DIR, MSTOOLS, Mstools, MSSDK, MSSdk, VC71COMNTOOLS,
+# DXSDK_DIR, MSTOOLS, Mstools, MSSDK, MSSdk, VCnnCOMNTOOLS,
# MSVCDIR, MSVCDir.
# So use $(subst \,/,) on them first adding quotes and placing them in
# their own variable assigned with :=, then use FullPath.
@@ -247,22 +247,36 @@
endif
endif
endif
- ifneq ($(subst MSDev98,OLDOLDOLD,$(_msvc_dir)),$(_msvc_dir))
- _msvc_dir :=
- endif
- # If we still don't have it, look for VS71COMNTOOLS, setup by installer?
+ # If we still don't have it, look for VSnnCOMNTOOLS (newest first),
+ # set by installer?
ifeq ($(_msvc_dir),)
+ ifdef VS90COMNTOOLS # /Common/Tools directory, use ../../Vc
+ xVS90COMNTOOLS :="$(subst \,/,$(VS90COMNTOOLS))"
+ _vs90tools :=$(call FullPath,$(xVS90COMNTOOLS))
+ endif
+ ifneq ($(_vs90tools),)
+ _msvc_dir :=$(_vs90tools)/../../Vc
+ _redist_sdk :=$(_msvc_dir)/../SDK/v3.5/Bin
+ endif
+ ifdef VS80COMNTOOLS # /Common/Tools directory, use ../../Vc
+ xVS80COMNTOOLS :="$(subst \,/,$(VS80COMNTOOLS))"
+ _vs80tools :=$(call FullPath,$(xVS80COMNTOOLS))
+ endif
+ ifneq ($(_vs80tools),)
+ _msvc_dir :=$(_vs80tools)/../../Vc
+ _redist_sdk :=$(_msvc_dir)/../SDK/v2.0/Bin
+ endif
ifdef VS71COMNTOOLS # /Common/Tools directory, use ../../Vc7
xVS71COMNTOOLS :="$(subst \,/,$(VS71COMNTOOLS))"
_vs71tools :=$(call FullPath,$(xVS71COMNTOOLS))
endif
ifneq ($(_vs71tools),)
_msvc_dir :=$(_vs71tools)/../../Vc7
+ _redist_sdk :=$(_vs71tools)/../..
endif
endif
ifneq ($(_msvc_dir),)
_compiler_bin :=$(_msvc_dir)/Bin
- _redist_sdk :=$(_msvc_dir)/../SDK/v1.1/Bin
_ms_sdk :=$(_msvc_dir)/PlatformSDK
endif
endif
@@ -410,8 +424,8 @@
else \
echo "false"; \
fi)
-_REDIST71_SDK_EXISTS := $(shell \
- if [ -f "$(_redist_sdk)/msvcr71.dll" ]; then \
+_REDISTNN_SDK_EXISTS := $(shell \
+ if [ -f "$(_redist_sdk)/$(MSVCRNN_DLL)" ]; then \
echo "true"; \
else \
echo "false"; \
@@ -435,20 +449,20 @@
MSVCRT_DLL_PATH:=$(call AltCheckSpaces,MSVCRT_DLL_PATH)
MSVCRT_DLL_PATH:=$(call AltCheckValue,MSVCRT_DLL_PATH)
- # MSVCR71_DLL_PATH: location of msvcr71.dll that will be re-distributed
- ifdef ALT_MSVCR71_DLL_PATH
- xALT_MSVCR71_DLL_PATH :="$(subst \,/,$(ALT_MSVCR71_DLL_PATH))"
- MSVCR71_DLL_PATH :=$(call FullPath,$(xALT_MSVCR71_DLL_PATH))
+ # MSVCRNN_DLL_PATH: location of msvcrnn.dll that will be re-distributed
+ ifdef ALT_MSVCRNN_DLL_PATH
+ xALT_MSVCRNN_DLL_PATH :="$(subst \,/,$(ALT_MSVCRNN_DLL_PATH))"
+ MSVCRNN_DLL_PATH :=$(call FullPath,$(xALT_MSVCRNN_DLL_PATH))
else
- ifeq ($(_REDIST71_SDK_EXISTS), true)
- xREDIST71_DIR :=$(_redist_sdk)
+ ifeq ($(_REDISTNN_SDK_EXISTS), true)
+ xREDISTNN_DIR :=$(_redist_sdk)
else
- xREDIST71_DIR :=$(_system_root)/system32
+ xREDISTNN_DIR :=$(_system_root)/system32
endif
- MSVCR71_DLL_PATH :=$(call FullPath,$(xREDIST71_DIR))
+ MSVCRNN_DLL_PATH :=$(call FullPath,$(xREDISTNN_DIR))
endif
- MSVCR71_DLL_PATH :=$(call AltCheckSpaces,MSVCR71_DLL_PATH)
- MSVCR71_DLL_PATH:=$(call AltCheckValue,MSVCR71_DLL_PATH)
+ MSVCRNN_DLL_PATH :=$(call AltCheckSpaces,MSVCRNN_DLL_PATH)
+ MSVCRNN_DLL_PATH:=$(call AltCheckValue,MSVCRNN_DLL_PATH)
else
--- a/jdk/make/common/shared/Sanity-Settings.gmk Wed Jul 05 16:44:40 2017 +0200
+++ b/jdk/make/common/shared/Sanity-Settings.gmk Wed Jan 14 21:35:03 2009 -0800
@@ -98,7 +98,7 @@
ifeq ($(PLATFORM),windows)
ALL_SETTINGS+=$(call addAltSetting,MSVCRT_DLL_PATH)
ifeq ($(ARCH_DATA_MODEL), 32)
- ALL_SETTINGS+=$(call addAltSetting,MSVCR71_DLL_PATH)
+ ALL_SETTINGS+=$(call addAltSetting,MSVCRNN_DLL_PATH)
endif
ALL_SETTINGS+=$(call addAltSetting,MSDEVTOOLS_PATH)
endif
--- a/jdk/make/common/shared/Sanity.gmk Wed Jul 05 16:44:40 2017 +0200
+++ b/jdk/make/common/shared/Sanity.gmk Wed Jan 14 21:35:03 2009 -0800
@@ -835,15 +835,13 @@
"" >> $(ERROR_FILE) ; \
fi
ifeq ($(ARCH_DATA_MODEL), 32)
- ifeq ($(COMPILER_VERSION), VS2003)
- @if [ ! -r "$(MSVCR71_DLL_PATH)/msvcr71.dll" ]; then \
- $(ECHO) "ERROR: You do not have access to msvcr71.dll. \n" \
+ @if [ ! -r "$(MSVCRNN_DLL_PATH)/$(MSVCRNN_DLL)" ]; then \
+ $(ECHO) "ERROR: You do not have access to $(MSVCRNN_DLL). \n" \
" Please check your access to \n" \
- " $(MSVCR71_DLL_PATH) \n" \
- " and/or check your value of ALT_MSVCR71_DLL_PATH. \n" \
+ " $(MSVCRNN_DLL_PATH) \n" \
+ " and/or check your value of ALT_MSVCRNN_DLL_PATH. \n" \
"" >> $(ERROR_FILE) ; \
fi
- endif
endif
endif
--- a/jdk/make/java/main/java/Makefile Wed Jul 05 16:44:40 2017 +0200
+++ b/jdk/make/java/main/java/Makefile Wed Jan 14 21:35:03 2009 -0800
@@ -28,11 +28,10 @@
PRODUCT = java
#
-# Statically link java to avoid the dependency on msvcr71.dll. This
+# Statically link java to avoid the dependency on msvcrNN.dll. This
# must be set before Defs.gmk is included.
#
MS_RUNTIME_STATIC = true
-
#
# Statically link java to avoid the dependency on jli.dll. This
# must be set before Program.gmk is included.
@@ -44,6 +43,7 @@
# Override the default version info with our own resource file (see 5106536)
ifeq ($(PLATFORM), windows)
LDLIBS_COMMON += user32.lib comctl32.lib
+
ifdef OPENJDK
RC_FLAGS += -i "$(PLATFORM_SRC)/resource/icons"
else
--- a/jdk/make/java/main/javaw/Makefile Wed Jul 05 16:44:40 2017 +0200
+++ b/jdk/make/java/main/javaw/Makefile Wed Jan 14 21:35:03 2009 -0800
@@ -32,11 +32,10 @@
PRODUCT = java
#
-# Statically link javaw to avoid the dependency on msvcr71.dll. This
+# Statically link javaw to avoid the dependency on msvcrNN.dll. This
# must be set before Defs.gmk is included.
#
MS_RUNTIME_STATIC = true
-
#
# Statically link javaw to avoid the dependency on jli.dll. This
# must be set before Program.gmk is included.
--- a/jdk/make/java/redist/Makefile Wed Jul 05 16:44:40 2017 +0200
+++ b/jdk/make/java/redist/Makefile Wed Jan 14 21:35:03 2009 -0800
@@ -109,7 +109,7 @@
$(BINDIR)/msvcrt.dll: $(MSVCRT_DLL_PATH)/msvcrt.dll
$(install-import-file)
$(CHMOD) a+x $@
-$(BINDIR)/msvcr71.dll: $(MSVCR71_DLL_PATH)/msvcr71.dll
+$(BINDIR)/$(MSVCRNN_DLL): $(MSVCRNN_DLL_PATH)/$(MSVCRNN_DLL)
$(install-import-file)
$(CHMOD) a+x $@
--- a/jdk/src/share/bin/main.c Wed Jul 05 16:44:40 2017 +0200
+++ b/jdk/src/share/bin/main.c Wed Jan 14 21:35:03 2009 -0800
@@ -32,6 +32,43 @@
#include "defines.h"
+#ifdef _MSC_VER
+#if _MSC_VER > 1400
+
+/*
+ * When building for Microsoft Windows, main has a dependency on msvcr??.dll.
+ *
+ * When using Visual Studio 2005 or later, that must be recorded in
+ * the [java,javaw].exe.manifest file.
+ *
+ * Reference:
+ * C:/Program Files/Microsoft SDKs/Windows/v6.1/include/crtdefs.h
+ */
+#include <crtassem.h>
+#ifdef _M_IX86
+
+#pragma comment(linker,"/manifestdependency:\"type='win32' " \
+ "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' " \
+ "version='" _CRT_ASSEMBLY_VERSION "' " \
+ "processorArchitecture='x86' " \
+ "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
+
+#endif /* _M_IX86 */
+
+//This may not be necessary yet for the Windows 64-bit build, but it
+//will be when that build environment is updated. Need to test to see
+//if it is harmless:
+#ifdef _M_AMD64
+
+#pragma comment(linker,"/manifestdependency:\"type='win32' " \
+ "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' " \
+ "version='" _CRT_ASSEMBLY_VERSION "' " \
+ "processorArchitecture='amd64' " \
+ "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
+
+#endif /* _M_AMD64 */
+#endif /* _MSC_VER > 1400 */
+#endif /* _MSC_VER */
/*
* Entry point.
--- a/jdk/src/windows/bin/java_md.c Wed Jul 05 16:44:40 2017 +0200
+++ b/jdk/src/windows/bin/java_md.c Wed Jan 14 21:35:03 2009 -0800
@@ -41,7 +41,6 @@
#define JVM_DLL "jvm.dll"
#define JAVA_DLL "java.dll"
-#define CRT_DLL "msvcr71.dll"
/*
* Prototypes.
@@ -206,7 +205,15 @@
* assumed to be present in the "JRE path" directory. If it is not found
* there (or "JRE path" fails to resolve), skip the explicit load and let
* nature take its course, which is likely to be a failure to execute.
+ *
+ * (NOTE: the above statement is only true for Visual Studio 2003 and
+ * msvcr71.dll.)
*/
+#ifdef _MSC_VER
+#if _MSC_VER < 1400
+#define CRT_DLL "msvcr71.dll"
+#endif
+#ifdef CRT_DLL
if (GetJREPath(crtpath, MAXPATHLEN)) {
(void)JLI_StrCat(crtpath, "\\bin\\" CRT_DLL); /* Add crt dll */
JLI_TraceLauncher("CRT path is %s\n", crtpath);
@@ -217,6 +224,8 @@
}
}
}
+#endif /* CRT_DLL */
+#endif /* _MSC_VER */
/* Load the Java VM DLL */
if ((handle = LoadLibrary(jvmpath)) == 0) {