summaryrefslogtreecommitdiff
path: root/Tests/Preprocess
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2012-10-30 15:39:57 -0700
committerAnas Nashif <anas.nashif@intel.com>2012-10-30 15:39:57 -0700
commit035c7fabc3b82cbc9a346c11abe2e9462b4c0379 (patch)
tree7e40f5a790eae329a8c5d3e59f046451767956ff /Tests/Preprocess
downloadcmake-035c7fabc3b82cbc9a346c11abe2e9462b4c0379.tar.gz
cmake-035c7fabc3b82cbc9a346c11abe2e9462b4c0379.tar.bz2
cmake-035c7fabc3b82cbc9a346c11abe2e9462b4c0379.zip
Imported Upstream version 2.8.9upstream/2.8.9
Diffstat (limited to 'Tests/Preprocess')
-rw-r--r--Tests/Preprocess/CMakeLists.txt269
-rw-r--r--Tests/Preprocess/file_def.h1
-rw-r--r--Tests/Preprocess/preprocess.c198
-rw-r--r--Tests/Preprocess/preprocess.cxx225
-rw-r--r--Tests/Preprocess/preprocess.h.in16
-rw-r--r--Tests/Preprocess/preprocess_vs6.cxx3
-rw-r--r--Tests/Preprocess/target_def.h1
7 files changed, 713 insertions, 0 deletions
diff --git a/Tests/Preprocess/CMakeLists.txt b/Tests/Preprocess/CMakeLists.txt
new file mode 100644
index 000000000..1ed7b83ac
--- /dev/null
+++ b/Tests/Preprocess/CMakeLists.txt
@@ -0,0 +1,269 @@
+cmake_minimum_required(VERSION 2.6)
+project(Preprocess)
+
+# This test is meant both as a test and as a reference for supported
+# syntax on native tool command lines.
+
+# Determine the build tool being used. Not all characters can be
+# escaped for all build tools. This test checks all characters known
+# to work with each tool and documents those known to not work.
+if("${CMAKE_GENERATOR}" MATCHES "Xcode")
+ set(PP_XCODE 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Xcode")
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
+ set(PP_VS6 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
+if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
+ set(PP_UMAKE 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
+if("${CMAKE_GENERATOR}" MATCHES "NMake Makefiles")
+ set(PP_NMAKE 1)
+endif("${CMAKE_GENERATOR}" MATCHES "NMake Makefiles")
+if("${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles")
+ set(PP_MINGW 1)
+endif("${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles")
+if("${CMAKE_GENERATOR}" MATCHES "Borland Makefiles")
+ set(PP_BORLAND 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Borland Makefiles")
+if("${CMAKE_GENERATOR}" MATCHES "Watcom WMake")
+ set(PP_WATCOM 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Watcom WMake")
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 7$")
+ set(PP_VS70 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio 7$")
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
+ set(PP_VS 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 10")
+ set(PP_VS100 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio 10")
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 11")
+ set(PP_VS110 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio 11")
+
+# Some tests below check the PP_* variables set above. They are meant
+# to test the case that the build tool is at fault. Other tests below
+# check the compiler that will be used when the compiler is at fault
+# (does not work even from a command shell).
+
+#-----------------------------------------------------------------------------
+# Construct a C-string literal to test passing through a definition on
+# the command line. We configure the value into a header so it can be
+# checked in the executable at runtime. The semicolon is handled
+# specially because it needs to be escaped in the COMPILE_DEFINITIONS
+# property value to avoid separating definitions but the string value
+# must not have it escaped inside the configured header.
+set(STRING_EXTRA "")
+
+if(NOT BORLAND AND NOT PP_VS70 AND NOT PP_VS100 AND NOT PP_VS110)
+ # Borland, VS70 IDE: ;
+ # The Borland compiler will simply not accept a non-escaped semicolon
+ # on the command line. If it is escaped \; then the escape character
+ # shows up in the preprocessing output too.
+ #
+ # The VS 7.0 IDE separates definitions on semicolons and commas with
+ # no regard for quotes. Fortunately VS 7.1 and above are okay.
+ # VS 10 seems to also not like semicolons
+ set(SEMICOLON "\;")
+endif()
+
+if(NOT PP_VS6)
+ # VS 6 IDE: spaces and '"', '$', or ';'
+ # The project parser cannot handle spaces if there are quotes.
+ # Since we test passing in a quoted string, we cannot have spaces.
+ set(STRING_EXTRA "${STRING_EXTRA} ")
+
+ if(NOT PP_BORLAND AND NOT PP_WATCOM)
+ # Borland, WMake: multiple spaces
+ # The make tool seems to remove extra whitespace from inside
+ # quoted strings when passing to the compiler. It does not have
+ # trouble passing to other tools, and the compiler may be directly
+ # invoked from the command line.
+ set(STRING_EXTRA "${STRING_EXTRA} ")
+ endif(NOT PP_BORLAND AND NOT PP_WATCOM)
+endif(NOT PP_VS6)
+
+if(NOT PP_VS)
+ # VS: ,
+ # Visual Studio will not accept a comma in the value of a definition.
+ # The comma-separated list of PreprocessorDefinitions in the project
+ # file seems to be parsed before the content of entries is examined.
+ set(STRING_EXTRA "${STRING_EXTRA},")
+endif(NOT PP_VS)
+
+if(NOT PP_MINGW)
+ # MinGW: &
+ # When inside -D"FOO=\"a & b\"" MinGW make wants -D"FOO=\"a "&" b\""
+ # but it does not like quoted ampersand elsewhere.
+ set(STRING_EXTRA "${STRING_EXTRA}&")
+endif(NOT PP_MINGW)
+
+if(NOT PP_MINGW)
+ # MinGW: |
+ # When inside -D"FOO=\"a | b\"" MinGW make wants -D"FOO=\"a "|" b\""
+ # but it does not like quoted pipe elsewhere.
+ set(STRING_EXTRA "${STRING_EXTRA}|")
+endif(NOT PP_MINGW)
+
+if(NOT PP_BORLAND AND NOT PP_MINGW AND NOT PP_NMAKE)
+ # Borland, NMake, MinGW: ^
+ # When inside -D"FOO=\"a ^ b\"" the make tools want -D"FOO=\"a "^" b\""
+ # but do not like quoted carrot elsewhere. In NMake the non-quoted
+ # syntax works when the flags are not in a make variable.
+ set(STRING_EXTRA "${STRING_EXTRA}^")
+endif(NOT PP_BORLAND AND NOT PP_MINGW AND NOT PP_NMAKE)
+
+if(NOT PP_BORLAND AND NOT PP_MINGW AND NOT PP_NMAKE)
+ # Borland, MinGW: < >
+ # Angle-brackets have funny behavior that is hard to escape.
+ set(STRING_EXTRA "${STRING_EXTRA}<>")
+endif(NOT PP_BORLAND AND NOT PP_MINGW AND NOT PP_NMAKE)
+
+set(EXPR_OP1 "/")
+if((NOT MSVC OR PP_NMAKE) AND
+ NOT "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$")
+ # MSVC cl, Intel icl: %
+ # When the cl compiler is invoked from the command line then % must
+ # be written %% (to distinguish from %ENV% syntax). However cl does
+ # not seem to accept the syntax when it is invoked from inside a
+ # make tool (nmake, mingw32-make, etc.). Instead the argument must
+ # be placed inside a response file. Then cl accepts it because it
+ # parses the response file as it would the normal windows command
+ # line. Currently only NMake supports running cl with a response
+ # file. Supporting other make tools would require CMake to generate
+ # response files explicitly for each object file.
+ #
+ # When the icl compiler is invoked from the command line then % must
+ # be written just '%'. However nmake requires '%%' except when using
+ # response files. Currently we have no way to affect escaping based
+ # on whether flags go in a response file, so we just have to skip it.
+ set(STRING_EXTRA "${STRING_EXTRA}%")
+ set(EXPR_OP1 "%")
+endif()
+
+# General: \"
+# Make tools do not reliably accept \\\" syntax:
+# - MinGW and MSYS make tools crash with \\\"
+# - Borland make actually wants a mis-matched quote \\"
+# or $(BACKSLASH)\" where BACKSLASH is a variable set to \\
+# - VS IDE gets confused about the bounds of the definition value \\\"
+# - NMake is okay with just \\\"
+if(PP_NMAKE OR PP_UMAKE)
+ set(STRING_EXTRA "${STRING_EXTRA}\\\"")
+endif(PP_NMAKE OR PP_UMAKE)
+
+# General: #
+# MSVC will not accept a # in the value of a string definition on the
+# command line. The character seems to be simply replaced by an
+# equals =. According to "cl -help" definitions may be specified by
+# -DMACRO#VALUE as well as -DMACRO=VALUE. It must be implemented by a
+# simple search-and-replace.
+#
+# The Borland compiler will parse both # and \# as just # but the make
+# tool seems to want \# sometimes and not others.
+#
+# Unix make does not like # in variable settings without extra
+# escaping. This could probably be fixed but since MSVC does not
+# support it and it is not an operator it is not worthwhile.
+
+# Compose the final test string.
+set(STRING_VALUE "hello`~!@$*)(_+-=}{][:'.?/${STRING_EXTRA}world")
+
+#-----------------------------------------------------------------------------
+# Function-style macro command-line support:
+# - Borland does not support
+# - MSVC does not support
+# - Watcom does not support
+# - GCC supports
+
+# Too few platforms support this to bother implementing.
+# People can just configure headers with the macros.
+
+#-----------------------------------------------------------------------------
+# Construct a sample expression to pass as a macro definition.
+
+set(EXPR "x*y+!(x==(y+1*2))*f(x${EXPR_OP1}2)")
+
+if(NOT WATCOM)
+ # Watcom does not support - or / because it parses them as options.
+ set(EXPR "${EXPR} + y/x-x")
+endif(NOT WATCOM)
+
+#-----------------------------------------------------------------------------
+
+# Inform the test if the debug configuration is getting built.
+# The NDEBUG definition takes care of this for release.
+set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DPREPROCESS_DEBUG")
+set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DPREPROCESS_DEBUG")
+
+# Inform the test if it built from Xcode or VS6 IDE.
+if(PP_XCODE)
+ set(PREPROCESS_XCODE 1)
+endif(PP_XCODE)
+if(PP_VS6)
+ set(PREPROCESS_VS6 1)
+ set(VS6 _vs6)
+endif(PP_VS6)
+
+# Test old-style definitions.
+add_definitions(-DOLD_DEF -DOLD_EXPR=2)
+
+# Make sure old-style definitions are converted to directory property.
+set(OLD_DEFS_EXPECTED "OLD_DEF;OLD_EXPR=2")
+get_property(OLD_DEFS DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+if(NOT "${OLD_DEFS}" STREQUAL "${OLD_DEFS_EXPECTED}")
+ message(SEND_ERROR "add_definitions not converted to directory property!")
+endif(NOT "${OLD_DEFS}" STREQUAL "${OLD_DEFS_EXPECTED}")
+
+add_executable(Preprocess preprocess.c preprocess${VS6}.cxx)
+
+set(FILE_PATH "${Preprocess_SOURCE_DIR}/file_def.h")
+set(TARGET_PATH "${Preprocess_SOURCE_DIR}/target_def.h")
+
+# Set some definition properties.
+foreach(c "" "_DEBUG" "_RELEASE")
+ set_property(
+ DIRECTORY .
+ APPEND PROPERTY COMPILE_DEFINITIONS${c} "DIRECTORY_DEF${c}"
+ )
+ set_property(
+ TARGET Preprocess
+ PROPERTY COMPILE_DEFINITIONS${c} "TARGET_DEF${c}"
+ )
+ set_property(
+ SOURCE preprocess.c preprocess${VS6}.cxx
+ PROPERTY COMPILE_DEFINITIONS${c} "FILE_DEF${c}"
+ )
+endforeach(c)
+
+# Add definitions with values.
+if(NOT PREPROCESS_VS6)
+ # The path might have spaces, which VS6 does not support.
+ set(DEF_TARGET_PATH "TARGET_PATH=\"${TARGET_PATH}\"")
+ set(DEF_FILE_PATH "FILE_PATH=\"${FILE_PATH}\"")
+endif(NOT PREPROCESS_VS6)
+set_property(
+ TARGET Preprocess
+ APPEND PROPERTY COMPILE_DEFINITIONS
+ "TARGET_STRING=\"${STRING_VALUE}${SEMICOLON}\""
+ "TARGET_EXPR=${EXPR}"
+ ${DEF_TARGET_PATH}
+ )
+set_property(
+ SOURCE preprocess.c preprocess${VS6}.cxx
+ APPEND PROPERTY COMPILE_DEFINITIONS
+ "FILE_STRING=\"${STRING_VALUE}${SEMICOLON}\""
+ "FILE_EXPR=${EXPR}"
+ ${DEF_FILE_PATH}
+ )
+
+# Helper target for running test manually in build tree.
+add_custom_target(drive COMMAND Preprocess)
+
+# Configure the header file with the desired string value.
+if(SEMICOLON)
+ set(STRING_VALUE "${STRING_VALUE};")
+endif(SEMICOLON)
+configure_file(${Preprocess_SOURCE_DIR}/preprocess.h.in
+ ${Preprocess_BINARY_DIR}/preprocess.h)
+include_directories(${Preprocess_BINARY_DIR})
diff --git a/Tests/Preprocess/file_def.h b/Tests/Preprocess/file_def.h
new file mode 100644
index 000000000..fbf8986a0
--- /dev/null
+++ b/Tests/Preprocess/file_def.h
@@ -0,0 +1 @@
+#define FILE_PATH_DEF
diff --git a/Tests/Preprocess/preprocess.c b/Tests/Preprocess/preprocess.c
new file mode 100644
index 000000000..16209acf4
--- /dev/null
+++ b/Tests/Preprocess/preprocess.c
@@ -0,0 +1,198 @@
+#include <preprocess.h>
+
+#include FILE_PATH
+#include TARGET_PATH
+
+#include <string.h>
+#include <stdio.h>
+
+int check_defines_C(void)
+{
+ int result = 1;
+ if(strcmp(FILE_STRING, STRING_VALUE) != 0)
+ {
+ fprintf(stderr,
+ "FILE_STRING has wrong value in C [%s]\n", FILE_STRING);
+ result = 0;
+ }
+ if(strcmp(TARGET_STRING, STRING_VALUE) != 0)
+ {
+ fprintf(stderr,
+ "TARGET_STRING has wrong value in C [%s]\n", TARGET_STRING);
+ result = 0;
+ }
+ {
+ int x = 2;
+ int y = 3;
+ if((FILE_EXPR) != (EXPR))
+ {
+ fprintf(stderr, "FILE_EXPR did not work in C [%s]\n",
+ TO_STRING(FILE_EXPR));
+ result = 0;
+ }
+ if((TARGET_EXPR) != (EXPR))
+ {
+ fprintf(stderr, "TARGET_EXPR did not work in C [%s]\n",
+ TO_STRING(FILE_EXPR));
+ result = 0;
+ }
+ }
+#ifdef NDEBUG
+# ifdef FILE_DEF_DEBUG
+ {
+ fprintf(stderr, "FILE_DEF_DEBUG should not be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifdef TARGET_DEF_DEBUG
+ {
+ fprintf(stderr, "TARGET_DEF_DEBUG should not be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifdef DIRECTORY_DEF_DEBUG
+ {
+ fprintf(stderr, "DIRECTORY_DEF_DEBUG should not be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifndef FILE_DEF_RELEASE
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr, "FILE_DEF_RELEASE should be defined in C\n");
+ result = 0;
+ }
+# endif
+# endif
+# ifndef TARGET_DEF_RELEASE
+ {
+ fprintf(stderr, "TARGET_DEF_RELEASE should be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifndef DIRECTORY_DEF_RELEASE
+ {
+ fprintf(stderr, "DIRECTORY_DEF_RELEASE should be defined in C\n");
+ result = 0;
+ }
+# endif
+#endif
+#ifdef PREPROCESS_DEBUG
+# ifndef FILE_DEF_DEBUG
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr, "FILE_DEF_DEBUG should be defined in C\n");
+ result = 0;
+ }
+# endif
+# endif
+# ifndef TARGET_DEF_DEBUG
+ {
+ fprintf(stderr, "TARGET_DEF_DEBUG should be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifndef DIRECTORY_DEF_DEBUG
+ {
+ fprintf(stderr, "DIRECTORY_DEF_DEBUG should be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifdef FILE_DEF_RELEASE
+ {
+ fprintf(stderr, "FILE_DEF_RELEASE should not be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifdef TARGET_DEF_RELEASE
+ {
+ fprintf(stderr, "TARGET_DEF_RELEASE should not be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifdef DIRECTORY_DEF_RELEASE
+ {
+ fprintf(stderr, "DIRECTORY_DEF_RELEASE should not be defined in C\n");
+ result = 0;
+ }
+# endif
+#endif
+#if defined(FILE_DEF_DEBUG) || defined(TARGET_DEF_DEBUG)
+# if !defined(FILE_DEF_DEBUG) || !defined(TARGET_DEF_DEBUG)
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr,
+ "FILE_DEF_DEBUG and TARGET_DEF_DEBUG inconsistent in C\n");
+ result = 0;
+ }
+# endif
+# endif
+# if defined(FILE_DEF_RELEASE) || defined(TARGET_DEF_RELEASE)
+ {
+ fprintf(stderr, "DEBUG and RELEASE definitions inconsistent in C\n");
+ result = 0;
+ }
+# endif
+#endif
+#if defined(FILE_DEF_RELEASE) || defined(TARGET_DEF_RELEASE)
+# if !defined(FILE_DEF_RELEASE) || !defined(TARGET_DEF_RELEASE)
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr,
+ "FILE_DEF_RELEASE and TARGET_DEF_RELEASE inconsistent in C\n");
+ result = 0;
+ }
+# endif
+# endif
+# if defined(FILE_DEF_DEBUG) || defined(TARGET_DEF_DEBUG)
+ {
+ fprintf(stderr, "RELEASE and DEBUG definitions inconsistent in C\n");
+ result = 0;
+ }
+# endif
+#endif
+#ifndef FILE_PATH_DEF
+ {
+ fprintf(stderr, "FILE_PATH_DEF not defined in C\n");
+ result = 0;
+ }
+#endif
+#ifndef TARGET_PATH_DEF
+ {
+ fprintf(stderr, "TARGET_PATH_DEF not defined in C\n");
+ result = 0;
+ }
+#endif
+#ifndef FILE_DEF
+ {
+ fprintf(stderr, "FILE_DEF not defined in C\n");
+ result = 0;
+ }
+#endif
+#ifndef TARGET_DEF
+ {
+ fprintf(stderr, "TARGET_DEF not defined in C\n");
+ result = 0;
+ }
+#endif
+#ifndef DIRECTORY_DEF
+ {
+ fprintf(stderr, "DIRECTORY_DEF not defined in C\n");
+ result = 0;
+ }
+#endif
+#ifndef OLD_DEF
+ {
+ fprintf(stderr, "OLD_DEF not defined in C\n");
+ result = 0;
+ }
+#endif
+#if !defined(OLD_EXPR) || OLD_EXPR != 2
+ {
+ fprintf(stderr, "OLD_EXPR id not work in C [%s]\n",
+ TO_STRING(OLD_EXPR));
+ result = 0;
+ }
+#endif
+ return result;
+}
diff --git a/Tests/Preprocess/preprocess.cxx b/Tests/Preprocess/preprocess.cxx
new file mode 100644
index 000000000..27b6ac89a
--- /dev/null
+++ b/Tests/Preprocess/preprocess.cxx
@@ -0,0 +1,225 @@
+#include <preprocess.h>
+
+#include FILE_PATH
+#include TARGET_PATH
+
+#include <string.h>
+#include <stdio.h>
+
+extern "C" int check_defines_C(void);
+
+int check_defines_CXX()
+{
+ int result = 1;
+ if(strcmp(FILE_STRING, STRING_VALUE) != 0)
+ {
+ fprintf(stderr,
+ "FILE_STRING has wrong value in CXX [%s]\n", FILE_STRING);
+ result = 0;
+ }
+ if(strcmp(TARGET_STRING, STRING_VALUE) != 0)
+ {
+ fprintf(stderr,
+ "TARGET_STRING has wrong value in CXX [%s]\n", TARGET_STRING);
+ result = 0;
+ }
+ {
+ int x = 2;
+ int y = 3;
+ if((FILE_EXPR) != (EXPR))
+ {
+ fprintf(stderr, "FILE_EXPR did not work in CXX [%s]\n",
+ TO_STRING(FILE_EXPR));
+ result = 0;
+ }
+ if((TARGET_EXPR) != (EXPR))
+ {
+ fprintf(stderr, "TARGET_EXPR did not work in CXX [%s]\n",
+ TO_STRING(FILE_EXPR));
+ result = 0;
+ }
+ }
+#ifdef NDEBUG
+# ifdef FILE_DEF_DEBUG
+ {
+ fprintf(stderr, "FILE_DEF_DEBUG should not be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifdef TARGET_DEF_DEBUG
+ {
+ fprintf(stderr, "TARGET_DEF_DEBUG should not be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifdef DIRECTORY_DEF_DEBUG
+ {
+ fprintf(stderr, "DIRECTORY_DEF_DEBUG should not be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifndef FILE_DEF_RELEASE
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr, "FILE_DEF_RELEASE should be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# endif
+# ifndef TARGET_DEF_RELEASE
+ {
+ fprintf(stderr, "TARGET_DEF_RELEASE should be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifndef DIRECTORY_DEF_RELEASE
+ {
+ fprintf(stderr, "DIRECTORY_DEF_RELEASE should be defined in CXX\n");
+ result = 0;
+ }
+# endif
+#endif
+#ifdef PREPROCESS_DEBUG
+# ifndef FILE_DEF_DEBUG
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr, "FILE_DEF_DEBUG should be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# endif
+# ifndef TARGET_DEF_DEBUG
+ {
+ fprintf(stderr, "TARGET_DEF_DEBUG should be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifndef DIRECTORY_DEF_DEBUG
+ {
+ fprintf(stderr, "DIRECTORY_DEF_DEBUG should be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifdef FILE_DEF_RELEASE
+ {
+ fprintf(stderr, "FILE_DEF_RELEASE should not be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifdef TARGET_DEF_RELEASE
+ {
+ fprintf(stderr, "TARGET_DEF_RELEASE should not be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifdef DIRECTORY_DEF_RELEASE
+ {
+ fprintf(stderr, "DIRECTORY_DEF_RELEASE should not be defined in CXX\n");
+ result = 0;
+ }
+# endif
+#endif
+#if defined(FILE_DEF_DEBUG) || defined(TARGET_DEF_DEBUG)
+# if !defined(FILE_DEF_DEBUG) || !defined(TARGET_DEF_DEBUG)
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr,
+ "FILE_DEF_DEBUG and TARGET_DEF_DEBUG inconsistent in CXX\n");
+ result = 0;
+ }
+# endif
+# endif
+# if defined(FILE_DEF_RELEASE) || defined(TARGET_DEF_RELEASE)
+ {
+ fprintf(stderr, "DEBUG and RELEASE definitions inconsistent in CXX\n");
+ result = 0;
+ }
+# endif
+#endif
+#if defined(FILE_DEF_RELEASE) || defined(TARGET_DEF_RELEASE)
+# if !defined(FILE_DEF_RELEASE) || !defined(TARGET_DEF_RELEASE)
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr,
+ "FILE_DEF_RELEASE and TARGET_DEF_RELEASE inconsistent in CXX\n");
+ result = 0;
+ }
+# endif
+# endif
+# if defined(FILE_DEF_DEBUG) || defined(TARGET_DEF_DEBUG)
+ {
+ fprintf(stderr, "RELEASE and DEBUG definitions inconsistent in CXX\n");
+ result = 0;
+ }
+# endif
+#endif
+#ifndef FILE_PATH_DEF
+ {
+ fprintf(stderr, "FILE_PATH_DEF not defined in CXX\n");
+ result = 0;
+ }
+#endif
+#ifndef TARGET_PATH_DEF
+ {
+ fprintf(stderr, "TARGET_PATH_DEF not defined in CXX\n");
+ result = 0;
+ }
+#endif
+#ifndef FILE_DEF
+ {
+ fprintf(stderr, "FILE_DEF not defined in CXX\n");
+ result = 0;
+ }
+#endif
+#ifndef TARGET_DEF
+ {
+ fprintf(stderr, "TARGET_DEF not defined in CXX\n");
+ result = 0;
+ }
+#endif
+#ifndef DIRECTORY_DEF
+ {
+ fprintf(stderr, "DIRECTORY_DEF not defined in CXX\n");
+ result = 0;
+ }
+#endif
+#ifndef OLD_DEF
+ {
+ fprintf(stderr, "OLD_DEF not defined in CXX\n");
+ result = 0;
+ }
+#endif
+#if !defined(OLD_EXPR) || OLD_EXPR != 2
+ {
+ fprintf(stderr, "OLD_EXPR id not work in C [%s]\n",
+ TO_STRING(OLD_EXPR));
+ result = 0;
+ }
+#endif
+ return result;
+}
+
+int main()
+{
+ int result = 1;
+
+ if(!check_defines_C())
+ {
+ result = 0;
+ }
+
+ if(!check_defines_CXX())
+ {
+ result = 0;
+ }
+
+ if(result)
+ {
+ printf("All preprocessor definitions are correct.\n");
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
diff --git a/Tests/Preprocess/preprocess.h.in b/Tests/Preprocess/preprocess.h.in
new file mode 100644
index 000000000..3e1c7a07a
--- /dev/null
+++ b/Tests/Preprocess/preprocess.h.in
@@ -0,0 +1,16 @@
+/* Define configured macros. */
+#define STRING_VALUE "@STRING_VALUE@"
+#define EXPR @EXPR@
+#cmakedefine PREPROCESS_XCODE
+#cmakedefine PREPROCESS_VS6
+
+#ifdef PREPROCESS_VS6
+# define FILE_PATH "@FILE_PATH@"
+# define TARGET_PATH "@TARGET_PATH@"
+#endif
+
+/* Declarations and macros shared by all sources. */
+#define TO_STRING(x) TO_STRING0(x)
+#define TO_STRING0(x) #x
+
+static int f(int i) { return i*3; }
diff --git a/Tests/Preprocess/preprocess_vs6.cxx b/Tests/Preprocess/preprocess_vs6.cxx
new file mode 100644
index 000000000..9df89f6a0
--- /dev/null
+++ b/Tests/Preprocess/preprocess_vs6.cxx
@@ -0,0 +1,3 @@
+// The VS6 IDE does not support object name configuration so we need a
+// source file with a different name. Include the real source file.
+#include "preprocess.cxx"
diff --git a/Tests/Preprocess/target_def.h b/Tests/Preprocess/target_def.h
new file mode 100644
index 000000000..f016d5cd2
--- /dev/null
+++ b/Tests/Preprocess/target_def.h
@@ -0,0 +1 @@
+#define TARGET_PATH_DEF