summaryrefslogtreecommitdiffstats
path: root/intl/icu/source/tools/icuinfo
diff options
context:
space:
mode:
Diffstat (limited to 'intl/icu/source/tools/icuinfo')
-rw-r--r--intl/icu/source/tools/icuinfo/Makefile.in117
-rw-r--r--intl/icu/source/tools/icuinfo/icuinfo.cpp307
-rw-r--r--intl/icu/source/tools/icuinfo/icuinfo.vcxproj83
-rw-r--r--intl/icu/source/tools/icuinfo/icuplugins_windows_sample.txt59
-rw-r--r--intl/icu/source/tools/icuinfo/plugin_sources.txt1
-rw-r--r--intl/icu/source/tools/icuinfo/sources.txt1
-rw-r--r--intl/icu/source/tools/icuinfo/testplug.c212
-rw-r--r--intl/icu/source/tools/icuinfo/testplug.vcxproj83
-rw-r--r--intl/icu/source/tools/icuinfo/testplug.vcxproj.filters22
9 files changed, 885 insertions, 0 deletions
diff --git a/intl/icu/source/tools/icuinfo/Makefile.in b/intl/icu/source/tools/icuinfo/Makefile.in
new file mode 100644
index 0000000000..68eeb084bf
--- /dev/null
+++ b/intl/icu/source/tools/icuinfo/Makefile.in
@@ -0,0 +1,117 @@
+## Makefile.in for ICU - tools/icuinfo
+## Copyright (C) 2016 and later: Unicode, Inc. and others.
+## License & terms of use: http://www.unicode.org/copyright.html
+## Copyright (c) 1999-2015, International Business Machines Corporation and
+## others. All Rights Reserved.
+## Madhu Katragadda
+
+## Source directory information
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+top_builddir = ../..
+
+include $(top_builddir)/icudefs.mk
+
+## Build directory information
+subdir = tools/icuinfo
+
+## Extra files to remove for 'make clean'
+CLEANFILES = *~ $(DEPS) $(PLUGIN_OBJECTS) $(PLUGINFILE) $(PLUGIN)
+
+## Target information
+TARGET = icuinfo$(EXEEXT)
+
+CPPFLAGS += -I$(top_srcdir)/common -I$(srcdir)/../toolutil -I$(top_srcdir)/tools/ctestfw
+CPPFLAGS+= -I$(top_srcdir)/i18n
+LIBS = $(LIBICUTOOLUTIL) $(LIBICUI18N) $(LIBICUUC) $(DEFAULT_LIBS) $(LIB_M)
+
+SOURCES = $(shell cat $(srcdir)/sources.txt)
+OBJECTS = $(SOURCES:.cpp=.o)
+@PLUGINS_TRUE@PLUGIN_SOURCES = $(shell cat $(srcdir)/plugin_sources.txt)
+@PLUGINS_TRUE@PLUGIN_OBJECTS = $(@PLUGINS_TRUE@PLUGIN_SOURCES:.c=.o)
+
+DEPS = $(OBJECTS:.o=.d)
+
+# pass some information
+
+ICUINFO_OPTS=-i ../../data/out/build/$(ICUDATA_PLATFORM_NAME) -x $(top_builddir)/config/icuinfo.xml -v -K
+
+## List of phony targets
+.PHONY : all all-local install install-local clean clean-local \
+distclean distclean-local dist dist-local check check-local plugin-check
+
+## Clear suffix list
+.SUFFIXES :
+
+## List of standard targets
+all: all-local
+install: install-local
+clean: clean-local
+distclean : distclean-local
+dist: dist-local
+check: all check-local
+
+all-local: $(TARGET)
+
+install-local: all-local
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+ $(INSTALL) $(TARGET) $(DESTDIR)$(bindir)
+
+dist-local:
+
+clean-local:
+ test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES)
+ $(RMV) $(TARGET) $(OBJECTS)
+
+distclean-local: clean-local
+ $(RMV) Makefile
+
+check-local: $(TARGET)
+ $(INVOKE) ./$(TARGET) $(ICUINFO_OPTS)
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+-include Makefile.local
+
+$(TARGET) : $(OBJECTS)
+ $(LINK.cc) $(OUTOPT)$@ $^ $(LIBS)
+ $(POST_BUILD_STEP)
+
+PLUGIN=$(LIBPREFIX)plugin.$(SO)
+SO_TARGET=$(PLUGIN)
+
+PLUGINDIR=$(shell pwd)
+
+PLUGINFILE=$(PLUGINDIR)/icuplugins$(SO_TARGET_VERSION_MAJOR).txt
+
+CFLAGS+=$(SHAREDLIBCFLAGS)
+
+@PLUGINS_TRUE@HAVE_PLUGINS=yes
+
+ifeq ($(HAVE_PLUGINS),yes)
+$(PLUGINFILE): Makefile
+ echo "$(CURR_FULL_DIR)/$(PLUGIN) myPlugin x=4" > $@
+
+
+$(PLUGIN): $(PLUGIN_OBJECTS)
+ $(SHLIB.cc) $(SHAREDLIBCFLAGS) $(LD_SONAME) $(OUTOPT)$@ $^ $(LIBS)
+
+plugin: $(PLUGIN)
+
+plugin-check: $(PLUGIN) $(PLUGINFILE)
+ $(INVOKE) ICU_PLUGINS="$(CURR_FULL_DIR)" ./$(TARGET) -v -L
+else
+plugin plugin-check $(PLUGIN):
+ @echo "Plugins are disabled (use --enable-plugins to enable)"
+endif
+
+ifeq (,$(MAKECMDGOALS))
+-include $(DEPS)
+else
+ifneq ($(patsubst %clean,,$(MAKECMDGOALS)),)
+-include $(DEPS)
+endif
+endif
+
diff --git a/intl/icu/source/tools/icuinfo/icuinfo.cpp b/intl/icu/source/tools/icuinfo/icuinfo.cpp
new file mode 100644
index 0000000000..39dc6ab890
--- /dev/null
+++ b/intl/icu/source/tools/icuinfo/icuinfo.cpp
@@ -0,0 +1,307 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+*******************************************************************************
+*
+* Copyright (C) 1999-2016, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+*******************************************************************************
+* file name: icuinfo.cpp
+* encoding: UTF-8
+* tab size: 8 (not used)
+* indentation:4
+*
+* created on: 2009-2010
+* created by: Steven R. Loomis
+*
+* This program shows some basic info about the current ICU.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "unicode/utypes.h"
+#include "unicode/putil.h"
+#include "unicode/uclean.h"
+#include "udbgutil.h"
+#include "unewdata.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "uoptions.h"
+#include "toolutil.h"
+#include "icuplugimp.h"
+#include <unicode/uloc.h>
+#include <unicode/ucnv.h>
+#include "unicode/ucal.h"
+#include <unicode/ulocdata.h>
+#include "putilimp.h"
+#include "unicode/uchar.h"
+
+static UOption options[]={
+ /*0*/ UOPTION_HELP_H,
+ /*1*/ UOPTION_HELP_QUESTION_MARK,
+ /*2*/ UOPTION_ICUDATADIR,
+ /*3*/ UOPTION_VERBOSE,
+ /*4*/ UOPTION_DEF("list-plugins", 'L', UOPT_NO_ARG), // may be a no-op if disabled
+ /*5*/ UOPTION_DEF("milisecond-time", 'm', UOPT_NO_ARG),
+ /*6*/ UOPTION_DEF("cleanup", 'K', UOPT_NO_ARG),
+ /*7*/ UOPTION_DEF("xml", 'x', UOPT_REQUIRES_ARG),
+};
+
+static UErrorCode initStatus = U_ZERO_ERROR;
+static UBool icuInitted = false;
+
+static void do_init() {
+ if(!icuInitted) {
+ u_init(&initStatus);
+ icuInitted = true;
+ }
+}
+
+static void do_cleanup() {
+ if (icuInitted) {
+ u_cleanup();
+ icuInitted = false;
+ }
+}
+
+void cmd_millis()
+{
+ printf("Milliseconds since Epoch: %.0f\n", uprv_getUTCtime());
+}
+
+void cmd_version(UBool /* noLoad */, UErrorCode &errorCode)
+{
+
+ do_init();
+
+ udbg_writeIcuInfo(stdout); /* print the XML format */
+
+ union {
+ uint8_t byte;
+ uint16_t word;
+ } u;
+ u.word=0x0100;
+ if(U_IS_BIG_ENDIAN==u.byte) {
+ //printf("U_IS_BIG_ENDIAN: %d\n", U_IS_BIG_ENDIAN);
+ } else {
+ fprintf(stderr, " error: U_IS_BIG_ENDIAN=%d != %d=actual 'is big endian'\n",
+ U_IS_BIG_ENDIAN, u.byte);
+ errorCode=U_INTERNAL_PROGRAM_ERROR;
+ }
+
+#if defined(_MSC_VER)
+// Ignore warning 4127, conditional expression is constant. This is intentional below.
+#pragma warning(push)
+#pragma warning(disable: 4127)
+#endif
+
+ if(U_SIZEOF_WCHAR_T==sizeof(wchar_t)) {
+ //printf("U_SIZEOF_WCHAR_T: %d\n", U_SIZEOF_WCHAR_T);
+ } else {
+ fprintf(stderr, " error: U_SIZEOF_WCHAR_T=%d != %d=sizeof(wchar_t)\n",
+ U_SIZEOF_WCHAR_T, (int)sizeof(wchar_t));
+ errorCode=U_INTERNAL_PROGRAM_ERROR;
+ }
+
+ int charsetFamily;
+ if('A'==0x41) {
+ charsetFamily=U_ASCII_FAMILY;
+ } else if('A'==0xc1) {
+ charsetFamily=U_EBCDIC_FAMILY;
+ } else {
+ charsetFamily=-1; // unknown
+ }
+ if(U_CHARSET_FAMILY==charsetFamily) {
+ //printf("U_CHARSET_FAMILY: %d\n", U_CHARSET_FAMILY);
+ } else {
+ fprintf(stderr, " error: U_CHARSET_FAMILY=%d != %d=actual charset family\n",
+ U_CHARSET_FAMILY, charsetFamily);
+ errorCode=U_INTERNAL_PROGRAM_ERROR;
+ }
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+ printf("\n\nICU Initialization returned: %s\n", u_errorName(initStatus));
+
+
+#if UCONFIG_ENABLE_PLUGINS
+#if U_ENABLE_DYLOAD
+ const char *pluginFile = uplug_getPluginFile();
+ printf("Plugin file is: %s\n", (pluginFile&&*pluginFile)?pluginFile:"(not set. try setting ICU_PLUGINS to a directory.)");
+#else
+ fprintf(stderr, "Dynamic Loading: is disabled. No plugins will be loaded at start-up.\n");
+#endif
+#else
+ fprintf(stderr, "Plugins are disabled.\n");
+#endif
+}
+
+void cmd_cleanup()
+{
+ u_cleanup();
+ fprintf(stdout, "ICU u_cleanup() called.\n");
+}
+
+
+void cmd_listplugins() {
+#if UCONFIG_ENABLE_PLUGINS
+ int32_t i;
+ UPlugData *plug;
+
+ do_init();
+ printf("ICU Initialized: u_init() returned %s\n", u_errorName(initStatus));
+
+ printf("Plugins: \n");
+ printf( "# %6s %s \n",
+ "Level",
+ "Name" );
+ printf( " %10s:%-10s\n",
+ "Library",
+ "Symbol"
+ );
+
+
+ printf( " config| (configuration string)\n");
+ printf( " >>> Error | Explanation \n");
+ printf( "-----------------------------------\n");
+
+ for(i=0;(plug=uplug_getPlugInternal(i))!=nullptr;i++) {
+ UErrorCode libStatus = U_ZERO_ERROR;
+ const char *name = uplug_getPlugName(plug);
+ const char *sym = uplug_getSymbolName(plug);
+ const char *lib = uplug_getLibraryName(plug, &libStatus);
+ const char *config = uplug_getConfiguration(plug);
+ UErrorCode loadStatus = uplug_getPlugLoadStatus(plug);
+ const char *message = nullptr;
+
+ printf("\n#%d %-6s %s \n",
+ i+1,
+ udbg_enumName(UDBG_UPlugLevel,(int32_t)uplug_getPlugLevel(plug)),
+ name!=nullptr?(*name?name:"this plugin did not call uplug_setPlugName()"):"(null)"
+ );
+ printf(" plugin| %10s:%-10s\n",
+ (U_SUCCESS(libStatus)?(lib!=nullptr?lib:"(null)"):u_errorName(libStatus)),
+ sym!=nullptr?sym:"(null)"
+ );
+
+ if(config!=nullptr&&*config) {
+ printf(" config| %s\n", config);
+ }
+
+ switch(loadStatus) {
+ case U_PLUGIN_CHANGED_LEVEL_WARNING:
+ message = "Note: This plugin changed the system level (by allocating memory or calling something which does). Later plugins may not load.";
+ break;
+
+ case U_PLUGIN_DIDNT_SET_LEVEL:
+ message = "Error: This plugin did not call uplug_setPlugLevel during QUERY.";
+ break;
+
+ case U_PLUGIN_TOO_HIGH:
+ message = "Error: This plugin couldn't load because the system level was too high. Try loading this plugin earlier.";
+ break;
+
+ case U_ZERO_ERROR:
+ message = nullptr; /* no message */
+ break;
+ default:
+ if(U_FAILURE(loadStatus)) {
+ message = "error loading:";
+ } else {
+ message = "warning during load:";
+ }
+ }
+
+ if(message!=nullptr) {
+ printf("\\\\\\ status| %s\n"
+ "/// %s\n", u_errorName(loadStatus), message);
+ }
+
+ }
+ if(i==0) {
+ printf("No plugins loaded.\n");
+ }
+#endif
+}
+
+
+
+extern int
+main(int argc, char* argv[]) {
+ UErrorCode errorCode = U_ZERO_ERROR;
+ UBool didSomething = false;
+
+ /* preset then read command line options */
+ argc=u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options);
+
+ /* error handling, printing usage message */
+ if(argc<0) {
+ fprintf(stderr,
+ "error in command line argument \"%s\"\n",
+ argv[-argc]);
+ }
+ if( options[0].doesOccur || options[1].doesOccur) {
+ fprintf(stderr, "%s: Output information about the current ICU\n", argv[0]);
+ fprintf(stderr, "Options:\n"
+ " -h or --help - Print this help message.\n"
+ " -m or --millisecond-time - Print the current UTC time in milliseconds.\n"
+ " -d <dir> or --icudatadir <dir> - Set the ICU Data Directory\n"
+ " -v - Print version and configuration information about ICU\n"
+#if UCONFIG_ENABLE_PLUGINS
+ " -L or --list-plugins - List and diagnose issues with ICU Plugins\n"
+#endif
+ " -K or --cleanup - Call u_cleanup() before exiting (will attempt to unload plugins)\n"
+ "\n"
+ "If no arguments are given, the tool will print ICU version and configuration information.\n"
+ );
+ fprintf(stderr, "International Components for Unicode %s\n%s\n", U_ICU_VERSION, U_COPYRIGHT_STRING );
+ return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
+ }
+
+ if(options[2].doesOccur) {
+ u_setDataDirectory(options[2].value);
+ }
+
+ if(options[5].doesOccur) {
+ cmd_millis();
+ didSomething=true;
+ }
+ if(options[4].doesOccur) {
+ cmd_listplugins();
+ didSomething = true;
+ }
+
+ if(options[3].doesOccur) {
+ cmd_version(false, errorCode);
+ didSomething = true;
+ }
+
+ if(options[7].doesOccur) { /* 2nd part of version: cleanup */
+ FILE *out = fopen(options[7].value, "w");
+ if(out==nullptr) {
+ fprintf(stderr,"ERR: can't write to XML file %s\n", options[7].value);
+ return 1;
+ }
+ /* todo: API for writing DTD? */
+ fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+ udbg_writeIcuInfo(out);
+ fclose(out);
+ didSomething = true;
+ }
+
+ if(options[6].doesOccur) { /* 2nd part of version: cleanup */
+ cmd_cleanup();
+ didSomething = true;
+ }
+
+ if(!didSomething) {
+ cmd_version(false, errorCode); /* at least print the version # */
+ }
+
+ do_cleanup();
+
+ return U_FAILURE(errorCode);
+}
diff --git a/intl/icu/source/tools/icuinfo/icuinfo.vcxproj b/intl/icu/source/tools/icuinfo/icuinfo.vcxproj
new file mode 100644
index 0000000000..ac8bfa88eb
--- /dev/null
+++ b/intl/icu/source/tools/icuinfo/icuinfo.vcxproj
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{E7611F49-F088-4175-9446-6111444E72C8}</ProjectGuid>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <!-- The following import will include the 'default' configuration options for VS projects. -->
+ <Import Project="..\..\allinone\Build.Windows.ProjectConfiguration.props" />
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+ <!-- The ICU projects use "Win32" to mean "x86", so we need to special case it. -->
+ <OutDir Condition="'$(Platform)'=='Win32'">.\x86\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Platform)'=='Win32'">.\x86\$(Configuration)\</IntDir>
+ <!-- Disable Incremental Linking for Release builds as it prevents Link-time Code Generation -->
+ <LinkIncremental Condition="'$(Configuration)'=='Debug'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)'=='Release'">false</LinkIncremental>
+ </PropertyGroup>
+ <!-- Options that are common to *all* configurations -->
+ <ItemDefinitionGroup>
+ <Midl>
+ <TypeLibraryName>$(OutDir)\icuinfo.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <CompileAs>Default</CompileAs>
+ <DisableLanguageExtensions>false</DisableLanguageExtensions>
+ <AdditionalIncludeDirectories>..\..\common;..\..\i18n;..\toolutil;..\ctestfw;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PrecompiledHeaderOutputFile>$(OutDir)\icuinfo.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(OutDir)/</AssemblerListingLocation>
+ <ObjectFileName>$(OutDir)/</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)\icuinfo.pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <OutputFile>$(OutDir)\icuinfo.exe</OutputFile>
+ <AdditionalLibraryDirectories>..\..\..\$(IcuLibOutputDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <CustomBuildStep>
+ <Command>copy "$(TargetPath)" ..\..\..\$(IcuBinOutputDir)</Command>
+ <Outputs>..\..\..\$(IcuBinOutputDir)\$(TargetFileName);%(Outputs)</Outputs>
+ </CustomBuildStep>
+ </ItemDefinitionGroup>
+ <!-- Options that are common to all 'Debug' project configurations -->
+ <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
+ <ClCompile>
+ <BrowseInformation>true</BrowseInformation>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>icuucd.lib;icuind.lib;icutud.lib;icutestd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <!-- Options that are common to all 'Release' project configurations -->
+ <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>icuuc.lib;icuin.lib;icutu.lib;icutest.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="icuinfo.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="icuplugins_windows_sample.txt" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/intl/icu/source/tools/icuinfo/icuplugins_windows_sample.txt b/intl/icu/source/tools/icuinfo/icuplugins_windows_sample.txt
new file mode 100644
index 0000000000..936e917b63
--- /dev/null
+++ b/intl/icu/source/tools/icuinfo/icuplugins_windows_sample.txt
@@ -0,0 +1,59 @@
+# Copyright (C) 2016 and later: Unicode, Inc. and others.
+# License & terms of use: http://www.unicode.org/copyright.html
+# Copyright (C) 2009-2010 IBM Corporation and Others. All Rights Reserved.
+#
+# This is a sample ICU Plugins control file for Windows.
+# It's also an example control file for any platform.
+#
+# This file can be copied to, for example, C:\SOMEDIRECTORY\icuplugins##.txt
+# where ## is the major and minor ICU versions (i.e. just 96 for version 9.6.3)
+# and C:\SOMEDIRECTORY is any directory.
+#
+# Then, set the variable ICU_PLUGINS to C:\SOMEDIRECTORY
+#
+# Then, ICU will load the test plugin from either the debug or non-debug
+# plugin DLL (depending on whether ICU is in debug or non-debug state).
+#
+# To see the results, run the command "icuinfo -v -L"
+#
+# The format of this file is pretty simple.
+# These lines are comments.
+#
+# Non-comment lines have two or three elements in them, and look like this:
+#
+# LIBRARYNAME ENTRYPOINT [ CONFIGURATION .. ]
+#
+# Tabs or spaces separate the three items.
+#
+# LIBRARYNAME is the name of a shared library, either a short name if it is on the PATH,
+# or a full pathname.
+#
+# ENTRYPOINT is the short (undecorated) symbol name of the plugin's entrypoint.
+# see unicode/icuplug.h for information.
+#
+# CONFIGURATION is the entire rest of the line. It's passed as-is to the plugin.
+#
+#
+# This sample file tries to load 'myPlugin'.
+# It is in the testplug project. (You will need to rebuild either the debug or release version of this DLL.)
+# The configuration string isn't used, but is just an example
+
+## A high level test plugin that does nothing.
+testplug.dll myPlugin hello=world
+
+## A "bad" plugin that is low level but performs a malloc.
+## Sometimes this is desired, but, note that it may cause
+## later plugins to fail to load.
+#testplug.dll myPluginBad hello=world
+
+## A "high-level" plugin that does nothing.
+## It will be loaded after the low level plugins.
+#testplug.dll myPluginHigh
+
+## A "low-level" plugin that does nothing.
+## It will be loaded before the high level plugins.
+#testplug.dll myPluginLow
+
+## A low level plugin that just prints a message when uprv_malloc and related functions are called
+## Note, it cannot be unloaded.
+#testplug.dll debugMemoryPlugin
diff --git a/intl/icu/source/tools/icuinfo/plugin_sources.txt b/intl/icu/source/tools/icuinfo/plugin_sources.txt
new file mode 100644
index 0000000000..7d5e663382
--- /dev/null
+++ b/intl/icu/source/tools/icuinfo/plugin_sources.txt
@@ -0,0 +1 @@
+testplug.c
diff --git a/intl/icu/source/tools/icuinfo/sources.txt b/intl/icu/source/tools/icuinfo/sources.txt
new file mode 100644
index 0000000000..67b9aa2df8
--- /dev/null
+++ b/intl/icu/source/tools/icuinfo/sources.txt
@@ -0,0 +1 @@
+icuinfo.cpp
diff --git a/intl/icu/source/tools/icuinfo/testplug.c b/intl/icu/source/tools/icuinfo/testplug.c
new file mode 100644
index 0000000000..8b48bc66d4
--- /dev/null
+++ b/intl/icu/source/tools/icuinfo/testplug.c
@@ -0,0 +1,212 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+******************************************************************************
+*
+* Copyright (C) 2009-2015, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+******************************************************************************
+*
+* FILE NAME : testplug.c
+*
+* Date Name Description
+* 10/29/2009 srl New.
+******************************************************************************
+*
+*
+* This file implements a number of example ICU plugins.
+*
+*/
+
+#include "unicode/icuplug.h"
+
+#if UCONFIG_ENABLE_PLUGINS
+/* This file isn't usually compiled except on Windows. Guard it. */
+
+#include <stdbool.h>
+#include <stdio.h> /* for fprintf */
+#include <stdlib.h> /* for malloc */
+#include "udbgutil.h"
+#include "unicode/uclean.h"
+#include "cmemory.h"
+
+/**
+ * Prototypes
+ */
+#define DECLARE_PLUGIN(x) U_CAPI UPlugTokenReturn U_EXPORT2 x (UPlugData *data, UPlugReason reason, UErrorCode *status)
+
+DECLARE_PLUGIN(myPlugin);
+DECLARE_PLUGIN(myPluginLow);
+DECLARE_PLUGIN(myPluginFailQuery);
+DECLARE_PLUGIN(myPluginFailToken);
+DECLARE_PLUGIN(myPluginBad);
+DECLARE_PLUGIN(myPluginHigh);
+DECLARE_PLUGIN(debugMemoryPlugin);
+
+/**
+ * A simple, trivial plugin.
+ */
+
+U_CAPI
+UPlugTokenReturn U_EXPORT2 myPlugin (
+ UPlugData *data,
+ UPlugReason reason,
+ UErrorCode *status) {
+ /* Just print this for debugging */
+ fprintf(stderr,"MyPlugin: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
+
+ if(reason==UPLUG_REASON_QUERY) {
+ uplug_setPlugName(data, "Just a Test High-Level Plugin"); /* This call is optional in response to UPLUG_REASON_QUERY, but is a good idea. */
+ uplug_setPlugLevel(data, UPLUG_LEVEL_HIGH); /* This call is Mandatory in response to UPLUG_REASON_QUERY */
+ }
+
+ return UPLUG_TOKEN; /* This must always be returned, to indicate that the entrypoint was actually a plugin. */
+}
+
+
+U_CAPI
+UPlugTokenReturn U_EXPORT2 myPluginLow (
+ UPlugData *data,
+ UPlugReason reason,
+ UErrorCode *status) {
+ fprintf(stderr,"MyPluginLow: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
+
+ if(reason==UPLUG_REASON_QUERY) {
+ uplug_setPlugName(data, "Low Plugin");
+ uplug_setPlugLevel(data, UPLUG_LEVEL_LOW);
+ }
+
+ return UPLUG_TOKEN;
+}
+
+/**
+ * Doesn't respond to QUERY properly.
+ */
+U_CAPI
+UPlugTokenReturn U_EXPORT2 myPluginFailQuery (
+ UPlugData *data,
+ UPlugReason reason,
+ UErrorCode *status) {
+ fprintf(stderr,"MyPluginFailQuery: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
+
+ /* Should respond to UPLUG_REASON_QUERY here. */
+
+ return UPLUG_TOKEN;
+}
+
+/**
+ * Doesn't return the proper token.
+ */
+U_CAPI
+UPlugTokenReturn U_EXPORT2 myPluginFailToken (
+ UPlugData *data,
+ UPlugReason reason,
+ UErrorCode *status) {
+ fprintf(stderr,"MyPluginFailToken: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
+
+ if(reason==UPLUG_REASON_QUERY) {
+ uplug_setPlugName(data, "myPluginFailToken Plugin");
+ uplug_setPlugLevel(data, UPLUG_LEVEL_LOW);
+ }
+
+ return 0; /* Wrong. */
+}
+
+
+
+/**
+ * Says it's low, but isn't.
+ */
+U_CAPI
+UPlugTokenReturn U_EXPORT2 myPluginBad (
+ UPlugData *data,
+ UPlugReason reason,
+ UErrorCode *status) {
+ fprintf(stderr,"MyPluginLow: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
+
+ if(reason==UPLUG_REASON_QUERY) {
+ uplug_setPlugName(data, "Bad Plugin");
+ uplug_setPlugLevel(data, UPLUG_LEVEL_LOW);
+ } else if(reason == UPLUG_REASON_LOAD) {
+ void *ctx = uprv_malloc(12345);
+
+ uplug_setContext(data, ctx);
+ fprintf(stderr,"I'm %p and I did a bad thing and malloced %p\n", (void*)data, (void*)ctx);
+ } else if(reason == UPLUG_REASON_UNLOAD) {
+ void * ctx = uplug_getContext(data);
+
+ uprv_free(ctx);
+ }
+
+
+ return UPLUG_TOKEN;
+}
+
+U_CAPI
+UPlugTokenReturn U_EXPORT2 myPluginHigh (
+ UPlugData *data,
+ UPlugReason reason,
+ UErrorCode *status) {
+ fprintf(stderr,"MyPluginHigh: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
+
+ if(reason==UPLUG_REASON_QUERY) {
+ uplug_setPlugName(data, "High Plugin");
+ uplug_setPlugLevel(data, UPLUG_LEVEL_HIGH);
+ }
+
+ return UPLUG_TOKEN;
+}
+
+
+/* Debug Memory Plugin (see hpmufn.c) */
+static void * U_CALLCONV myMemAlloc(const void *context, size_t size) {
+ void *retPtr = (void *)malloc(size);
+ (void)context; /* unused */
+ fprintf(stderr, "MEM: malloc(%d) = %p\n", (int32_t)size, retPtr);
+ return retPtr;
+}
+
+static void U_CALLCONV myMemFree(const void *context, void *mem) {
+ (void)context; /* unused */
+
+ free(mem);
+ fprintf(stderr, "MEM: free(%p)\n", mem);
+}
+
+static void * U_CALLCONV myMemRealloc(const void *context, void *mem, size_t size) {
+ void *retPtr;
+ (void)context; /* unused */
+
+
+ if(mem==NULL) {
+ retPtr = NULL;
+ } else {
+ retPtr = realloc(mem, size);
+ }
+ fprintf(stderr, "MEM: realloc(%p, %d) = %p\n", mem, (int32_t)size, retPtr);
+ return retPtr;
+}
+
+U_CAPI
+UPlugTokenReturn U_EXPORT2 debugMemoryPlugin (
+ UPlugData *data,
+ UPlugReason reason,
+ UErrorCode *status) {
+ fprintf(stderr,"debugMemoryPlugin: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
+
+ if(reason==UPLUG_REASON_QUERY) {
+ uplug_setPlugLevel(data, UPLUG_LEVEL_LOW);
+ uplug_setPlugName(data, "Memory Plugin");
+ } else if(reason==UPLUG_REASON_LOAD) {
+ u_setMemoryFunctions(uplug_getContext(data), &myMemAlloc, &myMemRealloc, &myMemFree, status);
+ fprintf(stderr, "MEM: status now %s\n", u_errorName(*status));
+ } else if(reason==UPLUG_REASON_UNLOAD) {
+ fprintf(stderr, "MEM: not possible to unload this plugin (no way to reset memory functions)...\n");
+ uplug_setPlugNoUnload(data, true);
+ }
+
+ return UPLUG_TOKEN;
+}
+
+#endif
diff --git a/intl/icu/source/tools/icuinfo/testplug.vcxproj b/intl/icu/source/tools/icuinfo/testplug.vcxproj
new file mode 100644
index 0000000000..dac99beb4e
--- /dev/null
+++ b/intl/icu/source/tools/icuinfo/testplug.vcxproj
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{659D0C08-D4ED-4BF3-B02B-2D8D4B5A7A7A}</ProjectGuid>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <!-- The following import will include the 'default' configuration options for VS projects. -->
+ <Import Project="..\..\allinone\Build.Windows.ProjectConfiguration.props" />
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir>.\$(Platform)\$(Configuration)\</OutDir>
+ <IntDir>.\$(Platform)\$(Configuration)\</IntDir>
+ <!-- The ICU projects use "Win32" to mean "x86", so we need to special case it. -->
+ <OutDir Condition="'$(Platform)'=='Win32'">.\x86\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Platform)'=='Win32'">.\x86\$(Configuration)\</IntDir>
+ <!-- Disable Incremental Linking for Release builds as it prevents Link-time Code Generation -->
+ <LinkIncremental Condition="'$(Configuration)'=='Debug'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)'=='Release'">false</LinkIncremental>
+ </PropertyGroup>
+ <!-- Options that are common to *all* project configurations -->
+ <ItemDefinitionGroup>
+ <Midl>
+ <TypeLibraryName>$(OutDir)\testplug.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..\include;..\..\common;..\toolutil;..\ctestfw;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>T_CTEST_IMPLEMENTATION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <DisableLanguageExtensions>true</DisableLanguageExtensions>
+ <WarningLevel>Level3</WarningLevel>
+ <CompileAs>Default</CompileAs>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <PrecompiledHeaderOutputFile>$(OutDir)\testplug.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(OutDir)/</AssemblerListingLocation>
+ <ObjectFileName>$(OutDir)/</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)\testplug.pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <Link>
+ <AdditionalLibraryDirectories>..\..\..\$(IcuLibOutputDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <!-- Options that are common to all 'Debug' project configurations -->
+ <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
+ <ClCompile>
+ <BrowseInformation>true</BrowseInformation>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OutputFile>..\..\..\$(IcuBinOutputDir)\testplugd.dll</OutputFile>
+ <ProgramDatabaseFile>..\..\..\$(IcuLibOutputDir)\testplugd.pdb</ProgramDatabaseFile>
+ <ImportLibrary>..\..\..\$(IcuLibOutputDir)\testplugd.lib</ImportLibrary>
+ <AdditionalDependencies>icuucd.lib;icutud.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <!-- Options that are common to all 'Release' project configurations -->
+ <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ </ClCompile>
+ <Link>
+ <OutputFile>..\..\..\$(IcuBinOutputDir)\testplug.dll</OutputFile>
+ <ProgramDatabaseFile>..\..\..\$(IcuLibOutputDir)\testplug.pdb</ProgramDatabaseFile>
+ <ImportLibrary>..\..\..\$(IcuLibOutputDir)\testplug.lib</ImportLibrary>
+ <AdditionalDependencies>icuuc.lib;icutu.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="testplug.c" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/intl/icu/source/tools/icuinfo/testplug.vcxproj.filters b/intl/icu/source/tools/icuinfo/testplug.vcxproj.filters
new file mode 100644
index 0000000000..5c9125e5dd
--- /dev/null
+++ b/intl/icu/source/tools/icuinfo/testplug.vcxproj.filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{a83708c0-2dc6-44b5-96e7-01cb39fcc0fe}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{f2528795-0c58-475a-a156-75756f9246eb}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{7c635351-2ada-418e-b675-5fbd534925b5}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="testplug.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file