[libcxx-commits] [libcxx] 7928d40 - [libc++][dsl] Run checks for locale names aliases using a single %exec

Alex Richardson via libcxx-commits libcxx-commits at lists.llvm.org
Sun Oct 18 10:47:17 PDT 2020


Author: Alex Richardson
Date: 2020-10-18T18:17:50+01:00
New Revision: 7928d40c6b892c977472cdb7fbf67703222e15e5

URL: https://github.com/llvm/llvm-project/commit/7928d40c6b892c977472cdb7fbf67703222e15e5
DIFF: https://github.com/llvm/llvm-project/commit/7928d40c6b892c977472cdb7fbf67703222e15e5.diff

LOG: [libc++][dsl] Run checks for locale names aliases using a single %exec

This changes the checking for available locales to use one program that
iterates over argv to test multiple locale names instead of checking each
name with a separate executable.

This massively speeds up running individual tests using an SSH executor
(it can take up to 10 seconds to compile and run a single test in some
emulated environments) in case no locales are installed since then all
fallback names are tested idividually. But even on a native machine
this reduces the libc++ lit startup time by ~1-2 second for me on a machine
that does not have locale data installed.

Reviewed By: #libc, ldionne
Differential Revision: https://reviews.llvm.org/D88884

Added: 
    

Modified: 
    libcxx/test/libcxx/selftest/dsl/dsl.sh.py
    libcxx/utils/libcxx/test/dsl.py
    libcxx/utils/libcxx/test/features.py

Removed: 
    


################################################################################
diff  --git a/libcxx/test/libcxx/selftest/dsl/dsl.sh.py b/libcxx/test/libcxx/selftest/dsl/dsl.sh.py
index d20781ab9ea6..27c88e9e3ca7 100644
--- a/libcxx/test/libcxx/selftest/dsl/dsl.sh.py
+++ b/libcxx/test/libcxx/selftest/dsl/dsl.sh.py
@@ -215,12 +215,12 @@ def test_doesnt_explode(self):
         # It's really hard to test that a system has a given locale, so at least
         # make sure we don't explode when we try to check it.
         try:
-            dsl.hasLocale(self.config, 'en_US.UTF-8')
+            dsl.hasAnyLocale(self.config, ['en_US.UTF-8'])
         except subprocess.CalledProcessError:
             self.fail("checking for hasLocale should not explode")
 
     def test_nonexistent_locale(self):
-        self.assertFalse(dsl.hasLocale(self.config, 'for_sure_this_is_not_an_existing_locale'))
+        self.assertFalse(dsl.hasAnyLocale(self.config, ['for_sure_this_is_not_an_existing_locale']))
 
 
 class TestCompilerMacros(SetupConfigs):

diff  --git a/libcxx/utils/libcxx/test/dsl.py b/libcxx/utils/libcxx/test/dsl.py
index 78f9841c0673..938d3711b765 100644
--- a/libcxx/utils/libcxx/test/dsl.py
+++ b/libcxx/utils/libcxx/test/dsl.py
@@ -150,9 +150,12 @@ def hasCompileFlag(config, flag):
     return exitCode == 0
 
 @_memoizeExpensiveOperation(lambda c, l: (c.substitutions, c.environment, l))
-def hasLocale(config, locale):
+def hasAnyLocale(config, locales):
   """
   Return whether the runtime execution environment supports a given locale.
+  Different systems may use 
diff erent names for a locale, so this function checks
+  whether any of the passed locale names is supported by setlocale() and returns
+  true if one of them works.
 
   This is done by executing a program that tries to set the given locale using
   %{exec} -- this means that the command may be executed on a remote host
@@ -160,13 +163,21 @@ def hasLocale(config, locale):
   """
   program = """
     #include <locale.h>
-    int main(int, char** argv) {
-      if (::setlocale(LC_ALL, argv[1]) != NULL) return 0;
-      else                                      return 1;
+    #include <stdio.h>
+    int main(int argc, char** argv) {
+      // For debugging purposes print which locales are (not) supported.
+      for (int i = 1; i < argc; i++) {
+        if (::setlocale(LC_ALL, argv[i]) != NULL) {
+          printf("%s is supported.\\n", argv[i]);
+          return 0;
+        }
+        printf("%s is not supported.\\n", argv[i]);
+      }
+      return 1;
     }
   """
-  return programOutput(config, program, args=[pipes.quote(locale)],
-                       testPrefix="check_locale_" + locale) is not None
+  return programOutput(config, program, args=[pipes.quote(l) for l in locales],
+                       testPrefix="check_locale_" + locales[0]) is not None
 
 @_memoizeExpensiveOperation(lambda c, flags='': (c.substitutions, c.environment, flags))
 def compilerMacros(config, flags=''):

diff  --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py
index 14d4dcb17943..47cfa7da67f8 100644
--- a/libcxx/utils/libcxx/test/features.py
+++ b/libcxx/utils/libcxx/test/features.py
@@ -108,7 +108,7 @@
   # Note: Using alts directly in the lambda body here will bind it to the value at the
   # end of the loop. Assigning it to a default argument works around this issue.
   DEFAULT_FEATURES.append(Feature(name='locale.{}'.format(locale),
-                                  when=lambda cfg, alts=alts: any(hasLocale(cfg, alt) for alt in alts)))
+                                  when=lambda cfg, alts=alts: hasAnyLocale(cfg, alts)))
 
 
 # Add features representing the platform name: darwin, linux, windows, etc...


        


More information about the libcxx-commits mailing list