520cc8
commit 477a02f63751c4b759ddd9454d17f2a7ad120ee3
520cc8
Author: Joseph Myers <joseph@codesourcery.com>
520cc8
Date:   Mon Dec 3 22:08:50 2018 +0000
520cc8
520cc8
    Make gen-as-const.py handle '--' consistently with awk script.
520cc8
    
520cc8
    It was reported in
520cc8
    <https://sourceware.org/ml/libc-alpha/2018-12/msg00045.html> that
520cc8
    gen-as-const.py fails to generate test code in the case where a .sym
520cc8
    file has no symbols in it, so resulting in a test failing to link for
520cc8
    Hurd.
520cc8
    
520cc8
    The relevant difference from the old awk script is that the old script
520cc8
    treated '--' lines as indicating that the text to do at the start of
520cc8
    the test (or file used to compute constants) should be output at that
520cc8
    point if not already output, as well as treating lines with actual
520cc8
    entries for constants like that.  This patch changes gen-as-const.py
520cc8
    accordingly, making it the sole responsibility of the code parsing
520cc8
    .sym files to determine when such text should be output and ensuring
520cc8
    it's always output at some point even if there are no symbols and no
520cc8
    '--' lines, since not outputting it means the test fails to link.
520cc8
    Handling '--' like that also avoids any problems that would arise if
520cc8
    the first entry for a symbol were inside #ifdef (since the text in
520cc8
    question must not be output inside #ifdef).
520cc8
    
520cc8
    Tested for x86_64, and with build-many-glibcs.py for i686-gnu.  Note
520cc8
    that there are still compilation test failures for i686-gnu
520cc8
    (linknamespace tests, possibly arising from recent posix_spawn-related
520cc8
    changes).
520cc8
    
520cc8
            * scripts/gen-as-const.py (compute_c_consts): Take an argument
520cc8
            'START' to indicate that start text should be output.
520cc8
            (gen_test): Likewise.
520cc8
            (main): Generate 'START' for first symbol or '--' line, or at end
520cc8
            of input if not previously generated.
520cc8
520cc8
diff --git a/scripts/gen-as-const.py b/scripts/gen-as-const.py
520cc8
index cabf401ed15e8367..eb85ef1aa0f4934d 100644
520cc8
--- a/scripts/gen-as-const.py
520cc8
+++ b/scripts/gen-as-const.py
520cc8
@@ -34,28 +34,28 @@ def compute_c_consts(sym_data, cc):
520cc8
     """Compute the values of some C constants.
520cc8
 
520cc8
     The first argument is a list whose elements are either strings
520cc8
-    (preprocessor directives) or pairs of strings (a name and a C
520cc8
+    (preprocessor directives, or the special string 'START' to
520cc8
+    indicate this function should insert its initial boilerplate text
520cc8
+    in the output there) or pairs of strings (a name and a C
520cc8
     expression for the corresponding value).  Preprocessor directives
520cc8
     in the middle of the list may be used to select which constants
520cc8
     end up being evaluated using which expressions.
520cc8
 
520cc8
     """
520cc8
     out_lines = []
520cc8
-    started = False
520cc8
     for arg in sym_data:
520cc8
         if isinstance(arg, str):
520cc8
-            out_lines.append(arg)
520cc8
+            if arg == 'START':
520cc8
+                out_lines.append('void\ndummy (void)\n{')
520cc8
+            else:
520cc8
+                out_lines.append(arg)
520cc8
             continue
520cc8
         name = arg[0]
520cc8
         value = arg[1]
520cc8
-        if not started:
520cc8
-            out_lines.append('void\ndummy (void)\n{')
520cc8
-            started = True
520cc8
         out_lines.append('asm ("@@@name@@@%s@@@value@@@%%0@@@end@@@" '
520cc8
                          ': : \"i\" ((long int) (%s)));'
520cc8
                          % (name, value))
520cc8
-    if started:
520cc8
-        out_lines.append('}')
520cc8
+    out_lines.append('}')
520cc8
     out_lines.append('')
520cc8
     out_text = '\n'.join(out_lines)
520cc8
     with tempfile.TemporaryDirectory() as temp_dir:
520cc8
@@ -89,32 +89,32 @@ def gen_test(sym_data):
520cc8
 
520cc8
     """
520cc8
     out_lines = []
520cc8
-    started = False
520cc8
     for arg in sym_data:
520cc8
         if isinstance(arg, str):
520cc8
-            out_lines.append(arg)
520cc8
+            if arg == 'START':
520cc8
+                out_lines.append('#include <stdint.h>\n'
520cc8
+                                 '#include <stdio.h>\n'
520cc8
+                                 '#include <bits/wordsize.h>\n'
520cc8
+                                 '#if __WORDSIZE == 64\n'
520cc8
+                                 'typedef uint64_t c_t;\n'
520cc8
+                                 '# define U(n) UINT64_C (n)\n'
520cc8
+                                 '#else\n'
520cc8
+                                 'typedef uint32_t c_t;\n'
520cc8
+                                 '# define U(n) UINT32_C (n)\n'
520cc8
+                                 '#endif\n'
520cc8
+                                 'static int\n'
520cc8
+                                 'do_test (void)\n'
520cc8
+                                 '{\n'
520cc8
+                                 # Compilation test only, using static
520cc8
+                                 # assertions.
520cc8
+                                 '  return 0;\n'
520cc8
+                                 '}\n'
520cc8
+                                 '#include <support/test-driver.c>')
520cc8
+            else:
520cc8
+                out_lines.append(arg)
520cc8
             continue
520cc8
         name = arg[0]
520cc8
         value = arg[1]
520cc8
-        if not started:
520cc8
-            out_lines.append('#include <stdint.h>\n'
520cc8
-                             '#include <stdio.h>\n'
520cc8
-                             '#include <bits/wordsize.h>\n'
520cc8
-                             '#if __WORDSIZE == 64\n'
520cc8
-                             'typedef uint64_t c_t;\n'
520cc8
-                             '# define U(n) UINT64_C (n)\n'
520cc8
-                             '#else\n'
520cc8
-                             'typedef uint32_t c_t;\n'
520cc8
-                             '# define U(n) UINT32_C (n)\n'
520cc8
-                             '#endif\n'
520cc8
-                             'static int\n'
520cc8
-                             'do_test (void)\n'
520cc8
-                             '{\n'
520cc8
-                             # Compilation test only, using static assertions.
520cc8
-                             '  return 0;\n'
520cc8
-                             '}\n'
520cc8
-                             '#include <support/test-driver.c>')
520cc8
-            started = True
520cc8
         out_lines.append('_Static_assert (U (asconst_%s) == (c_t) (%s), '
520cc8
                          '"value of %s");'
520cc8
                          % (name, value, name))
520cc8
@@ -134,6 +134,7 @@ def main():
520cc8
     args = parser.parse_args()
520cc8
     sym_data = []
520cc8
     with open(args.sym_file, 'r') as sym_file:
520cc8
+        started = False
520cc8
         for line in sym_file:
520cc8
             line = line.strip()
520cc8
             if line == '':
520cc8
@@ -143,12 +144,17 @@ def main():
520cc8
                 sym_data.append(line)
520cc8
                 continue
520cc8
             words = line.split(maxsplit=1)
520cc8
+            if not started:
520cc8
+                sym_data.append('START')
520cc8
+                started = True
520cc8
             # Separator.
520cc8
             if words[0] == '--':
520cc8
                 continue
520cc8
             name = words[0]
520cc8
             value = words[1] if len(words) > 1 else words[0]
520cc8
             sym_data.append((name, value))
520cc8
+        if not started:
520cc8
+            sym_data.append('START')
520cc8
     if args.test:
520cc8
         print(gen_test(sym_data))
520cc8
     else: