nasm: don't depend on canonicalize_file_name(3)

It is a glibc-specific function that has a portable replacement, and
nasm already has code to fall back to this portable replacement.
Having nasm depend on the glibc-specific function is one of the
obstacles to chromium building with other libcs, so getting rid of
it is nice.

Note that the relevant config header (config/config-linux.h) is an
indirect result of running autoconf + configure on a developer
workstation when rolling a new nasm version, so those config
headers do not necessarily reflect the environment chromium is being
built in when we ship source tarballs. To work around that, this
change adds a post-processing step that corrects configure's output,
and adds a note to run it as part of the nasm uprev process.

Since I was touching nasm anyway, this change also ports
generate_nasm_sources.py from python2 to python3.

Bug: 1380656
Change-Id: I59dc3bda4a119cd440d05674550aa5c3af6b2390
diff --git a/README.chromium b/README.chromium
index e5d7a11..936a0b4 100644
--- a/README.chromium
+++ b/README.chromium
@@ -50,6 +50,7 @@
 
   # Copy config/config.h to config-(mac|linux).h
   # Revert config/config.h to the checked in version
+  ./generate_nasm_configs.py
 
   git commit -a
 
diff --git a/config/config-linux.h b/config/config-linux.h
index 9e59df4..ccf4c52 100644
--- a/config/config-linux.h
+++ b/config/config-linux.h
@@ -139,7 +139,7 @@
 #define HAVE_ACCESS 1
 
 /* Define to 1 if you have the `canonicalize_file_name' function. */
-#define HAVE_CANONICALIZE_FILE_NAME 1
+/* #undef HAVE_CANONICALIZE_FILE_NAME */ // Controlled by the Chromium build process - see generate_nasm_configs.py
 
 /* Define to 1 if you have the `cpu_to_le16' intrinsic function. */
 /* #undef HAVE_CPU_TO_LE16 */
diff --git a/generate_nasm_configs.py b/generate_nasm_configs.py
new file mode 100755
index 0000000..371c489
--- /dev/null
+++ b/generate_nasm_configs.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+#
+# Copyright 2022 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""A script to update and tweak nasm's generated configs post-autoconf."""
+
+import re
+import os
+
+
+def RewriteFile(path, search_replace):
+    with open(path) as f:
+        contents = f.read()
+    with open(path, 'w') as f:
+        for search, replace in search_replace:
+            contents = re.sub(search, replace, contents)
+
+        # Cleanup trailing newlines.
+        f.write(contents.strip() + '\n')
+
+
+def UpdateLinuxConfig(path):
+    RewriteFile(
+        path,
+        [
+            # While glibc has canonicalize_file_name(3), other libcs do not,
+            # and we want the source tree not to depend on glibc if we can avoid it,
+            # especially for linux distribution tarballs. Since nasm has fallback
+            # code for not having canonicalize_file_name(3) anyway, just pretend it
+            # doesn't exist.
+            (r'#define HAVE_CANONICALIZE_FILE_NAME 1',
+             r'/* #undef HAVE_CANONICALIZE_FILE_NAME */ // Controlled by the Chromium build process - see generate_nasm_configs.py'
+             )
+        ])
+
+
+def UpdateMacConfig(path):
+    pass
+
+
+def main():
+    UpdateLinuxConfig('config/config-linux.h')
+    UpdateMacConfig('config/config-mac.h')
+
+
+if __name__ == "__main__":
+    main()
diff --git a/generate_nasm_sources.py b/generate_nasm_sources.py
index 341c729..356cb47 100755
--- a/generate_nasm_sources.py
+++ b/generate_nasm_sources.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright 2018 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
@@ -10,63 +10,66 @@
 import sys
 
 def ParseFileLists(path):
-  ret = {}
-  with open(path) as f:
-    in_file_list = False
-    split_line = ""
-    for line in f:
-      line = line.rstrip()
-      if not in_file_list:
-        if "-- Begin File Lists --" in line:
-          in_file_list = True
-        continue
-      if "-- End File Lists --" in line:
-        if split_line:
-          raise ValueError("End comment was preceded by split line")
-        break
-      line = split_line + line
-      split_line = ""
-      if line.endswith('\\'):
-        split_line = line[:-1]
-        continue
-      line = line.strip()
-      if not line:
-        continue
-      name, value = line.split('=')
-      name = name.strip()
-      value = value.replace("$(O)", "c")
-      files = value.split()
-      files.sort()
-      files = [file for file in files]
-      ret[name] = files
-  return ret
+    ret = {}
+    with open(path) as f:
+        in_file_list = False
+        split_line = ""
+        for line in f:
+            line = line.rstrip()
+            if not in_file_list:
+                if "-- Begin File Lists --" in line:
+                    in_file_list = True
+                continue
+            if "-- End File Lists --" in line:
+                if split_line:
+                    raise ValueError("End comment was preceded by split line")
+                break
+            line = split_line + line
+            split_line = ""
+            if line.endswith('\\'):
+                split_line = line[:-1]
+                continue
+            line = line.strip()
+            if not line:
+                continue
+            name, value = line.split('=')
+            name = name.strip()
+            value = value.replace("$(O)", "c")
+            files = value.split()
+            files.sort()
+            files = [file for file in files]
+            ret[name] = files
+    return ret
 
 def PrintFileList(out, name, files):
-  if len(files) == 0:
-    print >>out, "%s = []" % (name,)
-  elif len(files) == 1:
-    print >>out, "%s = [ \"%s\" ]" % (name, files[0])
-  else:
-    print >>out, "%s = [" % (name,)
-    for f in files:
-      print >>out, "  \"%s\"," % (f,)
-    print >>out, "]"
+    if len(files) == 0:
+        print("%s = []" % (name, ), file=out)
+    elif len(files) == 1:
+        print("%s = [ \"%s\" ]" % (name, files[0]), file=out)
+    else:
+        print("%s = [" % (name, ), file=out)
+        for f in files:
+            print("  \"%s\"," % (f, ), file=out)
+        print("]", file=out)
+
 
 def main():
-  file_lists = ParseFileLists("Makefile.in")
-  with open("nasm_sources.gni", "w") as out:
-    print >>out, """# Copyright (c) 2018 The Chromium Authors. All rights reserved.
+    file_lists = ParseFileLists("Makefile.in")
+    with open("nasm_sources.gni", "w") as out:
+        print(
+            """# Copyright (c) 2018 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 # This file is created by generate_nasm_sources.py. Do not edit manually.
-"""
-    # Results in duplicated symbols in nasm.c
-    file_lists['LIBOBJ'].remove('nasmlib/errfile.c')
+""",
+            file=out)
+        # Results in duplicated symbols in nasm.c
+        file_lists['LIBOBJ'].remove('nasmlib/errfile.c')
 
-    PrintFileList(out, "ndisasm_sources", file_lists['NDISASM'])
-    PrintFileList(out, "nasmlib_sources", file_lists['LIBOBJ'])
-    PrintFileList(out, "nasm_sources", file_lists['NASM'])
+        PrintFileList(out, "ndisasm_sources", file_lists['NDISASM'])
+        PrintFileList(out, "nasmlib_sources", file_lists['LIBOBJ'])
+        PrintFileList(out, "nasm_sources", file_lists['NASM'])
 
 if __name__ == "__main__":
-  main()
+    main()