Removes uses of GTEST_HAS_STD_STRING.


git-svn-id: http://googletest.googlecode.com/svn/trunk@353 861a406c-534a-0410-8894-cb66d6ee9925
diff --git a/include/gtest/gtest.h b/include/gtest/gtest.h
index c7df7f0..02d4c5e 100644
--- a/include/gtest/gtest.h
+++ b/include/gtest/gtest.h
@@ -62,24 +62,19 @@
 #include <gtest/gtest-typed-test.h>
 
 // Depending on the platform, different string classes are available.
-// On Windows, ::std::string compiles only when exceptions are
-// enabled.  On Linux, in addition to ::std::string, Google also makes
-// use of class ::string, which has the same interface as
-// ::std::string, but has a different implementation.
+// On Linux, in addition to ::std::string, Google also makes use of
+// class ::string, which has the same interface as ::std::string, but
+// has a different implementation.
 //
-// The user can tell us whether ::std::string is available in his
-// environment by defining the macro GTEST_HAS_STD_STRING to either 1
-// or 0 on the compiler command line.  He can also define
-// GTEST_HAS_GLOBAL_STRING to 1 to indicate that ::string is available
-// AND is a distinct type to ::std::string, or define it to 0 to
-// indicate otherwise.
+// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that
+// ::string is available AND is a distinct type to ::std::string, or
+// define it to 0 to indicate otherwise.
 //
 // If the user's ::std::string and ::string are the same class due to
-// aliasing, he should define GTEST_HAS_STD_STRING to 1 and
-// GTEST_HAS_GLOBAL_STRING to 0.
+// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0.
 //
-// If the user doesn't define GTEST_HAS_STD_STRING and/or
-// GTEST_HAS_GLOBAL_STRING, they are defined heuristically.
+// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined
+// heuristically.
 
 namespace testing {
 
@@ -1210,11 +1205,9 @@
 namespace internal {
 
 // These overloaded versions handle ::std::string and ::std::wstring.
-#if GTEST_HAS_STD_STRING
 inline String FormatForFailureMessage(const ::std::string& str) {
   return (Message() << '"' << str << '"').GetString();
 }
-#endif  // GTEST_HAS_STD_STRING
 
 #if GTEST_HAS_STD_WSTRING
 inline String FormatForFailureMessage(const ::std::wstring& wstr) {
@@ -1464,14 +1457,12 @@
 AssertionResult IsNotSubstring(
     const char* needle_expr, const char* haystack_expr,
     const wchar_t* needle, const wchar_t* haystack);
-#if GTEST_HAS_STD_STRING
 AssertionResult IsSubstring(
     const char* needle_expr, const char* haystack_expr,
     const ::std::string& needle, const ::std::string& haystack);
 AssertionResult IsNotSubstring(
     const char* needle_expr, const char* haystack_expr,
     const ::std::string& needle, const ::std::string& haystack);
-#endif  // GTEST_HAS_STD_STRING
 
 #if GTEST_HAS_STD_WSTRING
 AssertionResult IsSubstring(
diff --git a/include/gtest/internal/gtest-internal.h b/include/gtest/internal/gtest-internal.h
index e9f8e7c..50f9fdf 100644
--- a/include/gtest/internal/gtest-internal.h
+++ b/include/gtest/internal/gtest-internal.h
@@ -259,9 +259,7 @@
   return operand1_printer(str);\
 }
 
-#if GTEST_HAS_STD_STRING
 GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted)
-#endif  // GTEST_HAS_STD_STRING
 #if GTEST_HAS_STD_WSTRING
 GTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted)
 #endif  // GTEST_HAS_STD_WSTRING
diff --git a/include/gtest/internal/gtest-port.h b/include/gtest/internal/gtest-port.h
index c0a1f11..253ce18 100644
--- a/include/gtest/internal/gtest-port.h
+++ b/include/gtest/internal/gtest-port.h
@@ -52,9 +52,6 @@
 //                              is/isn't available.
 //   GTEST_HAS_RTTI           - Define it to 1/0 to indicate that RTTI is/isn't
 //                              enabled.
-//   GTEST_HAS_STD_STRING     - Define it to 1/0 to indicate that
-//                              std::string does/doesn't work (Google Test can
-//                              be used where std::string is unavailable).
 //   GTEST_HAS_STD_WSTRING    - Define it to 1/0 to indicate that
 //                              std::wstring does/doesn't work (Google Test can
 //                              be used where std::wstring is unavailable).
@@ -261,23 +258,14 @@
 #endif  // defined(__GNUC__) && __EXCEPTIONS
 #endif  // defined(_MSC_VER) || defined(__BORLANDC__)
 
-// Determines whether ::std::string and ::string are available.
-
-#ifndef GTEST_HAS_STD_STRING
-// The user didn't tell us whether ::std::string is available, so we
-// need to figure it out.  The only environment that we know
-// ::std::string is not available is MSVC 7.1 or lower with exceptions
-// disabled.
-#if defined(_MSC_VER) && (_MSC_VER < 1400) && !GTEST_HAS_EXCEPTIONS
-#if !GTEST_ALLOW_VC71_WITHOUT_EXCEPTIONS_
-#error "When compiling gtest using MSVC 7.1, exceptions must be enabled."
-#error "Otherwise std::string and std::vector don't compile."
-#endif
-#define GTEST_HAS_STD_STRING 0
-#else
+#if !defined(GTEST_HAS_STD_STRING)
+// Even though we don't use this macro any longer, we keep it in case
+// some clients still depend on it.
 #define GTEST_HAS_STD_STRING 1
-#endif
-#endif  // GTEST_HAS_STD_STRING
+#elif !GTEST_HAS_STD_STRING
+// The user told us that ::std::string isn't available.
+#error "Google Test cannot be used where ::std::string isn't available."
+#endif  // !defined(GTEST_HAS_STD_STRING)
 
 #ifndef GTEST_HAS_GLOBAL_STRING
 // The user didn't tell us whether ::string is available, so we need
@@ -293,14 +281,10 @@
 // TODO(wan@google.com): uses autoconf to detect whether ::std::wstring
 //   is available.
 
-#if GTEST_OS_CYGWIN || GTEST_OS_SOLARIS
 // Cygwin 1.5 and below doesn't support ::std::wstring.
 // Cygwin 1.7 might add wstring support; this should be updated when clear.
 // Solaris' libc++ doesn't support it either.
-#define GTEST_HAS_STD_WSTRING 0
-#else
-#define GTEST_HAS_STD_WSTRING GTEST_HAS_STD_STRING
-#endif  // GTEST_OS_CYGWIN || GTEST_OS_SOLARIS
+#define GTEST_HAS_STD_WSTRING (!(GTEST_OS_CYGWIN || GTEST_OS_SOLARIS))
 
 #endif  // GTEST_HAS_STD_WSTRING
 
@@ -311,17 +295,8 @@
     (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING)
 #endif  // GTEST_HAS_GLOBAL_WSTRING
 
-#if GTEST_HAS_STD_STRING || GTEST_HAS_GLOBAL_STRING || \
-    GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
 #include <string>  // NOLINT
-#endif  // GTEST_HAS_STD_STRING || GTEST_HAS_GLOBAL_STRING ||
-        // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
-
-#if GTEST_HAS_STD_STRING
 #include <sstream>  // NOLINT
-#else
-#include <strstream>  // NOLINT
-#endif  // GTEST_HAS_STD_STRING
 
 // Determines whether RTTI is available.
 #ifndef GTEST_HAS_RTTI
@@ -457,15 +432,10 @@
 #endif  // GTEST_HAS_CLONE
 
 // Determines whether to support death tests.
-// Google Test does not support death tests for VC 7.1 and earlier for
-// these reasons:
-//   1. std::vector does not build in VC 7.1 when exceptions are disabled.
-//   2. std::string does not build in VC 7.1 when exceptions are disabled
-//      (this is covered by GTEST_HAS_STD_STRING guard).
-//   3. abort() in a VC 7.1 application compiled as GUI in debug config
-//      pops up a dialog window that cannot be suppressed programmatically.
-#if GTEST_HAS_STD_STRING && \
-    (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || \
+// Google Test does not support death tests for VC 7.1 and earlier as
+// abort() in a VC 7.1 application compiled as GUI in debug config
+// pops up a dialog window that cannot be suppressed programmatically.
+#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || \
      (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || GTEST_OS_WINDOWS_MINGW)
 #define GTEST_HAS_DEATH_TEST 1
 #include <vector>  // NOLINT
@@ -572,15 +542,7 @@
 
 class String;
 
-// std::strstream is deprecated.  However, we have to use it on
-// Windows as std::stringstream won't compile on Windows when
-// exceptions are disabled.  We use std::stringstream on other
-// platforms to avoid compiler warnings there.
-#if GTEST_HAS_STD_STRING
 typedef ::std::stringstream StrStream;
-#else
-typedef ::std::strstream StrStream;
-#endif  // GTEST_HAS_STD_STRING
 
 // A helper for suppressing warnings on constant condition.  It just
 // returns 'condition'.
@@ -629,9 +591,7 @@
 class RE {
  public:
   // Constructs an RE from a string.
-#if GTEST_HAS_STD_STRING
   RE(const ::std::string& regex) { Init(regex.c_str()); }  // NOLINT
-#endif  // GTEST_HAS_STD_STRING
 
 #if GTEST_HAS_GLOBAL_STRING
   RE(const ::string& regex) { Init(regex.c_str()); }  // NOLINT
@@ -650,14 +610,12 @@
   //
   // TODO(wan@google.com): make FullMatch() and PartialMatch() work
   // when str contains NUL characters.
-#if GTEST_HAS_STD_STRING
   static bool FullMatch(const ::std::string& str, const RE& re) {
     return FullMatch(str.c_str(), re);
   }
   static bool PartialMatch(const ::std::string& str, const RE& re) {
     return PartialMatch(str.c_str(), re);
   }
-#endif  // GTEST_HAS_STD_STRING
 
 #if GTEST_HAS_GLOBAL_STRING
   static bool FullMatch(const ::string& str, const RE& re) {
diff --git a/include/gtest/internal/gtest-string.h b/include/gtest/internal/gtest-string.h
index 076119a..6f9ba05 100644
--- a/include/gtest/internal/gtest-string.h
+++ b/include/gtest/internal/gtest-string.h
@@ -44,9 +44,7 @@
 #include <string.h>
 #include <gtest/internal/gtest-port.h>
 
-#if GTEST_HAS_GLOBAL_STRING || GTEST_HAS_STD_STRING
 #include <string>
-#endif  // GTEST_HAS_GLOBAL_STRING || GTEST_HAS_STD_STRING
 
 namespace testing {
 namespace internal {
@@ -221,13 +219,11 @@
   // Converting a ::std::string or ::string containing an embedded NUL
   // character to a String will result in the prefix up to the first
   // NUL character.
-#if GTEST_HAS_STD_STRING
   String(const ::std::string& str) {
     ConstructNonNull(str.c_str(), str.length());
   }
 
   operator ::std::string() const { return ::std::string(c_str(), length()); }
-#endif  // GTEST_HAS_STD_STRING
 
 #if GTEST_HAS_GLOBAL_STRING
   String(const ::string& str) {
diff --git a/run_tests.py b/run_tests.py
index e108405..aa2313e 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -39,6 +39,12 @@
 
 SCRIPT_DIR = os.path.dirname(__file__) or '.'
 
+# Some Python tests don't work in all configurations.
+PYTHON_TESTS_TO_SKIP = (
+    ('win-dbg', 'gtest_throw_on_failure_test.py'),
+    ('win-opt', 'gtest_throw_on_failure_test.py'),
+    )
+
 sys.path.append(os.path.join(SCRIPT_DIR, 'test'))
 import run_tests_util
 
@@ -50,7 +56,8 @@
   test_runner = run_tests_util.TestRunner(script_dir=SCRIPT_DIR)
   tests = test_runner.GetTestsToRun(args,
                                     options.configurations,
-                                    options.built_configurations)
+                                    options.built_configurations,
+                                    python_tests_to_skip=PYTHON_TESTS_TO_SKIP)
   if not tests:
     sys.exit(1)  # Incorrect parameters given, abort execution.
 
diff --git a/scons/SConscript.common b/scons/SConscript.common
index a49cf0a..7fda32e 100644
--- a/scons/SConscript.common
+++ b/scons/SConscript.common
@@ -88,9 +88,6 @@
     if env['PLATFORM'] == 'win32':
       env.Append(CCFLAGS=['/EHsc'])
       env.Append(CPPDEFINES='_HAS_EXCEPTIONS=1')
-      # Undoes the _TYPEINFO_ hack, which is unnecessary and only creates
-      # trouble when exceptions are enabled.
-      cls._Remove(env, 'CPPDEFINES', '_TYPEINFO_')
       cls._Remove(env, 'CPPDEFINES', '_HAS_EXCEPTIONS=0')
     else:
       env.Append(CCFLAGS='-fexceptions')
diff --git a/scons/SConstruct b/scons/SConstruct
index 1f2f37f..c749d6a 100644
--- a/scons/SConstruct
+++ b/scons/SConstruct
@@ -50,8 +50,12 @@
 
 win_base = sconstruct_helper.MakeWinBaseEnvironment()
 
+# We don't support VC 7.1 with exceptions disabled, so we always
+# enable exceptions for VC 7.1.  For newer versions of VC, we still
+# compile with exceptions disabled by default, as that's a more common
+# setting for our users.
 if win_base.get('MSVS_VERSION', None) == '7.1':
-  sconstruct_helper.AllowVc71StlWithoutExceptions(win_base)
+  sconstruct_helper.EnableExceptions(win_base)
 
 sconstruct_helper.MakeWinDebugEnvironment(win_base, 'win-dbg')
 sconstruct_helper.MakeWinOptimizedEnvironment(win_base, 'win-opt')
diff --git a/scons/SConstruct.common b/scons/SConstruct.common
index 7f6db15..cb9a63d 100644
--- a/scons/SConstruct.common
+++ b/scons/SConstruct.common
@@ -45,6 +45,13 @@
     # A dictionary to look up an environment by its name.
     self.env_dict = {}
 
+  def _Remove(self, env, attribute, value):
+    """Removes the given attribute value from the environment."""
+
+    attribute_values = env[attribute]
+    if value in attribute_values:
+      attribute_values.remove(value)
+
   def Initialize(self, build_root_path, support_multiple_win_builds=False):
     test_env = Environment()
     platform = test_env['PLATFORM']
@@ -83,13 +90,14 @@
     # Enable scons -h
     Help(vars.GenerateHelpText(self.env_base))
 
-  def AllowVc71StlWithoutExceptions(self, env):
-    env.Append(
-        CPPDEFINES = [# needed for using some parts of STL with exception
-                      # disabled.  The scoop is given here, with comments
-                      # from P.J. Plauger at
-                      # http://groups.google.com/group/microsoft.public.vc.stl/browse_thread/thread/5e719833c6bdb177?q=_HAS_EXCEPTIONS+using+namespace+std&pli=1
-                      '_TYPEINFO_'])
+  def EnableExceptions(self, env):
+    if env['PLATFORM'] == 'win32':
+      env.Append(CCFLAGS=['/EHsc'])
+      env.Append(CPPDEFINES='_HAS_EXCEPTIONS=1')
+      self._Remove(env, 'CPPDEFINES', '_HAS_EXCEPTIONS=0')
+    else:
+      env.Append(CCFLAGS='-fexceptions')
+      self._Remove(env, 'CCFLAGS', '-fno-exceptions')
 
   def MakeWinBaseEnvironment(self):
     win_base = self.env_base.Clone(
@@ -117,7 +125,6 @@
                     'STRICT',
                     'WIN32_LEAN_AND_MEAN',
                     '_HAS_EXCEPTIONS=0',
-                    'GTEST_ALLOW_VC71_WITHOUT_EXCEPTIONS_=1',
                     ],
         LIBPATH=['#/$MAIN_DIR/lib'],
         LINKFLAGS=['-MACHINE:x86',  # Enable safe SEH (not supp. on x64)
diff --git a/src/gtest.cc b/src/gtest.cc
index bd16bc6..c6d6c09 100644
--- a/src/gtest.cc
+++ b/src/gtest.cc
@@ -1316,7 +1316,6 @@
   return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
 }
 
-#if GTEST_HAS_STD_STRING
 AssertionResult IsSubstring(
     const char* needle_expr, const char* haystack_expr,
     const ::std::string& needle, const ::std::string& haystack) {
@@ -1328,7 +1327,6 @@
     const ::std::string& needle, const ::std::string& haystack) {
   return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
 }
-#endif  // GTEST_HAS_STD_STRING
 
 #if GTEST_HAS_STD_WSTRING
 AssertionResult IsSubstring(
@@ -1748,14 +1746,9 @@
 // Converts the buffer in a StrStream to a String, converting NUL
 // bytes to "\\0" along the way.
 String StrStreamToString(StrStream* ss) {
-#if GTEST_HAS_STD_STRING
   const ::std::string& str = ss->str();
   const char* const start = str.c_str();
   const char* const end = start + str.length();
-#else
-  const char* const start = ss->str();
-  const char* const end = start + ss->pcount();
-#endif  // GTEST_HAS_STD_STRING
 
   // We need to use a helper StrStream to do this transformation
   // because String doesn't support push_back().
@@ -1768,14 +1761,7 @@
     }
   }
 
-#if GTEST_HAS_STD_STRING
   return String(helper.str().c_str());
-#else
-  const String str(helper.str(), helper.pcount());
-  helper.freeze(false);
-  ss->freeze(false);
-  return str;
-#endif  // GTEST_HAS_STD_STRING
 }
 
 // Appends the user-supplied message to the Google-Test-generated message.
diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc
index 288c70a..4dc85b4 100644
--- a/test/gtest-death-test_test.cc
+++ b/test/gtest-death-test_test.cc
@@ -449,10 +449,8 @@
   EXPECT_DEATH(GlobalFunction(), regex_str);
 #endif  // GTEST_HAS_GLOBAL_STRING
 
-#if GTEST_HAS_STD_STRING
   const ::std::string regex_std_str(regex_c_str);
   EXPECT_DEATH(GlobalFunction(), regex_std_str);
-#endif  // GTEST_HAS_STD_STRING
 }
 
 // Tests that a non-void function can be used in a death test.
diff --git a/test/gtest-message_test.cc b/test/gtest-message_test.cc
index 6c43c33..f3dda11 100644
--- a/test/gtest-message_test.cc
+++ b/test/gtest-message_test.cc
@@ -92,8 +92,6 @@
   EXPECT_STREQ("(null)", ToCString(Message() << p));
 }
 
-#if GTEST_HAS_STD_STRING
-
 // Tests streaming std::string.
 //
 // As std::string has problem in MSVC when exception is disabled, we only
@@ -113,8 +111,6 @@
                ToCString(Message() << string_with_nul));
 }
 
-#endif  // GTEST_HAS_STD_STRING
-
 // Tests streaming a NUL char.
 TEST(MessageTest, StreamsNULChar) {
   EXPECT_STREQ("\\0", ToCString(Message() << '\0'));
diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc
index a2b0059..551c98b 100644
--- a/test/gtest-port_test.cc
+++ b/test/gtest-port_test.cc
@@ -177,9 +177,7 @@
 // Defines StringTypes as the list of all string types that class RE
 // supports.
 typedef testing::Types<
-#if GTEST_HAS_STD_STRING
     ::std::string,
-#endif  // GTEST_HAS_STD_STRING
 #if GTEST_HAS_GLOBAL_STRING
     ::string,
 #endif  // GTEST_HAS_GLOBAL_STRING
diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py
index c8a38f5..8d9a40b 100755
--- a/test/gtest_output_test.py
+++ b/test/gtest_output_test.py
@@ -126,15 +126,15 @@
 def RemoveTestCounts(output):
   """Removes test counts from a Google Test program's output."""
 
-  output = re.sub(r'\d+ tests, listed below',
+  output = re.sub(r'\d+ tests?, listed below',
                   '? tests, listed below', output)
   output = re.sub(r'\d+ FAILED TESTS',
                   '? FAILED TESTS', output)
-  output = re.sub(r'\d+ tests from \d+ test cases',
+  output = re.sub(r'\d+ tests? from \d+ test cases?',
                   '? tests from ? test cases', output)
-  output = re.sub(r'\d+ tests from ([a-zA-Z_])',
+  output = re.sub(r'\d+ tests? from ([a-zA-Z_])',
                   r'? tests from \1', output)
-  return re.sub(r'\d+ tests\.', '? tests.', output)
+  return re.sub(r'\d+ tests?\.', '? tests.', output)
 
 
 def RemoveMatchingTests(test_output, pattern):
@@ -268,16 +268,16 @@
       normalized_actual = RemoveTestCounts(output)
       normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests(golden))
 
-      # This code is very handy when debugging test differences so I left it
-      # here, commented.
-      # open(os.path.join(
-      #     gtest_test_utils.GetSourceDir(),
-      #     '_gtest_output_test_normalized_actual.txt'), 'wb').write(
-      #         normalized_actual)
-      # open(os.path.join(
-      #     gtest_test_utils.GetSourceDir(),
-      #     '_gtest_output_test_normalized_golden.txt'), 'wb').write(
-      #         normalized_golden)
+      # This code is very handy when debugging golden file differences:
+      if os.getenv('DEBUG_GTEST_OUTPUT_TEST'):
+        open(os.path.join(
+            gtest_test_utils.GetSourceDir(),
+            '_gtest_output_test_normalized_actual.txt'), 'wb').write(
+                normalized_actual)
+        open(os.path.join(
+            gtest_test_utils.GetSourceDir(),
+            '_gtest_output_test_normalized_golden.txt'), 'wb').write(
+                normalized_golden)
 
       self.assert_(normalized_golden == normalized_actual)
 
diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc
index 9745f93..ba5eb60 100644
--- a/test/gtest_unittest.cc
+++ b/test/gtest_unittest.cc
@@ -1111,8 +1111,6 @@
   EXPECT_EQ('c', s7.c_str()[3]);
 }
 
-#if GTEST_HAS_STD_STRING
-
 TEST(StringTest, ConvertsFromStdString) {
   // An empty std::string.
   const std::string src1("");
@@ -1152,8 +1150,6 @@
   EXPECT_EQ(std::string("x\0y", 3), dest3);
 }
 
-#endif  // GTEST_HAS_STD_STRING
-
 #if GTEST_HAS_GLOBAL_STRING
 
 TEST(StringTest, ConvertsFromGlobalString) {
@@ -2818,8 +2814,6 @@
                            "needle", "haystack").failure_message());
 }
 
-#if GTEST_HAS_STD_STRING
-
 // Tests that IsSubstring returns the correct result when the input
 // argument type is ::std::string.
 TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) {
@@ -2827,8 +2821,6 @@
   EXPECT_FALSE(IsSubstring("", "", "hello", std::string("world")));
 }
 
-#endif  // GTEST_HAS_STD_STRING
-
 #if GTEST_HAS_STD_WSTRING
 // Tests that IsSubstring returns the correct result when the input
 // argument type is ::std::wstring.
@@ -2879,8 +2871,6 @@
                    L"needle", L"two needles").failure_message());
 }
 
-#if GTEST_HAS_STD_STRING
-
 // Tests that IsNotSubstring returns the correct result when the input
 // argument type is ::std::string.
 TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) {
@@ -2900,8 +2890,6 @@
                    ::std::string("needle"), "two needles").failure_message());
 }
 
-#endif  // GTEST_HAS_STD_STRING
-
 #if GTEST_HAS_STD_WSTRING
 
 // Tests that IsNotSubstring returns the correct result when the input
@@ -4575,7 +4563,6 @@
 
 // Tests using streamable values as assertion messages.
 
-#if GTEST_HAS_STD_STRING
 // Tests using std::string as an assertion message.
 TEST(StreamableTest, string) {
   static const std::string str(
@@ -4596,8 +4583,6 @@
                        "Here's a NUL\\0 and some more string");
 }
 
-#endif  // GTEST_HAS_STD_STRING
-
 // Tests that we can output a NUL char.
 TEST(StreamableTest, NULChar) {
   EXPECT_FATAL_FAILURE({  // NOLINT
@@ -4720,7 +4705,6 @@
                        "Value of: wchar");
 }
 
-#if GTEST_HAS_STD_STRING
 // Tests using ::std::string values in {EXPECT|ASSERT}_EQ.
 TEST(EqAssertionTest, StdString) {
   // Compares a const char* to an std::string that has identical
@@ -4751,8 +4735,6 @@
                        "  Actual: \"A \\0 in the middle\"");
 }
 
-#endif  // GTEST_HAS_STD_STRING
-
 #if GTEST_HAS_STD_WSTRING
 
 // Tests using ::std::wstring values in {EXPECT|ASSERT}_EQ.
diff --git a/test/run_tests_util.py b/test/run_tests_util.py
index f1bb3e0..fb7fd38 100755
--- a/test/run_tests_util.py
+++ b/test/run_tests_util.py
@@ -152,6 +152,20 @@
                                                          'gtest/scons'))
 
 
+def _GetConfigFromBuildDir(build_dir):
+  """Extracts the configuration name from the build directory."""
+
+  # We don't want to depend on build_dir containing the correct path
+  # separators.
+  m = re.match(r'.*[\\/]([^\\/]+)[\\/][^\\/]+[\\/]scons[\\/]?$', build_dir)
+  if m:
+    return m.group(1)
+  else:
+    print >>sys.stderr, ('%s is an invalid build directory that does not '
+                         'correspond to any configuration.' % (build_dir,))
+    return ''
+
+
 # All paths in this script are either absolute or relative to the current
 # working directory, unless otherwise specified.
 class TestRunner(object):
@@ -270,7 +284,8 @@
                     args,
                     named_configurations,
                     built_configurations,
-                    available_configurations=CONFIGS):
+                    available_configurations=CONFIGS,
+                    python_tests_to_skip=None):
     """Determines what tests should be run.
 
     Args:
@@ -278,7 +293,9 @@
       named_configurations: The list of configurations specified via -c or -a.
       built_configurations: True if -b has been specified.
       available_configurations: a list of configurations available on the
-                                current platform, injectable for testing.
+                            current platform, injectable for testing.
+      python_tests_to_skip: a collection of (configuration, python test name)s
+                            that need to be skipped.
 
     Returns:
       A tuple with 2 elements: the list of Python tests to run and the list of
@@ -356,7 +373,13 @@
     python_test_pairs = []
     for directory in build_dirs:
       for test in selected_python_tests:
-        python_test_pairs.append((directory, test))
+        config = _GetConfigFromBuildDir(directory)
+        file_name = os.path.basename(test)
+        if python_tests_to_skip and (config, file_name) in python_tests_to_skip:
+          print ('NOTE: %s is skipped for configuration %s, as it does not '
+                 'work there.' % (file_name, config))
+        else:
+          python_test_pairs.append((directory, test))
 
     binary_test_pairs = []
     for directory in build_dirs: