[libc++] Add tests verifying alphabetical order for several things.

These things are header #includes, CMakeLists.txt, and module.modulemap.

Differential Revision: https://reviews.llvm.org/D116958

NOKEYCHECK=True
GitOrigin-RevId: 42185ad870cb750ede2be38cf5ac5326ab9ac424
diff --git a/include/__debug b/include/__debug
index 4e80474..29c51b2 100644
--- a/include/__debug
+++ b/include/__debug
@@ -23,9 +23,9 @@
 #endif
 
 #if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY)
-#   include <cstdlib>
-#   include <cstdio>
 #   include <cstddef>
+#   include <cstdio>
+#   include <cstdlib>
 #endif
 
 #if _LIBCPP_DEBUG_LEVEL == 0
diff --git a/test/libcxx/lint/lint_cmakelists.sh.py b/test/libcxx/lint/lint_cmakelists.sh.py
new file mode 100644
index 0000000..1a94b44
--- /dev/null
+++ b/test/libcxx/lint/lint_cmakelists.sh.py
@@ -0,0 +1,31 @@
+# RUN: %{python} %s
+
+# Verify that libcxx/include/CMakeLists.txt's list of header files
+# is maintained in alphabetical order.
+
+import os
+
+
+if __name__ == '__main__':
+    libcxx_test_libcxx_lint = os.path.dirname(os.path.abspath(__file__))
+    libcxx = os.path.abspath(os.path.join(libcxx_test_libcxx_lint, '../../..'))
+    cmakelists_name = os.path.join(libcxx, 'include/CMakeLists.txt')
+    assert os.path.isfile(cmakelists_name)
+
+    with open(cmakelists_name, 'r') as f:
+        lines = f.readlines()
+
+    assert lines[0] == 'set(files\n'
+
+    okay = True
+    prevline = lines[1]
+    for line in lines[2:]:
+        if (line == '  )\n'):
+            break
+        if (line < prevline):
+            okay = False
+            print('LINES OUT OF ORDER in libcxx/include/CMakeLists.txt!')
+            print(prevline)
+            print(line)
+        prevline = line
+    assert okay
diff --git a/test/libcxx/lint/lint_headers.sh.py b/test/libcxx/lint/lint_headers.sh.py
new file mode 100644
index 0000000..e0c9e8c
--- /dev/null
+++ b/test/libcxx/lint/lint_headers.sh.py
@@ -0,0 +1,52 @@
+# RUN: %{python} %s
+
+# Verify that each run of consecutive #include directives
+# in each libcxx/include/ header is maintained in alphabetical order.
+
+import glob
+import os
+import re
+
+
+def exclude_from_consideration(path):
+    return (
+        path.endswith('.txt') or
+        path.endswith('.modulemap') or
+        os.path.basename(path) == '__config' or
+        os.path.basename(path) == '__locale' or
+        not os.path.isfile(path)
+    )
+
+
+if __name__ == '__main__':
+    libcxx_test_libcxx_lint = os.path.dirname(os.path.abspath(__file__))
+    libcxx_include = os.path.abspath(os.path.join(libcxx_test_libcxx_lint, '../../../include'))
+    assert os.path.isdir(libcxx_include)
+
+    def pretty(path):
+        return path[len(libcxx_include) + 1:]
+
+    all_headers = [
+        p for p in (
+            glob.glob(os.path.join(libcxx_include, '*')) +
+            glob.glob(os.path.join(libcxx_include, '__*/*.h'))
+        ) if not exclude_from_consideration(p)
+    ]
+
+    okay = True
+    for fname in all_headers:
+        with open(fname, 'r') as f:
+            lines = f.readlines()
+        # Examine each consecutive run of #include directives.
+        prevline = None
+        for line in lines:
+            if re.match(r'^\s*#\s*include ', line):
+                if (prevline is not None) and (line < prevline):
+                    okay = False
+                    print('LINES OUT OF ORDER in libcxx/include/%s!' % pretty(fname))
+                    print(prevline)
+                    print(line)
+                prevline = line
+            else:
+                prevline = None
+    assert okay
diff --git a/test/libcxx/lint/lint_modulemap.sh.py b/test/libcxx/lint/lint_modulemap.sh.py
new file mode 100644
index 0000000..870708d
--- /dev/null
+++ b/test/libcxx/lint/lint_modulemap.sh.py
@@ -0,0 +1,29 @@
+# RUN: %{python} %s
+
+# Verify that each list of private submodules in libcxx/include/module.modulemap
+# is maintained in alphabetical order.
+
+import os
+import re
+
+
+if __name__ == '__main__':
+    libcxx_test_libcxx_lint = os.path.dirname(os.path.abspath(__file__))
+    libcxx = os.path.abspath(os.path.join(libcxx_test_libcxx_lint, '../../..'))
+    modulemap_name = os.path.join(libcxx, 'include/module.modulemap')
+    assert os.path.isfile(modulemap_name)
+
+    okay = True
+    prevline = None
+    with open(modulemap_name, 'r') as f:
+        for line in f.readlines():
+            if re.match(r'^\s*module.*[{]\s*private', line):
+                if (prevline is not None) and (line < prevline):
+                    okay = False
+                    print('LINES OUT OF ORDER in libcxx/include/module.modulemap!')
+                    print(prevline)
+                    print(line)
+                prevline = line
+            else:
+                prevline = None
+    assert okay
diff --git a/test/libcxx/lint/lit.local.cfg b/test/libcxx/lint/lit.local.cfg
new file mode 100644
index 0000000..f328db3
--- /dev/null
+++ b/test/libcxx/lint/lit.local.cfg
@@ -0,0 +1,3 @@
+# The tests in this directory need to run Python
+import pipes, sys
+config.substitutions.append(('%{python}', pipes.quote(sys.executable)))