about summary refs log tree commit diff
path: root/conform/glibcconform.py
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2018-08-31 21:19:51 +0000
committerJoseph Myers <joseph@codesourcery.com>2018-08-31 21:19:51 +0000
commit2bbd06bcee5fe62896d71f78c6c2b6d0f3a23467 (patch)
tree4c28e38e786a26898976945861a014d591a94b2a /conform/glibcconform.py
parent81b9d87bae23efc42e2121ac066fe38fceb96124 (diff)
downloadglibc-2bbd06bcee5fe62896d71f78c6c2b6d0f3a23467.tar.gz
glibc-2bbd06bcee5fe62896d71f78c6c2b6d0f3a23467.tar.xz
glibc-2bbd06bcee5fe62896d71f78c6c2b6d0f3a23467.zip
Replace conform/list-header-symbols.pl with a Python script.
Continuing the move of test code from Perl to Python (which seems
uncontroversial, unlike dependencies on Python in the actual build of
glibc), this patch replaces conform/list-header-symbols.pl with a
Python script, as a first step in converting the conform/ tests.
(conform/glibcconform.py is an equivalent to GlibcConform.pm,
containing code that will be relevant to move than one of the conform/
scripts.)

Tested for x86_64, including verifying that the symbol lists generated
are identical to those generated by the Perl version.

	* conform/glibcconform.py: New file.
	* conform/list-header-symbols.py: Likewise.
	* conform/list-header-symbols.pl: Remove.
	* conform/Makefile (tests-special): Only add linknamespace tests
	if [PYTHON].
	($(linknamespace-symlists-tests)): Use list-header-symbols.py.
Diffstat (limited to 'conform/glibcconform.py')
-rw-r--r--conform/glibcconform.py77
1 files changed, 77 insertions, 0 deletions
diff --git a/conform/glibcconform.py b/conform/glibcconform.py
new file mode 100644
index 0000000000..31ad4a9f9f
--- /dev/null
+++ b/conform/glibcconform.py
@@ -0,0 +1,77 @@
+#!/usr/bin/python
+# Shared code for glibc conformance tests.
+# Copyright (C) 2018 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+import os.path
+import re
+import shutil
+import subprocess
+import tempfile
+
+
+# Compiler options for each standard.
+CFLAGS = {'ISO': '-ansi',
+          'ISO99': '-std=c99',
+          'ISO11': '-std=c11',
+          'POSIX': '-D_POSIX_C_SOURCE=199506L -ansi',
+          'XPG4': '-ansi -D_XOPEN_SOURCE',
+          'XPG42': '-ansi -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED',
+          'UNIX98': '-ansi -D_XOPEN_SOURCE=500',
+          'XOPEN2K': '-std=c99 -D_XOPEN_SOURCE=600',
+          'XOPEN2K8': '-std=c99 -D_XOPEN_SOURCE=700',
+          'POSIX2008': '-std=c99 -D_POSIX_C_SOURCE=200809L'}
+
+
+def list_exported_functions(cc, standard, header):
+    """Return the set of functions exported by a header, empty if an
+    include of the header does not compile.
+
+    """
+    cc_all = '%s -D_ISOMAC %s' % (cc, CFLAGS[standard])
+    # tempfile.TemporaryDirectory requires Python 3.2, so use mkdtemp.
+    temp_dir = tempfile.mkdtemp()
+    c_file_name = os.path.join(temp_dir, 'test.c')
+    aux_file_name = os.path.join(temp_dir, 'test.c.aux')
+    try:
+        with open(c_file_name, 'w') as c_file:
+            c_file.write('#include <%s>\n' % header)
+        fns = set()
+        cmd = ('%s -c %s -o /dev/null -aux-info %s'
+               % (cc_all, c_file_name, aux_file_name))
+        try:
+            subprocess.check_call(cmd, shell=True)
+        except subprocess.CalledProcessError:
+            return fns
+        with open(aux_file_name, 'r') as aux_file:
+            for line in aux_file:
+                line = re.sub(r'/\*.*?\*/', '', line)
+                line = line.strip()
+                if line:
+                    # The word before a '(' that isn't '(*' is the
+                    # function name before the argument list (not
+                    # fully general, but sufficient for -aux-info
+                    # output on standard headers).
+                    m = re.search(r'([A-Za-z0-9_]+) *\([^*]', line)
+                    if m:
+                        fns.add(m.group(1))
+                    else:
+                        raise ValueError("couldn't parse -aux-info output: %s"
+                                         % line)
+    finally:
+        shutil.rmtree(temp_dir)
+    return fns